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