1 //
2 // Copyright (c) 2018, 2021, Red Hat, Inc. All rights reserved.
3 // Copyright (c) 2012, 2021 SAP SE. All rights reserved.
4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 //
6 // This code is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License version 2 only, as
8 // published by the Free Software Foundation.
9 //
10 // This code is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // version 2 for more details (a copy is included in the LICENSE file that
14 // accompanied this code).
15 //
16 // You should have received a copy of the GNU General Public License version
17 // 2 along with this work; if not, write to the Free Software Foundation,
18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 // or visit www.oracle.com if you need additional information or have any
22 // questions.
23 //
24 //
25
26 source_hpp %{
27 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
28 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
29 %}
30
31 // Weak compareAndSwap operations are treated as strong compareAndSwap operations.
32 // This is motivated by the retry logic of ShenandoahBarrierSetAssembler::cmpxchg_oop which is hard to realise
33 // using weak CAS operations.
34
35 instruct compareAndSwapP_shenandoah(iRegIdst res, indirect mem, iRegPsrc oldval, iRegPsrc newval,
36 iRegPdst tmp1, iRegPdst tmp2, flagsRegCR0 cr) %{
37 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
38 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval)));
39 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
40
41 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire
42 && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
43
44 format %{ "CMPXCHG $res, $mem, $oldval, $newval; as bool; ptr" %}
45 ins_encode %{
46 ShenandoahBarrierSet::assembler()->cmpxchg_oop(
47 masm,
48 $mem$$Register, $oldval$$Register, $newval$$Register,
49 $tmp1$$Register, $tmp2$$Register,
50 false, $res$$Register
51 );
52 %}
53 ins_pipe(pipe_class_default);
54 %}
55
56 instruct compareAndSwapN_shenandoah(iRegIdst res, indirect mem, iRegNsrc oldval, iRegNsrc newval,
57 iRegNdst tmp1, iRegNdst tmp2, flagsRegCR0 cr) %{
58 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
59 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval)));
60 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
61
62 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire
63 && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
64
65 format %{ "CMPXCHG $res, $mem, $oldval, $newval; as bool; ptr" %}
66 ins_encode %{
67 ShenandoahBarrierSet::assembler()->cmpxchg_oop(
68 masm,
69 $mem$$Register, $oldval$$Register, $newval$$Register,
70 $tmp1$$Register, $tmp2$$Register,
71 false, $res$$Register
72 );
73 %}
74 ins_pipe(pipe_class_default);
75 %}
76
77 instruct compareAndSwapP_acq_shenandoah(iRegIdst res, indirect mem, iRegPsrc oldval, iRegPsrc newval,
78 iRegPdst tmp1, iRegPdst tmp2, flagsRegCR0 cr) %{
79 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
80 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval)));
81 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
82
83 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire
84 || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
85
86 format %{ "CMPXCHGD acq $res, $mem, $oldval, $newval; as bool; ptr" %}
87 ins_encode %{
88 ShenandoahBarrierSet::assembler()->cmpxchg_oop(
89 masm,
90 $mem$$Register, $oldval$$Register, $newval$$Register,
91 $tmp1$$Register, $tmp2$$Register,
92 false, $res$$Register
93 );
94 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
95 __ isync();
96 } else {
97 __ sync();
98 }
99 %}
100 ins_pipe(pipe_class_default);
101 %}
102
103 instruct compareAndSwapN_acq_shenandoah(iRegIdst res, indirect mem, iRegNsrc oldval, iRegNsrc newval,
104 iRegNdst tmp1, iRegNdst tmp2, flagsRegCR0 cr) %{
105 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
106 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval)));
107 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
108
109 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire
110 || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
111
112 format %{ "CMPXCHGD acq $res, $mem, $oldval, $newval; as bool; ptr" %}
113 ins_encode %{
114 ShenandoahBarrierSet::assembler()->cmpxchg_oop(
115 masm,
116 $mem$$Register, $oldval$$Register, $newval$$Register,
117 $tmp1$$Register, $tmp2$$Register,
118 false, $res$$Register
119 );
120 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
121 __ isync();
122 } else {
123 __ sync();
124 }
125 %}
126 ins_pipe(pipe_class_default);
127 %}
128
129 instruct compareAndExchangeP_shenandoah(iRegPdst res, indirect mem, iRegPsrc oldval, iRegPsrc newval,
130 iRegPdst tmp1, iRegPdst tmp2, flagsRegCR0 cr) %{
131 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval)));
132 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
133
134 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire
135 && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
136
137 format %{ "CMPXCHGD $res, $mem, $oldval, $newval; as ptr; ptr" %}
138 ins_encode %{
139 ShenandoahBarrierSet::assembler()->cmpxchg_oop(
140 masm,
141 $mem$$Register, $oldval$$Register, $newval$$Register,
142 $tmp1$$Register, $tmp2$$Register,
143 true, $res$$Register
144 );
145 %}
146 ins_pipe(pipe_class_default);
147 %}
148
149 instruct compareAndExchangeN_shenandoah(iRegNdst res, indirect mem, iRegNsrc oldval, iRegNsrc newval,
150 iRegNdst tmp1, iRegNdst tmp2, flagsRegCR0 cr) %{
151 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval)));
152 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
153
154 predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire
155 && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
156
157 format %{ "CMPXCHGD $res, $mem, $oldval, $newval; as ptr; ptr" %}
158 ins_encode %{
159 ShenandoahBarrierSet::assembler()->cmpxchg_oop(
160 masm,
161 $mem$$Register, $oldval$$Register, $newval$$Register,
162 $tmp1$$Register, $tmp2$$Register,
163 true, $res$$Register
164 );
165 %}
166 ins_pipe(pipe_class_default);
167 %}
168
169 instruct compareAndExchangePAcq_shenandoah(iRegPdst res, indirect mem, iRegPsrc oldval, iRegPsrc newval,
170 iRegPdst tmp1, iRegPdst tmp2, flagsRegCR0 cr) %{
171 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval)));
172 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
173
174 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire
175 || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
176
177 format %{ "CMPXCHGD acq $res, $mem, $oldval, $newval; as ptr; ptr" %}
178 ins_encode %{
179 ShenandoahBarrierSet::assembler()->cmpxchg_oop(
180 masm,
181 $mem$$Register, $oldval$$Register, $newval$$Register,
182 $tmp1$$Register, $tmp2$$Register,
183 true, $res$$Register
184 );
185 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
186 __ isync();
187 } else {
188 __ sync();
189 }
190 %}
191 ins_pipe(pipe_class_default);
192 %}
193
194 instruct compareAndExchangeNAcq_shenandoah(iRegNdst res, indirect mem, iRegNsrc oldval, iRegNsrc newval,
195 iRegNdst tmp1, iRegNdst tmp2, flagsRegCR0 cr) %{
196 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval)));
197 effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr);
198
199 predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire
200 || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
201
202 format %{ "CMPXCHGD acq $res, $mem, $oldval, $newval; as ptr; ptr" %}
203 ins_encode %{
204 ShenandoahBarrierSet::assembler()->cmpxchg_oop(
205 masm,
206 $mem$$Register, $oldval$$Register, $newval$$Register,
207 $tmp1$$Register, $tmp2$$Register,
208 true, $res$$Register
209 );
210 if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
211 __ isync();
212 } else {
213 __ sync();
214 }
215 %}
216 ins_pipe(pipe_class_default);
217 %}