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 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
 29 %}
 30 
 31 // ---------------------------------- LOADS ---------------------------------------
 32 //
 33 
 34 instruct loadP_shenandoah(rRegP dst, memory mem, rFlagsReg cr)
 35 %{
 36   match(Set dst (LoadP mem));
 37   predicate(UseShenandoahGC && n->as_Load()->barrier_data() != 0);
 38   effect(TEMP_DEF dst, KILL cr);
 39   // The main load is a candidate to implement implicit null checks.
 40   ins_is_late_expanded_null_check_candidate(true);
 41   format %{ "shenandoah_load $dst, $mem\t# ptr" %}
 42   ins_encode %{
 43     ShenandoahBarrierSet::assembler()->load_c2(this, masm,
 44       $dst$$Register,
 45       $mem$$Address
 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     );
 65   %}
 66   ins_cost(125);
 67   ins_pipe(ialu_cr_reg_mem);
 68 %}
 69 
 70 // ---------------------------------- STORES ---------------------------------------
 71 //
 72 
 73 instruct storeP_shenandoah(memory mem, any_RegP src, rRegP tmp, rFlagsReg cr)
 74 %{
 75   match(Set mem (StoreP mem src));
 76   predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0);
 77   effect(TEMP tmp, KILL cr);
 78   format %{ "shenandoah_store $mem, $src\t# ptr" %}
 79   ins_encode %{
 80     ShenandoahBarrierSet::assembler()->store_c2(this, masm,
 81       $mem$$Address,  /* dst_narrow = */ false,
 82       $src$$Register, /* src_narrow = */ false,
 83       $tmp$$Register);
 84   %}
 85   ins_cost(125);
 86   ins_pipe(ialu_cr_reg_mem);
 87 %}
 88 
 89 instruct storeN_shenandoah(memory mem, rRegN src, rRegP tmp, rFlagsReg cr)
 90 %{
 91   match(Set mem (StoreN mem src));
 92   predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0);
 93   effect(TEMP tmp, KILL cr);
 94   format %{ "shenandoah_store $mem, $src\t# compressed ptr" %}
 95   ins_encode %{
 96     ShenandoahBarrierSet::assembler()->store_c2(this, masm,
 97       $mem$$Address,  /* dst_narrow = */ true,
 98       $src$$Register, /* src_narrow = */ true,
 99       $tmp$$Register);
100   %}
101   ins_cost(125);
102   ins_pipe(ialu_cr_reg_mem);
103 %}
104 
105 instruct encodePAndStoreN_shenandoah(memory mem, any_RegP src, rRegP tmp, rFlagsReg cr)
106 %{
107   match(Set mem (StoreN mem (EncodeP src)));
108   predicate(UseShenandoahGC && n->as_Store()->barrier_data() != 0);
109   effect(TEMP tmp, KILL cr);
110   format %{ "shenandoah_store $mem, $src\t# compressed ptr (with encoding)" %}
111   ins_encode %{
112     ShenandoahBarrierSet::assembler()->store_c2(this, masm,
113       $mem$$Address,  /* dst_narrow = */ true,
114       $src$$Register, /* src_narrow = */ false,
115       $tmp$$Register);
116   %}
117   ins_cost(125);
118   ins_pipe(ialu_cr_reg_mem);
119 %}
120 
121 // ---------------------- LOAD-STORES -----------------------------------
122 
123 instruct compareAndSwapP_shenandoah(rRegI res, memory mem, rRegP tmp1, rRegP tmp2, rax_RegP oldval, rRegP newval, rFlagsReg cr)
124 %{
125   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
126   match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
127   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
128   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval);
129   format %{ "shenandoah_cas $mem, $newval\t# ptr" %}
130   ins_encode %{
131     ShenandoahBarrierSet::assembler()->cae_c2(this, masm,
132       $res$$Register,
133       $mem$$Address,
134       $oldval$$Register,
135       $newval$$Register,
136       $tmp1$$Register,
137       $tmp2$$Register,
138       /* exchange = */ false,
139       /* maybe_null = */ true,
140       /* narrow = */ false);
141   %}
142   ins_pipe(pipe_cmpxchg);
143 %}
144 
145 instruct compareAndSwapN_shenandoah(rRegI res, memory mem, rRegP tmp1, rRegP tmp2, rax_RegN oldval, rRegN newval, rFlagsReg cr)
146 %{
147   match(Set res (CompareAndSwapN mem (Binary oldval newval)));
148   match(Set res (WeakCompareAndSwapN mem (Binary oldval newval)));
149   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
150   effect(TEMP_DEF res, TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval);
151   format %{ "shenandoah_cas $mem, $newval\t# compressed ptr" %}
152   ins_encode %{
153     ShenandoahBarrierSet::assembler()->cae_c2(this, masm,
154       $res$$Register,
155       $mem$$Address,
156       $oldval$$Register,
157       $newval$$Register,
158       $tmp1$$Register,
159       $tmp2$$Register,
160       /* exchange = */ false,
161       /* maybe_null = */ true,
162       /* narrow = */ true);
163   %}
164   ins_pipe(pipe_cmpxchg);
165 %}
166 
167 instruct compareAndExchangeP_shenandoah(memory mem, rax_RegP oldval, rRegP newval, rRegP tmp1, rRegP tmp2, rFlagsReg cr)
168 %{
169   match(Set oldval (CompareAndExchangeP mem (Binary oldval newval)));
170   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
171   effect(KILL cr, TEMP tmp1, TEMP tmp2);
172   ins_cost(1000);
173   format %{ "shenandoah_cae $mem, $newval\t# ptr" %}
174   ins_encode %{
175     ShenandoahBarrierSet::assembler()->cae_c2(this, masm,
176       noreg,
177       $mem$$Address,
178       $oldval$$Register,
179       $newval$$Register,
180       $tmp1$$Register,
181       $tmp2$$Register,
182       /* exchange = */ true,
183       /* maybe_null = */ true,
184       /* narrow = */ false);
185   %}
186   ins_pipe(pipe_cmpxchg);
187 %}
188 
189 instruct compareAndExchangeN_shenandoah(memory mem, rax_RegN oldval, rRegN newval, rRegP tmp1, rRegP tmp2, rFlagsReg cr)
190 %{
191   match(Set oldval (CompareAndExchangeN mem (Binary oldval newval)));
192   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
193   effect(TEMP tmp1, TEMP tmp2, KILL cr);
194   format %{ "shenandoah_cae $mem, $newval\t# compressed ptr" %}
195   ins_encode %{
196     ShenandoahBarrierSet::assembler()->cae_c2(this, masm,
197       noreg,
198       $mem$$Address,
199       $oldval$$Register,
200       $newval$$Register,
201       $tmp1$$Register,
202       $tmp2$$Register,
203       /* exchange = */ true,
204       /* maybe_null = */ true,
205       /* narrow = */ true);
206   %}
207   ins_pipe(pipe_cmpxchg);
208 %}
209 
210 instruct getAndSetP_shenandoah(memory mem, rRegP newval, rRegP tmp, rFlagsReg cr)
211 %{
212   match(Set newval (GetAndSetP mem newval));
213   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
214   effect(TEMP tmp, KILL cr);
215   format %{ "shenandoah_gas $newval, $mem\t# ptr" %}
216   ins_encode %{
217     ShenandoahBarrierSet::assembler()->get_and_set_c2(this, masm,
218       $newval$$Register,
219       $mem$$Address,
220       $tmp$$Register
221     );
222   %}
223   ins_pipe(pipe_cmpxchg);
224 %}
225 
226 instruct getAndSetN_shenandoah(memory mem, rRegN newval, rRegP tmp, rFlagsReg cr)
227 %{
228   match(Set newval (GetAndSetN mem newval));
229   predicate(UseShenandoahGC && n->as_LoadStore()->barrier_data() != 0);
230   effect(TEMP tmp, KILL cr);
231   format %{ "shenandoah_gas $newval, $mem\t# compressed ptr" %}
232   ins_encode %{
233     ShenandoahBarrierSet::assembler()->get_and_set_c2(this, masm,
234       $newval$$Register,
235       $mem$$Address,
236       $tmp$$Register
237     );
238   %}
239   ins_pipe(pipe_cmpxchg);
240 %}