1 //
2 // Copyright (c) 2018, Red Hat, Inc. All rights reserved.
3 // Copyright (c) 2020, 2021, Huawei Technologies Co., Ltd. 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 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
32 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
33 ins_cost(10 * DEFAULT_COST);
34
35 effect(TEMP tmp, KILL cr);
36
37 format %{
38 "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapP_shenandoah"
39 %}
40
41 ins_encode %{
42 Register tmp = $tmp$$Register;
43 __ mv(tmp, $oldval$$Register); // Must not clobber oldval.
44 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
45 Assembler::relaxed /* acquire */, Assembler::rl /* release */,
46 false /* is_cae */, $res$$Register);
47 %}
48
49 ins_pipe(pipe_slow);
50 %}
51
52 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
53 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
54 ins_cost(10 * DEFAULT_COST);
55
56 effect(TEMP tmp, KILL cr);
57
58 format %{
59 "cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapN_shenandoah"
60 %}
61
62 ins_encode %{
63 Register tmp = $tmp$$Register;
64 __ mv(tmp, $oldval$$Register); // Must not clobber oldval.
65 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
66 Assembler::relaxed /* acquire */, Assembler::rl /* release */,
67 false /* is_cae */, $res$$Register);
68 %}
69
70 ins_pipe(pipe_slow);
71 %}
72
73 instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
74 predicate(needs_acquiring_load_reserved(n));
75 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval)));
76 ins_cost(10 * DEFAULT_COST);
77
78 effect(TEMP tmp, KILL cr);
79
80 format %{
81 "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapPAcq_shenandoah"
82 %}
83
84 ins_encode %{
85 Register tmp = $tmp$$Register;
86 __ mv(tmp, $oldval$$Register); // Must not clobber oldval.
87 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
88 Assembler::aq /* acquire */, Assembler::rl /* release */,
89 false /* is_cae */, $res$$Register);
90 %}
91
92 ins_pipe(pipe_slow);
93 %}
94
95 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
96 predicate(needs_acquiring_load_reserved(n));
97 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval)));
98 ins_cost(10 * DEFAULT_COST);
99
100 effect(TEMP tmp, KILL cr);
101
102 format %{
103 "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndSwapNAcq_shenandoah"
104 %}
105
106 ins_encode %{
107 Register tmp = $tmp$$Register;
108 __ mv(tmp, $oldval$$Register); // Must not clobber oldval.
109 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
110 Assembler::aq /* acquire */, Assembler::rl /* release */,
111 false /* is_cae */, $res$$Register);
112 %}
113
114 ins_pipe(pipe_slow);
115 %}
116
117 instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
118 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval)));
119 ins_cost(10 * DEFAULT_COST);
120 effect(TEMP_DEF res, TEMP tmp, KILL cr);
121
122 format %{
123 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeN_shenandoah"
124 %}
125
126 ins_encode %{
127 Register tmp = $tmp$$Register;
128 __ mv(tmp, $oldval$$Register); // Must not clobber oldval.
129 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
130 Assembler::relaxed /* acquire */, Assembler::rl /* release */,
131 true /* is_cae */, $res$$Register);
132 %}
133
134 ins_pipe(pipe_slow);
135 %}
136
137 instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
138 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval)));
139 ins_cost(10 * DEFAULT_COST);
140
141 effect(TEMP_DEF res, TEMP tmp, KILL cr);
142 format %{
143 "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp, #@compareAndExchangeP_shenandoah"
144 %}
145
146 ins_encode %{
147 Register tmp = $tmp$$Register;
148 __ mv(tmp, $oldval$$Register); // Must not clobber oldval.
149 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
150 Assembler::relaxed /* acquire */, Assembler::rl /* release */,
151 true /* is_cae */, $res$$Register);
152 %}
153
154 ins_pipe(pipe_slow);
155 %}
156
157 instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
158 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval)));
159 ins_cost(10 * DEFAULT_COST);
160
161 effect(TEMP tmp, KILL cr);
162 format %{
163 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapN_shenandoah"
164 "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)"
165 %}
166
167 ins_encode %{
168 Register tmp = $tmp$$Register;
169 __ mv(tmp, $oldval$$Register); // Must not clobber oldval.
170 // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop
171 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
172 Assembler::relaxed /* acquire */, Assembler::rl /* release */,
173 false /* is_cae */, $res$$Register);
174 %}
175
176 ins_pipe(pipe_slow);
177 %}
178
179 instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
180 predicate(needs_acquiring_load_reserved(n));
181 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval)));
182 ins_cost(10 * DEFAULT_COST);
183
184 effect(TEMP_DEF res, TEMP tmp, KILL cr);
185 format %{
186 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangeNAcq_shenandoah"
187 %}
188
189 ins_encode %{
190 Register tmp = $tmp$$Register;
191 __ mv(tmp, $oldval$$Register);
192 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
193 Assembler::aq /* acquire */, Assembler::rl /* release */,
194 true /* is_cae */, $res$$Register);
195 %}
196
197 ins_pipe(pipe_slow);
198 %}
199
200 instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
201 predicate(needs_acquiring_load_reserved(n));
202 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval)));
203 ins_cost(10 * DEFAULT_COST);
204
205 effect(TEMP_DEF res, TEMP tmp, KILL cr);
206 format %{
207 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval, #@compareAndExchangePAcq_shenandoah"
208 %}
209
210 ins_encode %{
211 Register tmp = $tmp$$Register;
212 __ mv(tmp, $oldval$$Register);
213 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
214 Assembler::aq /* acquire */, Assembler::rl /* release */,
215 true /* is_cae */, $res$$Register);
216 %}
217
218 ins_pipe(pipe_slow);
219 %}
220
221 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
222 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval)));
223 ins_cost(10 * DEFAULT_COST);
224
225 effect(TEMP tmp, KILL cr);
226 format %{
227 "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapP_shenandoah"
228 %}
229
230 ins_encode %{
231 Register tmp = $tmp$$Register;
232 __ mv(tmp, $oldval$$Register); // Must not clobber oldval.
233 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
234 Assembler::relaxed /* acquire */, Assembler::rl /* release */,
235 false /* is_cae */, $res$$Register);
236 %}
237
238 ins_pipe(pipe_slow);
239 %}
240
241 instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{
242 predicate(needs_acquiring_load_reserved(n));
243 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval)));
244 ins_cost(10 * DEFAULT_COST);
245
246 effect(TEMP tmp, KILL cr);
247 format %{
248 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapNAcq_shenandoah"
249 "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)"
250 %}
251
252 ins_encode %{
253 Register tmp = $tmp$$Register;
254 __ mv(tmp, $oldval$$Register); // Must not clobber oldval.
255 // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop
256 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
257 Assembler::aq /* acquire */, Assembler::rl /* release */,
258 false /* is_cae */, $res$$Register);
259 %}
260
261 ins_pipe(pipe_slow);
262 %}
263
264 instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{
265 predicate(needs_acquiring_load_reserved(n));
266 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval)));
267 ins_cost(10 * DEFAULT_COST);
268
269 effect(TEMP tmp, KILL cr);
270 format %{
271 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval, #@weakCompareAndSwapPAcq_shenandoah"
272 "mv $res, EQ\t# $res <-- (EQ ? 1 : 0)"
273 %}
274
275 ins_encode %{
276 Register tmp = $tmp$$Register;
277 __ mv(tmp, $oldval$$Register); // Must not clobber oldval.
278 // Weak is not current supported by ShenandoahBarrierSet::cmpxchg_oop
279 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm, $mem$$Register, tmp, $newval$$Register,
280 Assembler::aq /* acquire */, Assembler::rl /* release */,
281 false /* is_cae */, $res$$Register);
282 %}
283
284 ins_pipe(pipe_slow);
285 %}