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, 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, $res$$Register); 36 %} 37 38 enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{ 39 MacroAssembler _masm(&cbuf); 40 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 41 Register tmp = $tmp$$Register; 42 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 43 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 44 /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); 45 %} 46 %} 47 48 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 49 50 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); 51 ins_cost(2 * VOLATILE_REF_COST); 52 53 effect(TEMP tmp, KILL cr); 54 55 format %{ 56 "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 57 %} 58 59 ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp, res)); 60 61 ins_pipe(pipe_slow); 62 %} 63 64 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 65 66 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); 67 ins_cost(2 * VOLATILE_REF_COST); 68 69 effect(TEMP tmp, KILL cr); 70 71 format %{ 72 "cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 73 %} 74 75 ins_encode %{ 76 Register tmp = $tmp$$Register; 77 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 78 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); 79 %} 80 81 ins_pipe(pipe_slow); 82 %} 83 84 instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 85 86 predicate(needs_acquiring_load_exclusive(n)); 87 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); 88 ins_cost(VOLATILE_REF_COST); 89 90 effect(TEMP tmp, KILL cr); 91 92 format %{ 93 "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 94 %} 95 96 ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp, res)); 97 98 ins_pipe(pipe_slow); 99 %} 100 101 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 102 103 predicate(needs_acquiring_load_exclusive(n)); 104 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); 105 ins_cost(VOLATILE_REF_COST); 106 107 effect(TEMP tmp, KILL cr); 108 109 format %{ 110 "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 111 %} 112 113 ins_encode %{ 114 Register tmp = $tmp$$Register; 115 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 116 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register); 117 %} 118 119 ins_pipe(pipe_slow); 120 %} 121 122 instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 123 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); 124 ins_cost(2 * VOLATILE_REF_COST); 125 effect(TEMP_DEF res, TEMP tmp, KILL cr); 126 format %{ 127 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 128 %} 129 ins_encode %{ 130 Register tmp = $tmp$$Register; 131 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 132 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 133 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register); 134 %} 135 ins_pipe(pipe_slow); 136 %} 137 138 instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 139 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); 140 ins_cost(2 * VOLATILE_REF_COST); 141 effect(TEMP_DEF res, TEMP tmp, KILL cr); 142 format %{ 143 "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 144 %} 145 ins_encode %{ 146 Register tmp = $tmp$$Register; 147 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 148 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 149 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register); 150 %} 151 ins_pipe(pipe_slow); 152 %} 153 154 instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 155 predicate(needs_acquiring_load_exclusive(n)); 156 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); 157 ins_cost(VOLATILE_REF_COST); 158 effect(TEMP_DEF res, TEMP tmp, KILL cr); 159 format %{ 160 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 161 %} 162 ins_encode %{ 163 Register tmp = $tmp$$Register; 164 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 165 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 166 /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register); 167 %} 168 ins_pipe(pipe_slow); 169 %} 170 171 instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 172 predicate(needs_acquiring_load_exclusive(n)); 173 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); 174 ins_cost(VOLATILE_REF_COST); 175 effect(TEMP_DEF res, TEMP tmp, KILL cr); 176 format %{ 177 "cmpxchg_acq_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" 178 %} 179 ins_encode %{ 180 Register tmp = $tmp$$Register; 181 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 182 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 183 /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register); 184 %} 185 ins_pipe(pipe_slow); 186 %} 187 188 instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 189 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); 190 ins_cost(2 * VOLATILE_REF_COST); 191 effect(TEMP tmp, KILL cr); 192 format %{ 193 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 194 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 195 %} 196 ins_encode %{ 197 Register tmp = $tmp$$Register; 198 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 199 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 200 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); 201 %} 202 ins_pipe(pipe_slow); 203 %} 204 205 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 206 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 207 ins_cost(2 * VOLATILE_REF_COST); 208 effect(TEMP tmp, KILL cr); 209 format %{ 210 "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 211 %} 212 ins_encode %{ 213 Register tmp = $tmp$$Register; 214 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 215 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 216 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); 217 %} 218 ins_pipe(pipe_slow); 219 %} 220 221 instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 222 predicate(needs_acquiring_load_exclusive(n)); 223 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); 224 ins_cost(VOLATILE_REF_COST); 225 effect(TEMP tmp, KILL cr); 226 format %{ 227 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 228 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 229 %} 230 ins_encode %{ 231 Register tmp = $tmp$$Register; 232 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 233 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 234 /*acquire*/ true, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); 235 %} 236 ins_pipe(pipe_slow); 237 %} 238 239 instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 240 predicate(needs_acquiring_load_exclusive(n)); 241 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 242 ins_cost(VOLATILE_REF_COST); 243 effect(TEMP tmp, KILL cr); 244 format %{ 245 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 246 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 247 %} 248 ins_encode %{ 249 Register tmp = $tmp$$Register; 250 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 251 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 252 /*acquire*/ true, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); 253 %} 254 ins_pipe(pipe_slow); 255 %}