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 ins_cost(1000);
172 format %{ "shenandoah_cae $mem, $newval\t# ptr" %}
173 ins_encode %{
174 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
175 noreg,
176 $mem$$Address,
177 $oldval$$Register,
178 $newval$$Register,
179 $tmp$$Register,
180 /* narrow = */ false
181 );
182 %}
183 ins_pipe(pipe_cmpxchg);
184 %}
185
186 instruct compareAndExchangeN_shenandoah(memory mem, rax_RegN oldval, rRegN newval, rRegP tmp, rFlagsReg cr)
187 %{
188 match(Set oldval (CompareAndExchangeN mem (Binary oldval newval)));
189 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
190 effect(TEMP tmp, KILL cr);
191 format %{ "shenandoah_cae $mem, $newval\t# compressed ptr" %}
192 ins_encode %{
193 ShenandoahBarrierSet::assembler()->compare_and_set_c2(this, masm,
194 noreg,
195 $mem$$Address,
196 $oldval$$Register,
197 $newval$$Register,
198 $tmp$$Register,
199 /* narrow = */ true
200 );
201 %}
202 ins_pipe(pipe_cmpxchg);
203 %}
204
205 instruct getAndSetP_shenandoah(memory mem, rRegP newval, rRegP tmp, rFlagsReg cr)
206 %{
207 match(Set newval (GetAndSetP mem newval));
208 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
209 effect(TEMP tmp, KILL cr);
210 format %{ "shenandoah_gas $newval, $mem\t# ptr" %}
211 ins_encode %{
212 ShenandoahBarrierSet::assembler()->get_and_set_c2(this, masm,
213 $newval$$Register,
214 $mem$$Address,
215 $tmp$$Register,
216 /* narrow = */ false
217 );
218 %}
219 ins_pipe(pipe_cmpxchg);
220 %}
221
222 instruct getAndSetN_shenandoah(memory mem, rRegN newval, rRegP tmp, rFlagsReg cr)
223 %{
224 match(Set newval (GetAndSetN mem newval));
225 predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
226 effect(TEMP tmp, KILL cr);
227 format %{ "shenandoah_gas $newval, $mem\t# compressed ptr" %}
228 ins_encode %{
229 ShenandoahBarrierSet::assembler()->get_and_set_c2(this, masm,
230 $newval$$Register,
231 $mem$$Address,
232 $tmp$$Register,
233 /* narrow = */ true
234 );
235 %}
236 ins_pipe(pipe_cmpxchg);
237 %}