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 
  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     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
  47     __ ldrb($tmp$$Register, gcs_addr);
  48 
  49     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
  50                                                         $mem$$Register /* addr, used in slow path only */,
  51                                                         noreg          /* pre_val, used in slow path only */,
  52                                                         $tmp$$Register /* gc_state on fas path */,
  53                                                         false           /* unused in this case */);
  54 
  55     __ str($src$$Register, $mem$$Register);
  56 
  57     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
  58                                                        $mem$$Register /* addr */,
  59                                                        $tmp$$Register /* tmp */);
  60   %}
  61   ins_pipe(pipe_class_memory);
  62 %}
  63 
  64 // This pattern is generated automatically from shenandoah_aarch64.m4.
  65 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
  66 instruct store_P_Volatile_shenandoah(indirect mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
  67 %{
  68   match(Set mem (StoreP mem src));
  69   predicate(UseShenandoahGC && needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
  70   effect(TEMP tmp, KILL cr);
  71   ins_cost(VOLATILE_REF_COST);
  72   format %{ "stlr  $src, $mem" %}
  73   ins_encode %{
  74     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
  75     __ ldrb($tmp$$Register, gcs_addr);
  76 
  77     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
  78                                                         $mem$$Register /* addr, used in slow path only */,
  79                                                         noreg          /* pre_val, used in slow path only */,
  80                                                         $tmp$$Register /* gc_state on fas path */,
  81                                                         false           /* unused in this case */);
  82 
  83     __ stlr($src$$Register, $mem$$Register);

  84 
  85     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
  86                                                        $mem$$Register /* addr */,
  87                                                        $tmp$$Register /* tmp */);
  88   %}
  89   ins_pipe(pipe_class_memory);
  90 %}
  91 
  92 // This pattern is generated automatically from shenandoah_aarch64.m4.
  93 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
  94 instruct store_N_Normal_shenandoah(indirect mem, iRegN src, iRegPNoSp tmp, rFlagsReg cr)
  95 %{
  96   match(Set mem (StoreN mem src));
  97   predicate(UseShenandoahGC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
  98   effect(TEMP tmp, KILL cr);
  99   ins_cost(3*INSN_COST);
 100   format %{ "strw  $src, $mem" %}
 101   ins_encode %{
 102     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 103     __ ldrb($tmp$$Register, gcs_addr);
 104 
 105     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 106                                                         $mem$$Register /* addr, used in slow path only */,
 107                                                         noreg          /* pre_val, used in slow path only */,
 108                                                         $tmp$$Register /* gc_state on fas path */,
 109                                                         false           /* unused in this case */);
 110 
 111     __ strw($src$$Register, $mem$$Register);
 112 
 113     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 114                                                        $mem$$Register /* addr */,
 115                                                        $tmp$$Register /* tmp */);
 116   %}
 117   ins_pipe(pipe_class_memory);
 118 %}
 119 
 120 // This pattern is generated automatically from shenandoah_aarch64.m4.
 121 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 122 instruct store_N_Volatile_shenandoah(indirect mem, iRegN src, iRegPNoSp tmp, rFlagsReg cr)
 123 %{
 124   match(Set mem (StoreN mem src));
 125   predicate(UseShenandoahGC && needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
 126   effect(TEMP tmp, KILL cr);
 127   ins_cost(VOLATILE_REF_COST);
 128   format %{ "stlrw  $src, $mem" %}
 129   ins_encode %{
 130     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 131     __ ldrb($tmp$$Register, gcs_addr);
 132 
 133     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 134                                                         $mem$$Register /* addr, used in slow path only */,
 135                                                         noreg          /* pre_val, used in slow path only */,
 136                                                         $tmp$$Register /* gc_state on fas path */,
 137                                                         false           /* unused in this case */);
 138 
 139     __ stlrw($src$$Register, $mem$$Register);
 140 
 141     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 142                                                        $mem$$Register /* addr */,
 143                                                        $tmp$$Register /* tmp */);
 144   %}
 145   ins_pipe(pipe_class_memory);
 146 %}
 147 

 148 


 149 
 150 
 151 
 152 
 153 
 154 
 155 
 156 
 157 // This pattern is generated automatically from shenandoah_aarch64.m4.
 158 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 159 instruct encodePAndStoreN_Normal_shenandoah(indirect mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
 160 %{
 161   match(Set mem (StoreN mem (EncodeP src)));
 162   predicate(UseShenandoahGC && !needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
 163   effect(TEMP tmp, KILL cr);
 164   ins_cost(4*INSN_COST);
 165   format %{ "encode_heap_oop $tmp, $src\n\t"
 166             "strw  $tmp, $mem\t# compressed ptr" %}
 167   ins_encode %{
 168     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 169     __ ldrb($tmp$$Register, gcs_addr);
 170 
 171     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 172                                                         $mem$$Register /* addr, used in slow path only */,
 173                                                         noreg /* pre_val, used in slow path only */,
 174                                                         $tmp$$Register /* gc_state on fas path */,
 175                                                         false           /* encoded_preval */);
 176 
 177     if ((barrier_data() & ShenandoahBarrierNotNull) == 0) {
 178       __ encode_heap_oop($tmp$$Register, $src$$Register);
 179     } else {
 180       __ encode_heap_oop_not_null($tmp$$Register, $src$$Register);
 181     }
 182 
 183     __ strw($tmp$$Register, $mem$$Register);
 184 
 185     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 186                                                        $mem$$Register /* addr */,
 187                                                        $tmp$$Register /* tmp */);
 188   %}
 189   ins_pipe(pipe_class_memory);
 190 %}
 191 
 192 // This pattern is generated automatically from shenandoah_aarch64.m4.
 193 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 194 instruct encodePAndStoreN_Volatile_shenandoah(indirect mem, iRegP src, iRegPNoSp tmp, rFlagsReg cr)
 195 %{
 196   match(Set mem (StoreN mem (EncodeP src)));
 197   predicate(UseShenandoahGC && needs_releasing_store(n) && n->as_Store()->barrier_data() != 0);
 198   effect(TEMP tmp, KILL cr);
 199   ins_cost(VOLATILE_REF_COST);
 200   format %{ "encode_heap_oop $tmp, $src\n\t"
 201             "stlrw  $tmp, $mem\t# compressed ptr" %}
 202   ins_encode %{
 203     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 204     __ ldrb($tmp$$Register, gcs_addr);


 205 
 206     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 207                                                         $mem$$Register /* addr, used in slow path only */,
 208                                                         noreg /* pre_val, used in slow path only */,
 209                                                         $tmp$$Register /* gc_state on fas path */,
 210                                                         false           /* encoded_preval */);
 211 
 212     if ((barrier_data() & ShenandoahBarrierNotNull) == 0) {
 213       __ encode_heap_oop($tmp$$Register, $src$$Register);
 214     } else {
 215       __ encode_heap_oop_not_null($tmp$$Register, $src$$Register);
 216     }
 217 
 218     __ stlrw($tmp$$Register, $mem$$Register);
 219 
 220     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 221                                                        $mem$$Register /* addr */,
 222                                                        $tmp$$Register /* tmp */);
 223   %}
 224   ins_pipe(pipe_class_memory);
 225 %}
 226 

 227 
 228 
 229 
 230 
 231 
 232 
 233 
 234 
 235 
 236 // This pattern is generated automatically from shenandoah_aarch64.m4.
 237 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 238 instruct compareAndSwap_P_Normal_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 239 %{
 240   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
 241   predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 242   ins_cost(VOLATILE_REF_COST);
 243   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 244   format %{
 245     "cmpxchg_P_Normal_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
 246   %}
 247   ins_encode %{
 248     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 249     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 250 
 251     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 252     __ ldrb($tmp1$$Register, gcs_addr);
 253 
 254     bool is_narrow = false;
 255     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 256                                                         noreg             /* addr */,
 257                                                         $oldval$$Register /* pre_val, only used in slow path */,
 258                                                         $tmp1$$Register   /* gc_state */,
 259                                                         is_narrow         /* encoded_preval */);
 260 
 261     bool is_acquire = false;
 262     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 263                                                         $mem$$base$$Register,
 264                                                         $oldval$$Register,
 265                                                         $newval$$Register,
 266                                                         $res$$Register,
 267                                                         $tmp1$$Register,    /* gc_state */
 268                                                         $tmp2$$Register,
 269                                                         /*acquire*/ is_acquire,
 270                                                         /*release*/ true,
 271                                                         /*weak*/ false,
 272                                                         /*is_cae*/ false);
 273 
 274     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 275                                                        $mem$$Register /* addr */,
 276                                                        $tmp1$$Register /* tmp */);
 277   %}
 278 
 279   ins_pipe(pipe_slow);
 280 %}
 281 
 282 // This pattern is generated automatically from shenandoah_aarch64.m4.
 283 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 284 instruct compareAndSwap_N_Normal_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 285 %{
 286   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
 287   predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 288   ins_cost(VOLATILE_REF_COST);
 289   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 290   format %{
 291     "cmpxchg_N_Normal_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
 292   %}
 293   ins_encode %{
 294     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 295     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 296 
 297     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 298     __ ldrb($tmp1$$Register, gcs_addr);
 299 
 300     bool is_narrow = true;
 301     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 302                                                         noreg             /* addr */,
 303                                                         $oldval$$Register /* pre_val, only used in slow path */,
 304                                                         $tmp1$$Register   /* gc_state */,
 305                                                         is_narrow         /* encoded_preval */);
 306 
 307     bool is_acquire = false;
 308     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 309                                                         $mem$$base$$Register,
 310                                                         $oldval$$Register,
 311                                                         $newval$$Register,
 312                                                         $res$$Register,
 313                                                         $tmp1$$Register,    /* gc_state */
 314                                                         $tmp2$$Register,
 315                                                         /*acquire*/ is_acquire,
 316                                                         /*release*/ true,
 317                                                         /*weak*/ false,
 318                                                         /*is_cae*/ false);
 319 
 320     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 321                                                        $mem$$Register /* addr */,
 322                                                        $tmp1$$Register /* tmp */);
 323   %}
 324 
 325   ins_pipe(pipe_slow);
 326 %}
 327 
 328 // This pattern is generated automatically from shenandoah_aarch64.m4.
 329 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 330 instruct compareAndSwap_P_Volatile_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 331 %{
 332   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
 333   predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 334   ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
 335   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 336   format %{
 337     "cmpxchg_P_Volatile_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
 338   %}
 339   ins_encode %{
 340     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 341     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 342 
 343     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 344     __ ldrb($tmp1$$Register, gcs_addr);
 345 
 346     bool is_narrow = false;
 347     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 348                                                         noreg             /* addr */,
 349                                                         $oldval$$Register /* pre_val, only used in slow path */,
 350                                                         $tmp1$$Register   /* gc_state */,
 351                                                         is_narrow         /* encoded_preval */);
 352 
 353     bool is_acquire = true;
 354     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 355                                                         $mem$$base$$Register,
 356                                                         $oldval$$Register,
 357                                                         $newval$$Register,
 358                                                         $res$$Register,
 359                                                         $tmp1$$Register,    /* gc_state */
 360                                                         $tmp2$$Register,
 361                                                         /*acquire*/ is_acquire,
 362                                                         /*release*/ true,
 363                                                         /*weak*/ false,
 364                                                         /*is_cae*/ false);
 365 
 366     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 367                                                        $mem$$Register /* addr */,
 368                                                        $tmp1$$Register /* tmp */);
 369   %}
 370 
 371   ins_pipe(pipe_slow);
 372 %}
 373 
 374 // This pattern is generated automatically from shenandoah_aarch64.m4.
 375 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 376 instruct compareAndSwap_N_Volatile_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 377 %{
 378   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
 379   predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 380   ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
 381   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 382   format %{
 383     "cmpxchg_N_Volatile_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
 384   %}
 385   ins_encode %{
 386     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 387     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 388 
 389     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 390     __ ldrb($tmp1$$Register, gcs_addr);
 391 
 392     bool is_narrow = true;
 393     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 394                                                         noreg             /* addr */,
 395                                                         $oldval$$Register /* pre_val, only used in slow path */,
 396                                                         $tmp1$$Register   /* gc_state */,
 397                                                         is_narrow         /* encoded_preval */);
 398 
 399     bool is_acquire = true;
 400     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 401                                                         $mem$$base$$Register,
 402                                                         $oldval$$Register,
 403                                                         $newval$$Register,
 404                                                         $res$$Register,
 405                                                         $tmp1$$Register,    /* gc_state */
 406                                                         $tmp2$$Register,
 407                                                         /*acquire*/ is_acquire,
 408                                                         /*release*/ true,
 409                                                         /*weak*/ false,
 410                                                         /*is_cae*/ false);
 411 
 412     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 413                                                        $mem$$Register /* addr */,
 414                                                        $tmp1$$Register /* tmp */);
 415   %}
 416 
 417   ins_pipe(pipe_slow);
 418 %}
 419 
 420 
 421 
 422 
 423 
 424 
 425 // This pattern is generated automatically from shenandoah_aarch64.m4.
 426 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 427 instruct compareAndExchange_N_Normal_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 428 %{
 429   match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
 430   predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 431   ins_cost(2*VOLATILE_REF_COST);
 432   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 433   format %{
 434     "cmpxchg_N_Normal_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
 435   %}
 436   ins_encode %{
 437     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 438     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 439 
 440     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 441     __ ldrb($tmp1$$Register, gcs_addr);
 442 
 443     bool is_narrow = true;
 444     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 445                                                         noreg             /* addr */,
 446                                                         $oldval$$Register /* pre_val */,
 447                                                         $tmp1$$Register   /* gc_state */,
 448                                                         is_narrow         /* encoded_preval */);
 449 
 450     bool is_acquire = false;
 451     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 452                                                         $mem$$base$$Register,
 453                                                         $oldval$$Register,
 454                                                         $newval$$Register,
 455                                                         $res$$Register,
 456                                                         $tmp1$$Register,        /* gc_state */
 457                                                         $tmp2$$Register,
 458                                                         /*acquire*/ is_acquire,
 459                                                         /*release*/ true,
 460                                                         /*weak*/ false,
 461                                                         /*is_cae*/ true);
 462 
 463     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 464     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
 465                                                            $res$$Register     /* obj */,
 466                                                            $mem$$Register     /* addr */,
 467                                                            is_narrow          /* narrow */,
 468                                                            maybe_null,
 469                                                            $tmp1$$Register    /* gc_state */);
 470 
 471     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 472                                                        $mem$$Register         /* addr */,
 473                                                        $tmp1$$Register        /* tmp */);
 474   %}
 475   ins_pipe(pipe_slow);
 476 %}
 477 
 478 // This pattern is generated automatically from shenandoah_aarch64.m4.
 479 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 480 instruct compareAndExchange_P_Normal_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 481 %{
 482   match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
 483   predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 484   ins_cost(2*VOLATILE_REF_COST);
 485   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 486   format %{
 487     "cmpxchg_P_Normal_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
 488   %}
 489   ins_encode %{
 490     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 491     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 492 
 493     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 494     __ ldrb($tmp1$$Register, gcs_addr);
 495 
 496     bool is_narrow = false;
 497     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 498                                                         noreg             /* addr */,
 499                                                         $oldval$$Register /* pre_val */,
 500                                                         $tmp1$$Register   /* gc_state */,
 501                                                         is_narrow         /* encoded_preval */);
 502 
 503     bool is_acquire = false;
 504     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 505                                                         $mem$$base$$Register,
 506                                                         $oldval$$Register,
 507                                                         $newval$$Register,
 508                                                         $res$$Register,
 509                                                         $tmp1$$Register,        /* gc_state */
 510                                                         $tmp2$$Register,
 511                                                         /*acquire*/ is_acquire,
 512                                                         /*release*/ true,
 513                                                         /*weak*/ false,
 514                                                         /*is_cae*/ true);
 515 
 516     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 517     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
 518                                                            $res$$Register     /* obj */,
 519                                                            $mem$$Register     /* addr */,
 520                                                            is_narrow          /* narrow */,
 521                                                            maybe_null,
 522                                                            $tmp1$$Register    /* gc_state */);
 523 
 524     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 525                                                        $mem$$Register         /* addr */,
 526                                                        $tmp1$$Register        /* tmp */);
 527   %}
 528   ins_pipe(pipe_slow);
 529 %}
 530 
 531 // This pattern is generated automatically from shenandoah_aarch64.m4.
 532 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 533 instruct compareAndExchange_N_Volatile_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 534 %{
 535   match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
 536   predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 537   ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
 538   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 539   format %{
 540     "cmpxchg_N_Volatile_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
 541   %}
 542   ins_encode %{
 543     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 544     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 545 
 546     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 547     __ ldrb($tmp1$$Register, gcs_addr);
 548 
 549     bool is_narrow = true;
 550     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 551                                                         noreg             /* addr */,
 552                                                         $oldval$$Register /* pre_val */,
 553                                                         $tmp1$$Register   /* gc_state */,
 554                                                         is_narrow         /* encoded_preval */);
 555 
 556     bool is_acquire = true;
 557     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 558                                                         $mem$$base$$Register,
 559                                                         $oldval$$Register,
 560                                                         $newval$$Register,
 561                                                         $res$$Register,
 562                                                         $tmp1$$Register,        /* gc_state */
 563                                                         $tmp2$$Register,
 564                                                         /*acquire*/ is_acquire,
 565                                                         /*release*/ true,
 566                                                         /*weak*/ false,
 567                                                         /*is_cae*/ true);
 568 
 569     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 570     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
 571                                                            $res$$Register     /* obj */,
 572                                                            $mem$$Register     /* addr */,
 573                                                            is_narrow          /* narrow */,
 574                                                            maybe_null,
 575                                                            $tmp1$$Register    /* gc_state */);
 576 
 577     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 578                                                        $mem$$Register         /* addr */,
 579                                                        $tmp1$$Register        /* tmp */);
 580   %}
 581   ins_pipe(pipe_slow);
 582 %}
 583 
 584 // This pattern is generated automatically from shenandoah_aarch64.m4.
 585 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 586 instruct compareAndExchange_P_Volatile_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 587 %{
 588   match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
 589   predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 590   ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
 591   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 592   format %{
 593     "cmpxchg_P_Volatile_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
 594   %}
 595   ins_encode %{
 596     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 597     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 598 
 599     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 600     __ ldrb($tmp1$$Register, gcs_addr);
 601 
 602     bool is_narrow = false;
 603     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 604                                                         noreg             /* addr */,
 605                                                         $oldval$$Register /* pre_val */,
 606                                                         $tmp1$$Register   /* gc_state */,
 607                                                         is_narrow         /* encoded_preval */);
 608 
 609     bool is_acquire = true;
 610     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 611                                                         $mem$$base$$Register,
 612                                                         $oldval$$Register,
 613                                                         $newval$$Register,
 614                                                         $res$$Register,
 615                                                         $tmp1$$Register,        /* gc_state */
 616                                                         $tmp2$$Register,
 617                                                         /*acquire*/ is_acquire,
 618                                                         /*release*/ true,
 619                                                         /*weak*/ false,
 620                                                         /*is_cae*/ true);
 621 
 622     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 623     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
 624                                                            $res$$Register     /* obj */,
 625                                                            $mem$$Register     /* addr */,
 626                                                            is_narrow          /* narrow */,
 627                                                            maybe_null,
 628                                                            $tmp1$$Register    /* gc_state */);
 629 
 630     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 631                                                        $mem$$Register         /* addr */,
 632                                                        $tmp1$$Register        /* tmp */);
 633   %}
 634   ins_pipe(pipe_slow);
 635 %}
 636 
 637 
 638 
 639 
 640 
 641 
 642 
 643 
 644 // This pattern is generated automatically from shenandoah_aarch64.m4.
 645 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 646 instruct weakCompareAndSwap_N_Normal_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 647 %{
 648   match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
 649   predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 650   ins_cost(VOLATILE_REF_COST);
 651   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 652   format %{
 653     "cmpxchg_oop_c2 $res = $mem, $oldval, $newval\t# (N, weak, Normal) if $mem == $oldval then $mem <-- $newval\n\t"
 654     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
 655   %}
 656   ins_encode %{
 657     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 658     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 659 
 660     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 661     __ ldrb($tmp1$$Register, gcs_addr);
 662 
 663     bool is_narrow = true;
 664     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 665                                                         noreg             /* addr */,
 666                                                         $oldval$$Register /* pre_val */,
 667                                                         $tmp1$$Register   /* gc_state */,
 668                                                         is_narrow         /* encoded_preval */);
 669 
 670     bool is_acquire = false;
 671     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 672                                                         $mem$$base$$Register,
 673                                                         $oldval$$Register,
 674                                                         $newval$$Register,
 675                                                         $res$$Register,
 676                                                         $tmp1$$Register,
 677                                                         $tmp2$$Register,
 678                                                         /*acquire*/ is_acquire,
 679                                                         /*release*/ true,
 680                                                         /*weak*/ true,
 681                                                         /*is_cae*/ false);
 682 
 683     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 684                                                        $mem$$Register /* addr */,
 685                                                        $tmp1$$Register /* tmp */);
 686   %}
 687   ins_pipe(pipe_slow);
 688 %}
 689 
 690 // This pattern is generated automatically from shenandoah_aarch64.m4.
 691 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 692 instruct weakCompareAndSwap_P_Normal_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 693 %{
 694   match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
 695   predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 696   ins_cost(VOLATILE_REF_COST);
 697   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 698   format %{
 699     "cmpxchg_oop_c2 $res = $mem, $oldval, $newval\t# (P, weak, Normal) if $mem == $oldval then $mem <-- $newval\n\t"
 700     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
 701   %}
 702   ins_encode %{
 703     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 704     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 705 
 706     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 707     __ ldrb($tmp1$$Register, gcs_addr);
 708 
 709     bool is_narrow = false;
 710     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 711                                                         noreg             /* addr */,
 712                                                         $oldval$$Register /* pre_val */,
 713                                                         $tmp1$$Register   /* gc_state */,
 714                                                         is_narrow         /* encoded_preval */);
 715 
 716     bool is_acquire = false;
 717     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 718                                                         $mem$$base$$Register,
 719                                                         $oldval$$Register,
 720                                                         $newval$$Register,
 721                                                         $res$$Register,
 722                                                         $tmp1$$Register,
 723                                                         $tmp2$$Register,
 724                                                         /*acquire*/ is_acquire,
 725                                                         /*release*/ true,
 726                                                         /*weak*/ true,
 727                                                         /*is_cae*/ false);
 728 
 729     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 730                                                        $mem$$Register /* addr */,
 731                                                        $tmp1$$Register /* tmp */);
 732   %}
 733   ins_pipe(pipe_slow);
 734 %}
 735 
 736 // This pattern is generated automatically from shenandoah_aarch64.m4.
 737 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 738 instruct weakCompareAndSwap_N_Volatile_shenandoah(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegN newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 739 %{
 740   match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
 741   predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 742   ins_cost(VOLATILE_REF_COST);
 743   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 744   format %{
 745     "cmpxchg_oop_c2 $res = $mem, $oldval, $newval\t# (N, weak, Volatile) if $mem == $oldval then $mem <-- $newval\n\t"
 746     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
 747   %}
 748   ins_encode %{
 749     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 750     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 751 
 752     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 753     __ ldrb($tmp1$$Register, gcs_addr);
 754 
 755     bool is_narrow = true;
 756     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 757                                                         noreg             /* addr */,
 758                                                         $oldval$$Register /* pre_val */,
 759                                                         $tmp1$$Register   /* gc_state */,
 760                                                         is_narrow         /* encoded_preval */);
 761 
 762     bool is_acquire = true;
 763     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 764                                                         $mem$$base$$Register,
 765                                                         $oldval$$Register,
 766                                                         $newval$$Register,
 767                                                         $res$$Register,
 768                                                         $tmp1$$Register,
 769                                                         $tmp2$$Register,
 770                                                         /*acquire*/ is_acquire,
 771                                                         /*release*/ true,
 772                                                         /*weak*/ true,
 773                                                         /*is_cae*/ false);
 774 
 775     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 776                                                        $mem$$Register /* addr */,
 777                                                        $tmp1$$Register /* tmp */);
 778   %}
 779   ins_pipe(pipe_slow);
 780 %}
 781 
 782 // This pattern is generated automatically from shenandoah_aarch64.m4.
 783 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 784 instruct weakCompareAndSwap_P_Volatile_shenandoah(iRegINoSp res, indirect mem, iRegPNoSp oldval, iRegP newval, iRegPNoSp tmp1, iRegPNoSp tmp2, rFlagsReg cr)
 785 %{
 786   match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
 787   predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 788   ins_cost(VOLATILE_REF_COST);
 789   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
 790   format %{
 791     "cmpxchg_oop_c2 $res = $mem, $oldval, $newval\t# (P, weak, Volatile) if $mem == $oldval then $mem <-- $newval\n\t"
 792     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
 793   %}
 794   ins_encode %{
 795     assert_different_registers($tmp1$$Register, $tmp2$$Register);
 796     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
 797 
 798     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 799     __ ldrb($tmp1$$Register, gcs_addr);
 800 
 801     bool is_narrow = false;
 802     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 803                                                         noreg             /* addr */,
 804                                                         $oldval$$Register /* pre_val */,
 805                                                         $tmp1$$Register   /* gc_state */,
 806                                                         is_narrow         /* encoded_preval */);
 807 
 808     bool is_acquire = true;
 809     ShenandoahBarrierSet::assembler()->cmpxchg_oop_c2(this, masm,
 810                                                         $mem$$base$$Register,
 811                                                         $oldval$$Register,
 812                                                         $newval$$Register,
 813                                                         $res$$Register,
 814                                                         $tmp1$$Register,
 815                                                         $tmp2$$Register,
 816                                                         /*acquire*/ is_acquire,
 817                                                         /*release*/ true,
 818                                                         /*weak*/ true,
 819                                                         /*is_cae*/ false);
 820 
 821     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 822                                                        $mem$$Register /* addr */,
 823                                                        $tmp1$$Register /* tmp */);
 824   %}
 825   ins_pipe(pipe_slow);
 826 %}
 827 
 828 
 829 
 830 // This pattern is generated automatically from shenandoah_aarch64.m4.
 831 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 832 instruct getAndSet_P_Normal_shenandoah(indirect mem, iRegP newval, iRegPNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
 833 %{
 834   match(Set preval (GetAndSetP mem newval));
 835   predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 836   effect(TEMP_DEF preval, TEMP tmp, KILL cr);
 837   ins_cost(2*VOLATILE_REF_COST);
 838   format %{ "atomic_xchg $preval, $newval, [$mem]" %}
 839   ins_encode %{
 840     __ atomic_xchg($preval$$Register, $newval$$Register, $mem$$Register);
 841 
 842     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 843     __ ldrb($tmp$$Register, gcs_addr);
 844 
 845     bool is_narrow = false;
 846     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 847                                                         noreg             /* addr */,
 848                                                         $preval$$Register /* pre_val */,
 849                                                         $tmp$$Register    /* gc_state */,
 850                                                         is_narrow         /* encoded_preval */);
 851 
 852     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 853     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
 854                                                         $preval$$Register /* obj */,
 855                                                         $mem$$Register    /* addr */,
 856                                                         is_narrow         /* narrow */,
 857                                                         maybe_null,
 858                                                         $tmp$$Register    /* gc_state */);
 859 
 860     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 861                                                        $mem$$Register     /* addr */,
 862                                                        $tmp$$Register     /* tmp */);
 863   %}
 864   ins_pipe(pipe_serial);
 865 %}
 866 
 867 // This pattern is generated automatically from shenandoah_aarch64.m4.
 868 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 869 instruct getAndSet_P_Volatile_shenandoah(indirect mem, iRegP newval, iRegPNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
 870 %{
 871   match(Set preval (GetAndSetP mem newval));
 872   predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 873   effect(TEMP_DEF preval, TEMP tmp, KILL cr);
 874   ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
 875   format %{ "atomic_xchgal $preval, $newval, [$mem]" %}
 876   ins_encode %{
 877     __ atomic_xchgal($preval$$Register, $newval$$Register, $mem$$Register);
 878 
 879     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 880     __ ldrb($tmp$$Register, gcs_addr);
 881 
 882     bool is_narrow = false;
 883     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 884                                                         noreg             /* addr */,
 885                                                         $preval$$Register /* pre_val */,
 886                                                         $tmp$$Register    /* gc_state */,
 887                                                         is_narrow         /* encoded_preval */);
 888 
 889     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 890     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
 891                                                         $preval$$Register /* obj */,
 892                                                         $mem$$Register    /* addr */,
 893                                                         is_narrow         /* narrow */,
 894                                                         maybe_null,
 895                                                         $tmp$$Register    /* gc_state */);
 896 
 897     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 898                                                        $mem$$Register     /* addr */,
 899                                                        $tmp$$Register     /* tmp */);
 900   %}
 901   ins_pipe(pipe_serial);
 902 %}
 903 
 904 // This pattern is generated automatically from shenandoah_aarch64.m4.
 905 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 906 instruct getAndSet_N_Normal_shenandoah(indirect mem, iRegN newval, iRegNNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
 907 %{
 908   match(Set preval (GetAndSetN mem newval));
 909   predicate(UseShenandoahGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 910   effect(TEMP_DEF preval, TEMP tmp, KILL cr);
 911   ins_cost(2*VOLATILE_REF_COST);
 912   format %{ "atomic_xchgw $preval, $newval, [$mem]" %}
 913   ins_encode %{
 914     __ atomic_xchgw($preval$$Register, $newval$$Register, $mem$$Register);
 915 
 916     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 917     __ ldrb($tmp$$Register, gcs_addr);
 918 
 919     bool is_narrow = true;
 920     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 921                                                         noreg             /* addr */,
 922                                                         $preval$$Register /* pre_val */,
 923                                                         $tmp$$Register    /* gc_state */,
 924                                                         is_narrow         /* encoded_preval */);
 925 
 926     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 927     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
 928                                                         $preval$$Register /* obj */,
 929                                                         $mem$$Register    /* addr */,
 930                                                         is_narrow         /* narrow */,
 931                                                         maybe_null,
 932                                                         $tmp$$Register    /* gc_state */);
 933 
 934     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 935                                                        $mem$$Register     /* addr */,
 936                                                        $tmp$$Register     /* tmp */);
 937   %}
 938   ins_pipe(pipe_serial);
 939 %}
 940 
 941 // This pattern is generated automatically from shenandoah_aarch64.m4.
 942 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 943 instruct getAndSet_N_Volatile_shenandoah(indirect mem, iRegN newval, iRegNNoSp preval, iRegPNoSp tmp, rFlagsReg cr)
 944 %{
 945   match(Set preval (GetAndSetN mem newval));
 946   predicate(UseShenandoahGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() != 0);
 947   effect(TEMP_DEF preval, TEMP tmp, KILL cr);
 948   ins_cost(VOLATILE_REF_COST + 3*INSN_COST);
 949   format %{ "atomic_xchgalw $preval, $newval, [$mem]" %}
 950   ins_encode %{
 951     __ atomic_xchgalw($preval$$Register, $newval$$Register, $mem$$Register);
 952 
 953     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 954     __ ldrb($tmp$$Register, gcs_addr);
 955 
 956     bool is_narrow = true;
 957     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 958                                                         noreg             /* addr */,
 959                                                         $preval$$Register /* pre_val */,
 960                                                         $tmp$$Register    /* gc_state */,
 961                                                         is_narrow         /* encoded_preval */);
 962 
 963     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
 964     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
 965                                                         $preval$$Register /* obj */,
 966                                                         $mem$$Register    /* addr */,
 967                                                         is_narrow         /* narrow */,
 968                                                         maybe_null,
 969                                                         $tmp$$Register    /* gc_state */);
 970 
 971     ShenandoahBarrierSet::assembler()->card_barrier_c2(this, masm,
 972                                                        $mem$$Register     /* addr */,
 973                                                        $tmp$$Register     /* tmp */);
 974   %}
 975   ins_pipe(pipe_serial);
 976 %}
 977 
 978 
 979 // This pattern is generated automatically from shenandoah_aarch64.m4.
 980 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
 981 instruct load_P_Normal_shenandoah(iRegPNoSp dst, indirect mem, iRegPNoSp tmp, rFlagsReg cr)
 982 %{
 983   match(Set dst (LoadP mem));
 984   predicate(UseShenandoahGC && !needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
 985   effect(TEMP_DEF dst, TEMP tmp, KILL cr);
 986   ins_cost(3*INSN_COST);
 987   format %{ "ldr  $dst, $mem\t# ptr" %}
 988   ins_encode %{
 989     __ ldr($dst$$Register, $mem$$Register);
 990 
 991     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
 992     __ ldrb($tmp$$Register, gcs_addr);
 993 
 994     bool is_narrow = false;
 995     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
 996                                                         noreg            /* obj */,
 997                                                         $dst$$Register   /* pre_val, in this case it will be only used in the slowpath as tmp. */,
 998                                                         $tmp$$Register   /* gc_state */,
 999                                                         is_narrow        /* encoded_preval */);
1000 
1001     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
1002     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
1003                                                         $dst$$Register /* obj */,
1004                                                         $mem$$Register /* addr */,
1005                                                         is_narrow      /* narrow */,
1006                                                         maybe_null,
1007                                                         $tmp$$Register /* gc_state */);
1008   %}
1009   ins_pipe(pipe_class_memory);
1010 %}
1011 
1012 // This pattern is generated automatically from shenandoah_aarch64.m4.
1013 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
1014 instruct load_P_Volatile_shenandoah(iRegPNoSp dst, indirect mem, iRegPNoSp tmp, rFlagsReg cr)
1015 %{
1016   match(Set dst (LoadP mem));
1017   predicate(UseShenandoahGC && needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
1018   effect(TEMP_DEF dst, TEMP tmp, KILL cr);
1019   ins_cost(VOLATILE_REF_COST);
1020   format %{ "ldar  $dst, $mem\t# ptr" %}
1021   ins_encode %{
1022     __ ldar($dst$$Register, $mem$$Register);
1023 
1024     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
1025     __ ldrb($tmp$$Register, gcs_addr);
1026 
1027     bool is_narrow = false;
1028     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
1029                                                         noreg            /* obj */,
1030                                                         $dst$$Register   /* pre_val, in this case it will be only used in the slowpath as tmp. */,
1031                                                         $tmp$$Register   /* gc_state */,
1032                                                         is_narrow        /* encoded_preval */);
1033 
1034     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
1035     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
1036                                                         $dst$$Register /* obj */,
1037                                                         $mem$$Register /* addr */,
1038                                                         is_narrow      /* narrow */,
1039                                                         maybe_null,
1040                                                         $tmp$$Register /* gc_state */);
1041   %}
1042   ins_pipe(pipe_class_memory);
1043 %}
1044 
1045 // This pattern is generated automatically from shenandoah_aarch64.m4.
1046 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
1047 instruct load_N_Normal_shenandoah(iRegNNoSp dst, indirect mem, iRegPNoSp tmp, rFlagsReg cr)
1048 %{
1049   match(Set dst (LoadN mem));
1050   predicate(UseShenandoahGC && !needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
1051   effect(TEMP_DEF dst, TEMP tmp, KILL cr);
1052   ins_cost(3*INSN_COST);
1053   format %{ "ldrw  $dst, $mem\t# ptr" %}
1054   ins_encode %{
1055     __ ldrw($dst$$Register, $mem$$Register);
1056 
1057     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
1058     __ ldrb($tmp$$Register, gcs_addr);
1059 
1060     bool is_narrow = true;
1061     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
1062                                                         noreg            /* obj */,
1063                                                         $dst$$Register   /* pre_val, in this case it will be only used in the slowpath as tmp. */,
1064                                                         $tmp$$Register   /* gc_state */,
1065                                                         is_narrow        /* encoded_preval */);
1066 
1067     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
1068     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
1069                                                         $dst$$Register /* obj */,
1070                                                         $mem$$Register /* addr */,
1071                                                         is_narrow      /* narrow */,
1072                                                         maybe_null,
1073                                                         $tmp$$Register /* gc_state */);
1074   %}
1075   ins_pipe(pipe_class_memory);
1076 %}
1077 
1078 // This pattern is generated automatically from shenandoah_aarch64.m4.
1079 // DO NOT EDIT ANYTHING IN THIS SECTION OF THE FILE
1080 instruct load_N_Volatile_shenandoah(iRegNNoSp dst, indirect mem, iRegPNoSp tmp, rFlagsReg cr)
1081 %{
1082   match(Set dst (LoadN mem));
1083   predicate(UseShenandoahGC && needs_acquiring_load(n) && n->as_Load()->barrier_data() != 0);
1084   effect(TEMP_DEF dst, TEMP tmp, KILL cr);
1085   ins_cost(VOLATILE_REF_COST);
1086   format %{ "ldarw  $dst, $mem\t# ptr" %}
1087   ins_encode %{
1088     __ ldarw($dst$$Register, $mem$$Register);
1089 
1090     Address gcs_addr(rthread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
1091     __ ldrb($tmp$$Register, gcs_addr);
1092 
1093     bool is_narrow = true;
1094     ShenandoahBarrierSet::assembler()->satb_barrier_c2(this, masm,
1095                                                         noreg            /* obj */,
1096                                                         $dst$$Register   /* pre_val, in this case it will be only used in the slowpath as tmp. */,
1097                                                         $tmp$$Register   /* gc_state */,
1098                                                         is_narrow        /* encoded_preval */);
1099 
1100     bool maybe_null = (this->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
1101     ShenandoahBarrierSet::assembler()->load_ref_barrier_c2(this, masm,
1102                                                         $dst$$Register /* obj */,
1103                                                         $mem$$Register /* addr */,
1104                                                         is_narrow      /* narrow */,
1105                                                         maybe_null,
1106                                                         $tmp$$Register /* gc_state */);
1107   %}
1108   ins_pipe(pipe_class_memory);
1109 %}
1110 
1111 // END This section of the file is automatically generated from shenandoah_aarch64.m4.
--- EOF ---