1880 // and barrier nodes employ a few simple helper functions (described
1881 // below) which identify the presence or absence of all these
1882 // subgraph configurations and provide a means of traversing from
1883 // one node in the subgraph to another.
1884
1885 // is_CAS(int opcode)
1886 //
1887 // return true if opcode is one of the possible CompareAndSwapX
1888 // values otherwise false.
1889
1890 bool is_CAS(int opcode)
1891 {
1892 switch(opcode) {
1893 // We handle these
1894 case Op_CompareAndSwapI:
1895 case Op_CompareAndSwapL:
1896 case Op_CompareAndSwapP:
1897 case Op_CompareAndSwapN:
1898 // case Op_CompareAndSwapB:
1899 // case Op_CompareAndSwapS:
1900 return true;
1901 // These are TBD
1902 case Op_WeakCompareAndSwapB:
1903 case Op_WeakCompareAndSwapS:
1904 case Op_WeakCompareAndSwapI:
1905 case Op_WeakCompareAndSwapL:
1906 case Op_WeakCompareAndSwapP:
1907 case Op_WeakCompareAndSwapN:
1908 case Op_CompareAndExchangeB:
1909 case Op_CompareAndExchangeS:
1910 case Op_CompareAndExchangeI:
1911 case Op_CompareAndExchangeL:
1912 case Op_CompareAndExchangeP:
1913 case Op_CompareAndExchangeN:
1914 return false;
1915 default:
1916 return false;
1917 }
1918 }
1919
9653 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
9654
9655 match(Set res (CompareAndSwapL mem (Binary oldval newval)));
9656 ins_cost(2 * VOLATILE_REF_COST);
9657
9658 effect(KILL cr);
9659
9660 format %{
9661 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
9662 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9663 %}
9664
9665 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
9666 aarch64_enc_cset_eq(res));
9667
9668 ins_pipe(pipe_slow);
9669 %}
9670
9671 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9672
9673 predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR);
9674 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
9675 ins_cost(2 * VOLATILE_REF_COST);
9676
9677 effect(KILL cr);
9678
9679 format %{
9680 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
9681 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9682 %}
9683
9684 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
9685 aarch64_enc_cset_eq(res));
9686
9687 ins_pipe(pipe_slow);
9688 %}
9689
9690 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
9691
9692 predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR);
9693 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
9694 ins_cost(2 * VOLATILE_REF_COST);
9695
9696 effect(TEMP tmp, KILL cr);
9697
9698 format %{
9699 "cmpxchg_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
9700 %}
9701
9702 ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp, res));
9703
9704 ins_pipe(pipe_slow);
9705 %}
9706
9707 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
9708
9709 predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR);
9710 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
9711 ins_cost(2 * VOLATILE_REF_COST);
9712
9713 effect(KILL cr);
9714
9715 format %{
9716 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
9717 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9718 %}
9719
9720 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
9721 aarch64_enc_cset_eq(res));
9722
9723 ins_pipe(pipe_slow);
9724 %}
9725
9726 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
9727
9728 predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR);
9729 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
9730 ins_cost(2 * VOLATILE_REF_COST);
9731
9732 effect(TEMP tmp, KILL cr);
9733
9734 format %{
9735 "cmpxchgw_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
9736 %}
9737
9738 ins_encode %{
9739 Register tmp = $tmp$$Register;
9740 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
9741 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
9742 %}
9743
9744 ins_pipe(pipe_slow);
9745 %}
9746
9747 // alternative CompareAndSwapX when we are eliding barriers
9748
9749 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
9769
9770 predicate(needs_acquiring_load_exclusive(n));
9771 match(Set res (CompareAndSwapL mem (Binary oldval newval)));
9772 ins_cost(VOLATILE_REF_COST);
9773
9774 effect(KILL cr);
9775
9776 format %{
9777 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
9778 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9779 %}
9780
9781 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
9782 aarch64_enc_cset_eq(res));
9783
9784 ins_pipe(pipe_slow);
9785 %}
9786
9787 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9788
9789 predicate(needs_acquiring_load_exclusive(n) && (!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR));
9790 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
9791 ins_cost(VOLATILE_REF_COST);
9792
9793 effect(KILL cr);
9794
9795 format %{
9796 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
9797 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9798 %}
9799
9800 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
9801 aarch64_enc_cset_eq(res));
9802
9803 ins_pipe(pipe_slow);
9804 %}
9805
9806 instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
9807
9808 predicate(needs_acquiring_load_exclusive(n) && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR);
9809 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
9810 ins_cost(VOLATILE_REF_COST);
9811
9812 effect(TEMP tmp, KILL cr);
9813
9814 format %{
9815 "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
9816 %}
9817
9818 ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp, res));
9819
9820 ins_pipe(pipe_slow);
9821 %}
9822
9823 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
9824
9825 predicate(needs_acquiring_load_exclusive(n) && (!UseShenandoahGC || !ShenandoahCASBarrier|| n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR));
9826 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
9827 ins_cost(VOLATILE_REF_COST);
9828
9829 effect(KILL cr);
9830
9831 format %{
9832 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
9833 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9834 %}
9835
9836 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
9837 aarch64_enc_cset_eq(res));
9838
9839 ins_pipe(pipe_slow);
9840 %}
9841
9842 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
9843
9844 predicate(needs_acquiring_load_exclusive(n) && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR);
9845 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
9846 ins_cost(VOLATILE_REF_COST);
9847
9848 effect(TEMP tmp, KILL cr);
9849
9850 format %{
9851 "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
9852 %}
9853
9854 ins_encode %{
9855 Register tmp = $tmp$$Register;
9856 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
9857 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
9858 %}
9859
9860 ins_pipe(pipe_slow);
9861 %}
9862
9863 // ---------------------------------------------------------------------
9864
9865
9922 %}
9923 ins_pipe(pipe_slow);
9924 %}
9925
9926 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
9927 match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
9928 ins_cost(2 * VOLATILE_REF_COST);
9929 effect(TEMP_DEF res, KILL cr);
9930 format %{
9931 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
9932 %}
9933 ins_encode %{
9934 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9935 Assembler::xword, /*acquire*/ false, /*release*/ true,
9936 /*weak*/ false, $res$$Register);
9937 %}
9938 ins_pipe(pipe_slow);
9939 %}
9940
9941 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
9942 predicate(!UseShenandoahGC || !ShenandoahCASBarrier);
9943 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
9944 ins_cost(2 * VOLATILE_REF_COST);
9945 effect(TEMP_DEF res, KILL cr);
9946 format %{
9947 "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9948 %}
9949 ins_encode %{
9950 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9951 Assembler::word, /*acquire*/ false, /*release*/ true,
9952 /*weak*/ false, $res$$Register);
9953 %}
9954 ins_pipe(pipe_slow);
9955 %}
9956
9957 instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
9958 predicate(UseShenandoahGC && ShenandoahCASBarrier);
9959 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
9960 ins_cost(3 * VOLATILE_REF_COST);
9961 effect(TEMP_DEF res, TEMP tmp, KILL cr);
9962 format %{
9963 "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9964 %}
9965 ins_encode %{
9966 Register tmp = $tmp$$Register;
9967 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
9968 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
9969 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register);
9970 %}
9971 ins_pipe(pipe_slow);
9972 %}
9973
9974 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9975 predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR);
9976 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
9977 ins_cost(2 * VOLATILE_REF_COST);
9978 effect(TEMP_DEF res, KILL cr);
9979 format %{
9980 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
9981 %}
9982 ins_encode %{
9983 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9984 Assembler::xword, /*acquire*/ false, /*release*/ true,
9985 /*weak*/ false, $res$$Register);
9986 %}
9987 ins_pipe(pipe_slow);
9988 %}
9989
9990 instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
9991 predicate(UseShenandoahGC && ShenandoahCASBarrier);
9992 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
9993 ins_cost(3 * VOLATILE_REF_COST);
9994 effect(TEMP_DEF res, TEMP tmp, KILL cr);
9995 format %{
9996 "cmpxchg_oop_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
9997 %}
9998 ins_encode %{
9999 Register tmp = $tmp$$Register;
10000 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
10001 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
10002 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register);
10003 %}
10004 ins_pipe(pipe_slow);
10005 %}
10006
10007 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
10008 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
10009 ins_cost(2 * VOLATILE_REF_COST);
10010 effect(KILL cr);
10011 format %{
10012 "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
10056 %}
10057
10058 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
10059 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
10060 ins_cost(2 * VOLATILE_REF_COST);
10061 effect(KILL cr);
10062 format %{
10063 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
10064 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
10065 %}
10066 ins_encode %{
10067 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
10068 Assembler::xword, /*acquire*/ false, /*release*/ true,
10069 /*weak*/ true, noreg);
10070 __ csetw($res$$Register, Assembler::EQ);
10071 %}
10072 ins_pipe(pipe_slow);
10073 %}
10074
10075 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
10076 predicate(!UseShenandoahGC || !ShenandoahCASBarrier);
10077 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
10078 ins_cost(2 * VOLATILE_REF_COST);
10079 effect(KILL cr);
10080 format %{
10081 "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
10082 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
10083 %}
10084 ins_encode %{
10085 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
10086 Assembler::word, /*acquire*/ false, /*release*/ true,
10087 /*weak*/ true, noreg);
10088 __ csetw($res$$Register, Assembler::EQ);
10089 %}
10090 ins_pipe(pipe_slow);
10091 %}
10092
10093 instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
10094 predicate(UseShenandoahGC && ShenandoahCASBarrier);
10095 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
10096 ins_cost(3 * VOLATILE_REF_COST);
10097 effect(TEMP tmp, KILL cr);
10098 format %{
10099 "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
10100 %}
10101 ins_encode %{
10102 Register tmp = $tmp$$Register;
10103 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
10104 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
10105 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register);
10106 %}
10107 ins_pipe(pipe_slow);
10108 %}
10109
10110 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
10111 predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR);
10112 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
10113 ins_cost(2 * VOLATILE_REF_COST);
10114 effect(KILL cr);
10115 format %{
10116 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
10117 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
10118 %}
10119 ins_encode %{
10120 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
10121 Assembler::xword, /*acquire*/ false, /*release*/ true,
10122 /*weak*/ true, noreg);
10123 __ csetw($res$$Register, Assembler::EQ);
10124 %}
10125 ins_pipe(pipe_slow);
10126 %}
10127
10128 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
10129 predicate(UseShenandoahGC && ShenandoahCASBarrier);
10130 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
10131 ins_cost(3 * VOLATILE_REF_COST);
10132 effect(TEMP tmp, KILL cr);
10133 format %{
10134 "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
10135 %}
10136 ins_encode %{
10137 Register tmp = $tmp$$Register;
10138 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
10139 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
10140 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register);
10141 %}
10142 ins_pipe(pipe_slow);
10143 %}
10144 // END This section of the file is automatically generated. Do not edit --------------
10145 // ---------------------------------------------------------------------
10146
10147 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
10148 match(Set prev (GetAndSetI mem newv));
10149 format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
10150 ins_encode %{
|
1880 // and barrier nodes employ a few simple helper functions (described
1881 // below) which identify the presence or absence of all these
1882 // subgraph configurations and provide a means of traversing from
1883 // one node in the subgraph to another.
1884
1885 // is_CAS(int opcode)
1886 //
1887 // return true if opcode is one of the possible CompareAndSwapX
1888 // values otherwise false.
1889
1890 bool is_CAS(int opcode)
1891 {
1892 switch(opcode) {
1893 // We handle these
1894 case Op_CompareAndSwapI:
1895 case Op_CompareAndSwapL:
1896 case Op_CompareAndSwapP:
1897 case Op_CompareAndSwapN:
1898 // case Op_CompareAndSwapB:
1899 // case Op_CompareAndSwapS:
1900 #if INCLUDE_SHENANDOAHGC
1901 case Op_ShenandoahCompareAndSwapP:
1902 case Op_ShenandoahCompareAndSwapN:
1903 #endif
1904 return true;
1905 // These are TBD
1906 case Op_WeakCompareAndSwapB:
1907 case Op_WeakCompareAndSwapS:
1908 case Op_WeakCompareAndSwapI:
1909 case Op_WeakCompareAndSwapL:
1910 case Op_WeakCompareAndSwapP:
1911 case Op_WeakCompareAndSwapN:
1912 case Op_CompareAndExchangeB:
1913 case Op_CompareAndExchangeS:
1914 case Op_CompareAndExchangeI:
1915 case Op_CompareAndExchangeL:
1916 case Op_CompareAndExchangeP:
1917 case Op_CompareAndExchangeN:
1918 return false;
1919 default:
1920 return false;
1921 }
1922 }
1923
9657 instruct compareAndSwapL(iRegINoSp res, indirect mem, iRegLNoSp oldval, iRegLNoSp newval, rFlagsReg cr) %{
9658
9659 match(Set res (CompareAndSwapL mem (Binary oldval newval)));
9660 ins_cost(2 * VOLATILE_REF_COST);
9661
9662 effect(KILL cr);
9663
9664 format %{
9665 "cmpxchg $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
9666 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9667 %}
9668
9669 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
9670 aarch64_enc_cset_eq(res));
9671
9672 ins_pipe(pipe_slow);
9673 %}
9674
9675 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9676
9677 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
9678 ins_cost(2 * VOLATILE_REF_COST);
9679
9680 effect(KILL cr);
9681
9682 format %{
9683 "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
9684 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9685 %}
9686
9687 ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
9688 aarch64_enc_cset_eq(res));
9689
9690 ins_pipe(pipe_slow);
9691 %}
9692
9693 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
9694
9695 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
9696 ins_cost(2 * VOLATILE_REF_COST);
9697
9698 effect(TEMP tmp, KILL cr);
9699
9700 format %{
9701 "cmpxchg_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
9702 %}
9703
9704 ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp, res));
9705
9706 ins_pipe(pipe_slow);
9707 %}
9708
9709 instruct compareAndSwapN(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
9710
9711 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
9712 ins_cost(2 * VOLATILE_REF_COST);
9713
9714 effect(KILL cr);
9715
9716 format %{
9717 "cmpxchgw $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
9718 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9719 %}
9720
9721 ins_encode(aarch64_enc_cmpxchgw(mem, oldval, newval),
9722 aarch64_enc_cset_eq(res));
9723
9724 ins_pipe(pipe_slow);
9725 %}
9726
9727 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
9728
9729 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
9730 ins_cost(2 * VOLATILE_REF_COST);
9731
9732 effect(TEMP tmp, KILL cr);
9733
9734 format %{
9735 "cmpxchgw_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
9736 %}
9737
9738 ins_encode %{
9739 Register tmp = $tmp$$Register;
9740 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
9741 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
9742 %}
9743
9744 ins_pipe(pipe_slow);
9745 %}
9746
9747 // alternative CompareAndSwapX when we are eliding barriers
9748
9749 instruct compareAndSwapIAcq(iRegINoSp res, indirect mem, iRegINoSp oldval, iRegINoSp newval, rFlagsReg cr) %{
9769
9770 predicate(needs_acquiring_load_exclusive(n));
9771 match(Set res (CompareAndSwapL mem (Binary oldval newval)));
9772 ins_cost(VOLATILE_REF_COST);
9773
9774 effect(KILL cr);
9775
9776 format %{
9777 "cmpxchg_acq $mem, $oldval, $newval\t# (long) if $mem == $oldval then $mem <-- $newval"
9778 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9779 %}
9780
9781 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
9782 aarch64_enc_cset_eq(res));
9783
9784 ins_pipe(pipe_slow);
9785 %}
9786
9787 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9788
9789 predicate(needs_acquiring_load_exclusive(n));
9790 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
9791 ins_cost(VOLATILE_REF_COST);
9792
9793 effect(KILL cr);
9794
9795 format %{
9796 "cmpxchg_acq $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
9797 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9798 %}
9799
9800 ins_encode(aarch64_enc_cmpxchg_acq(mem, oldval, newval),
9801 aarch64_enc_cset_eq(res));
9802
9803 ins_pipe(pipe_slow);
9804 %}
9805
9806 instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
9807
9808 predicate(needs_acquiring_load_exclusive(n));
9809 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
9810 ins_cost(VOLATILE_REF_COST);
9811
9812 effect(TEMP tmp, KILL cr);
9813
9814 format %{
9815 "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
9816 %}
9817
9818 ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp, res));
9819
9820 ins_pipe(pipe_slow);
9821 %}
9822
9823 instruct compareAndSwapNAcq(iRegINoSp res, indirect mem, iRegNNoSp oldval, iRegNNoSp newval, rFlagsReg cr) %{
9824
9825 predicate(needs_acquiring_load_exclusive(n));
9826 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
9827 ins_cost(VOLATILE_REF_COST);
9828
9829 effect(KILL cr);
9830
9831 format %{
9832 "cmpxchgw_acq $mem, $oldval, $newval\t# (narrow oop) if $mem == $oldval then $mem <-- $newval"
9833 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
9834 %}
9835
9836 ins_encode(aarch64_enc_cmpxchgw_acq(mem, oldval, newval),
9837 aarch64_enc_cset_eq(res));
9838
9839 ins_pipe(pipe_slow);
9840 %}
9841
9842 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
9843
9844 predicate(needs_acquiring_load_exclusive(n));
9845 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
9846 ins_cost(VOLATILE_REF_COST);
9847
9848 effect(TEMP tmp, KILL cr);
9849
9850 format %{
9851 "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
9852 %}
9853
9854 ins_encode %{
9855 Register tmp = $tmp$$Register;
9856 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
9857 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*is_cae*/ false, $res$$Register);
9858 %}
9859
9860 ins_pipe(pipe_slow);
9861 %}
9862
9863 // ---------------------------------------------------------------------
9864
9865
9922 %}
9923 ins_pipe(pipe_slow);
9924 %}
9925
9926 instruct compareAndExchangeL(iRegLNoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
9927 match(Set res (CompareAndExchangeL mem (Binary oldval newval)));
9928 ins_cost(2 * VOLATILE_REF_COST);
9929 effect(TEMP_DEF res, KILL cr);
9930 format %{
9931 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
9932 %}
9933 ins_encode %{
9934 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9935 Assembler::xword, /*acquire*/ false, /*release*/ true,
9936 /*weak*/ false, $res$$Register);
9937 %}
9938 ins_pipe(pipe_slow);
9939 %}
9940
9941 instruct compareAndExchangeN(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
9942 match(Set res (CompareAndExchangeN mem (Binary oldval newval)));
9943 ins_cost(2 * VOLATILE_REF_COST);
9944 effect(TEMP_DEF res, KILL cr);
9945 format %{
9946 "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9947 %}
9948 ins_encode %{
9949 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9950 Assembler::word, /*acquire*/ false, /*release*/ true,
9951 /*weak*/ false, $res$$Register);
9952 %}
9953 ins_pipe(pipe_slow);
9954 %}
9955
9956 instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
9957 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval)));
9958 ins_cost(3 * VOLATILE_REF_COST);
9959 effect(TEMP_DEF res, TEMP tmp, KILL cr);
9960 format %{
9961 "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
9962 %}
9963 ins_encode %{
9964 Register tmp = $tmp$$Register;
9965 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
9966 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
9967 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register);
9968 %}
9969 ins_pipe(pipe_slow);
9970 %}
9971
9972 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
9973 match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
9974 ins_cost(2 * VOLATILE_REF_COST);
9975 effect(TEMP_DEF res, KILL cr);
9976 format %{
9977 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
9978 %}
9979 ins_encode %{
9980 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
9981 Assembler::xword, /*acquire*/ false, /*release*/ true,
9982 /*weak*/ false, $res$$Register);
9983 %}
9984 ins_pipe(pipe_slow);
9985 %}
9986
9987 instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
9988 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval)));
9989 ins_cost(3 * VOLATILE_REF_COST);
9990 effect(TEMP_DEF res, TEMP tmp, KILL cr);
9991 format %{
9992 "cmpxchg_oop_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp"
9993 %}
9994 ins_encode %{
9995 Register tmp = $tmp$$Register;
9996 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
9997 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
9998 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*is_cae*/ true, $res$$Register);
9999 %}
10000 ins_pipe(pipe_slow);
10001 %}
10002
10003 instruct weakCompareAndSwapB(iRegINoSp res, indirect mem, iRegI oldval, iRegI newval, rFlagsReg cr) %{
10004 match(Set res (WeakCompareAndSwapB mem (Binary oldval newval)));
10005 ins_cost(2 * VOLATILE_REF_COST);
10006 effect(KILL cr);
10007 format %{
10008 "cmpxchg $res = $mem, $oldval, $newval\t# (byte, weak) if $mem == $oldval then $mem <-- $newval"
10052 %}
10053
10054 instruct weakCompareAndSwapL(iRegINoSp res, indirect mem, iRegL oldval, iRegL newval, rFlagsReg cr) %{
10055 match(Set res (WeakCompareAndSwapL mem (Binary oldval newval)));
10056 ins_cost(2 * VOLATILE_REF_COST);
10057 effect(KILL cr);
10058 format %{
10059 "cmpxchg $res = $mem, $oldval, $newval\t# (long, weak) if $mem == $oldval then $mem <-- $newval"
10060 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
10061 %}
10062 ins_encode %{
10063 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
10064 Assembler::xword, /*acquire*/ false, /*release*/ true,
10065 /*weak*/ true, noreg);
10066 __ csetw($res$$Register, Assembler::EQ);
10067 %}
10068 ins_pipe(pipe_slow);
10069 %}
10070
10071 instruct weakCompareAndSwapN(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, rFlagsReg cr) %{
10072 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
10073 ins_cost(2 * VOLATILE_REF_COST);
10074 effect(KILL cr);
10075 format %{
10076 "cmpxchg $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
10077 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
10078 %}
10079 ins_encode %{
10080 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
10081 Assembler::word, /*acquire*/ false, /*release*/ true,
10082 /*weak*/ true, noreg);
10083 __ csetw($res$$Register, Assembler::EQ);
10084 %}
10085 ins_pipe(pipe_slow);
10086 %}
10087
10088 instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
10089 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval)));
10090 ins_cost(3 * VOLATILE_REF_COST);
10091 effect(TEMP tmp, KILL cr);
10092 format %{
10093 "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval"
10094 %}
10095 ins_encode %{
10096 Register tmp = $tmp$$Register;
10097 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
10098 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
10099 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register);
10100 %}
10101 ins_pipe(pipe_slow);
10102 %}
10103
10104 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
10105 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
10106 ins_cost(2 * VOLATILE_REF_COST);
10107 effect(KILL cr);
10108 format %{
10109 "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
10110 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)"
10111 %}
10112 ins_encode %{
10113 __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
10114 Assembler::xword, /*acquire*/ false, /*release*/ true,
10115 /*weak*/ true, noreg);
10116 __ csetw($res$$Register, Assembler::EQ);
10117 %}
10118 ins_pipe(pipe_slow);
10119 %}
10120
10121 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
10122 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval)));
10123 ins_cost(3 * VOLATILE_REF_COST);
10124 effect(TEMP tmp, KILL cr);
10125 format %{
10126 "cmpxchg_oop_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
10127 %}
10128 ins_encode %{
10129 Register tmp = $tmp$$Register;
10130 __ mov(tmp, $oldval$$Register); // Must not clobber oldval.
10131 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register,
10132 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*is_cae*/ false, $res$$Register);
10133 %}
10134 ins_pipe(pipe_slow);
10135 %}
10136 // END This section of the file is automatically generated. Do not edit --------------
10137 // ---------------------------------------------------------------------
10138
10139 instruct get_and_setI(indirect mem, iRegI newv, iRegINoSp prev) %{
10140 match(Set prev (GetAndSetI mem newv));
10141 format %{ "atomic_xchgw $prev, $newv, [$mem]" %}
10142 ins_encode %{
|