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 24source_hpp %{ 25#include "gc/shenandoah/shenandoahBarrierSet.hpp" 26#include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" 27%} 28 29encode %{ 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 49instruct 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_oop $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 65instruct 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_narrow_oop $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 85instruct 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 102instruct 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 123instruct 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(3 * VOLATILE_REF_COST); 126 effect(TEMP_DEF res, TEMP tmp, KILL cr); 127 format %{ 128 "cmpxchg_oop_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 139instruct 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(3 * VOLATILE_REF_COST); 142 effect(TEMP_DEF res, TEMP tmp, KILL cr); 143 format %{ 144 "cmpxchg_oop_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 155instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ 156 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); 157 ins_cost(3 * VOLATILE_REF_COST); 158 effect(TEMP tmp, KILL cr); 159 format %{ 160 "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" 161 %} 162 ins_encode %{ 163 Register tmp = $tmp$$Register; 164 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 165 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop 166 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 167 /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register); 168 %} 169 ins_pipe(pipe_slow); 170%} 171 172instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 173 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 174 ins_cost(3 * VOLATILE_REF_COST); 175 effect(TEMP tmp, KILL cr); 176 format %{ 177 "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 178 %} 179 ins_encode %{ 180 Register tmp = $tmp$$Register; 181 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 182 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop 183 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 184 /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register); 185 %} 186 ins_pipe(pipe_slow); 187%} 188 189 190