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/shenandoahBarrierSet.hpp"
27 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
28 %}
29
30 encode %{
31 enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{
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 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, /*is_cae*/ false, $res$$Register);
45 %}
46 %}
47
48 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
49
50 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
51 ins_cost(2 * VOLATILE_REF_COST);
52
53 effect(TEMP tmp, KILL cr);
54
55 format %{
56 "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
57 %}
58
59 ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp, res));
60
61 ins_pipe(pipe_slow);
62 %}
63
64 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
65
66 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
67 ins_cost(2 * VOLATILE_REF_COST);
68
69 effect(TEMP tmp, KILL cr);
70
71 format %{
72 "cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
73 %}
74
75 ins_encode %{
76 Register tmp = $tmp$$Register;
77 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
78 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register);
79 %}
80
81 ins_pipe(pipe_slow);
82 %}
83
84 instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
85
86 predicate(needs_acquiring_load_exclusive(n));
87 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
88 ins_cost(VOLATILE_REF_COST);
89
90 effect(TEMP tmp, KILL cr);
91
92 format %{
93 "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
94 %}
95
96 ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp, res));
97
98 ins_pipe(pipe_slow);
99 %}
100
101 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
102
103 predicate(needs_acquiring_load_exclusive(n));
104 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
105 ins_cost(VOLATILE_REF_COST);
106
107 effect(TEMP tmp, KILL cr);
108
109 format %{
110 "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
111 %}
112
113 ins_encode %{
114 Register tmp = $tmp$$Register;
115 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
116 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*is_cae*/ false, $res$$Register);
117 %}
118
119 ins_pipe(pipe_slow);
120 %}
121
122 instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
123 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval)));
124 ins_cost(2 * VOLATILE_REF_COST);
125 effect(TEMP_DEF res, TEMP tmp, KILL cr);
126 format %{
127 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
128 %}
129 ins_encode %{
130 Register tmp = $tmp$$Register;
131 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
132 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
133 /*acquire*/ false, /*release*/ true, /*is_cae*/ true, $res$$Register);
134 %}
135 ins_pipe(pipe_slow);
136 %}
137
138 instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
139 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval)));
140 ins_cost(2 * VOLATILE_REF_COST);
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"
144 %}
145 ins_encode %{
146 Register tmp = $tmp$$Register;
147 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
148 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
149 /*acquire*/ false, /*release*/ true, /*is_cae*/ true, $res$$Register);
150 %}
151 ins_pipe(pipe_slow);
152 %}
153
154 instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
155 predicate(needs_acquiring_load_exclusive(n));
156 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval)));
157 ins_cost(VOLATILE_REF_COST);
158 effect(TEMP_DEF res, TEMP tmp, KILL cr);
159 format %{
160 "cmpxchgw_acq_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*/ true, /*release*/ true, /*is_cae*/ true, $res$$Register);
167 %}
168 ins_pipe(pipe_slow);
169 %}
170
171 instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
172 predicate(needs_acquiring_load_exclusive(n));
173 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval)));
174 ins_cost(VOLATILE_REF_COST);
175 effect(TEMP_DEF res, TEMP tmp, KILL cr);
176 format %{
177 "cmpxchg_acq_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
178 %}
179 ins_encode %{
180 Register tmp = $tmp$$Register;
181 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
182 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
183 /*acquire*/ true, /*release*/ true, /*is_cae*/ true, $res$$Register);
184 %}
185 ins_pipe(pipe_slow);
186 %}
187
188 instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
189 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval)));
190 ins_cost(2 * VOLATILE_REF_COST);
191 effect(TEMP tmp, KILL cr);
192 format %{
193 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
194 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
195 %}
196 ins_encode %{
197 Register tmp = $tmp$$Register;
198 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
199 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop
200 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
201 /*acquire*/ false, /*release*/ 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 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop
217 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
218 /*acquire*/ false, /*release*/ true, /*is_cae*/ false, $res$$Register);
219 %}
220 ins_pipe(pipe_slow);
221 %}
222
223 instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
224 predicate(needs_acquiring_load_exclusive(n));
225 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval)));
226 ins_cost(VOLATILE_REF_COST);
227 effect(TEMP tmp, KILL cr);
228 format %{
229 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
230 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
231 %}
232 ins_encode %{
233 Register tmp = $tmp$$Register;
234 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
235 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop
236 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
237 /*acquire*/ true, /*release*/ true, /*is_cae*/ false, $res$$Register);
238 %}
239 ins_pipe(pipe_slow);
240 %}
241
242 instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
243 predicate(needs_acquiring_load_exclusive(n));
244 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval)));
245 ins_cost(VOLATILE_REF_COST);
246 effect(TEMP tmp, KILL cr);
247 format %{
248 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
249 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
250 %}
251 ins_encode %{
252 Register tmp = $tmp$$Register;
253 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
254 // Weak is not currently supported by ShenandoahBarrierSet::cmpxchg_oop
255 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
256 /*acquire*/ true, /*release*/ true, /*is_cae*/ false, $res$$Register);
257 %}
258 ins_pipe(pipe_slow);
259 %}
|
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 %{
26 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
27 #include "gc/shenandoah/shenandoahBarrierSetAssembler_aarch64.hpp"
28 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
29 %}
30
31 instruct store_P_Normal_shenandoah(memory8 mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
32 %{
33 match(Set mem (StoreP mem src));
34 predicate(UseShenandoahGC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
35 effect(TEMP tmp, KILL cr);
36 format %{ "str $src, $mem" %}
37 ins_encode %{
38 const Address addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
39 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
40 addr, /* dst_narrow = */ false,
41 $src$$Register, /* src_narrow = */ false,
42 $tmp$$Register, /* is_volatile = */ false);
43 %}
44 ins_cost(3*INSN_COST);
45 ins_pipe(pipe_class_memory);
46 %}
47
48 instruct store_P_Volatile_shenandoah(indirect mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
49 %{
50 match(Set mem (StoreP mem src));
51 predicate(UseShenandoahGC && needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
52 effect(TEMP tmp, KILL cr);
53 format %{ "str $src, $mem" %}
54 ins_encode %{
55 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
56 Address($mem$$Register), /* dst_narrow = */ false,
57 $src$$Register, /* src_narrow = */ false,
58 $tmp$$Register, /* is_volatile = */ true);
59 %}
60 ins_cost(VOLATILE_REF_COST);
61 ins_pipe(pipe_class_memory);
62 %}
63
64 instruct store_N_Normal_shenandoah(memory4 mem, iRegN src, iRegPNoSp tmp, rFlagsReg cr)
65 %{
66 match(Set mem (StoreN mem src));
67 predicate(UseShenandoahGC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
68 effect(TEMP tmp, KILL cr);
69 format %{ "str $src, $mem" %}
70 ins_encode %{
71 const Address addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
72 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
73 addr, /* dst_narrow = */ true,
74 $src$$Register, /* src_narrow = */ true,
75 $tmp$$Register, /* is_volatile = */ false);
76 %}
77 ins_cost(3*INSN_COST);
78 ins_pipe(pipe_class_memory);
79 %}
80
81 instruct store_N_Volatile_shenandoah(indirect mem, iRegN src, iRegPNoSp tmp, rFlagsReg cr)
82 %{
83 match(Set mem (StoreN mem src));
84 predicate(UseShenandoahGC && needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
85 effect(TEMP tmp, KILL cr);
86 format %{ "str $src, $mem" %}
87 ins_encode %{
88 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
89 Address($mem$$Register), /* dst_narrow = */ true,
90 $src$$Register, /* src_narrow = */ true,
91 $tmp$$Register, /* is_volatile = */ true);
92 %}
93 ins_cost(VOLATILE_REF_COST);
94 ins_pipe(pipe_class_memory);
95 %}
96
97 instruct encodePAndStoreN_Normal_shenandoah(memory4 mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
98 %{
99 match(Set mem (StoreN mem (EncodeP src)));
100 predicate(UseShenandoahGC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
101 effect(TEMP tmp, KILL cr);
102 format %{ "encode_heap_oop tmp, $src\n\t"
103 "str tmp, $mem\t# compressed ptr" %}
104 ins_encode %{
105 const Address addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
106 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
107 addr, /* dst_narrow = */ true,
108 $src$$Register, /* src_narrow = */ false,
109 $tmp$$Register, /* is_volatile = */ false);
110 %}
111 ins_cost(4*INSN_COST);
112 ins_pipe(pipe_class_memory);
113 %}
114
115 instruct encodePAndStoreN_Volatile_shenandoah(indirect mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
116 %{
117 match(Set mem (StoreN mem (EncodeP src)));
118 predicate(UseShenandoahGC && needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
119 effect(TEMP tmp, KILL cr);
120 format %{ "encode_heap_oop tmp, $src\n\t"
121 "str tmp, $mem\t# compressed ptr" %}
122 ins_encode %{
123 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
124 Address($mem$$Register), /* dst_narrow = */ true,
125 $src$$Register, /* src_narrow = */ false,
126 $tmp$$Register, /* is_volatile = */ true);
127 %}
128 ins_cost(4*INSN_COST);
129 ins_pipe(pipe_class_memory);
130 %}
131
132 instruct compareAndSwap_P_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr)
133 %{
134 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
135 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
136 effect(TEMP_DEF res, TEMP tmp, KILL cr);
137 format %{
138 "cmpxchg_P_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
139 %}
140 ins_encode %{
141 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
142
143 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
144 $res$$Register,
145 $mem$$base$$Register,
146 $oldval$$Register,
147 $newval$$Register,
148 $tmp$$Register,
149 /* exchange */ false,
150 /* is_narrow */ false,
151 /* weak */ false,
152 /* acquire */ false);
153 %}
154 ins_cost(VOLATILE_REF_COST);
155 ins_pipe(pipe_slow);
156 %}
157
158 instruct compareAndSwap_P_A_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr)
159 %{
160 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
161 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
162 effect(TEMP_DEF res, TEMP tmp, KILL cr);
163 format %{
164 "cmpxchg_P_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
165 %}
166 ins_encode %{
167 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
168
169 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
170 $res$$Register,
171 $mem$$base$$Register,
172 $oldval$$Register,
173 $newval$$Register,
174 $tmp$$Register,
175 /* exchange */ false,
176 /* is_narrow */ false,
177 /* weak */ false,
178 /* acquire */ true);
179 %}
180 ins_cost(VOLATILE_REF_COST);
181 ins_pipe(pipe_slow);
182 %}
183
184 instruct compareAndSwap_N_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp, rFlagsReg cr)
185 %{
186 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
187 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
188 effect(TEMP_DEF res, TEMP tmp, KILL cr);
189 format %{
190 "cmpxchg_N_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
191 %}
192 ins_encode %{
193 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
194
195 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
196 $res$$Register,
197 $mem$$base$$Register,
198 $oldval$$Register,
199 $newval$$Register,
200 $tmp$$Register,
201 /* exchange */ false,
202 /* is_narrow */ true,
203 /* weak */ false,
204 /* acquire */ false);
205 %}
206 ins_cost(VOLATILE_REF_COST);
207 ins_pipe(pipe_slow);
208 %}
209
210 instruct compareAndSwap_N_A_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp, rFlagsReg cr)
211 %{
212 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
213 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
214 effect(TEMP_DEF res, TEMP tmp, KILL cr);
215 format %{
216 "cmpxchg_N_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
217 %}
218 ins_encode %{
219 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
220
221 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
222 $res$$Register,
223 $mem$$base$$Register,
224 $oldval$$Register,
225 $newval$$Register,
226 $tmp$$Register,
227 /* exchange */ false,
228 /* is_narrow */ true,
229 /* weak */ false,
230 /* acquire */ true);
231 %}
232 ins_cost(VOLATILE_REF_COST);
233 ins_pipe(pipe_slow);
234 %}
235
236 instruct compareAndExchange_N_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegPNoSp tmp, rFlagsReg cr)
237 %{
238 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
239 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
240 effect(TEMP_DEF res, TEMP tmp, KILL cr);
241 format %{
242 "cae_N_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
243 %}
244 ins_encode %{
245 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
246
247 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
248 $res$$Register,
249 $mem$$base$$Register,
250 $oldval$$Register,
251 $newval$$Register,
252 $tmp$$Register,
253 /* exchange */ true,
254 /* is_narrow */ true,
255 /* weak */ false,
256 /* acquire */ false);
257 %}
258 ins_cost(2*VOLATILE_REF_COST);
259 ins_pipe(pipe_slow);
260 %}
261
262 instruct compareAndExchange_N_A_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegPNoSp tmp, rFlagsReg cr)
263 %{
264 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
265 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
266 effect(TEMP_DEF res, TEMP tmp, KILL cr);
267 format %{
268 "cae_N_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
269 %}
270 ins_encode %{
271 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
272
273 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
274 $res$$Register,
275 $mem$$base$$Register,
276 $oldval$$Register,
277 $newval$$Register,
278 $tmp$$Register,
279 /* exchange */ true,
280 /* is_narrow */ true,
281 /* weak */ false,
282 /* acquire */ true);
283 %}
284 ins_cost(2*VOLATILE_REF_COST);
285 ins_pipe(pipe_slow);
286 %}
287
288 instruct compareAndExchange_P_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr)
289 %{
290 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
291 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
292 effect(TEMP_DEF res, TEMP tmp, KILL cr);
293 format %{
294 "cae_P_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
295 %}
296 ins_encode %{
297 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
298
299 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
300 $res$$Register,
301 $mem$$base$$Register,
302 $oldval$$Register,
303 $newval$$Register,
304 $tmp$$Register,
305 /* exchange */ true,
306 /* is_narrow */ false,
307 /* weak */ false,
308 /* acquire */ false);
309 %}
310 ins_cost(2*VOLATILE_REF_COST);
311 ins_pipe(pipe_slow);
312 %}
313
314 instruct compareAndExchange_P_A_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr)
315 %{
316 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
317 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
318 effect(TEMP_DEF res, TEMP tmp, KILL cr);
319 format %{
320 "cae_P_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
321 %}
322 ins_encode %{
323 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
324
325 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
326 $res$$Register,
327 $mem$$base$$Register,
328 $oldval$$Register,
329 $newval$$Register,
330 $tmp$$Register,
331 /* exchange */ true,
332 /* is_narrow */ false,
333 /* weak */ false,
334 /* acquire */ true);
335 %}
336 ins_cost(2*VOLATILE_REF_COST);
337 ins_pipe(pipe_slow);
338 %}
339
340 instruct weakCompareAndSwap_N_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp, rFlagsReg cr)
341 %{
342 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
343 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
344 effect(TEMP_DEF res, TEMP tmp, KILL cr);
345 format %{
346 "cae_N_weak_shenandoah $res = $mem, $oldval, $newval\t# (N, weak) if $mem == $oldval then $mem <-- $newval\n\t"
347 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
348 %}
349 ins_encode %{
350 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
351
352 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
353 $res$$Register,
354 $mem$$base$$Register,
355 $oldval$$Register,
356 $newval$$Register,
357 $tmp$$Register,
358 /* exchange */ false,
359 /* is_narrow */ true,
360 /* weak */ true,
361 /* acquire */ false);
362 %}
363 ins_cost(VOLATILE_REF_COST);
364 ins_pipe(pipe_slow);
365 %}
366
367 instruct weakCompareAndSwap_N_A_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp, rFlagsReg cr)
368 %{
369 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
370 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
371 effect(TEMP_DEF res, TEMP tmp, KILL cr);
372 format %{
373 "cae_N_weak_shenandoah $res = $mem, $oldval, $newval\t# (N, weak) if $mem == $oldval then $mem <-- $newval\n\t"
374 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
375 %}
376 ins_encode %{
377 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
378
379 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
380 $res$$Register,
381 $mem$$base$$Register,
382 $oldval$$Register,
383 $newval$$Register,
384 $tmp$$Register,
385 /* exchange */ false,
386 /* is_narrow */ true,
387 /* weak */ true,
388 /* acquire */ true);
389 %}
390 ins_cost(VOLATILE_REF_COST);
391 ins_pipe(pipe_slow);
392 %}
393
394 instruct weakCompareAndSwap_P_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr)
395 %{
396 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
397 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
398 effect(TEMP_DEF res, TEMP tmp, KILL cr);
399 format %{
400 "cae_P_weak_shenandoah $res = $mem, $oldval, $newval\t# (P, weak) if $mem == $oldval then $mem <-- $newval\n\t"
401 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
402 %}
403 ins_encode %{
404 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
405
406 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
407 $res$$Register,
408 $mem$$base$$Register,
409 $oldval$$Register,
410 $newval$$Register,
411 $tmp$$Register,
412 /* exchange */ false,
413 /* is_narrow */ false,
414 /* weak */ true,
415 /* acquire */ false);
416 %}
417 ins_cost(VOLATILE_REF_COST);
418 ins_pipe(pipe_slow);
419 %}
420
421 instruct weakCompareAndSwap_P_A_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr)
422 %{
423 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
424 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
425 effect(TEMP_DEF res, TEMP tmp, KILL cr);
426 format %{
427 "cae_P_weak_shenandoah $res = $mem, $oldval, $newval\t# (P, weak) if $mem == $oldval then $mem <-- $newval\n\t"
428 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
429 %}
430 ins_encode %{
431 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
432
433 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
434 $res$$Register,
435 $mem$$base$$Register,
436 $oldval$$Register,
437 $newval$$Register,
438 $tmp$$Register,
439 /* exchange */ false,
440 /* is_narrow */ false,
441 /* weak */ true,
442 /* acquire */ true);
443 %}
444 ins_cost(VOLATILE_REF_COST);
445 ins_pipe(pipe_slow);
446 %}
447
448 instruct getAndSet_P_shenandoah(indirect mem, iRegP newval, iRegPNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
449 %{
450 match(Set preval (GetAndSetP mem newval));
451 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
452 effect(TEMP_DEF preval, TEMP tmp, KILL cr);
453 format %{ "get_and_set_P $preval, $newval, [$mem]" %}
454 ins_encode %{
455 ShenandoahBarrierSet::assembler()->get_and_set_c2(this, masm,
456 $preval$$Register,
457 $newval$$Register,
458 $mem$$Register,
459 $tmp$$Register,
460 /* acquire */ false);
461 %}
462 ins_cost(2*VOLATILE_REF_COST);
463 ins_pipe(pipe_serial);
464 %}
465
466 instruct getAndSet_P_A_shenandoah(indirect mem, iRegP newval, iRegPNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
467 %{
468 match(Set preval (GetAndSetP mem newval));
469 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
470 effect(TEMP_DEF preval, TEMP tmp, KILL cr);
471 format %{ "get_and_set_P $preval, $newval, [$mem]" %}
472 ins_encode %{
473 ShenandoahBarrierSet::assembler()->get_and_set_c2(this, masm,
474 $preval$$Register,
475 $newval$$Register,
476 $mem$$Register,
477 $tmp$$Register,
478 /* acquire */ true);
479 %}
480 ins_cost(2*VOLATILE_REF_COST);
481 ins_pipe(pipe_serial);
482 %}
483
484 instruct getAndSet_N_shenandoah(indirect mem, iRegN newval, iRegNNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
485 %{
486 match(Set preval (GetAndSetN mem newval));
487 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
488 effect(TEMP_DEF preval, TEMP tmp, KILL cr);
489 format %{ "get_and_set_N $preval, $newval, [$mem]" %}
490 ins_encode %{
491 ShenandoahBarrierSet::assembler()->get_and_set_c2(this, masm,
492 $preval$$Register,
493 $newval$$Register,
494 $mem$$Register,
495 $tmp$$Register,
496 /* acquire */ false);
497 %}
498 ins_cost(2*VOLATILE_REF_COST);
499 ins_pipe(pipe_serial);
500 %}
501
502 instruct getAndSet_N_A_shenandoah(indirect mem, iRegN newval, iRegNNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
503 %{
504 match(Set preval (GetAndSetN mem newval));
505 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
506 effect(TEMP_DEF preval, TEMP tmp, KILL cr);
507 format %{ "get_and_set_N $preval, $newval, [$mem]" %}
508 ins_encode %{
509 ShenandoahBarrierSet::assembler()->get_and_set_c2(this, masm,
510 $preval$$Register,
511 $newval$$Register,
512 $mem$$Register,
513 $tmp$$Register,
514 /* acquire */ true);
515 %}
516 ins_cost(2*VOLATILE_REF_COST);
517 ins_pipe(pipe_serial);
518 %}
519
520 instruct load_P_Normal_shenandoah(iRegPNoSp dst, memory8 mem, iRegPNoSp tmp, rFlagsReg cr)
521 %{
522 match(Set dst (LoadP mem));
523 predicate(UseShenandoahGC && !needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
524 effect(TEMP_DEF dst, TEMP tmp, KILL cr);
525 // The main load is a candidate to implement implicit null checks.
526 ins_is_late_expanded_null_check_candidate(true);
527 format %{ "ldr $dst, $mem\t# ptr" %}
528 ins_encode %{
529 Address addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
530 if (addr.getMode() == Address::base_plus_offset) {
531 addr = __ legitimize_address(addr, /* size_in_memory */ 8, $tmp$$Register);
532 }
533 ShenandoahBarrierSet::assembler()->load_c2(this, masm, $dst$$Register, addr, /* is_narrow */ false, /* is_acquire */ false);
534 %}
535 ins_cost(3*INSN_COST);
536 ins_pipe(pipe_class_memory);
537 %}
538
539 instruct load_P_Volatile_shenandoah(iRegPNoSp dst, indirect mem, rFlagsReg cr)
540 %{
541 match(Set dst (LoadP mem));
542 predicate(UseShenandoahGC && needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
543 effect(TEMP_DEF dst, KILL cr);
544 // The main load is a candidate to implement implicit null checks.
545 ins_is_late_expanded_null_check_candidate(true);
546 format %{ "ldr $dst, $mem\t# ptr" %}
547 ins_encode %{
548 ShenandoahBarrierSet::assembler()->load_c2(this, masm, $dst$$Register, Address($mem$$Register), /* is_narrow */ false, /* is_acquire */ true);
549 %}
550 ins_cost(3*INSN_COST);
551 ins_pipe(pipe_class_memory);
552 %}
553
554 instruct load_N_Normal_shenandoah(iRegNNoSp dst, memory4 mem, iRegPNoSp tmp, rFlagsReg cr)
555 %{
556 match(Set dst (LoadN mem));
557 predicate(UseShenandoahGC && !needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
558 effect(TEMP_DEF dst, TEMP tmp, KILL cr);
559 // The main load is a candidate to implement implicit null checks.
560 ins_is_late_expanded_null_check_candidate(true);
561 format %{ "ldrw $dst, $mem\t# ptr" %}
562 ins_encode %{
563 Address addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
564 if (addr.getMode() == Address::base_plus_offset) {
565 addr = __ legitimize_address(addr, /* size_in_memory */ 4, $tmp$$Register);
566 }
567 ShenandoahBarrierSet::assembler()->load_c2(this, masm, $dst$$Register, addr, /* is_narrow */ true, /* is_acquire */ false);
568 %}
569 ins_cost(3*INSN_COST);
570 ins_pipe(pipe_class_memory);
571 %}
572
573 instruct load_N_Volatile_shenandoah(iRegNNoSp dst, indirect mem, rFlagsReg cr)
574 %{
575 match(Set dst (LoadN mem));
576 predicate(UseShenandoahGC && needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
577 effect(TEMP_DEF dst, KILL cr);
578 // The main load is a candidate to implement implicit null checks.
579 ins_is_late_expanded_null_check_candidate(true);
580 format %{ "ldrw $dst, $mem\t# ptr" %}
581 ins_encode %{
582 ShenandoahBarrierSet::assembler()->load_c2(this, masm, $dst$$Register, Address($mem$$Register), /* is_narrow */ true, /* is_acquire */ true);
583 %}
584 ins_cost(VOLATILE_REF_COST);
585 ins_pipe(pipe_class_memory);
586 %}
587
|