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