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     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.