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