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 MacroAssembler _masm(&cbuf); 33 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 34 Register tmp = $tmp$$Register; 35 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 36 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 37 /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register); 38 %} 39 40 enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{ 41 MacroAssembler _masm(&cbuf); 42 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); 43 Register tmp = $tmp$$Register; 44 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 45 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 46 /*acquire*/ true, /*release*/ true, /*is_cae*/ false, $res$$Register); 47 %} 48 %} 49 50 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 51 52 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); 53 ins_cost(2 * VOLATILE_REF_COST); 54 55 effect(TEMP tmp, 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, res)); 62 63 ins_pipe(pipe_slow); 64 %} 65 66 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 67 68 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); 69 ins_cost(2 * VOLATILE_REF_COST); 70 71 effect(TEMP tmp, 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, /*is_cae*/ false, $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, 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, 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, res)); 99 100 ins_pipe(pipe_slow); 101 %} 102 103 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, 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, 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, /*is_cae*/ false, $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, 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, 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, /*is_cae*/ true, $res$$Register); 136 %} 137 ins_pipe(pipe_slow); 138 %} 139 140 instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, 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, 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, /*is_cae*/ true, $res$$Register); 152 %} 153 ins_pipe(pipe_slow); 154 %} 155 156 instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, 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, 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, /*is_cae*/ true, $res$$Register); 169 %} 170 ins_pipe(pipe_slow); 171 %} 172 173 instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, 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, 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, /*is_cae*/ true, $res$$Register); 186 %} 187 ins_pipe(pipe_slow); 188 %} 189 190 instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 191 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); 192 ins_cost(2 * VOLATILE_REF_COST); 193 effect(TEMP tmp, 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 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop 202 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 203 /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register); 204 %} 205 ins_pipe(pipe_slow); 206 %} 207 208 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 209 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 210 ins_cost(2 * VOLATILE_REF_COST); 211 effect(TEMP tmp, KILL cr); 212 format %{ 213 "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 214 %} 215 ins_encode %{ 216 Register tmp = $tmp$$Register; 217 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 218 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop 219 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 220 /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register); 221 %} 222 ins_pipe(pipe_slow); 223 %} 224 225 instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 226 predicate(needs_acquiring_load_exclusive(n)); 227 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); 228 ins_cost(VOLATILE_REF_COST); 229 effect(TEMP tmp, KILL cr); 230 format %{ 231 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 232 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 233 %} 234 ins_encode %{ 235 Register tmp = $tmp$$Register; 236 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 237 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop 238 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 239 /*acquire*/ true, /*release*/ true, /*is_cae*/ false, $res$$Register); 240 %} 241 ins_pipe(pipe_slow); 242 %} 243 244 instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 245 predicate(needs_acquiring_load_exclusive(n)); 246 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 247 ins_cost(VOLATILE_REF_COST); 248 effect(TEMP tmp, KILL cr); 249 format %{ 250 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 251 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 252 %} 253 ins_encode %{ 254 Register tmp = $tmp$$Register; 255 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 256 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop 257 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 258 /*acquire*/ true, /*release*/ true, /*is_cae*/ false, $res$$Register); 259 %} 260 ins_pipe(pipe_slow); 261 %}