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
32 // BEGIN This section of the file is automatically generated from shenandoah_aarch64.m4.
33
34
35
36 // This pattern is generated automatically from shenandoah_aarch64.m4.
37 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
38 instruct store_P_Normal_shenandoah(indirect mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
39 %{
40 match(Set mem (StoreP mem src));
41 predicate(UseShenandoahGC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
42 effect(TEMP tmp, KILL cr);
43 ins_cost(3*INSN_COST);
44 format %{ "str $src, $mem" %}
45 ins_encode %{
46 bool is_narrow = false;
47 bool is_volatile = false;
48
49 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
50 $mem$$Register, /* dst_narrow = */ is_narrow,
51 $src$$Register, /* src_narrow = */ is_narrow,
52 $tmp$$Register, /* pre_val = */ noreg,
53 /* is_volatile = */ is_volatile);
54 %}
55 ins_pipe(pipe_class_memory);
56 %}
57
58 // This pattern is generated automatically from shenandoah_aarch64.m4.
59 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
60 instruct store_P_Volatile_shenandoah(indirect mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
61 %{
62 match(Set mem (StoreP mem src));
63 predicate(UseShenandoahGC && needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
64 effect(TEMP tmp, KILL cr);
65 ins_cost(VOLATILE_REF_COST);
66 format %{ "str $src, $mem" %}
67 ins_encode %{
68 bool is_narrow = false;
69 bool is_volatile = true;
70
71 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
72 $mem$$Register, /* dst_narrow = */ is_narrow,
73 $src$$Register, /* src_narrow = */ is_narrow,
74 $tmp$$Register, /* pre_val = */ noreg,
75 /* is_volatile = */ is_volatile);
76 %}
77 ins_pipe(pipe_class_memory);
78 %}
79
80 // This pattern is generated automatically from shenandoah_aarch64.m4.
81 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
82 instruct store_N_Normal_shenandoah(indirect mem, iRegN src, iRegPNoSp tmp, rFlagsReg cr)
83 %{
84 match(Set mem (StoreN mem src));
85 predicate(UseShenandoahGC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
86 effect(TEMP tmp, KILL cr);
87 ins_cost(3*INSN_COST);
88 format %{ "str $src, $mem" %}
89 ins_encode %{
90 bool is_narrow = true;
91 bool is_volatile = false;
92
93 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
94 $mem$$Register, /* dst_narrow = */ is_narrow,
95 $src$$Register, /* src_narrow = */ is_narrow,
96 $tmp$$Register, /* pre_val = */ noreg,
97 /* is_volatile = */ is_volatile);
98 %}
99 ins_pipe(pipe_class_memory);
100 %}
101
102 // This pattern is generated automatically from shenandoah_aarch64.m4.
103 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
104 instruct store_N_Volatile_shenandoah(indirect mem, iRegN src, iRegPNoSp tmp, rFlagsReg cr)
105 %{
106 match(Set mem (StoreN mem src));
107 predicate(UseShenandoahGC && needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
108 effect(TEMP tmp, KILL cr);
109 ins_cost(VOLATILE_REF_COST);
110 format %{ "str $src, $mem" %}
111 ins_encode %{
112 bool is_narrow = true;
113 bool is_volatile = true;
114
115 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
116 $mem$$Register, /* dst_narrow = */ is_narrow,
117 $src$$Register, /* src_narrow = */ is_narrow,
118 $tmp$$Register, /* pre_val = */ noreg,
119 /* is_volatile = */ is_volatile);
120 %}
121 ins_pipe(pipe_class_memory);
122 %}
123
124
125
126
127
128
129
130
131
132
133 // This pattern is generated automatically from shenandoah_aarch64.m4.
134 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
135 instruct encodePAndStoreN_Normal_shenandoah(indirect mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
136 %{
137 match(Set mem (StoreN mem (EncodeP src)));
138 predicate(UseShenandoahGC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
139 effect(TEMP tmp, KILL cr);
140 ins_cost(4*INSN_COST);
141 format %{ "encode_heap_oop $tmp, $src\n\t"
142 "str $tmp, $mem\t# compressed ptr" %}
143 ins_encode %{
144 bool is_volatile = false;
145
146 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
147 $mem$$Register, /* dst_narrow = */ true,
148 $src$$Register, /* src_narrow = */ false,
149 $tmp$$Register, /* pre_val = */ noreg,
150 /* is_volatile = */ is_volatile);
151 %}
152 ins_pipe(pipe_class_memory);
153 %}
154
155 // This pattern is generated automatically from shenandoah_aarch64.m4.
156 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
157 instruct encodePAndStoreN_Volatile_shenandoah(indirect mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
158 %{
159 match(Set mem (StoreN mem (EncodeP src)));
160 predicate(UseShenandoahGC && needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
161 effect(TEMP tmp, KILL cr);
162 ins_cost(VOLATILE_REF_COST);
163 format %{ "encode_heap_oop $tmp, $src\n\t"
164 "str $tmp, $mem\t# compressed ptr" %}
165 ins_encode %{
166 bool is_volatile = true;
167
168 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
169 $mem$$Register, /* dst_narrow = */ true,
170 $src$$Register, /* src_narrow = */ false,
171 $tmp$$Register, /* pre_val = */ noreg,
172 /* is_volatile = */ is_volatile);
173 %}
174 ins_pipe(pipe_class_memory);
175 %}
176
177
178
179
180
181
182
183
184
185
186 // This pattern is generated automatically from shenandoah_aarch64.m4.
187 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
188 instruct compareAndSwap_P_Normal_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
189 %{
190 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
191 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
192 ins_cost(VOLATILE_REF_COST);
193 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
194 format %{
195 "cmpxchg_P_Normal_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
196 %}
197 ins_encode %{
198 assert_different_registers($tmp1$$Register, $tmp2$$Register);
199 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
200
201 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
202 __ ldrb($tmp1$$Register, gcs_addr);
203
204 bool is_narrow = false;
205 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
206 noreg /* addr */,
207 $oldval$$Register /* pre_val, only used in slow path */,
208 $tmp1$$Register /* gc_state */,
209 is_narrow /* encoded_preval */);
210
211 bool is_acquire = false;
212 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
213 $mem$$base$$Register,
214 $oldval$$Register,
215 $newval$$Register,
216 $res$$Register,
217 $tmp1$$Register, /* gc_state */
218 $tmp2$$Register,
219 /*acquire*/ is_acquire,
220 /*release*/ true,
221 /*weak*/ false,
222 /*is_cae*/ false);
223
224 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
225 $mem$$Register /* addr */,
226 $tmp1$$Register /* tmp */);
227 %}
228
229 ins_pipe(pipe_slow);
230 %}
231
232 // This pattern is generated automatically from shenandoah_aarch64.m4.
233 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
234 instruct compareAndSwap_N_Normal_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
235 %{
236 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
237 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
238 ins_cost(VOLATILE_REF_COST);
239 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
240 format %{
241 "cmpxchg_N_Normal_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
242 %}
243 ins_encode %{
244 assert_different_registers($tmp1$$Register, $tmp2$$Register);
245 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
246
247 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
248 __ ldrb($tmp1$$Register, gcs_addr);
249
250 bool is_narrow = true;
251 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
252 noreg /* addr */,
253 $oldval$$Register /* pre_val, only used in slow path */,
254 $tmp1$$Register /* gc_state */,
255 is_narrow /* encoded_preval */);
256
257 bool is_acquire = false;
258 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
259 $mem$$base$$Register,
260 $oldval$$Register,
261 $newval$$Register,
262 $res$$Register,
263 $tmp1$$Register, /* gc_state */
264 $tmp2$$Register,
265 /*acquire*/ is_acquire,
266 /*release*/ true,
267 /*weak*/ false,
268 /*is_cae*/ false);
269
270 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
271 $mem$$Register /* addr */,
272 $tmp1$$Register /* tmp */);
273 %}
274
275 ins_pipe(pipe_slow);
276 %}
277
278 // This pattern is generated automatically from shenandoah_aarch64.m4.
279 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
280 instruct compareAndSwap_P_Volatile_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
281 %{
282 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
283 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
284 ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
285 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
286 format %{
287 "cmpxchg_P_Volatile_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
288 %}
289 ins_encode %{
290 assert_different_registers($tmp1$$Register, $tmp2$$Register);
291 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
292
293 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
294 __ ldrb($tmp1$$Register, gcs_addr);
295
296 bool is_narrow = false;
297 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
298 noreg /* addr */,
299 $oldval$$Register /* pre_val, only used in slow path */,
300 $tmp1$$Register /* gc_state */,
301 is_narrow /* encoded_preval */);
302
303 bool is_acquire = true;
304 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
305 $mem$$base$$Register,
306 $oldval$$Register,
307 $newval$$Register,
308 $res$$Register,
309 $tmp1$$Register, /* gc_state */
310 $tmp2$$Register,
311 /*acquire*/ is_acquire,
312 /*release*/ true,
313 /*weak*/ false,
314 /*is_cae*/ false);
315
316 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
317 $mem$$Register /* addr */,
318 $tmp1$$Register /* tmp */);
319 %}
320
321 ins_pipe(pipe_slow);
322 %}
323
324 // This pattern is generated automatically from shenandoah_aarch64.m4.
325 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
326 instruct compareAndSwap_N_Volatile_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
327 %{
328 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
329 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
330 ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
331 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
332 format %{
333 "cmpxchg_N_Volatile_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
334 %}
335 ins_encode %{
336 assert_different_registers($tmp1$$Register, $tmp2$$Register);
337 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
338
339 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
340 __ ldrb($tmp1$$Register, gcs_addr);
341
342 bool is_narrow = true;
343 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
344 noreg /* addr */,
345 $oldval$$Register /* pre_val, only used in slow path */,
346 $tmp1$$Register /* gc_state */,
347 is_narrow /* encoded_preval */);
348
349 bool is_acquire = true;
350 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
351 $mem$$base$$Register,
352 $oldval$$Register,
353 $newval$$Register,
354 $res$$Register,
355 $tmp1$$Register, /* gc_state */
356 $tmp2$$Register,
357 /*acquire*/ is_acquire,
358 /*release*/ true,
359 /*weak*/ false,
360 /*is_cae*/ false);
361
362 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
363 $mem$$Register /* addr */,
364 $tmp1$$Register /* tmp */);
365 %}
366
367 ins_pipe(pipe_slow);
368 %}
369
370
371
372
373
374
375 // This pattern is generated automatically from shenandoah_aarch64.m4.
376 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
377 instruct compareAndExchange_N_Normal_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
378 %{
379 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
380 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
381 ins_cost(2*VOLATILE_REF_COST);
382 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
383 format %{
384 "cmpxchg_N_Normal_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
385 %}
386 ins_encode %{
387 assert_different_registers($tmp1$$Register, $tmp2$$Register);
388 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
389
390 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
391 __ ldrb($tmp1$$Register, gcs_addr);
392
393 bool is_narrow = true;
394 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
395 noreg /* addr */,
396 $oldval$$Register /* pre_val */,
397 $tmp1$$Register /* gc_state */,
398 is_narrow /* encoded_preval */);
399
400 bool is_acquire = false;
401 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
402 $mem$$base$$Register,
403 $oldval$$Register,
404 $newval$$Register,
405 $res$$Register,
406 $tmp1$$Register, /* gc_state */
407 $tmp2$$Register,
408 /*acquire*/ is_acquire,
409 /*release*/ true,
410 /*weak*/ false,
411 /*is_cae*/ true);
412
413 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
414 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
415 $res$$Register /* obj */,
416 $mem$$Register /* addr */,
417 is_narrow /* narrow */,
418 maybe_null,
419 $tmp1$$Register /* gc_state */);
420
421 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
422 $mem$$Register /* addr */,
423 $tmp1$$Register /* tmp */);
424 %}
425 ins_pipe(pipe_slow);
426 %}
427
428 // This pattern is generated automatically from shenandoah_aarch64.m4.
429 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
430 instruct compareAndExchange_P_Normal_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
431 %{
432 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
433 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
434 ins_cost(2*VOLATILE_REF_COST);
435 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
436 format %{
437 "cmpxchg_P_Normal_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
438 %}
439 ins_encode %{
440 assert_different_registers($tmp1$$Register, $tmp2$$Register);
441 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
442
443 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
444 __ ldrb($tmp1$$Register, gcs_addr);
445
446 bool is_narrow = false;
447 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
448 noreg /* addr */,
449 $oldval$$Register /* pre_val */,
450 $tmp1$$Register /* gc_state */,
451 is_narrow /* encoded_preval */);
452
453 bool is_acquire = false;
454 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
455 $mem$$base$$Register,
456 $oldval$$Register,
457 $newval$$Register,
458 $res$$Register,
459 $tmp1$$Register, /* gc_state */
460 $tmp2$$Register,
461 /*acquire*/ is_acquire,
462 /*release*/ true,
463 /*weak*/ false,
464 /*is_cae*/ true);
465
466 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
467 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
468 $res$$Register /* obj */,
469 $mem$$Register /* addr */,
470 is_narrow /* narrow */,
471 maybe_null,
472 $tmp1$$Register /* gc_state */);
473
474 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
475 $mem$$Register /* addr */,
476 $tmp1$$Register /* tmp */);
477 %}
478 ins_pipe(pipe_slow);
479 %}
480
481 // This pattern is generated automatically from shenandoah_aarch64.m4.
482 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
483 instruct compareAndExchange_N_Volatile_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
484 %{
485 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
486 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
487 ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
488 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
489 format %{
490 "cmpxchg_N_Volatile_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
491 %}
492 ins_encode %{
493 assert_different_registers($tmp1$$Register, $tmp2$$Register);
494 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
495
496 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
497 __ ldrb($tmp1$$Register, gcs_addr);
498
499 bool is_narrow = true;
500 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
501 noreg /* addr */,
502 $oldval$$Register /* pre_val */,
503 $tmp1$$Register /* gc_state */,
504 is_narrow /* encoded_preval */);
505
506 bool is_acquire = true;
507 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
508 $mem$$base$$Register,
509 $oldval$$Register,
510 $newval$$Register,
511 $res$$Register,
512 $tmp1$$Register, /* gc_state */
513 $tmp2$$Register,
514 /*acquire*/ is_acquire,
515 /*release*/ true,
516 /*weak*/ false,
517 /*is_cae*/ true);
518
519 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
520 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
521 $res$$Register /* obj */,
522 $mem$$Register /* addr */,
523 is_narrow /* narrow */,
524 maybe_null,
525 $tmp1$$Register /* gc_state */);
526
527 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
528 $mem$$Register /* addr */,
529 $tmp1$$Register /* tmp */);
530 %}
531 ins_pipe(pipe_slow);
532 %}
533
534 // This pattern is generated automatically from shenandoah_aarch64.m4.
535 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
536 instruct compareAndExchange_P_Volatile_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
537 %{
538 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
539 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
540 ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
541 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
542 format %{
543 "cmpxchg_P_Volatile_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
544 %}
545 ins_encode %{
546 assert_different_registers($tmp1$$Register, $tmp2$$Register);
547 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
548
549 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
550 __ ldrb($tmp1$$Register, gcs_addr);
551
552 bool is_narrow = false;
553 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
554 noreg /* addr */,
555 $oldval$$Register /* pre_val */,
556 $tmp1$$Register /* gc_state */,
557 is_narrow /* encoded_preval */);
558
559 bool is_acquire = true;
560 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
561 $mem$$base$$Register,
562 $oldval$$Register,
563 $newval$$Register,
564 $res$$Register,
565 $tmp1$$Register, /* gc_state */
566 $tmp2$$Register,
567 /*acquire*/ is_acquire,
568 /*release*/ true,
569 /*weak*/ false,
570 /*is_cae*/ true);
571
572 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
573 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
574 $res$$Register /* obj */,
575 $mem$$Register /* addr */,
576 is_narrow /* narrow */,
577 maybe_null,
578 $tmp1$$Register /* gc_state */);
579
580 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
581 $mem$$Register /* addr */,
582 $tmp1$$Register /* tmp */);
583 %}
584 ins_pipe(pipe_slow);
585 %}
586
587
588
589
590
591
592
593
594 // This pattern is generated automatically from shenandoah_aarch64.m4.
595 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
596 instruct weakCompareAndSwap_N_Normal_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
597 %{
598 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
599 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
600 ins_cost(VOLATILE_REF_COST);
601 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
602 format %{
603 "cmpxchg_oop_c2 $res = $mem, $oldval, $newval\t# (N, weak, Normal) if $mem == $oldval then $mem <-- $newval\n\t"
604 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
605 %}
606 ins_encode %{
607 assert_different_registers($tmp1$$Register, $tmp2$$Register);
608 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
609
610 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
611 __ ldrb($tmp1$$Register, gcs_addr);
612
613 bool is_narrow = true;
614 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
615 noreg /* addr */,
616 $oldval$$Register /* pre_val */,
617 $tmp1$$Register /* gc_state */,
618 is_narrow /* encoded_preval */);
619
620 bool is_acquire = false;
621 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
622 $mem$$base$$Register,
623 $oldval$$Register,
624 $newval$$Register,
625 $res$$Register,
626 $tmp1$$Register,
627 $tmp2$$Register,
628 /*acquire*/ is_acquire,
629 /*release*/ true,
630 /*weak*/ true,
631 /*is_cae*/ false);
632
633 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
634 $mem$$Register /* addr */,
635 $tmp1$$Register /* tmp */);
636 %}
637 ins_pipe(pipe_slow);
638 %}
639
640 // This pattern is generated automatically from shenandoah_aarch64.m4.
641 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
642 instruct weakCompareAndSwap_P_Normal_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
643 %{
644 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
645 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
646 ins_cost(VOLATILE_REF_COST);
647 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
648 format %{
649 "cmpxchg_oop_c2 $res = $mem, $oldval, $newval\t# (P, weak, Normal) if $mem == $oldval then $mem <-- $newval\n\t"
650 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
651 %}
652 ins_encode %{
653 assert_different_registers($tmp1$$Register, $tmp2$$Register);
654 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
655
656 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
657 __ ldrb($tmp1$$Register, gcs_addr);
658
659 bool is_narrow = false;
660 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
661 noreg /* addr */,
662 $oldval$$Register /* pre_val */,
663 $tmp1$$Register /* gc_state */,
664 is_narrow /* encoded_preval */);
665
666 bool is_acquire = false;
667 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
668 $mem$$base$$Register,
669 $oldval$$Register,
670 $newval$$Register,
671 $res$$Register,
672 $tmp1$$Register,
673 $tmp2$$Register,
674 /*acquire*/ is_acquire,
675 /*release*/ true,
676 /*weak*/ true,
677 /*is_cae*/ false);
678
679 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
680 $mem$$Register /* addr */,
681 $tmp1$$Register /* tmp */);
682 %}
683 ins_pipe(pipe_slow);
684 %}
685
686 // This pattern is generated automatically from shenandoah_aarch64.m4.
687 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
688 instruct weakCompareAndSwap_N_Volatile_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
689 %{
690 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
691 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
692 ins_cost(VOLATILE_REF_COST);
693 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
694 format %{
695 "cmpxchg_oop_c2 $res = $mem, $oldval, $newval\t# (N, weak, Volatile) if $mem == $oldval then $mem <-- $newval\n\t"
696 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
697 %}
698 ins_encode %{
699 assert_different_registers($tmp1$$Register, $tmp2$$Register);
700 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
701
702 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
703 __ ldrb($tmp1$$Register, gcs_addr);
704
705 bool is_narrow = true;
706 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
707 noreg /* addr */,
708 $oldval$$Register /* pre_val */,
709 $tmp1$$Register /* gc_state */,
710 is_narrow /* encoded_preval */);
711
712 bool is_acquire = true;
713 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
714 $mem$$base$$Register,
715 $oldval$$Register,
716 $newval$$Register,
717 $res$$Register,
718 $tmp1$$Register,
719 $tmp2$$Register,
720 /*acquire*/ is_acquire,
721 /*release*/ true,
722 /*weak*/ true,
723 /*is_cae*/ false);
724
725 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
726 $mem$$Register /* addr */,
727 $tmp1$$Register /* tmp */);
728 %}
729 ins_pipe(pipe_slow);
730 %}
731
732 // This pattern is generated automatically from shenandoah_aarch64.m4.
733 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
734 instruct weakCompareAndSwap_P_Volatile_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
735 %{
736 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
737 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
738 ins_cost(VOLATILE_REF_COST);
739 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
740 format %{
741 "cmpxchg_oop_c2 $res = $mem, $oldval, $newval\t# (P, weak, Volatile) if $mem == $oldval then $mem <-- $newval\n\t"
742 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
743 %}
744 ins_encode %{
745 assert_different_registers($tmp1$$Register, $tmp2$$Register);
746 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
747
748 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
749 __ ldrb($tmp1$$Register, gcs_addr);
750
751 bool is_narrow = false;
752 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
753 noreg /* addr */,
754 $oldval$$Register /* pre_val */,
755 $tmp1$$Register /* gc_state */,
756 is_narrow /* encoded_preval */);
757
758 bool is_acquire = true;
759 ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
760 $mem$$base$$Register,
761 $oldval$$Register,
762 $newval$$Register,
763 $res$$Register,
764 $tmp1$$Register,
765 $tmp2$$Register,
766 /*acquire*/ is_acquire,
767 /*release*/ true,
768 /*weak*/ true,
769 /*is_cae*/ false);
770
771 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
772 $mem$$Register /* addr */,
773 $tmp1$$Register /* tmp */);
774 %}
775 ins_pipe(pipe_slow);
776 %}
777
778
779
780 // This pattern is generated automatically from shenandoah_aarch64.m4.
781 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
782 instruct getAndSet_P_Normal_shenandoah(indirect mem, iRegP newval, iRegPNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
783 %{
784 match(Set preval (GetAndSetP mem newval));
785 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
786 effect(TEMP_DEF preval, TEMP tmp, KILL cr);
787 ins_cost(2*VOLATILE_REF_COST);
788 format %{ "atomic_xchg $preval, $newval, [$mem]" %}
789 ins_encode %{
790 __ atomic_xchg($preval$$Register, $newval$$Register, $mem$$Register);
791
792 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
793 __ ldrb($tmp$$Register, gcs_addr);
794
795 bool is_narrow = false;
796 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
797 noreg /* addr */,
798 $preval$$Register /* pre_val */,
799 $tmp$$Register /* gc_state */,
800 is_narrow /* encoded_preval */);
801
802 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
803 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
804 $preval$$Register /* obj */,
805 $mem$$Register /* addr */,
806 is_narrow /* narrow */,
807 maybe_null,
808 $tmp$$Register /* gc_state */);
809
810 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
811 $mem$$Register /* addr */,
812 $tmp$$Register /* tmp */);
813 %}
814 ins_pipe(pipe_serial);
815 %}
816
817 // This pattern is generated automatically from shenandoah_aarch64.m4.
818 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
819 instruct getAndSet_P_Volatile_shenandoah(indirect mem, iRegP newval, iRegPNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
820 %{
821 match(Set preval (GetAndSetP mem newval));
822 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
823 effect(TEMP_DEF preval, TEMP tmp, KILL cr);
824 ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
825 format %{ "atomic_xchgal $preval, $newval, [$mem]" %}
826 ins_encode %{
827 __ atomic_xchgal($preval$$Register, $newval$$Register, $mem$$Register);
828
829 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
830 __ ldrb($tmp$$Register, gcs_addr);
831
832 bool is_narrow = false;
833 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
834 noreg /* addr */,
835 $preval$$Register /* pre_val */,
836 $tmp$$Register /* gc_state */,
837 is_narrow /* encoded_preval */);
838
839 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
840 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
841 $preval$$Register /* obj */,
842 $mem$$Register /* addr */,
843 is_narrow /* narrow */,
844 maybe_null,
845 $tmp$$Register /* gc_state */);
846
847 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
848 $mem$$Register /* addr */,
849 $tmp$$Register /* tmp */);
850 %}
851 ins_pipe(pipe_serial);
852 %}
853
854 // This pattern is generated automatically from shenandoah_aarch64.m4.
855 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
856 instruct getAndSet_N_Normal_shenandoah(indirect mem, iRegN newval, iRegNNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
857 %{
858 match(Set preval (GetAndSetN mem newval));
859 predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
860 effect(TEMP_DEF preval, TEMP tmp, KILL cr);
861 ins_cost(2*VOLATILE_REF_COST);
862 format %{ "atomic_xchgw $preval, $newval, [$mem]" %}
863 ins_encode %{
864 __ atomic_xchgw($preval$$Register, $newval$$Register, $mem$$Register);
865
866 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
867 __ ldrb($tmp$$Register, gcs_addr);
868
869 bool is_narrow = true;
870 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
871 noreg /* addr */,
872 $preval$$Register /* pre_val */,
873 $tmp$$Register /* gc_state */,
874 is_narrow /* encoded_preval */);
875
876 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
877 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
878 $preval$$Register /* obj */,
879 $mem$$Register /* addr */,
880 is_narrow /* narrow */,
881 maybe_null,
882 $tmp$$Register /* gc_state */);
883
884 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
885 $mem$$Register /* addr */,
886 $tmp$$Register /* tmp */);
887 %}
888 ins_pipe(pipe_serial);
889 %}
890
891 // This pattern is generated automatically from shenandoah_aarch64.m4.
892 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
893 instruct getAndSet_N_Volatile_shenandoah(indirect mem, iRegN newval, iRegNNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
894 %{
895 match(Set preval (GetAndSetN mem newval));
896 predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
897 effect(TEMP_DEF preval, TEMP tmp, KILL cr);
898 ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
899 format %{ "atomic_xchgalw $preval, $newval, [$mem]" %}
900 ins_encode %{
901 __ atomic_xchgalw($preval$$Register, $newval$$Register, $mem$$Register);
902
903 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
904 __ ldrb($tmp$$Register, gcs_addr);
905
906 bool is_narrow = true;
907 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
908 noreg /* addr */,
909 $preval$$Register /* pre_val */,
910 $tmp$$Register /* gc_state */,
911 is_narrow /* encoded_preval */);
912
913 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
914 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
915 $preval$$Register /* obj */,
916 $mem$$Register /* addr */,
917 is_narrow /* narrow */,
918 maybe_null,
919 $tmp$$Register /* gc_state */);
920
921 ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
922 $mem$$Register /* addr */,
923 $tmp$$Register /* tmp */);
924 %}
925 ins_pipe(pipe_serial);
926 %}
927
928
929 // This pattern is generated automatically from shenandoah_aarch64.m4.
930 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
931 instruct load_P_Normal_shenandoah(iRegPNoSp dst, indirect mem, iRegPNoSp tmp, rFlagsReg cr)
932 %{
933 match(Set dst (LoadP mem));
934 predicate(UseShenandoahGC && !needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
935 effect(TEMP_DEF dst, TEMP tmp, KILL cr);
936 ins_cost(3*INSN_COST);
937 format %{ "ldr $dst, $mem\t# ptr" %}
938 ins_encode %{
939 __ ldr($dst$$Register, $mem$$Register);
940
941 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
942 __ ldrb($tmp$$Register, gcs_addr);
943
944 bool is_narrow = false;
945 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
946 noreg /* obj */,
947 $dst$$Register /* pre_val, in this case it will be only used in the slowpath as tmp. */,
948 $tmp$$Register /* gc_state */,
949 is_narrow /* encoded_preval */);
950
951 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
952 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
953 $dst$$Register /* obj */,
954 $mem$$Register /* addr */,
955 is_narrow /* narrow */,
956 maybe_null,
957 $tmp$$Register /* gc_state */);
958 %}
959 ins_pipe(pipe_class_memory);
960 %}
961
962 // This pattern is generated automatically from shenandoah_aarch64.m4.
963 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
964 instruct load_P_Volatile_shenandoah(iRegPNoSp dst, indirect mem, iRegPNoSp tmp, rFlagsReg cr)
965 %{
966 match(Set dst (LoadP mem));
967 predicate(UseShenandoahGC && needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
968 effect(TEMP_DEF dst, TEMP tmp, KILL cr);
969 ins_cost(VOLATILE_REF_COST);
970 format %{ "ldar $dst, $mem\t# ptr" %}
971 ins_encode %{
972 __ ldar($dst$$Register, $mem$$Register);
973
974 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
975 __ ldrb($tmp$$Register, gcs_addr);
976
977 bool is_narrow = false;
978 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
979 noreg /* obj */,
980 $dst$$Register /* pre_val, in this case it will be only used in the slowpath as tmp. */,
981 $tmp$$Register /* gc_state */,
982 is_narrow /* encoded_preval */);
983
984 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
985 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
986 $dst$$Register /* obj */,
987 $mem$$Register /* addr */,
988 is_narrow /* narrow */,
989 maybe_null,
990 $tmp$$Register /* gc_state */);
991 %}
992 ins_pipe(pipe_class_memory);
993 %}
994
995 // This pattern is generated automatically from shenandoah_aarch64.m4.
996 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
997 instruct load_N_Normal_shenandoah(iRegNNoSp dst, indirect mem, iRegPNoSp tmp, rFlagsReg cr)
998 %{
999 match(Set dst (LoadN mem));
1000 predicate(UseShenandoahGC && !needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
1001 effect(TEMP_DEF dst, TEMP tmp, KILL cr);
1002 ins_cost(3*INSN_COST);
1003 format %{ "ldrw $dst, $mem\t# ptr" %}
1004 ins_encode %{
1005 __ ldrw($dst$$Register, $mem$$Register);
1006
1007 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
1008 __ ldrb($tmp$$Register, gcs_addr);
1009
1010 bool is_narrow = true;
1011 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
1012 noreg /* obj */,
1013 $dst$$Register /* pre_val, in this case it will be only used in the slowpath as tmp. */,
1014 $tmp$$Register /* gc_state */,
1015 is_narrow /* encoded_preval */);
1016
1017 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
1018 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
1019 $dst$$Register /* obj */,
1020 $mem$$Register /* addr */,
1021 is_narrow /* narrow */,
1022 maybe_null,
1023 $tmp$$Register /* gc_state */);
1024 %}
1025 ins_pipe(pipe_class_memory);
1026 %}
1027
1028 // This pattern is generated automatically from shenandoah_aarch64.m4.
1029 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
1030 instruct load_N_Volatile_shenandoah(iRegNNoSp dst, indirect mem, iRegPNoSp tmp, rFlagsReg cr)
1031 %{
1032 match(Set dst (LoadN mem));
1033 predicate(UseShenandoahGC && needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
1034 effect(TEMP_DEF dst, TEMP tmp, KILL cr);
1035 ins_cost(VOLATILE_REF_COST);
1036 format %{ "ldarw $dst, $mem\t# ptr" %}
1037 ins_encode %{
1038 __ ldarw($dst$$Register, $mem$$Register);
1039
1040 Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
1041 __ ldrb($tmp$$Register, gcs_addr);
1042
1043 bool is_narrow = true;
1044 ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
1045 noreg /* obj */,
1046 $dst$$Register /* pre_val, in this case it will be only used in the slowpath as tmp. */,
1047 $tmp$$Register /* gc_state */,
1048 is_narrow /* encoded_preval */);
1049
1050 bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
1051 ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
1052 $dst$$Register /* obj */,
1053 $mem$$Register /* addr */,
1054 is_narrow /* narrow */,
1055 maybe_null,
1056 $tmp$$Register /* gc_state */);
1057 %}
1058 ins_pipe(pipe_class_memory);
1059 %}
1060
1061 // END This section of the file is automatically generated from shenandoah_aarch64.m4.
|