|
1 // |
|
2 // Copyright (c) 2018, Red Hat, Inc. All rights reserved. |
|
3 // |
|
4 // This code is free software; you can redistribute it and/or modify it |
|
5 // under the terms of the GNU General Public License version 2 only, as |
|
6 // published by the Free Software Foundation. |
|
7 // |
|
8 // This code is distributed in the hope that it will be useful, but WITHOUT |
|
9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
11 // version 2 for more details (a copy is included in the LICENSE file that |
|
12 // accompanied this code). |
|
13 // |
|
14 // You should have received a copy of the GNU General Public License version |
|
15 // 2 along with this work; if not, write to the Free Software Foundation, |
|
16 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
17 // |
|
18 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
19 // or visit www.oracle.com if you need additional information or have any |
|
20 // questions. |
|
21 // |
|
22 // |
|
23 |
|
24 source_hpp %{ |
|
25 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" |
|
26 %} |
|
27 |
|
28 encode %{ |
|
29 enc_class aarch64_enc_cmpxchg_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{ |
|
30 MacroAssembler _masm(&cbuf); |
|
31 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); |
|
32 Register tmp = $tmp$$Register; |
|
33 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
34 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, |
|
35 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg); |
|
36 %} |
|
37 |
|
38 enc_class aarch64_enc_cmpxchg_acq_oop_shenandoah(memory mem, iRegP oldval, iRegP newval, iRegPNoSp tmp) %{ |
|
39 MacroAssembler _masm(&cbuf); |
|
40 guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding"); |
|
41 Register tmp = $tmp$$Register; |
|
42 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
43 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, |
|
44 /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg); |
|
45 %} |
|
46 %} |
|
47 |
|
48 instruct shenandoahRB(iRegPNoSp dst, iRegP src, rFlagsReg cr) %{ |
|
49 match(Set dst (ShenandoahReadBarrier src)); |
|
50 format %{ "shenandoah_rb $dst,$src" %} |
|
51 ins_encode %{ |
|
52 Register s = $src$$Register; |
|
53 Register d = $dst$$Register; |
|
54 __ ldr(d, Address(s, ShenandoahBrooksPointer::byte_offset())); |
|
55 %} |
|
56 ins_pipe(pipe_class_memory); |
|
57 %} |
|
58 |
|
59 |
|
60 instruct compareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ |
|
61 |
|
62 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); |
|
63 ins_cost(2 * VOLATILE_REF_COST); |
|
64 |
|
65 effect(TEMP tmp, KILL cr); |
|
66 |
|
67 format %{ |
|
68 "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" |
|
69 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" |
|
70 %} |
|
71 |
|
72 ins_encode(aarch64_enc_cmpxchg_oop_shenandoah(mem, oldval, newval, tmp), |
|
73 aarch64_enc_cset_eq(res)); |
|
74 |
|
75 ins_pipe(pipe_slow); |
|
76 %} |
|
77 |
|
78 instruct compareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ |
|
79 |
|
80 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); |
|
81 ins_cost(2 * VOLATILE_REF_COST); |
|
82 |
|
83 effect(TEMP tmp, KILL cr); |
|
84 |
|
85 format %{ |
|
86 "cmpxchgw_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" |
|
87 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" |
|
88 %} |
|
89 |
|
90 ins_encode %{ |
|
91 Register tmp = $tmp$$Register; |
|
92 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
93 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg); |
|
94 __ cset($res$$Register, Assembler::EQ); |
|
95 %} |
|
96 |
|
97 ins_pipe(pipe_slow); |
|
98 %} |
|
99 |
|
100 instruct compareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ |
|
101 |
|
102 predicate(needs_acquiring_load_exclusive(n)); |
|
103 match(Set res (ShenandoahCompareAndSwapP mem (Binary oldval newval))); |
|
104 ins_cost(VOLATILE_REF_COST); |
|
105 |
|
106 effect(TEMP tmp, KILL cr); |
|
107 |
|
108 format %{ |
|
109 "cmpxchg_acq_shenandoah_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" |
|
110 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" |
|
111 %} |
|
112 |
|
113 ins_encode(aarch64_enc_cmpxchg_acq_oop_shenandoah(mem, oldval, newval, tmp), |
|
114 aarch64_enc_cset_eq(res)); |
|
115 |
|
116 ins_pipe(pipe_slow); |
|
117 %} |
|
118 |
|
119 instruct compareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ |
|
120 |
|
121 predicate(needs_acquiring_load_exclusive(n)); |
|
122 match(Set res (ShenandoahCompareAndSwapN mem (Binary oldval newval))); |
|
123 ins_cost(VOLATILE_REF_COST); |
|
124 |
|
125 effect(TEMP tmp, KILL cr); |
|
126 |
|
127 format %{ |
|
128 "cmpxchgw_acq_shenandoah_narrow_oop $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" |
|
129 "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)" |
|
130 %} |
|
131 |
|
132 ins_encode %{ |
|
133 Register tmp = $tmp$$Register; |
|
134 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
135 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg); |
|
136 __ cset($res$$Register, Assembler::EQ); |
|
137 %} |
|
138 |
|
139 ins_pipe(pipe_slow); |
|
140 %} |
|
141 |
|
142 instruct compareAndExchangeN_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ |
|
143 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); |
|
144 ins_cost(2 * VOLATILE_REF_COST); |
|
145 effect(TEMP_DEF res, TEMP tmp, KILL cr); |
|
146 format %{ |
|
147 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" |
|
148 %} |
|
149 ins_encode %{ |
|
150 Register tmp = $tmp$$Register; |
|
151 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
152 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, |
|
153 /*acquire*/ false, /*release*/ true, /*weak*/ false, /* encode*/ false, noreg, noreg, rscratch2, $res$$Register); |
|
154 %} |
|
155 ins_pipe(pipe_slow); |
|
156 %} |
|
157 |
|
158 instruct compareAndExchangeP_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ |
|
159 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); |
|
160 ins_cost(2 * VOLATILE_REF_COST); |
|
161 effect(TEMP_DEF res, TEMP tmp, KILL cr); |
|
162 format %{ |
|
163 "cmpxchg_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" |
|
164 %} |
|
165 ins_encode %{ |
|
166 Register tmp = $tmp$$Register; |
|
167 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
168 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, |
|
169 /*acquire*/ false, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg, rscratch2, $res$$Register); |
|
170 %} |
|
171 ins_pipe(pipe_slow); |
|
172 %} |
|
173 |
|
174 instruct compareAndExchangeNAcq_shenandoah(iRegNNoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ |
|
175 predicate(needs_acquiring_load_exclusive(n)); |
|
176 match(Set res (ShenandoahCompareAndExchangeN mem (Binary oldval newval))); |
|
177 ins_cost(VOLATILE_REF_COST); |
|
178 effect(TEMP_DEF res, TEMP tmp, KILL cr); |
|
179 format %{ |
|
180 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" |
|
181 %} |
|
182 ins_encode %{ |
|
183 Register tmp = $tmp$$Register; |
|
184 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
185 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, |
|
186 /*acquire*/ true, /*release*/ true, /*weak*/ false, /* encode*/ false, noreg, noreg, rscratch2, $res$$Register); |
|
187 %} |
|
188 ins_pipe(pipe_slow); |
|
189 %} |
|
190 |
|
191 instruct compareAndExchangePAcq_shenandoah(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ |
|
192 predicate(needs_acquiring_load_exclusive(n)); |
|
193 match(Set res (ShenandoahCompareAndExchangeP mem (Binary oldval newval))); |
|
194 ins_cost(VOLATILE_REF_COST); |
|
195 effect(TEMP_DEF res, TEMP tmp, KILL cr); |
|
196 format %{ |
|
197 "cmpxchg_acq_shenandoah $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval with temp $tmp" |
|
198 %} |
|
199 ins_encode %{ |
|
200 Register tmp = $tmp$$Register; |
|
201 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
202 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, |
|
203 /*acquire*/ true, /*release*/ true, /*weak*/ false, /*encode*/ false, noreg, noreg, rscratch2, $res$$Register); |
|
204 %} |
|
205 ins_pipe(pipe_slow); |
|
206 %} |
|
207 |
|
208 instruct weakCompareAndSwapN_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ |
|
209 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); |
|
210 ins_cost(2 * VOLATILE_REF_COST); |
|
211 effect(TEMP tmp, KILL cr); |
|
212 format %{ |
|
213 "cmpxchgw_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" |
|
214 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" |
|
215 %} |
|
216 ins_encode %{ |
|
217 Register tmp = $tmp$$Register; |
|
218 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
219 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, |
|
220 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg); |
|
221 __ csetw($res$$Register, Assembler::EQ); |
|
222 %} |
|
223 ins_pipe(pipe_slow); |
|
224 %} |
|
225 |
|
226 instruct weakCompareAndSwapP_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ |
|
227 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); |
|
228 ins_cost(2 * VOLATILE_REF_COST); |
|
229 effect(TEMP tmp, KILL cr); |
|
230 format %{ |
|
231 "cmpxchg_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" |
|
232 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" |
|
233 %} |
|
234 ins_encode %{ |
|
235 Register tmp = $tmp$$Register; |
|
236 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
237 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, |
|
238 /*acquire*/ false, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg); |
|
239 __ csetw($res$$Register, Assembler::EQ); |
|
240 %} |
|
241 ins_pipe(pipe_slow); |
|
242 %} |
|
243 |
|
244 instruct weakCompareAndSwapNAcq_shenandoah(iRegINoSp res, indirect mem, iRegN oldval, iRegN newval, iRegNNoSp tmp, rFlagsReg cr) %{ |
|
245 predicate(needs_acquiring_load_exclusive(n)); |
|
246 match(Set res (ShenandoahWeakCompareAndSwapN mem (Binary oldval newval))); |
|
247 ins_cost(VOLATILE_REF_COST); |
|
248 effect(TEMP tmp, KILL cr); |
|
249 format %{ |
|
250 "cmpxchgw_acq_shenandoah $res = $mem, $oldval, $newval\t# (narrow oop, weak) if $mem == $oldval then $mem <-- $newval" |
|
251 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" |
|
252 %} |
|
253 ins_encode %{ |
|
254 Register tmp = $tmp$$Register; |
|
255 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
256 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, |
|
257 /*acquire*/ true, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg); |
|
258 __ csetw($res$$Register, Assembler::EQ); |
|
259 %} |
|
260 ins_pipe(pipe_slow); |
|
261 %} |
|
262 |
|
263 instruct weakCompareAndSwapPAcq_shenandoah(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, iRegPNoSp tmp, rFlagsReg cr) %{ |
|
264 predicate(needs_acquiring_load_exclusive(n)); |
|
265 match(Set res (ShenandoahWeakCompareAndSwapP mem (Binary oldval newval))); |
|
266 ins_cost(VOLATILE_REF_COST); |
|
267 effect(TEMP tmp, KILL cr); |
|
268 format %{ |
|
269 "cmpxchg_acq_shenandoah $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval" |
|
270 "csetw $res, EQ\t# $res <-- (EQ ? 1 : 0)" |
|
271 %} |
|
272 ins_encode %{ |
|
273 Register tmp = $tmp$$Register; |
|
274 __ mov(tmp, $oldval$$Register); // Must not clobber oldval. |
|
275 ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $mem$$Register, tmp, $newval$$Register, |
|
276 /*acquire*/ true, /*release*/ true, /*weak*/ true, /*encode*/ false, noreg, noreg); |
|
277 __ csetw($res$$Register, Assembler::EQ); |
|
278 %} |
|
279 ins_pipe(pipe_slow); |
|
280 %} |
|
281 |