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, /*weak*/ false, /*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, /*weak*/ false, /*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, /*weak*/ false, /*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, /*weak*/ false, /*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, /*weak*/ false, /*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, /*weak*/ false, /*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, /*weak*/ false, /*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, /*weak*/ false, /*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 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 201 /*acquire*/ false, /*release*/ true, /*weak*/ 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 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 217 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); 218 %} 219 ins_pipe(pipe_slow); 220 %} 221 222 instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 223 predicate(needs_acquiring_load_exclusive(n)); 224 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); 225 ins_cost(VOLATILE_REF_COST); 226 effect(TEMP tmp, KILL cr); 227 format %{ 228 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 229 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 230 %} 231 ins_encode %{ 232 Register tmp = $tmp$$Register; 233 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 234 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 235 /*acquire*/ true, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); 236 %} 237 ins_pipe(pipe_slow); 238 %} 239 240 instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 241 predicate(needs_acquiring_load_exclusive(n)); 242 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 243 ins_cost(VOLATILE_REF_COST); 244 effect(TEMP tmp, KILL cr); 245 format %{ 246 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 247 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" 248 %} 249 ins_encode %{ 250 Register tmp = $tmp$$Register; 251 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 252 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 253 /*acquire*/ true, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); 254 %} 255 ins_pipe(pipe_slow); 256 %}