< prev index next >

src/cpu/aarch64/vm/aarch64.ad

Print this page




 910 // branches as most expensive. the first two have a low as well as a
 911 // normal cost. huge cost appears to be a way of saying don't do
 912 // something
 913 
 914 definitions %{
 915   // The default cost (of a register move instruction).
 916   int_def INSN_COST            (    100,     100);
 917   int_def BRANCH_COST          (    200,     2 * INSN_COST);
 918   int_def CALL_COST            (    200,     2 * INSN_COST);
 919   int_def VOLATILE_REF_COST    (   1000,     10 * INSN_COST);
 920 %}
 921 
 922 
 923 //----------SOURCE BLOCK-------------------------------------------------------
 924 // This is a block of C++ code which provides values, functions, and
 925 // definitions necessary in the rest of the architecture description
 926 
 927 source_hpp %{
 928 
 929 #include "opto/addnode.hpp"



 930 
 931 class CallStubImpl {
 932  
 933   //--------------------------------------------------------------
 934   //---<  Used for optimization in Compile::shorten_branches  >---
 935   //--------------------------------------------------------------
 936 
 937  public:
 938   // Size of call trampoline stub.
 939   static uint size_call_trampoline() {
 940     return 0; // no call trampolines on this platform
 941   }
 942   
 943   // number of relocations needed by a call trampoline stub
 944   static uint reloc_call_trampoline() { 
 945     return 0; // no call trampolines on this platform
 946   }
 947 };
 948 
 949 class HandlerImpl {


2774       }
2775     }
2776     __ cmpw(rscratch1, zr);
2777   %}
2778 
2779   enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
2780     MacroAssembler _masm(&cbuf);
2781     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2782     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2783                Assembler::xword, /*acquire*/ false, /*release*/ true);
2784   %}
2785 
2786   enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2787     MacroAssembler _masm(&cbuf);
2788     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2789     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2790                Assembler::word, /*acquire*/ false, /*release*/ true);
2791   %}
2792 
2793 









2794   // The only difference between aarch64_enc_cmpxchg and
2795   // aarch64_enc_cmpxchg_acq is that we use load-acquire in the
2796   // CompareAndSwap sequence to serve as a barrier on acquiring a
2797   // lock.
2798   enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
2799     MacroAssembler _masm(&cbuf);
2800     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2801     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2802                Assembler::xword, /*acquire*/ true, /*release*/ true);
2803   %}
2804 
2805   enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2806     MacroAssembler _masm(&cbuf);
2807     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2808     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2809                Assembler::word, /*acquire*/ true, /*release*/ true);
2810   %}
2811 










