1 //
2 // Copyright (c) 2018, Red Hat, Inc. All rights reserved.
3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 //
5 // This code is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License version 2 only, as
7 // published by the Free Software Foundation.
8 //
9 // This code is distributed in the hope that it will be useful, but WITHOUT
10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 // version 2 for more details (a copy is included in the LICENSE file that
13 // accompanied this code).
14 //
15 // You should have received a copy of the GNU General Public License version
16 // 2 along with this work; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 //
19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 // or visit www.oracle.com if you need additional information or have any
21 // questions.
22 //
23 //
24
25 source %{
26 #include "gc/shenandoah/shenandoahBarrierSet.hpp"
27 #include "gc/shenandoah/shenandoahBarrierSetAssembler_x86.hpp"
28 %}
29
30 // ---------------------------------- LOADS ---------------------------------------
31 //
32
33 instruct loadP_shenandoah(rRegP dst, memory mem, rFlagsReg cr)
34 %{
35 match(Set dst (LoadP mem));
36 predicate(UseShenandoahGC && n->as_Load()->barrier_data() != 0);
37 effect(TEMP_DEF dst, KILL cr);
38 // The main load is a candidate to implement implicit null checks.
39 ins_is_late_expanded_null_check_candidate(true);
40 format %{ "shenandoah_load $dst, $mem\t# ptr" %}
41 ins_encode %{
42 ShenandoahBarrierSet::assembler()->load_c2(this, masm,
43 $dst$$Register,
44 $mem$$Address,
45 /* narrow = */ false
46 );
47 %}
48 ins_cost(125);
49 ins_pipe(ialu_cr_reg_mem);
50 %}
51
52 instruct loadN_shenandoah(rRegN dst, memory mem, rFlagsReg cr)
53 %{
54 match(Set dst (LoadN mem));
55 predicate(UseShenandoahGC && n->as_Load()->barrier_data() != 0);
56 effect(TEMP_DEF dst, KILL cr);
57 // The main load is a candidate to implement implicit null checks.
58 ins_is_late_expanded_null_check_candidate(true);
59 format %{ "shenandoah_load $dst, $mem\t# compressed ptr" %}
60 ins_encode %{
61 ShenandoahBarrierSet::assembler()->load_c2(this, masm,
62 $dst$$Register,
63 $mem$$Address,
64 /* narrow = */ true
65 );
66 %}
67 ins_cost(125);
68 ins_pipe(ialu_cr_reg_mem);
69 %}
70
71 // ---------------------------------- STORES ---------------------------------------
72 //
73
74 instruct storeP_shenandoah(memory mem, any_RegP src, rRegP tmp, rFlagsReg cr)
75 %{
76 match(Set mem (StoreP mem src));
77 predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0);
78 effect(TEMP tmp, KILL cr);
79 format %{ "shenandoah_store $mem, $src\t# ptr" %}
80 ins_encode %{
81 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
82 $mem$$Address, /* dst_narrow = */ false,
83 $src$$Register, /* src_narrow = */ false,
84 $tmp$$Register);
85 %}
86 ins_cost(125);
87 ins_pipe(ialu_cr_reg_mem);
88 %}
89
90 instruct storeN_shenandoah(memory mem, rRegN src, rRegP tmp, rFlagsReg cr)
91 %{
92 match(Set mem (StoreN mem src));
93 predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0);
94 effect(TEMP tmp, KILL cr);
95 format %{ "shenandoah_store $mem, $src\t# compressed ptr" %}
96 ins_encode %{
97 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
98 $mem$$Address, /* dst_narrow = */ true,
99 $src$$Register, /* src_narrow = */ true,
100 $tmp$$Register
101 );
102 %}
103 ins_cost(125);
104 ins_pipe(ialu_cr_reg_mem);
105 %}
106
107 instruct encodePAndStoreN_shenandoah(memory mem, any_RegP src, rRegP tmp, rFlagsReg cr)
108 %{
109 match(Set mem (StoreN mem (EncodeP src)));
110 predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0);
111 effect(TEMP tmp, KILL cr);
112 format %{ "shenandoah_store $mem, $src\t# compressed ptr (with encoding)" %}
113 ins_encode %{
114 ShenandoahBarrierSet::assembler()->store_c2(this, masm,
115 $mem$$Address, /* dst_narrow = */ true,
116 $src$$Register, /* src_narrow = */ false,
117 $tmp$$Register
118 );
119 %}
120 ins_cost(125);
121 ins_pipe(ialu_cr_reg_mem);
122 %}
123
124 // ---------------------- LOAD-STORES -----------------------------------
125
126 instruct compareAndSwapP_shenandoah(rRegI res, memory mem, rRegP tmp, rax_RegP oldval, rRegP newval, rFlagsReg cr)
127 %{
128 match(Set res (CompareAndSwapP mem (Binary oldval newval)));
129 match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
130 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
131 effect(TEMP_DEF res, TEMP tmp, KILL oldval, KILL cr);
132 format %{ "shenandoah_cas $mem, $newval\t# ptr" %}
133 ins_encode %{
134 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
135 $res$$Register,
136 $mem$$Address,
137 $oldval$$Register,
138 $newval$$Register,
139 $tmp$$Register,
140 /* narrow = */ false
141 );
142 %}
143 ins_pipe(pipe_cmpxchg);
144 %}
145
146 instruct compareAndSwapN_shenandoah(rRegI res, memory mem, rRegP tmp, rax_RegN oldval, rRegN newval, rFlagsReg cr)
147 %{
148 match(Set res (CompareAndSwapN mem (Binary oldval newval)));
149 match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
150 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
151 effect(TEMP_DEF res, TEMP tmp, KILL oldval, KILL cr);
152 format %{ "shenandoah_cas $mem, $newval\t# compressed ptr" %}
153 ins_encode %{
154 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
155 $res$$Register,
156 $mem$$Address,
157 $oldval$$Register,
158 $newval$$Register,
159 $tmp$$Register,
160 /* narrow = */ true
161 );
162 %}
163 ins_pipe(pipe_cmpxchg);
164 %}
165
166 instruct compareAndExchangeP_shenandoah(memory mem, rax_RegP oldval, rRegP newval, rRegP tmp, rFlagsReg cr)
167 %{
168 match(Set oldval (CompareAndExchangeP mem (Binary oldval newval)));
169 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
170 effect(TEMP tmp, KILL cr);
171 format %{ "shenandoah_cae $mem, $newval\t# ptr" %}
172 ins_encode %{
173 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
174 noreg,
175 $mem$$Address,
176 $oldval$$Register,
177 $newval$$Register,
178 $tmp$$Register,
179 /* narrow = */ false
180 );
181 %}
182 ins_pipe(pipe_cmpxchg);
183 %}
184
185 instruct compareAndExchangeN_shenandoah(memory mem, rax_RegN oldval, rRegN newval, rRegP tmp, rFlagsReg cr)
186 %{
187 match(Set oldval (CompareAndExchangeN mem (Binary oldval newval)));
188 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
189 effect(TEMP tmp, KILL cr);
190 format %{ "shenandoah_cae $mem, $newval\t# compressed ptr" %}
191 ins_encode %{
192 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
193 noreg,
194 $mem$$Address,
195 $oldval$$Register,
196 $newval$$Register,
197 $tmp$$Register,
198 /* narrow = */ true
199 );
200 %}
201 ins_pipe(pipe_cmpxchg);
202 %}
203
204 instruct getAndSetP_shenandoah(memory mem, rRegP newval, rRegP tmp, rFlagsReg cr)
205 %{
206 match(Set newval (GetAndSetP mem newval));
207 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
208 effect(TEMP tmp, KILL cr);
209 format %{ "shenandoah_gas $newval, $mem\t# ptr" %}
210 ins_encode %{
211 ShenandoahBarrierSet::assembler()->get_and_set_c2(this, masm,
212 $newval$$Register,
213 $mem$$Address,
214 $tmp$$Register,
215 /* narrow = */ false
216 );
217 %}
218 ins_pipe(pipe_cmpxchg);
219 %}
220
221 instruct getAndSetN_shenandoah(memory mem, rRegN newval, rRegP tmp, rFlagsReg cr)
222 %{
223 match(Set newval (GetAndSetN mem newval));
224 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
225 effect(TEMP tmp, KILL cr);
226 format %{ "shenandoah_gas $newval, $mem\t# compressed ptr" %}
227 ins_encode %{
228 ShenandoahBarrierSet::assembler()->get_and_set_c2(this, masm,
229 $newval$$Register,
230 $mem$$Address,
231 $tmp$$Register,
232 /* narrow = */ true
233 );
234 %}
235 ins_pipe(pipe_cmpxchg);
236 %}