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/shenandoahBarrierSet.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_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 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_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, /*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(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, /*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(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, /*weak*/ false, /*is_cae*/ true, $res$$Register); 151 %} 152 ins_pipe(pipe_slow); 153 %} 154 155 instruct 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 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 166 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); 167 %} 168 ins_pipe(pipe_slow); 169 %} 170 171 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ 172 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); 173 ins_cost(3 * VOLATILE_REF_COST); 174 effect(TEMP tmp, KILL cr); 175 format %{ 176 "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" 177 %} 178 ins_encode %{ 179 Register tmp = $tmp$$Register; 180 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. 181 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, 182 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register); 183 %} 184 ins_pipe(pipe_slow); 185 %} 186 187