2812   // auxiliary used for CompareAndSwapX to set result register
2813   enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
2814     MacroAssembler _masm(&cbuf);
2815     Register res_reg = as_Register($res$$reg);
2816     __ cset(res_reg, Assembler::EQ);
2817   %}
2818 
2819   // prefetch encodings
2820 
2821   enc_class aarch64_enc_prefetchr(memory mem) %{
2822     MacroAssembler _masm(&cbuf);
2823     Register base = as_Register($mem$$base);
2824     int index = $mem$$index;
2825     int scale = $mem$$scale;
2826     int disp = $mem$$disp;
2827     if (index == -1) {
2828       __ prfm(Address(base, disp), PLDL1KEEP);
2829     } else {
2830       Register index_reg = as_Register(index);
2831       if (disp == 0) {


4190   op_cost(0);
4191   format %{ %}
4192   interface(CONST_INTER);
4193 %}
4194 
4195 // Polling Page Pointer Immediate
4196 operand immPollPage()
4197 %{
4198   predicate((address)n->get_ptr() == os::get_polling_page());
4199   match(ConP);
4200 
4201   op_cost(0);
4202   format %{ %}
4203   interface(CONST_INTER);
4204 %}
4205 
4206 // Card Table Byte Map Base
4207 operand immByteMapBase()
4208 %{
4209   // Get base of card map
4210   predicate((jbyte*)n->get_ptr() ==
4211         ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base);
4212   match(ConP);
4213 
4214   op_cost(0);
4215   format %{ %}
4216   interface(CONST_INTER);
4217 %}
4218 
4219 // Pointer Immediate Minus One
4220 // this is used when we want to write the current PC to the thread anchor
4221 operand immP_M1()
4222 %{
4223   predicate(n->get_ptr() == -1);
4224   match(ConP);
4225 
4226   op_cost(0);
4227   format %{ %}
4228   interface(CONST_INTER);
4229 %}
4230 
4231 // Pointer Immediate Minus Two


6915   match(Set mem (StoreL mem zero));
6916   predicate(!needs_releasing_store(n));
6917 
6918   ins_cost(INSN_COST);
6919   format %{ "str  zr, $mem\t# int" %}
6920 
6921   ins_encode(aarch64_enc_str0(mem));
6922 
6923   ins_pipe(istore_mem);
6924 %}
6925 
6926 // Store Pointer
6927 instruct storeP(iRegP src, memory mem)
6928 %{
6929   match(Set mem (StoreP mem src));
6930   predicate(!needs_releasing_store(n));
6931 
6932   ins_cost(INSN_COST);
6933   format %{ "str  $src, $mem\t# ptr" %}
6934 
6935   ins_encode(aarch64_enc_str(src, mem));














































6936 
6937   ins_pipe(istore_reg_mem);
6938 %}
6939 
6940 // Store Pointer
6941 instruct storeimmP0(immP0 zero, memory mem)
6942 %{
6943   match(Set mem (StoreP mem zero));
6944   predicate(!needs_releasing_store(n));
6945 
6946   ins_cost(INSN_COST);
6947   format %{ "str zr, $mem\t# ptr" %}
6948 
6949   ins_encode(aarch64_enc_str0(mem));
6950 
6951   ins_pipe(istore_mem);
6952 %}
6953 
6954 // Store Compressed Pointer
6955 instruct storeN(iRegN src, memory mem)


8039 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8040 
8041   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8042   ins_cost(2 * VOLATILE_REF_COST);
8043 
8044   effect(KILL cr);
8045 
8046  format %{
8047     "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8048     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8049  %}
8050 
8051  ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8052             aarch64_enc_cset_eq(res));
8053 
8054   ins_pipe(pipe_slow);
8055 %}
8056 
8057 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8058 

8059   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8060   ins_cost(2 * VOLATILE_REF_COST);
8061 
8062   effect(KILL cr);
8063 
8064  format %{
8065     "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8066     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8067  %}
8068 
8069  ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8070             aarch64_enc_cset_eq(res));
8071 
8072   ins_pipe(pipe_slow);
8073 %}
8074 

















8075 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8076 

8077   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8078   ins_cost(2 * VOLATILE_REF_COST);
8079 
8080   effect(KILL cr);
8081 
8082  format %{
8083     "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8084     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8085  %}
8086 
8087  ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8088             aarch64_enc_cset_eq(res));
8089 
8090   ins_pipe(pipe_slow);
8091 %}
8092 




















8093 
8094 // alternative CompareAndSwapX when we are eliding barriers
8095 
8096 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8097 
8098   predicate(needs_acquiring_load_exclusive(n));
8099   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8100   ins_cost(VOLATILE_REF_COST);
8101 
8102   effect(KILL cr);
8103 
8104  format %{
8105     "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8106     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8107  %}
8108 
8109  ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8110             aarch64_enc_cset_eq(res));
8111 
8112   ins_pipe(pipe_slow);


8116 
8117   predicate(needs_acquiring_load_exclusive(n));
8118   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8119   ins_cost(VOLATILE_REF_COST);
8120 
8121   effect(KILL cr);
8122 
8123  format %{
8124     "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8125     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8126  %}
8127 
8128  ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8129             aarch64_enc_cset_eq(res));
8130 
8131   ins_pipe(pipe_slow);
8132 %}
8133 
8134 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8135 
8136   predicate(needs_acquiring_load_exclusive(n));
8137   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8138   ins_cost(VOLATILE_REF_COST);
8139 
8140   effect(KILL cr);
8141 
8142  format %{
8143     "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8144     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8145  %}
8146 
8147  ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8148             aarch64_enc_cset_eq(res));
8149 
8150   ins_pipe(pipe_slow);
8151 %}
8152 

















