1 // 2 // Copyright (c) 2018, Red Hat, Inc. All rights reserved. 3 // 4 // This code is free software; you can redistribute it and/or modify it 5 // under the terms of the GNU General Public License version 2 only, as 6 // published by the Free Software Foundation. 7 // 8 // This code is distributed in the hope that it will be useful, but WITHOUT 9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 // version 2 for more details (a copy is included in the LICENSE file that 12 // accompanied this code). 13 // 14 // You should have received a copy of the GNU General Public License version 15 // 2 along with this work; if not, write to the Free Software Foundation, 16 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 // 18 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 // or visit www.oracle.com if you need additional information or have any 20 // questions. 21 // 22 // 23 24 source_hpp %{ 25 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" 26 %} 27 28 encode %{ 29 enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegPNoSp tmp2, iRegINoSp res) %{ 30 MacroAssembler _masm(&cbuf); 31 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 32 Register tmp = $tmp$$Register; 33 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 34 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 35 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, 36 $tmp2$$Register, $res$$Register); 37 %} 38 39 enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegPNoSp tmp2, iRegINoSp res) %{ 40 MacroAssembler _masm(&cbuf); 41 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 42 Register tmp = $tmp$$Register; 43 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 44 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 45 /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, 46 $tmp2$$Register, $res$$Register); 47 %} 48 %} 49 50 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegPNoSp tmp2, rFlagsReg cr) %{ 51 52 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); 53 ins_cost(2 * VOLATILE_REF_COST); 54 55 effect(TEMP tmp, TEMP tmp2, KILL cr); 56 57 format %{ 58 "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 59 %} 60 61 ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp, tmp2, res)); 62 63 ins_pipe(pipe_slow); 64 %} 65 66 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, iRegNNoSp tmp2, rFlagsReg cr) %{ 67 68 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); 69 ins_cost(2 * VOLATILE_REF_COST); 70 71 effect(TEMP tmp, TEMP tmp2, KILL cr); 72 73 format %{ 74 "cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 75 %} 76 77 ins_encode %{ 78 Register tmp = $tmp$$Register; 79 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 80 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $tmp2$$Register, $res$$Register); 81 %} 82 83 ins_pipe(pipe_slow); 84 %} 85 86 instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegPNoSp tmp2, rFlagsReg cr) %{ 87 88 predicate(needs_acquiring_load_exclusive(n)); 89 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); 90 ins_cost(VOLATILE_REF_COST); 91 92 effect(TEMP tmp, TEMP tmp2, KILL cr); 93 94 format %{ 95 "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 96 %} 97 98 ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp, tmp2, res)); 99 100 ins_pipe(pipe_slow); 101 %} 102 103 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, iRegNNoSp tmp2, rFlagsReg cr) %{ 104 105 predicate(needs_acquiring_load_exclusive(n)); 106 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); 107 ins_cost(VOLATILE_REF_COST); 108 109 effect(TEMP tmp, TEMP tmp2, KILL cr); 110 111 format %{ 112 "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 113 %} 114 115 ins_encode %{ 116 Register tmp = $tmp$$Register; 117 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 118 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $tmp2$$Register, $res$$Register); 119 %} 120 121 ins_pipe(pipe_slow); 122 %} 123 124 instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, iRegNNoSp tmp2, rFlagsReg cr) %{ 125 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); 126 ins_cost(2 * VOLATILE_REF_COST); 127 effect(TEMP_DEF res, TEMP tmp, TEMP tmp2, KILL cr); 128 format %{ 129 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 130 %} 131 ins_encode %{ 132 Register tmp = $tmp$$Register; 133 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 134 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 135 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $tmp2$$Register, $res$$Register); 136 %} 137 ins_pipe(pipe_slow); 138 %} 139 140 instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegPNoSp tmp2, rFlagsReg cr) %{ 141 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); 142 ins_cost(2 * VOLATILE_REF_COST); 143 effect(TEMP_DEF res, TEMP tmp, TEMP tmp2, KILL cr); 144 format %{ 145 "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 146 %} 147 ins_encode %{ 148 Register tmp = $tmp$$Register; 149 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 150 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 151 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $tmp2$$Register, $res$$Register); 152 %} 153 ins_pipe(pipe_slow); 154 %} 155 156 instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, iRegNNoSp tmp2, rFlagsReg cr) %{ 157 predicate(needs_acquiring_load_exclusive(n)); 158 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); 159 ins_cost(VOLATILE_REF_COST); 160 effect(TEMP_DEF res, TEMP tmp, TEMP tmp2, KILL cr); 161 format %{ 162 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 163 %} 164 ins_encode %{ 165 Register tmp = $tmp$$Register; 166 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 167 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 168 /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $tmp2$$Register, $res$$Register); 169 %} 170 ins_pipe(pipe_slow); 171 %} 172 173 instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegPNoSp tmp2, rFlagsReg cr) %{ 174 predicate(needs_acquiring_load_exclusive(n)); 175 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); 176 ins_cost(VOLATILE_REF_COST); 177 effect(TEMP_DEF res, TEMP tmp, TEMP tmp2, KILL cr); 178 format %{ 179 "cmpxchg_acq_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 180 %} 181 ins_encode %{ 182 Register tmp = $tmp$$Register; 183 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 184 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 185 /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $tmp2$$Register, $res$$Register); 186 %} 187 ins_pipe(pipe_slow); 188 %} 189 190 instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, iRegNNoSp tmp2, rFlagsReg cr) %{ 191 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); 192 ins_cost(2 * VOLATILE_REF_COST); 193 effect(TEMP tmp, TEMP tmp2, KILL cr); 194 format %{ 195 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 196 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 197 %} 198 ins_encode %{ 199 Register tmp = $tmp$$Register; 200 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 201 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 202 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $tmp2$$Register, $res$$Register); 203 %} 204 ins_pipe(pipe_slow); 205 %} 206 207 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegPNoSp tmp2, rFlagsReg cr) %{ 208 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 209 ins_cost(2 * VOLATILE_REF_COST); 210 effect(TEMP tmp, TEMP tmp2, KILL cr); 211 format %{ 212 "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 213 %} 214 ins_encode %{ 215 Register tmp = $tmp$$Register; 216 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 217 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 218 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $tmp2$$Register, $res$$Register); 219 %} 220 ins_pipe(pipe_slow); 221 %} 222 223 instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, iRegNNoSp tmp2, rFlagsReg cr) %{ 224 predicate(needs_acquiring_load_exclusive(n)); 225 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); 226 ins_cost(VOLATILE_REF_COST); 227 effect(TEMP tmp, TEMP tmp2, KILL cr); 228 format %{ 229 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 230 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 231 %} 232 ins_encode %{ 233 Register tmp = $tmp$$Register; 234 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 235 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 236 /*acquire*/ true, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $tmp2$$Register, $res$$Register); 237 %} 238 ins_pipe(pipe_slow); 239 %} 240 241 instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegPNoSp tmp2, rFlagsReg cr) %{ 242 predicate(needs_acquiring_load_exclusive(n)); 243 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 244 ins_cost(VOLATILE_REF_COST); 245 effect(TEMP tmp, TEMP tmp2, KILL cr); 246 format %{ 247 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 248 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 249 %} 250 ins_encode %{ 251 Register tmp = $tmp$$Register; 252 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 253 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 254 /*acquire*/ true, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $tmp2$$Register, $res$$Register); 255 %} 256 ins_pipe(pipe_slow); 257 %}