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