1 // 2 // Copyright (c) 2018, Red Hat, Inc. All rights reserved. 3 // Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. All rights reserved. 4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 // 6 // This code is free software; you can redistribute it and/or modify it 7 // under the terms of the GNU General Public License version 2 only, as 8 // published by the Free Software Foundation. 9 // 10 // This code is distributed in the hope that it will be useful, but WITHOUT 11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 // version 2 for more details (a copy is included in the LICENSE file that 14 // accompanied this code). 15 // 16 // You should have received a copy of the GNU General Public License version 17 // 2 along with this work; if not, write to the Free Software Foundation, 18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 // 20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 // or visit www.oracle.com if you need additional information or have any 22 // questions. 23 // 24 // 25 26 source_hpp %{ 27 #include "gc/shenandoah/shenandoahBarrierSet.hpp" 28 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" 29 %} 30 31 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 32 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); 33 ins_cost(10 * DEFAULT_COST); 34 35 effect(TEMP tmp, KILL cr); 36 37 format %{ 38 "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapP_shenandoah" 39 %} 40 41 ins_encode %{ 42 Register tmp = $tmp$$Register; 43 __ mv(tmp, $oldval$$Register); // Must not clobber oldval. 44 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 45 Assembler::relaxed /* acquire */, Assembler::rl /* release */, 46 false /* is_cae */, $res$$Register); 47 %} 48 49 ins_pipe(pipe_slow); 50 %} 51 52 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 53 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); 54 ins_cost(10 * DEFAULT_COST); 55 56 effect(TEMP tmp, KILL cr); 57 58 format %{ 59 "cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapN_shenandoah" 60 %} 61 62 ins_encode %{ 63 Register tmp = $tmp$$Register; 64 __ mv(tmp, $oldval$$Register); // Must not clobber oldval. 65 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 66 Assembler::relaxed /* acquire */, Assembler::rl /* release */, 67 false /* is_cae */, $res$$Register); 68 %} 69 70 ins_pipe(pipe_slow); 71 %} 72 73 instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 74 predicate(needs_acquiring_load_reserved(n)); 75 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); 76 ins_cost(10 * DEFAULT_COST); 77 78 effect(TEMP tmp, KILL cr); 79 80 format %{ 81 "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapPAcq_shenandoah" 82 %} 83 84 ins_encode %{ 85 Register tmp = $tmp$$Register; 86 __ mv(tmp, $oldval$$Register); // Must not clobber oldval. 87 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 88 Assembler::aq /* acquire */, Assembler::rl /* release */, 89 false /* is_cae */, $res$$Register); 90 %} 91 92 ins_pipe(pipe_slow); 93 %} 94 95 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 96 predicate(needs_acquiring_load_reserved(n)); 97 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); 98 ins_cost(10 * DEFAULT_COST); 99 100 effect(TEMP tmp, KILL cr); 101 102 format %{ 103 "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapNAcq_shenandoah" 104 %} 105 106 ins_encode %{ 107 Register tmp = $tmp$$Register; 108 __ mv(tmp, $oldval$$Register); // Must not clobber oldval. 109 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 110 Assembler::aq /* acquire */, Assembler::rl /* release */, 111 false /* is_cae */, $res$$Register); 112 %} 113 114 ins_pipe(pipe_slow); 115 %} 116 117 instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 118 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); 119 ins_cost(10 * DEFAULT_COST); 120 effect(TEMP_DEF res, TEMP tmp, KILL cr); 121 122 format %{ 123 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeN_shenandoah" 124 %} 125 126 ins_encode %{ 127 Register tmp = $tmp$$Register; 128 __ mv(tmp, $oldval$$Register); // Must not clobber oldval. 129 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 130 Assembler::relaxed /* acquire */, Assembler::rl /* release */, 131 true /* is_cae */, $res$$Register); 132 %} 133 134 ins_pipe(pipe_slow); 135 %} 136 137 instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 138 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); 139 ins_cost(10 * DEFAULT_COST); 140 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, #@compareAndExchangeP_shenandoah" 144 %} 145 146 ins_encode %{ 147 Register tmp = $tmp$$Register; 148 __ mv(tmp, $oldval$$Register); // Must not clobber oldval. 149 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 150 Assembler::relaxed /* acquire */, Assembler::rl /* release */, 151 true /* is_cae */, $res$$Register); 152 %} 153 154 ins_pipe(pipe_slow); 155 %} 156 157 instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 158 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); 159 ins_cost(10 * DEFAULT_COST); 160 161 effect(TEMP tmp, KILL cr); 162 format %{ 163 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapN_shenandoah" 164 "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)" 165 %} 166 167 ins_encode %{ 168 Register tmp = $tmp$$Register; 169 __ mv(tmp, $oldval$$Register); // Must not clobber oldval. 170 // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop 171 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 172 Assembler::relaxed /* acquire */, Assembler::rl /* release */, 173 false /* is_cae */, $res$$Register); 174 %} 175 176 ins_pipe(pipe_slow); 177 %} 178 179 instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 180 predicate(needs_acquiring_load_reserved(n)); 181 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); 182 ins_cost(10 * DEFAULT_COST); 183 184 effect(TEMP_DEF res, TEMP tmp, KILL cr); 185 format %{ 186 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeNAcq_shenandoah" 187 %} 188 189 ins_encode %{ 190 Register tmp = $tmp$$Register; 191 __ mv(tmp, $oldval$$Register); 192 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 193 Assembler::aq /* acquire */, Assembler::rl /* release */, 194 true /* is_cae */, $res$$Register); 195 %} 196 197 ins_pipe(pipe_slow); 198 %} 199 200 instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 201 predicate(needs_acquiring_load_reserved(n)); 202 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); 203 ins_cost(10 * DEFAULT_COST); 204 205 effect(TEMP_DEF res, TEMP tmp, KILL cr); 206 format %{ 207 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangePAcq_shenandoah" 208 %} 209 210 ins_encode %{ 211 Register tmp = $tmp$$Register; 212 __ mv(tmp, $oldval$$Register); 213 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 214 Assembler::aq /* acquire */, Assembler::rl /* release */, 215 true /* is_cae */, $res$$Register); 216 %} 217 218 ins_pipe(pipe_slow); 219 %} 220 221 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 222 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 223 ins_cost(10 * DEFAULT_COST); 224 225 effect(TEMP tmp, KILL cr); 226 format %{ 227 "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapP_shenandoah" 228 %} 229 230 ins_encode %{ 231 Register tmp = $tmp$$Register; 232 __ mv(tmp, $oldval$$Register); // Must not clobber oldval. 233 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 234 Assembler::relaxed /* acquire */, Assembler::rl /* release */, 235 false /* is_cae */, $res$$Register); 236 %} 237 238 ins_pipe(pipe_slow); 239 %} 240 241 instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 242 predicate(needs_acquiring_load_reserved(n)); 243 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); 244 ins_cost(10 * DEFAULT_COST); 245 246 effect(TEMP tmp, KILL cr); 247 format %{ 248 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapNAcq_shenandoah" 249 "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)" 250 %} 251 252 ins_encode %{ 253 Register tmp = $tmp$$Register; 254 __ mv(tmp, $oldval$$Register); // Must not clobber oldval. 255 // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop 256 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 257 Assembler::aq /* acquire */, Assembler::rl /* release */, 258 false /* is_cae */, $res$$Register); 259 %} 260 261 ins_pipe(pipe_slow); 262 %} 263 264 instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 265 predicate(needs_acquiring_load_reserved(n)); 266 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 267 ins_cost(10 * DEFAULT_COST); 268 269 effect(TEMP tmp, KILL cr); 270 format %{ 271 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapPAcq_shenandoah" 272 "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)" 273 %} 274 275 ins_encode %{ 276 Register tmp = $tmp$$Register; 277 __ mv(tmp, $oldval$$Register); // Must not clobber oldval. 278 // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop 279 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 280 Assembler::aq /* acquire */, Assembler::rl /* release */, 281 false /* is_cae */, $res$$Register); 282 %} 283 284 ins_pipe(pipe_slow); 285 %}