8153 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8154 
8155   predicate(needs_acquiring_load_exclusive(n));
8156   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8157   ins_cost(VOLATILE_REF_COST);
8158 
8159   effect(KILL cr);
8160 
8161  format %{
8162     "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8163     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8164  %}
8165 
8166  ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8167             aarch64_enc_cset_eq(res));
8168 
8169   ins_pipe(pipe_slow);
8170 %}
8171 




















8172 
8173 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
8174   match(Set prev (GetAndSetI mem newv));
8175   ins_cost(2 * VOLATILE_REF_COST);
8176   format %{ "atomic_xchgw  $prev, $newv, [$mem]" %}
8177   ins_encode %{
8178     __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8179   %}
8180   ins_pipe(pipe_serial);
8181 %}
8182 
8183 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{
8184   match(Set prev (GetAndSetL mem newv));
8185   ins_cost(2 * VOLATILE_REF_COST);
8186   format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
8187   ins_encode %{
8188     __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
8189   %}
8190   ins_pipe(pipe_serial);
8191 %}




 910 // branches as most expensive. the first two have a low as well as a
 911 // normal cost. huge cost appears to be a way of saying don't do
 912 // something
 913 
 914 definitions %{
 915   // The default cost (of a register move instruction).
 916   int_def INSN_COST            (    100,     100);
 917   int_def BRANCH_COST          (    200,     2 * INSN_COST);
 918   int_def CALL_COST            (    200,     2 * INSN_COST);
 919   int_def VOLATILE_REF_COST    (   1000,     10 * INSN_COST);
 920 %}
 921 
 922 
 923 //----------SOURCE BLOCK-------------------------------------------------------
 924 // This is a block of C++ code which provides values, functions, and
 925 // definitions necessary in the rest of the architecture description
 926 
 927 source_hpp %{
 928 
 929 #include "opto/addnode.hpp"
 930 #if INCLUDE_ALL_GCS
 931 #include "shenandoahBarrierSetAssembler_aarch64.hpp"
 932 #endif
 933 
 934 class CallStubImpl {
 935  
 936   //--------------------------------------------------------------
 937   //---<  Used for optimization in Compile::shorten_branches  >---
 938   //--------------------------------------------------------------
 939 
 940  public:
 941   // Size of call trampoline stub.
 942   static uint size_call_trampoline() {
 943     return 0; // no call trampolines on this platform
 944   }
 945   
 946   // number of relocations needed by a call trampoline stub
 947   static uint reloc_call_trampoline() { 
 948     return 0; // no call trampolines on this platform
 949   }
 950 };
 951 
 952 class HandlerImpl {


2777       }
2778     }
2779     __ cmpw(rscratch1, zr);
2780   %}
2781 
2782   enc_class aarch64_enc_cmpxchg(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
2783     MacroAssembler _masm(&cbuf);
2784     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2785     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2786                Assembler::xword, /*acquire*/ false, /*release*/ true);
2787   %}
2788 
2789   enc_class aarch64_enc_cmpxchgw(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2790     MacroAssembler _masm(&cbuf);
2791     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2792     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2793                Assembler::word, /*acquire*/ false, /*release*/ true);
2794   %}
2795 
2796 
2797   enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{
2798     MacroAssembler _masm(&cbuf);
2799     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2800     Register tmp = $tmp$$Register;
2801     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
2802     ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
2803                               /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
2804   %}
2805 
2806   // The only difference between aarch64_enc_cmpxchg and
2807   // aarch64_enc_cmpxchg_acq is that we use load-acquire in the
2808   // CompareAndSwap sequence to serve as a barrier on acquiring a
2809   // lock.
2810   enc_class aarch64_enc_cmpxchg_acq(memory mem, iRegLNoSp oldval, iRegLNoSp newval) %{
2811     MacroAssembler _masm(&cbuf);
2812     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2813     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2814                Assembler::xword, /*acquire*/ true, /*release*/ true);
2815   %}
2816 
2817   enc_class aarch64_enc_cmpxchgw_acq(memory mem, iRegINoSp oldval, iRegINoSp newval) %{
2818     MacroAssembler _masm(&cbuf);
2819     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2820     __ cmpxchg($mem$$base$$Register, $oldval$$Register, $newval$$Register,
2821                Assembler::word, /*acquire*/ true, /*release*/ true);
2822   %}
2823 
2824   enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, iRegINoSp res) %{
2825     MacroAssembler _masm(&cbuf);
2826     guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
2827     Register tmp = $tmp$$Register;
2828     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
2829     ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
2830                               /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false,
2831                               $res$$Register);
2832   %}
2833 
2834   // auxiliary used for CompareAndSwapX to set result register
2835   enc_class aarch64_enc_cset_eq(iRegINoSp res) %{
2836     MacroAssembler _masm(&cbuf);
2837     Register res_reg = as_Register($res$$reg);
2838     __ cset(res_reg, Assembler::EQ);
2839   %}
2840 
2841   // prefetch encodings
2842 
2843   enc_class aarch64_enc_prefetchr(memory mem) %{
2844     MacroAssembler _masm(&cbuf);
2845     Register base = as_Register($mem$$base);
2846     int index = $mem$$index;
2847     int scale = $mem$$scale;
2848     int disp = $mem$$disp;
2849     if (index == -1) {
2850       __ prfm(Address(base, disp), PLDL1KEEP);
2851     } else {
2852       Register index_reg = as_Register(index);
2853       if (disp == 0) {


4212   op_cost(0);
4213   format %{ %}
4214   interface(CONST_INTER);
4215 %}
4216 
4217 // Polling Page Pointer Immediate
4218 operand immPollPage()
4219 %{
4220   predicate((address)n->get_ptr() == os::get_polling_page());
4221   match(ConP);
4222 
4223   op_cost(0);
4224   format %{ %}
4225   interface(CONST_INTER);
4226 %}
4227 
4228 // Card Table Byte Map Base
4229 operand immByteMapBase()
4230 %{
4231   // Get base of card map
4232   predicate(!UseShenandoahGC && // TODO: Should really check for BS::is_a, see JDK-8193193
4233     (jbyte*)n->get_ptr() == ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base);
4234   match(ConP);
4235 
4236   op_cost(0);
4237   format %{ %}
4238   interface(CONST_INTER);
4239 %}
4240 
4241 // Pointer Immediate Minus One
4242 // this is used when we want to write the current PC to the thread anchor
4243 operand immP_M1()
4244 %{
4245   predicate(n->get_ptr() == -1);
4246   match(ConP);
4247 
4248   op_cost(0);
4249   format %{ %}
4250   interface(CONST_INTER);
4251 %}
4252 
4253 // Pointer Immediate Minus Two


6937   match(Set mem (StoreL mem zero));
6938   predicate(!needs_releasing_store(n));
6939 
6940   ins_cost(INSN_COST);
6941   format %{ "str  zr, $mem\t# int" %}
6942 
6943   ins_encode(aarch64_enc_str0(mem));
6944 
6945   ins_pipe(istore_mem);
6946 %}
6947 
6948 // Store Pointer
6949 instruct storeP(iRegP src, memory mem)
6950 %{
6951   match(Set mem (StoreP mem src));
6952   predicate(!needs_releasing_store(n));
6953 
6954   ins_cost(INSN_COST);
6955   format %{ "str  $src, $mem\t# ptr" %}
6956 
6957   ins_encode %{
6958     int opcode = $mem->opcode();
6959     Register base = as_Register($mem$$base);
6960     int index = $mem$$index;
6961     int size = $mem$$scale;
6962     int disp = $mem$$disp;
6963     Register reg = as_Register($src$$reg);
6964 
6965     // we sometimes get asked to store the stack pointer into the
6966     // current thread -- we cannot do that directly on AArch64
6967     if (reg == r31_sp) {
6968       MacroAssembler _masm(&cbuf);
6969       assert(as_Register($mem$$base) == rthread, "unexpected store for sp");
6970       __ mov(rscratch2, sp);
6971       reg = rscratch2;
6972     }
6973     Address::extend scale;
6974 
6975     // Hooboy, this is fugly.  We need a way to communicate to the
6976     // encoder that the index needs to be sign extended, so we have to
6977     // enumerate all the cases.
6978     switch (opcode) {
6979     case INDINDEXSCALEDOFFSETI2L:
6980     case INDINDEXSCALEDI2L:
6981     case INDINDEXSCALEDOFFSETI2LN:
6982     case INDINDEXSCALEDI2LN:
6983     case INDINDEXOFFSETI2L:
6984     case INDINDEXOFFSETI2LN:
6985       scale = Address::sxtw(size);
6986       break;
6987     default:
6988       scale = Address::lsl(size);
6989     }
6990     Address adr;
6991     if (index == -1) {
6992       adr = Address(base, disp);
6993     } else {
6994       if (disp == 0) {
6995         adr = Address(base, as_Register(index), scale);
6996       } else {
6997         __ lea(rscratch1, Address(base, disp));
6998         adr = Address(rscratch1, as_Register(index), scale);
6999       }
7000     }
7001 
7002     __ str(reg, adr);
7003   %}
7004 
7005   ins_pipe(istore_reg_mem);
7006 %}
7007 
7008 // Store Pointer
7009 instruct storeimmP0(immP0 zero, memory mem)
7010 %{
7011   match(Set mem (StoreP mem zero));
7012   predicate(!needs_releasing_store(n));
7013 
7014   ins_cost(INSN_COST);
7015   format %{ "str zr, $mem\t# ptr" %}
7016 
7017   ins_encode(aarch64_enc_str0(mem));
7018 
7019   ins_pipe(istore_mem);
7020 %}
7021 
7022 // Store Compressed Pointer
7023 instruct storeN(iRegN src, memory mem)


8107 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
8108 
8109   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8110   ins_cost(2 * VOLATILE_REF_COST);
8111 
8112   effect(KILL cr);
8113 
8114  format %{
8115     "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8116     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8117  %}
8118 
8119  ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8120             aarch64_enc_cset_eq(res));
8121 
8122   ins_pipe(pipe_slow);
8123 %}
8124 
8125 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8126 
8127   predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR);
8128   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8129   ins_cost(2 * VOLATILE_REF_COST);
8130 
8131   effect(KILL cr);
8132 
8133  format %{
8134     "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8135     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8136  %}
8137 
8138  ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
8139             aarch64_enc_cset_eq(res));
8140 
8141   ins_pipe(pipe_slow);
8142 %}
8143 
8144 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
8145 
8146   predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR);
8147   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8148   ins_cost(2 * VOLATILE_REF_COST);
8149 
8150   effect(TEMP tmp, KILL cr);
8151 
8152   format %{
8153     "cmpxchg_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
8154   %}
8155 
8156   ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp, res));
8157 
8158   ins_pipe(pipe_slow);
8159 %}
8160 
8161 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8162 
8163   predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR);
8164   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8165   ins_cost(2 * VOLATILE_REF_COST);
8166 
8167   effect(KILL cr);
8168 
8169  format %{
8170     "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8171     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8172  %}
8173 
8174  ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
8175             aarch64_enc_cset_eq(res));
8176 
8177   ins_pipe(pipe_slow);
8178 %}
8179 
8180 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
8181 
8182   predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR);
8183   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8184   ins_cost(2 * VOLATILE_REF_COST);
8185 
8186   effect(TEMP tmp, KILL cr);
8187 
8188   format %{
8189     "cmpxchgw_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
8190   %}
8191 
8192   ins_encode %{
8193     Register tmp = $tmp$$Register;
8194     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
8195     ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
8196   %}
8197 
8198   ins_pipe(pipe_slow);
8199 %}
8200 
8201 // alternative CompareAndSwapX when we are eliding barriers
8202 
8203 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
8204 
8205   predicate(needs_acquiring_load_exclusive(n));
8206   match(Set res (CompareAndSwapI mem (Binary oldval newval)));
8207   ins_cost(VOLATILE_REF_COST);
8208 
8209   effect(KILL cr);
8210 
8211  format %{
8212     "cmpxchgw_acq $mem, $oldval, $newval\t# (int) if $mem == $oldval then $mem <-- $newval"
8213     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8214  %}
8215 
8216  ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8217             aarch64_enc_cset_eq(res));
8218 
8219   ins_pipe(pipe_slow);


