1 // 2 // Copyright (c) 2018, Red Hat, Inc. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 source_hpp %{ 26 #include "gc/shenandoah/shenandoahBarrierSet.hpp" 27 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" 28 %} 29 30 encode %{ 31 enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{ 32 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 33 Register tmp = $tmp$$Register; 34 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 35 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register, 36 /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register); 37 %} 38 39 enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{ 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, /*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, /*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, /*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, /*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, /*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, /*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, /*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 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop 200 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register, 201 /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register); 202 %} 203 ins_pipe(pipe_slow); 204 %} 205 206 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 207 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 208 ins_cost(2 * VOLATILE_REF_COST); 209 effect(TEMP tmp, KILL cr); 210 format %{ 211 "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 212 %} 213 ins_encode %{ 214 Register tmp = $tmp$$Register; 215 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 216 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop 217 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register, 218 /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register); 219 %} 220 ins_pipe(pipe_slow); 221 %} 222 223 instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, 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, 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 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop 236 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register, 237 /*acquire*/ true, /*release*/ true, /*is_cae*/ false, $res$$Register); 238 %} 239 ins_pipe(pipe_slow); 240 %} 241 242 instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 243 predicate(needs_acquiring_load_exclusive(n)); 244 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 245 ins_cost(VOLATILE_REF_COST); 246 effect(TEMP tmp, KILL cr); 247 format %{ 248 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 249 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 250 %} 251 ins_encode %{ 252 Register tmp = $tmp$$Register; 253 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 254 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop 255 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register, 256 /*acquire*/ true, /*release*/ true, /*is_cae*/ false, $res$$Register); 257 %} 258 ins_pipe(pipe_slow); 259 %} --- EOF ---