1 // Sundry CAS operations.  Note that release is always true,
   2 // regardless of the memory ordering of the CAS.  This is because we
   3 // need the volatile case to be sequentially consistent but there is
   4 // no trailing StoreLoad barrier emitted by C2.  Unfortunately we
   5 // can't check the type of memory ordering here, so we always emit a
   6 // STLXR.
   7 
   8 define(`CAS_INSN',
   9 `
  10 instruct compareAndExchange$1$5(iReg$2_R0 res, indirect mem, iReg$2_R2 oldval, iReg$2_R3 newval, rFlagsReg cr) %{
  11   match(Set res (CompareAndExchange$1 mem (Binary oldval newval)));
  12   ifelse($5,Acq,'  predicate(needs_acquiring_load_exclusive(n));
  13   ins_cost(VOLATILE_REF_COST);`,'  ins_cost(2 * VOLATILE_REF_COST);`)
  14   effect(KILL cr);
  15   format %{
  16     "cmpxchg $res = $mem, $oldval, $newval\t# ($3, weak) if $mem == $oldval then $mem <-- $newval"
  17   %}
  18   ins_encode %{
  19     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
  20                Assembler::$4, /*acquire*/ ifelse($5,Acq,true,false), /*release*/ true,
  21                /*weak*/ false, $res$$Register);
  22   %}
  23   ins_pipe(pipe_slow);
  24 %}')dnl
  25 define(`CAS_INSN4',
  26 `
  27 instruct compareAndExchange$1$7(iReg$2_R0 res, indirect mem, iReg$2_R2 oldval, iReg$2_R3 newval, rFlagsReg cr) %{
  28   match(Set res (CompareAndExchange$1 mem (Binary oldval newval)));
  29   ifelse($7,Acq,'  predicate(needs_acquiring_load_exclusive(n));
  30   ins_cost(VOLATILE_REF_COST);`,'  ins_cost(2 * VOLATILE_REF_COST);`)
  31   effect(KILL cr);
  32   format %{
  33     "cmpxchg $res = $mem, $oldval, $newval\t# ($3, weak) if $mem == $oldval then $mem <-- $newval"
  34   %}
  35   ins_encode %{
  36     __ $5(rscratch2, $oldval$$Register);
  37     __ cmpxchg($mem$$Register, rscratch2, $newval$$Register,
  38                Assembler::$4, /*acquire*/ ifelse($5,Acq,true,false), /*release*/ true,
  39                /*weak*/ false, $res$$Register);
  40     __ $6($res$$Register, $res$$Register);
  41   %}
  42   ins_pipe(pipe_slow);
  43 %}')dnl
  44 CAS_INSN4(B,I,byte,byte,uxtbw,sxtbw)
  45 CAS_INSN4(S,I,short,halfword,uxthw,sxthw)
  46 CAS_INSN(I,I,int,word)
  47 CAS_INSN(L,L,long,xword)
  48 CAS_INSN(N,N,narrow oop,word)
  49 CAS_INSN(P,P,ptr,xword)
  50 dnl
  51 dnl CAS_INSN4(B,I,byte,byte,uxtbw,sxtbw,Acq)
  52 dnl CAS_INSN4(S,I,short,halfword,uxthw,sxthw,Acq)
  53 dnl CAS_INSN(I,I,int,word,Acq)
  54 dnl CAS_INSN(L,L,long,xword,Acq)
  55 dnl CAS_INSN(N,N,narrow oop,word,Acq)
  56 dnl CAS_INSN(P,P,ptr,xword,Acq)
  57 dnl
  58 define(`CAS_INSN2',
  59 `
  60 instruct weakCompareAndSwap$1$6(iRegINoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{
  61   match(Set res (WeakCompareAndSwap$1 mem (Binary oldval newval)));
  62   ifelse($6,Acq,'  predicate(needs_acquiring_load_exclusive(n));
  63   ins_cost(VOLATILE_REF_COST);`,'  ins_cost(2 * VOLATILE_REF_COST);`)
  64   effect(KILL cr);
  65   format %{
  66     "cmpxchg $res = $mem, $oldval, $newval\t# ($3, weak) if $mem == $oldval then $mem <-- $newval"
  67     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
  68   %}
  69   ins_encode %{
  70     __ uxt$5(rscratch2, $oldval$$Register);
  71     __ cmpxchg($mem$$Register, rscratch2, $newval$$Register,
  72                Assembler::$4, /*acquire*/ ifelse($6,Acq,true,false), /*release*/ true,
  73                /*weak*/ true, noreg);
  74     __ csetw($res$$Register, Assembler::EQ);
  75   %}
  76   ins_pipe(pipe_slow);
  77 %}')dnl
  78 define(`CAS_INSN3',
  79 `
  80 instruct weakCompareAndSwap$1$5(iRegINoSp res, indirect mem, iReg$2 oldval, iReg$2 newval, rFlagsReg cr) %{
  81   match(Set res (WeakCompareAndSwap$1 mem (Binary oldval newval)));
  82   ifelse($5,Acq,'  predicate(needs_acquiring_load_exclusive(n));
  83   ins_cost(VOLATILE_REF_COST);`,'  ins_cost(2 * VOLATILE_REF_COST);`)
  84   effect(KILL cr);
  85   format %{
  86     "cmpxchg $res = $mem, $oldval, $newval\t# ($3, weak) if $mem == $oldval then $mem <-- $newval"
  87     "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
  88   %}
  89   ins_encode %{
  90     __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
  91                Assembler::$4, /*acquire*/ ifelse($5,Acq,true,false), /*release*/ true,
  92                /*weak*/ true, noreg);
  93     __ csetw($res$$Register, Assembler::EQ);
  94   %}
  95   ins_pipe(pipe_slow);
  96 %}')dnl
  97 CAS_INSN2(B,I,byte,byte,bw)
  98 CAS_INSN2(S,I,short,halfword,hw)
  99 CAS_INSN3(I,I,int,word)
 100 CAS_INSN3(L,L,long,xword)
 101 CAS_INSN3(N,N,narrow oop,word)
 102 CAS_INSN3(P,P,ptr,xword)
 103 dnl CAS_INSN2(B,I,byte,byte,bw,Acq)
 104 dnl CAS_INSN2(S,I,short,halfword,hw,Acq)
 105 dnl CAS_INSN3(I,I,int,word,Acq)
 106 dnl CAS_INSN3(L,L,long,xword,Acq)
 107 dnl CAS_INSN3(N,N,narrow oop,word,Acq)
 108 dnl CAS_INSN3(P,P,ptr,xword,Acq)
 109 dnl