8223 
8224   predicate(needs_acquiring_load_exclusive(n));
8225   match(Set res (CompareAndSwapL mem (Binary oldval newval)));
8226   ins_cost(VOLATILE_REF_COST);
8227 
8228   effect(KILL cr);
8229 
8230  format %{
8231     "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
8232     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8233  %}
8234 
8235  ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8236             aarch64_enc_cset_eq(res));
8237 
8238   ins_pipe(pipe_slow);
8239 %}
8240 
8241 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
8242 
8243   predicate(needs_acquiring_load_exclusive(n) && (!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR));
8244   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8245   ins_cost(VOLATILE_REF_COST);
8246 
8247   effect(KILL cr);
8248 
8249  format %{
8250     "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
8251     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8252  %}
8253 
8254  ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
8255             aarch64_enc_cset_eq(res));
8256 
8257   ins_pipe(pipe_slow);
8258 %}
8259 
8260 instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
8261 
8262   predicate(needs_acquiring_load_exclusive(n) && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR);
8263   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
8264   ins_cost(VOLATILE_REF_COST);
8265 
8266   effect(TEMP tmp, KILL cr);
8267 
8268   format %{
8269     "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
8270   %}
8271 
8272   ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp, res));
8273 
8274   ins_pipe(pipe_slow);
8275 %}
8276 
8277 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
8278 
8279   predicate(needs_acquiring_load_exclusive(n) && (!UseShenandoahGC || !ShenandoahCASBarrier|| n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR));
8280   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8281   ins_cost(VOLATILE_REF_COST);
8282 
8283   effect(KILL cr);
8284 
8285  format %{
8286     "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
8287     "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
8288  %}
8289 
8290  ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
8291             aarch64_enc_cset_eq(res));
8292 
8293   ins_pipe(pipe_slow);
8294 %}
8295 
8296 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
8297 
8298   predicate(needs_acquiring_load_exclusive(n) && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR);
8299   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
8300   ins_cost(VOLATILE_REF_COST);
8301 
8302   effect(TEMP tmp, KILL cr);
8303 
8304  format %{
8305     "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
8306  %}
8307 
8308   ins_encode %{
8309     Register tmp = $tmp$$Register;
8310     __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
8311     ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
8312   %}
8313 
8314   ins_pipe(pipe_slow);
8315 %}
8316 
8317 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
8318   match(Set prev (GetAndSetI mem newv));
8319   ins_cost(2 * VOLATILE_REF_COST);
8320   format %{ "atomic_xchgw  $prev, $newv, [$mem]" %}
8321   ins_encode %{
8322     __ atomic_xchgw($prev$$Register, $newv$$Register, as_Register($mem$$base));
8323   %}
8324   ins_pipe(pipe_serial);
8325 %}
8326 
8327 instruct get_and_setL(indirect mem, iRegL newv, iRegLNoSp prev) %{
8328   match(Set prev (GetAndSetL mem newv));
8329   ins_cost(2 * VOLATILE_REF_COST);
8330   format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
8331   ins_encode %{
8332     __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
8333   %}
8334   ins_pipe(pipe_serial);
8335 %}


< prev index next >