Thu, 13 Sep 2018 15:03:14 +0800
#7558 [C2] cmovL_cmpP_reg_reg was added im mips_64.ad
Effect:
java -XX:-UseCompressedOops SpecApplication _213_javac # passed
1 //
2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 // Copyright (c) 2015, 2018, Loongson Technology. 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 //
26 // GodSon3 Architecture Description File
28 //----------REGISTER DEFINITION BLOCK------------------------------------------
29 // This information is used by the matcher and the register allocator to
30 // describe individual registers and classes of registers within the target
31 // archtecture.
33 // format:
34 // reg_def name (call convention, c-call convention, ideal type, encoding);
35 // call convention :
36 // NS = No-Save
37 // SOC = Save-On-Call
38 // SOE = Save-On-Entry
39 // AS = Always-Save
40 // ideal type :
41 // see opto/opcodes.hpp for more info
42 // reg_class name (reg, ...);
43 // alloc_class name (reg, ...);
44 register %{
46 // General Registers
47 // Integer Registers
48 reg_def R0 ( NS, NS, Op_RegI, 0, VMRegImpl::Bad());
49 reg_def AT ( NS, NS, Op_RegI, 1, AT->as_VMReg());
50 reg_def AT_H ( NS, NS, Op_RegI, 1, AT->as_VMReg()->next());
51 reg_def V0 (SOC, SOC, Op_RegI, 2, V0->as_VMReg());
52 reg_def V0_H (SOC, SOC, Op_RegI, 2, V0->as_VMReg()->next());
53 reg_def V1 (SOC, SOC, Op_RegI, 3, V1->as_VMReg());
54 reg_def V1_H (SOC, SOC, Op_RegI, 3, V1->as_VMReg()->next());
55 reg_def A0 (SOC, SOC, Op_RegI, 4, A0->as_VMReg());
56 reg_def A0_H (SOC, SOC, Op_RegI, 4, A0->as_VMReg()->next());
57 reg_def A1 (SOC, SOC, Op_RegI, 5, A1->as_VMReg());
58 reg_def A1_H (SOC, SOC, Op_RegI, 5, A1->as_VMReg()->next());
59 reg_def A2 (SOC, SOC, Op_RegI, 6, A2->as_VMReg());
60 reg_def A2_H (SOC, SOC, Op_RegI, 6, A2->as_VMReg()->next());
61 reg_def A3 (SOC, SOC, Op_RegI, 7, A3->as_VMReg());
62 reg_def A3_H (SOC, SOC, Op_RegI, 7, A3->as_VMReg()->next());
63 reg_def A4 (SOC, SOC, Op_RegI, 8, A4->as_VMReg());
64 reg_def A4_H (SOC, SOC, Op_RegI, 8, A4->as_VMReg()->next());
65 reg_def A5 (SOC, SOC, Op_RegI, 9, A5->as_VMReg());
66 reg_def A5_H (SOC, SOC, Op_RegI, 9, A5->as_VMReg()->next());
67 reg_def A6 (SOC, SOC, Op_RegI, 10, A6->as_VMReg());
68 reg_def A6_H (SOC, SOC, Op_RegI, 10, A6->as_VMReg()->next());
69 reg_def A7 (SOC, SOC, Op_RegI, 11, A7->as_VMReg());
70 reg_def A7_H (SOC, SOC, Op_RegI, 11, A7->as_VMReg()->next());
71 reg_def T0 (SOC, SOC, Op_RegI, 12, T0->as_VMReg());
72 reg_def T0_H (SOC, SOC, Op_RegI, 12, T0->as_VMReg()->next());
73 reg_def T1 (SOC, SOC, Op_RegI, 13, T1->as_VMReg());
74 reg_def T1_H (SOC, SOC, Op_RegI, 13, T1->as_VMReg()->next());
75 reg_def T2 (SOC, SOC, Op_RegI, 14, T2->as_VMReg());
76 reg_def T2_H (SOC, SOC, Op_RegI, 14, T2->as_VMReg()->next());
77 reg_def T3 (SOC, SOC, Op_RegI, 15, T3->as_VMReg());
78 reg_def T3_H (SOC, SOC, Op_RegI, 15, T3->as_VMReg()->next());
79 reg_def S0 (SOC, SOE, Op_RegI, 16, S0->as_VMReg());
80 reg_def S0_H (SOC, SOE, Op_RegI, 16, S0->as_VMReg()->next());
81 reg_def S1 (SOC, SOE, Op_RegI, 17, S1->as_VMReg());
82 reg_def S1_H (SOC, SOE, Op_RegI, 17, S1->as_VMReg()->next());
83 reg_def S2 (SOC, SOE, Op_RegI, 18, S2->as_VMReg());
84 reg_def S2_H (SOC, SOE, Op_RegI, 18, S2->as_VMReg()->next());
85 reg_def S3 (SOC, SOE, Op_RegI, 19, S3->as_VMReg());
86 reg_def S3_H (SOC, SOE, Op_RegI, 19, S3->as_VMReg()->next());
87 reg_def S4 (SOC, SOE, Op_RegI, 20, S4->as_VMReg());
88 reg_def S4_H (SOC, SOE, Op_RegI, 20, S4->as_VMReg()->next());
89 reg_def S5 (SOC, SOE, Op_RegI, 21, S5->as_VMReg());
90 reg_def S5_H (SOC, SOE, Op_RegI, 21, S5->as_VMReg()->next());
91 reg_def S6 (SOC, SOE, Op_RegI, 22, S6->as_VMReg());
92 reg_def S6_H (SOC, SOE, Op_RegI, 22, S6->as_VMReg()->next());
93 reg_def S7 (SOC, SOE, Op_RegI, 23, S7->as_VMReg());
94 reg_def S7_H (SOC, SOE, Op_RegI, 23, S7->as_VMReg()->next());
95 reg_def T8 (SOC, SOC, Op_RegI, 24, T8->as_VMReg());
96 reg_def T8_H (SOC, SOC, Op_RegI, 24, T8->as_VMReg()->next());
97 reg_def T9 (SOC, SOC, Op_RegI, 25, T9->as_VMReg());
98 reg_def T9_H (SOC, SOC, Op_RegI, 25, T9->as_VMReg()->next());
100 // Special Registers
101 reg_def K0 ( NS, NS, Op_RegI, 26, K0->as_VMReg());
102 reg_def K1 ( NS, NS, Op_RegI, 27, K1->as_VMReg());
103 reg_def GP ( NS, NS, Op_RegI, 28, GP->as_VMReg());
104 reg_def GP_H ( NS, NS, Op_RegI, 28, GP->as_VMReg()->next());
105 reg_def SP ( NS, NS, Op_RegI, 29, SP->as_VMReg());
106 reg_def SP_H ( NS, NS, Op_RegI, 29, SP->as_VMReg()->next());
107 reg_def FP ( NS, NS, Op_RegI, 30, FP->as_VMReg());
108 reg_def FP_H ( NS, NS, Op_RegI, 30, FP->as_VMReg()->next());
109 reg_def RA ( NS, NS, Op_RegI, 31, RA->as_VMReg());
110 reg_def RA_H ( NS, NS, Op_RegI, 31, RA->as_VMReg()->next());
112 // Floating registers.
113 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg());
114 reg_def F0_H ( SOC, SOC, Op_RegF, 0, F0->as_VMReg()->next());
115 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg());
116 reg_def F1_H ( SOC, SOC, Op_RegF, 1, F1->as_VMReg()->next());
117 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg());
118 reg_def F2_H ( SOC, SOC, Op_RegF, 2, F2->as_VMReg()->next());
119 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg());
120 reg_def F3_H ( SOC, SOC, Op_RegF, 3, F3->as_VMReg()->next());
121 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg());
122 reg_def F4_H ( SOC, SOC, Op_RegF, 4, F4->as_VMReg()->next());
123 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg());
124 reg_def F5_H ( SOC, SOC, Op_RegF, 5, F5->as_VMReg()->next());
125 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg());
126 reg_def F6_H ( SOC, SOC, Op_RegF, 6, F6->as_VMReg()->next());
127 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg());
128 reg_def F7_H ( SOC, SOC, Op_RegF, 7, F7->as_VMReg()->next());
129 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg());
130 reg_def F8_H ( SOC, SOC, Op_RegF, 8, F8->as_VMReg()->next());
131 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg());
132 reg_def F9_H ( SOC, SOC, Op_RegF, 9, F9->as_VMReg()->next());
133 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg());
134 reg_def F10_H ( SOC, SOC, Op_RegF, 10, F10->as_VMReg()->next());
135 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg());
136 reg_def F11_H ( SOC, SOC, Op_RegF, 11, F11->as_VMReg()->next());
137 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg());
138 reg_def F12_H ( SOC, SOC, Op_RegF, 12, F12->as_VMReg()->next());
139 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg());
140 reg_def F13_H ( SOC, SOC, Op_RegF, 13, F13->as_VMReg()->next());
141 reg_def F14 ( SOC, SOC, Op_RegF, 14, F14->as_VMReg());
142 reg_def F14_H ( SOC, SOC, Op_RegF, 14, F14->as_VMReg()->next());
143 reg_def F15 ( SOC, SOC, Op_RegF, 15, F15->as_VMReg());
144 reg_def F15_H ( SOC, SOC, Op_RegF, 15, F15->as_VMReg()->next());
145 reg_def F16 ( SOC, SOC, Op_RegF, 16, F16->as_VMReg());
146 reg_def F16_H ( SOC, SOC, Op_RegF, 16, F16->as_VMReg()->next());
147 reg_def F17 ( SOC, SOC, Op_RegF, 17, F17->as_VMReg());
148 reg_def F17_H ( SOC, SOC, Op_RegF, 17, F17->as_VMReg()->next());
149 reg_def F18 ( SOC, SOC, Op_RegF, 18, F18->as_VMReg());
150 reg_def F18_H ( SOC, SOC, Op_RegF, 18, F18->as_VMReg()->next());
151 reg_def F19 ( SOC, SOC, Op_RegF, 19, F19->as_VMReg());
152 reg_def F19_H ( SOC, SOC, Op_RegF, 19, F19->as_VMReg()->next());
153 reg_def F20 ( SOC, SOC, Op_RegF, 20, F20->as_VMReg());
154 reg_def F20_H ( SOC, SOC, Op_RegF, 20, F20->as_VMReg()->next());
155 reg_def F21 ( SOC, SOC, Op_RegF, 21, F21->as_VMReg());
156 reg_def F21_H ( SOC, SOC, Op_RegF, 21, F21->as_VMReg()->next());
157 reg_def F22 ( SOC, SOC, Op_RegF, 22, F22->as_VMReg());
158 reg_def F22_H ( SOC, SOC, Op_RegF, 22, F22->as_VMReg()->next());
159 reg_def F23 ( SOC, SOC, Op_RegF, 23, F23->as_VMReg());
160 reg_def F23_H ( SOC, SOC, Op_RegF, 23, F23->as_VMReg()->next());
161 reg_def F24 ( SOC, SOC, Op_RegF, 24, F24->as_VMReg());
162 reg_def F24_H ( SOC, SOC, Op_RegF, 24, F24->as_VMReg()->next());
163 reg_def F25 ( SOC, SOC, Op_RegF, 25, F25->as_VMReg());
164 reg_def F25_H ( SOC, SOC, Op_RegF, 25, F25->as_VMReg()->next());
165 reg_def F26 ( SOC, SOC, Op_RegF, 26, F26->as_VMReg());
166 reg_def F26_H ( SOC, SOC, Op_RegF, 26, F26->as_VMReg()->next());
167 reg_def F27 ( SOC, SOC, Op_RegF, 27, F27->as_VMReg());
168 reg_def F27_H ( SOC, SOC, Op_RegF, 27, F27->as_VMReg()->next());
169 reg_def F28 ( SOC, SOC, Op_RegF, 28, F28->as_VMReg());
170 reg_def F28_H ( SOC, SOC, Op_RegF, 28, F28->as_VMReg()->next());
171 reg_def F29 ( SOC, SOC, Op_RegF, 29, F29->as_VMReg());
172 reg_def F29_H ( SOC, SOC, Op_RegF, 29, F29->as_VMReg()->next());
173 reg_def F30 ( SOC, SOC, Op_RegF, 30, F30->as_VMReg());
174 reg_def F30_H ( SOC, SOC, Op_RegF, 30, F30->as_VMReg()->next());
175 reg_def F31 ( SOC, SOC, Op_RegF, 31, F31->as_VMReg());
176 reg_def F31_H ( SOC, SOC, Op_RegF, 31, F31->as_VMReg()->next());
179 // ----------------------------
180 // Special Registers
181 // Condition Codes Flag Registers
182 reg_def MIPS_FLAG (SOC, SOC, Op_RegFlags, 1, as_Register(1)->as_VMReg());
183 //S6 is used for get_thread(S6)
184 //S5 is uesd for heapbase of compressed oop
185 alloc_class chunk0(
186 S7, S7_H,
187 S0, S0_H,
188 S1, S1_H,
189 S2, S2_H,
190 S4, S4_H,
191 S5, S5_H,
192 S6, S6_H,
193 S3, S3_H,
194 T2, T2_H,
195 T3, T3_H,
196 T8, T8_H,
197 T9, T9_H,
198 T1, T1_H, // inline_cache_reg
199 V1, V1_H,
200 A7, A7_H,
201 A6, A6_H,
202 A5, A5_H,
203 A4, A4_H,
204 V0, V0_H,
205 A3, A3_H,
206 A2, A2_H,
207 A1, A1_H,
208 A0, A0_H,
209 T0, T0_H,
210 GP, GP_H
211 RA, RA_H,
212 SP, SP_H, // stack_pointer
213 FP, FP_H // frame_pointer
214 );
216 alloc_class chunk1( F0, F0_H,
217 F1, F1_H,
218 F2, F2_H,
219 F3, F3_H,
220 F4, F4_H,
221 F5, F5_H,
222 F6, F6_H,
223 F7, F7_H,
224 F8, F8_H,
225 F9, F9_H,
226 F10, F10_H,
227 F11, F11_H,
228 F20, F20_H,
229 F21, F21_H,
230 F22, F22_H,
231 F23, F23_H,
232 F24, F24_H,
233 F25, F25_H,
234 F26, F26_H,
235 F27, F27_H,
236 F28, F28_H,
237 F19, F19_H,
238 F18, F18_H,
239 F17, F17_H,
240 F16, F16_H,
241 F15, F15_H,
242 F14, F14_H,
243 F13, F13_H,
244 F12, F12_H,
245 F29, F29_H,
246 F30, F30_H,
247 F31, F31_H);
249 alloc_class chunk2(MIPS_FLAG);
251 reg_class s_reg( S0, S1, S2, S3, S4, S5, S6, S7 );
252 reg_class s0_reg( S0 );
253 reg_class s1_reg( S1 );
254 reg_class s2_reg( S2 );
255 reg_class s3_reg( S3 );
256 reg_class s4_reg( S4 );
257 reg_class s5_reg( S5 );
258 reg_class s6_reg( S6 );
259 reg_class s7_reg( S7 );
261 reg_class t_reg( T0, T1, T2, T3, T8, T9 );
262 reg_class t0_reg( T0 );
263 reg_class t1_reg( T1 );
264 reg_class t2_reg( T2 );
265 reg_class t3_reg( T3 );
266 reg_class t8_reg( T8 );
267 reg_class t9_reg( T9 );
269 reg_class a_reg( A0, A1, A2, A3, A4, A5, A6, A7 );
270 reg_class a0_reg( A0 );
271 reg_class a1_reg( A1 );
272 reg_class a2_reg( A2 );
273 reg_class a3_reg( A3 );
274 reg_class a4_reg( A4 );
275 reg_class a5_reg( A5 );
276 reg_class a6_reg( A6 );
277 reg_class a7_reg( A7 );
279 reg_class v0_reg( V0 );
280 reg_class v1_reg( V1 );
282 reg_class sp_reg( SP, SP_H );
283 reg_class fp_reg( FP, FP_H );
285 reg_class mips_flags(MIPS_FLAG);
287 reg_class v0_long_reg( V0, V0_H );
288 reg_class v1_long_reg( V1, V1_H );
289 reg_class a0_long_reg( A0, A0_H );
290 reg_class a1_long_reg( A1, A1_H );
291 reg_class a2_long_reg( A2, A2_H );
292 reg_class a3_long_reg( A3, A3_H );
293 reg_class a4_long_reg( A4, A4_H );
294 reg_class a5_long_reg( A5, A5_H );
295 reg_class a6_long_reg( A6, A6_H );
296 reg_class a7_long_reg( A7, A7_H );
297 reg_class t0_long_reg( T0, T0_H );
298 reg_class t1_long_reg( T1, T1_H );
299 reg_class t2_long_reg( T2, T2_H );
300 reg_class t3_long_reg( T3, T3_H );
301 reg_class t8_long_reg( T8, T8_H );
302 reg_class t9_long_reg( T9, T9_H );
303 reg_class s0_long_reg( S0, S0_H );
304 reg_class s1_long_reg( S1, S1_H );
305 reg_class s2_long_reg( S2, S2_H );
306 reg_class s3_long_reg( S3, S3_H );
307 reg_class s4_long_reg( S4, S4_H );
308 reg_class s5_long_reg( S5, S5_H );
309 reg_class s6_long_reg( S6, S6_H );
310 reg_class s7_long_reg( S7, S7_H );
312 reg_class int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, A7, A6, A5, A4, V0, A3, A2, A1, A0, T0 );
314 reg_class no_Ax_int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, V0, T0 );
316 reg_class p_reg(
317 S7, S7_H,
318 S0, S0_H,
319 S1, S1_H,
320 S2, S2_H,
321 S4, S4_H,
322 S3, S3_H,
323 T8, T8_H,
324 T2, T2_H,
325 T3, T3_H,
326 T1, T1_H,
327 A7, A7_H,
328 A6, A6_H,
329 A5, A5_H,
330 A4, A4_H,
331 A3, A3_H,
332 A2, A2_H,
333 A1, A1_H,
334 A0, A0_H,
335 T0, T0_H
336 );
338 reg_class no_T8_p_reg(
339 S7, S7_H,
340 S0, S0_H,
341 S1, S1_H,
342 S2, S2_H,
343 S4, S4_H,
344 S3, S3_H,
345 T2, T2_H,
346 T3, T3_H,
347 T1, T1_H,
348 A7, A7_H,
349 A6, A6_H,
350 A5, A5_H,
351 A4, A4_H,
352 A3, A3_H,
353 A2, A2_H,
354 A1, A1_H,
355 A0, A0_H,
356 T0, T0_H
357 );
359 reg_class long_reg(
360 S7, S7_H,
361 S0, S0_H,
362 S1, S1_H,
363 S2, S2_H,
364 S4, S4_H,
365 S3, S3_H,
366 T8, T8_H,
367 T2, T2_H,
368 T3, T3_H,
369 T1, T1_H,
370 A7, A7_H,
371 A6, A6_H,
372 A5, A5_H,
373 A4, A4_H,
374 A3, A3_H,
375 A2, A2_H,
376 A1, A1_H,
377 A0, A0_H,
378 T0, T0_H
379 );
382 // Floating point registers.
383 // F31 are not used as temporary registers in D2I
384 reg_class flt_reg( F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17 F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F31);
385 reg_class dbl_reg( F0, F0_H,
386 F1, F1_H,
387 F2, F2_H,
388 F3, F3_H,
389 F4, F4_H,
390 F5, F5_H,
391 F6, F6_H,
392 F7, F7_H,
393 F8, F8_H,
394 F9, F9_H,
395 F10, F10_H,
396 F11, F11_H,
397 F12, F12_H,
398 F13, F13_H,
399 F14, F14_H,
400 F15, F15_H,
401 F16, F16_H,
402 F17, F17_H,
403 F18, F18_H,
404 F19, F19_H,
405 F20, F20_H,
406 F21, F21_H,
407 F22, F22_H,
408 F23, F23_H,
409 F24, F24_H,
410 F25, F25_H,
411 F26, F26_H,
412 F27, F27_H,
413 F28, F28_H,
414 F29, F29_H,
415 F31, F31_H);
417 reg_class flt_arg0( F12 );
418 reg_class dbl_arg0( F12, F12_H );
419 reg_class dbl_arg1( F14, F14_H );
421 %}
423 //----------DEFINITION BLOCK---------------------------------------------------
424 // Define name --> value mappings to inform the ADLC of an integer valued name
425 // Current support includes integer values in the range [0, 0x7FFFFFFF]
426 // Format:
427 // int_def <name> ( <int_value>, <expression>);
428 // Generated Code in ad_<arch>.hpp
429 // #define <name> (<expression>)
430 // // value == <int_value>
431 // Generated code in ad_<arch>.cpp adlc_verification()
432 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
433 //
434 definitions %{
435 int_def DEFAULT_COST ( 100, 100);
436 int_def HUGE_COST (1000000, 1000000);
438 // Memory refs are twice as expensive as run-of-the-mill.
439 int_def MEMORY_REF_COST ( 200, DEFAULT_COST * 2);
441 // Branches are even more expensive.
442 int_def BRANCH_COST ( 300, DEFAULT_COST * 3);
443 // we use jr instruction to construct call, so more expensive
444 int_def CALL_COST ( 500, DEFAULT_COST * 5);
445 /*
446 int_def EQUAL ( 1, 1 );
447 int_def NOT_EQUAL ( 2, 2 );
448 int_def GREATER ( 3, 3 );
449 int_def GREATER_EQUAL ( 4, 4 );
450 int_def LESS ( 5, 5 );
451 int_def LESS_EQUAL ( 6, 6 );
452 */
453 %}
457 //----------SOURCE BLOCK-------------------------------------------------------
458 // This is a block of C++ code which provides values, functions, and
459 // definitions necessary in the rest of the architecture description
461 source_hpp %{
462 // Header information of the source block.
463 // Method declarations/definitions which are used outside
464 // the ad-scope can conveniently be defined here.
465 //
466 // To keep related declarations/definitions/uses close together,
467 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
469 class CallStubImpl {
471 //--------------------------------------------------------------
472 //---< Used for optimization in Compile::shorten_branches >---
473 //--------------------------------------------------------------
475 public:
476 // Size of call trampoline stub.
477 static uint size_call_trampoline() {
478 return 0; // no call trampolines on this platform
479 }
481 // number of relocations needed by a call trampoline stub
482 static uint reloc_call_trampoline() {
483 return 0; // no call trampolines on this platform
484 }
485 };
487 class HandlerImpl {
489 public:
491 static int emit_exception_handler(CodeBuffer &cbuf);
492 static int emit_deopt_handler(CodeBuffer& cbuf);
494 static uint size_exception_handler() {
495 // NativeCall instruction size is the same as NativeJump.
496 // exception handler starts out as jump and can be patched to
497 // a call be deoptimization. (4932387)
498 // Note that this value is also credited (in output.cpp) to
499 // the size of the code section.
500 int size = NativeCall::instruction_size;
501 return round_to(size, 16);
502 }
504 #ifdef _LP64
505 static uint size_deopt_handler() {
506 int size = NativeCall::instruction_size;
507 return round_to(size, 16);
508 }
509 #else
510 static uint size_deopt_handler() {
511 // NativeCall instruction size is the same as NativeJump.
512 // exception handler starts out as jump and can be patched to
513 // a call be deoptimization. (4932387)
514 // Note that this value is also credited (in output.cpp) to
515 // the size of the code section.
516 return 5 + NativeJump::instruction_size; // pushl(); jmp;
517 }
518 #endif
519 };
521 %} // end source_hpp
523 source %{
525 #define NO_INDEX 0
526 #define RELOC_IMM64 Assembler::imm_operand
527 #define RELOC_DISP32 Assembler::disp32_operand
530 #define __ _masm.
533 // Emit exception handler code.
534 // Stuff framesize into a register and call a VM stub routine.
535 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
536 // Note that the code buffer's insts_mark is always relative to insts.
537 // That's why we must use the macroassembler to generate a handler.
538 MacroAssembler _masm(&cbuf);
539 address base = __ start_a_stub(size_exception_handler());
540 if (base == NULL) {
541 ciEnv::current()->record_failure("CodeCache is full");
542 return 0; // CodeBuffer::expand failed
543 }
545 int offset = __ offset();
547 __ block_comment("; emit_exception_handler");
549 cbuf.set_insts_mark();
550 __ relocate(relocInfo::runtime_call_type);
551 __ patchable_jump((address)OptoRuntime::exception_blob()->entry_point());
552 __ align(16);
553 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
554 __ end_a_stub();
555 return offset;
556 }
558 // Emit deopt handler code.
559 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
560 // Note that the code buffer's insts_mark is always relative to insts.
561 // That's why we must use the macroassembler to generate a handler.
562 MacroAssembler _masm(&cbuf);
563 address base = __ start_a_stub(size_deopt_handler());
564 if (base == NULL) {
565 ciEnv::current()->record_failure("CodeCache is full");
566 return 0; // CodeBuffer::expand failed
567 }
569 int offset = __ offset();
571 __ block_comment("; emit_deopt_handler");
573 cbuf.set_insts_mark();
574 __ relocate(relocInfo::runtime_call_type);
575 __ patchable_call(SharedRuntime::deopt_blob()->unpack());
576 __ align(16);
577 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
578 __ end_a_stub();
579 return offset;
580 }
583 const bool Matcher::match_rule_supported(int opcode) {
584 if (!has_match_rule(opcode))
585 return false;
587 switch (opcode) {
588 //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
589 case Op_CountLeadingZerosI:
590 case Op_CountLeadingZerosL:
591 if (!UseCountLeadingZerosInstructionMIPS64)
592 return false;
593 break;
594 case Op_CountTrailingZerosI:
595 case Op_CountTrailingZerosL:
596 if (!UseCountTrailingZerosInstructionMIPS64)
597 return false;
598 break;
599 }
601 return true; // Per default match rules are supported.
602 }
604 //FIXME
605 // emit call stub, compiled java to interpreter
606 void emit_java_to_interp(CodeBuffer &cbuf ) {
607 // Stub is fixed up when the corresponding call is converted from calling
608 // compiled code to calling interpreted code.
609 // mov rbx,0
610 // jmp -1
612 address mark = cbuf.insts_mark(); // get mark within main instrs section
614 // Note that the code buffer's insts_mark is always relative to insts.
615 // That's why we must use the macroassembler to generate a stub.
616 MacroAssembler _masm(&cbuf);
618 address base = __ start_a_stub(Compile::MAX_stubs_size);
619 if (base == NULL) { // CodeBuffer::expand failed
620 ciEnv::current()->record_failure("CodeCache is full");
621 }
623 // static stub relocation stores the instruction address of the call
625 __ relocate(static_stub_Relocation::spec(mark), 0);
627 // static stub relocation also tags the methodOop in the code-stream.
628 __ patchable_set48(S3, (long)0);
629 // This is recognized as unresolved by relocs/nativeInst/ic code
631 __ relocate(relocInfo::runtime_call_type);
633 cbuf.set_insts_mark();
634 address call_pc = (address)-1;
635 __ patchable_jump(call_pc);
636 __ align(16);
637 __ end_a_stub();
638 // Update current stubs pointer and restore code_end.
639 }
641 // size of call stub, compiled java to interpretor
642 uint size_java_to_interp() {
643 int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
644 return round_to(size, 16);
645 }
647 // relocation entries for call stub, compiled java to interpreter
648 uint reloc_java_to_interp() {
649 return 16; // in emit_java_to_interp + in Java_Static_Call
650 }
652 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
653 int offs = offset - br_size + 4;
654 // To be conservative on MIPS
655 // branch node should be end with:
656 // branch inst
657 // delay slot
658 const int safety_zone = 3 * BytesPerInstWord;
659 return Assembler::is_simm16((offs<0 ? offs-safety_zone : offs+safety_zone) >> 2);
660 }
663 // No additional cost for CMOVL.
664 const int Matcher::long_cmove_cost() { return 0; }
666 // No CMOVF/CMOVD with SSE2
667 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
669 // Does the CPU require late expand (see block.cpp for description of late expand)?
670 const bool Matcher::require_postalloc_expand = false;
672 // Should the Matcher clone shifts on addressing modes, expecting them
673 // to be subsumed into complex addressing expressions or compute them
674 // into registers? True for Intel but false for most RISCs
675 const bool Matcher::clone_shift_expressions = false;
677 // Do we need to mask the count passed to shift instructions or does
678 // the cpu only look at the lower 5/6 bits anyway?
679 const bool Matcher::need_masked_shift_count = false;
681 bool Matcher::narrow_oop_use_complex_address() {
682 NOT_LP64(ShouldNotCallThis());
683 assert(UseCompressedOops, "only for compressed oops code");
684 return false;
685 }
687 bool Matcher::narrow_klass_use_complex_address() {
688 NOT_LP64(ShouldNotCallThis());
689 assert(UseCompressedClassPointers, "only for compressed klass code");
690 return false;
691 }
693 // This is UltraSparc specific, true just means we have fast l2f conversion
694 const bool Matcher::convL2FSupported(void) {
695 return true;
696 }
698 // Max vector size in bytes. 0 if not supported.
699 const int Matcher::vector_width_in_bytes(BasicType bt) {
700 if (MaxVectorSize == 0)
701 return 0;
702 assert(MaxVectorSize == 8, "");
703 return 8;
704 }
706 // Vector ideal reg
707 const int Matcher::vector_ideal_reg(int size) {
708 assert(MaxVectorSize == 8, "");
709 switch(size) {
710 case 8: return Op_VecD;
711 }
712 ShouldNotReachHere();
713 return 0;
714 }
716 // Only lowest bits of xmm reg are used for vector shift count.
717 const int Matcher::vector_shift_count_ideal_reg(int size) {
718 fatal("vector shift is not supported");
719 return Node::NotAMachineReg;
720 }
722 // Limits on vector size (number of elements) loaded into vector.
723 const int Matcher::max_vector_size(const BasicType bt) {
724 assert(is_java_primitive(bt), "only primitive type vectors");
725 return vector_width_in_bytes(bt)/type2aelembytes(bt);
726 }
728 const int Matcher::min_vector_size(const BasicType bt) {
729 return max_vector_size(bt); // Same as max.
730 }
732 // MIPS supports misaligned vectors store/load? FIXME
733 const bool Matcher::misaligned_vectors_ok() {
734 return false;
735 //return !AlignVector; // can be changed by flag
736 }
738 // Register for DIVI projection of divmodI
739 RegMask Matcher::divI_proj_mask() {
740 ShouldNotReachHere();
741 return RegMask();
742 }
744 // Register for MODI projection of divmodI
745 RegMask Matcher::modI_proj_mask() {
746 ShouldNotReachHere();
747 return RegMask();
748 }
750 // Register for DIVL projection of divmodL
751 RegMask Matcher::divL_proj_mask() {
752 ShouldNotReachHere();
753 return RegMask();
754 }
756 int Matcher::regnum_to_fpu_offset(int regnum) {
757 return regnum - 32; // The FP registers are in the second chunk
758 }
761 const bool Matcher::isSimpleConstant64(jlong value) {
762 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
763 return true;
764 }
767 // Return whether or not this register is ever used as an argument. This
768 // function is used on startup to build the trampoline stubs in generateOptoStub.
769 // Registers not mentioned will be killed by the VM call in the trampoline, and
770 // arguments in those registers not be available to the callee.
771 bool Matcher::can_be_java_arg( int reg ) {
772 /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
773 if ( reg == T0_num || reg == T0_H_num
774 || reg == A0_num || reg == A0_H_num
775 || reg == A1_num || reg == A1_H_num
776 || reg == A2_num || reg == A2_H_num
777 || reg == A3_num || reg == A3_H_num
778 || reg == A4_num || reg == A4_H_num
779 || reg == A5_num || reg == A5_H_num
780 || reg == A6_num || reg == A6_H_num
781 || reg == A7_num || reg == A7_H_num )
782 return true;
784 if ( reg == F12_num || reg == F12_H_num
785 || reg == F13_num || reg == F13_H_num
786 || reg == F14_num || reg == F14_H_num
787 || reg == F15_num || reg == F15_H_num
788 || reg == F16_num || reg == F16_H_num
789 || reg == F17_num || reg == F17_H_num
790 || reg == F18_num || reg == F18_H_num
791 || reg == F19_num || reg == F19_H_num )
792 return true;
794 return false;
795 }
797 bool Matcher::is_spillable_arg( int reg ) {
798 return can_be_java_arg(reg);
799 }
801 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
802 return false;
803 }
805 // Register for MODL projection of divmodL
806 RegMask Matcher::modL_proj_mask() {
807 ShouldNotReachHere();
808 return RegMask();
809 }
811 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
812 return FP_REG_mask();
813 }
815 // MIPS doesn't support AES intrinsics
816 const bool Matcher::pass_original_key_for_aes() {
817 return false;
818 }
820 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
821 //lui
822 //ori
823 //dsll
824 //ori
826 //jalr
827 //nop
829 return round_to(current_offset, alignment_required()) - current_offset;
830 }
832 int CallLeafDirectNode::compute_padding(int current_offset) const {
833 //lui
834 //ori
835 //dsll
836 //ori
838 //jalr
839 //nop
841 return round_to(current_offset, alignment_required()) - current_offset;
842 }
844 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
845 //lui
846 //ori
847 //dsll
848 //ori
850 //jalr
851 //nop
853 return round_to(current_offset, alignment_required()) - current_offset;
854 }
856 // If CPU can load and store mis-aligned doubles directly then no fixup is
857 // needed. Else we split the double into 2 integer pieces and move it
858 // piece-by-piece. Only happens when passing doubles into C code as the
859 // Java calling convention forces doubles to be aligned.
860 const bool Matcher::misaligned_doubles_ok = false;
861 // Do floats take an entire double register or just half?
862 //const bool Matcher::float_in_double = true;
863 bool Matcher::float_in_double() { return false; }
864 // Threshold size for cleararray.
865 const int Matcher::init_array_short_size = 8 * BytesPerLong;
866 // Do ints take an entire long register or just half?
867 const bool Matcher::int_in_long = true;
868 // Is it better to copy float constants, or load them directly from memory?
869 // Intel can load a float constant from a direct address, requiring no
870 // extra registers. Most RISCs will have to materialize an address into a
871 // register first, so they would do better to copy the constant from stack.
872 const bool Matcher::rematerialize_float_constants = false;
873 // Advertise here if the CPU requires explicit rounding operations
874 // to implement the UseStrictFP mode.
875 const bool Matcher::strict_fp_requires_explicit_rounding = false;
876 // The ecx parameter to rep stos for the ClearArray node is in dwords.
877 const bool Matcher::init_array_count_is_in_bytes = false;
880 // Indicate if the safepoint node needs the polling page as an input.
881 // Since MIPS doesn't have absolute addressing, it needs.
882 bool SafePointNode::needs_polling_address_input() {
883 return false;
884 }
886 // !!!!! Special hack to get all type of calls to specify the byte offset
887 // from the start of the call to the point where the return address
888 // will point.
889 int MachCallStaticJavaNode::ret_addr_offset() {
890 //lui
891 //ori
892 //nop
893 //nop
894 //jalr
895 //nop
896 return 24;
897 }
899 int MachCallDynamicJavaNode::ret_addr_offset() {
900 //lui IC_Klass,
901 //ori IC_Klass,
902 //dsll IC_Klass
903 //ori IC_Klass
905 //lui T9
906 //ori T9
907 //nop
908 //nop
909 //jalr T9
910 //nop
911 return 4 * 4 + 4 * 6;
912 }
914 //=============================================================================
916 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
917 enum RC { rc_bad, rc_int, rc_float, rc_stack };
918 static enum RC rc_class( OptoReg::Name reg ) {
919 if( !OptoReg::is_valid(reg) ) return rc_bad;
920 if (OptoReg::is_stack(reg)) return rc_stack;
921 VMReg r = OptoReg::as_VMReg(reg);
922 if (r->is_Register()) return rc_int;
923 assert(r->is_FloatRegister(), "must be");
924 return rc_float;
925 }
927 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
928 // Get registers to move
929 OptoReg::Name src_second = ra_->get_reg_second(in(1));
930 OptoReg::Name src_first = ra_->get_reg_first(in(1));
931 OptoReg::Name dst_second = ra_->get_reg_second(this );
932 OptoReg::Name dst_first = ra_->get_reg_first(this );
934 enum RC src_second_rc = rc_class(src_second);
935 enum RC src_first_rc = rc_class(src_first);
936 enum RC dst_second_rc = rc_class(dst_second);
937 enum RC dst_first_rc = rc_class(dst_first);
939 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
941 // Generate spill code!
942 int size = 0;
944 if( src_first == dst_first && src_second == dst_second )
945 return 0; // Self copy, no move
947 if (src_first_rc == rc_stack) {
948 // mem ->
949 if (dst_first_rc == rc_stack) {
950 // mem -> mem
951 assert(src_second != dst_first, "overlap");
952 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
953 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
954 // 64-bit
955 int src_offset = ra_->reg2offset(src_first);
956 int dst_offset = ra_->reg2offset(dst_first);
957 if (cbuf) {
958 MacroAssembler _masm(cbuf);
959 __ ld(AT, Address(SP, src_offset));
960 __ sd(AT, Address(SP, dst_offset));
961 #ifndef PRODUCT
962 } else {
963 if(!do_size){
964 if (size != 0) st->print("\n\t");
965 st->print("ld AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
966 "sd AT, [SP + #%d]",
967 src_offset, dst_offset);
968 }
969 #endif
970 }
971 size += 8;
972 } else {
973 // 32-bit
974 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
975 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
976 // No pushl/popl, so:
977 int src_offset = ra_->reg2offset(src_first);
978 int dst_offset = ra_->reg2offset(dst_first);
979 if (cbuf) {
980 MacroAssembler _masm(cbuf);
981 __ lw(AT, Address(SP, src_offset));
982 __ sw(AT, Address(SP, dst_offset));
983 #ifndef PRODUCT
984 } else {
985 if(!do_size){
986 if (size != 0) st->print("\n\t");
987 st->print("lw AT, [SP + #%d] spill 2\n\t"
988 "sw AT, [SP + #%d]\n\t",
989 src_offset, dst_offset);
990 }
991 #endif
992 }
993 size += 8;
994 }
995 return size;
996 } else if (dst_first_rc == rc_int) {
997 // mem -> gpr
998 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
999 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1000 // 64-bit
1001 int offset = ra_->reg2offset(src_first);
1002 if (cbuf) {
1003 MacroAssembler _masm(cbuf);
1004 __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1005 #ifndef PRODUCT
1006 } else {
1007 if(!do_size){
1008 if (size != 0) st->print("\n\t");
1009 st->print("ld %s, [SP + #%d]\t# spill 3",
1010 Matcher::regName[dst_first],
1011 offset);
1012 }
1013 #endif
1014 }
1015 size += 4;
1016 } else {
1017 // 32-bit
1018 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1019 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1020 int offset = ra_->reg2offset(src_first);
1021 if (cbuf) {
1022 MacroAssembler _masm(cbuf);
1023 if (this->ideal_reg() == Op_RegI)
1024 __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1025 else
1026 __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1027 #ifndef PRODUCT
1028 } else {
1029 if(!do_size){
1030 if (size != 0) st->print("\n\t");
1031 if (this->ideal_reg() == Op_RegI)
1032 st->print("lw %s, [SP + #%d]\t# spill 4",
1033 Matcher::regName[dst_first],
1034 offset);
1035 else
1036 st->print("lwu %s, [SP + #%d]\t# spill 5",
1037 Matcher::regName[dst_first],
1038 offset);
1039 }
1040 #endif
1041 }
1042 size += 4;
1043 }
1044 return size;
1045 } else if (dst_first_rc == rc_float) {
1046 // mem-> xmm
1047 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1048 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1049 // 64-bit
1050 int offset = ra_->reg2offset(src_first);
1051 if (cbuf) {
1052 MacroAssembler _masm(cbuf);
1053 __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1054 #ifndef PRODUCT
1055 } else {
1056 if (!do_size) {
1057 if (size != 0) st->print("\n\t");
1058 st->print("ldc1 %s, [SP + #%d]\t# spill 6",
1059 Matcher::regName[dst_first],
1060 offset);
1061 }
1062 #endif
1063 }
1064 size += 4;
1065 } else {
1066 // 32-bit
1067 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1068 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1069 int offset = ra_->reg2offset(src_first);
1070 if (cbuf) {
1071 MacroAssembler _masm(cbuf);
1072 __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1073 #ifndef PRODUCT
1074 } else {
1075 if(!do_size){
1076 if (size != 0) st->print("\n\t");
1077 st->print("lwc1 %s, [SP + #%d]\t# spill 7",
1078 Matcher::regName[dst_first],
1079 offset);
1080 }
1081 #endif
1082 }
1083 size += 4;
1084 }
1085 return size;
1086 }
1087 } else if (src_first_rc == rc_int) {
1088 // gpr ->
1089 if (dst_first_rc == rc_stack) {
1090 // gpr -> mem
1091 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1092 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1093 // 64-bit
1094 int offset = ra_->reg2offset(dst_first);
1095 if (cbuf) {
1096 MacroAssembler _masm(cbuf);
1097 __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1098 #ifndef PRODUCT
1099 } else {
1100 if(!do_size){
1101 if (size != 0) st->print("\n\t");
1102 st->print("sd %s, [SP + #%d] # spill 8",
1103 Matcher::regName[src_first],
1104 offset);
1105 }
1106 #endif
1107 }
1108 size += 4;
1109 } else {
1110 // 32-bit
1111 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1112 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1113 int offset = ra_->reg2offset(dst_first);
1114 if (cbuf) {
1115 MacroAssembler _masm(cbuf);
1116 __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1117 #ifndef PRODUCT
1118 } else {
1119 if (!do_size) {
1120 if (size != 0) st->print("\n\t");
1121 st->print("sw %s, [SP + #%d]\t# spill 9",
1122 Matcher::regName[src_first], offset);
1123 }
1124 #endif
1125 }
1126 size += 4;
1127 }
1128 return size;
1129 } else if (dst_first_rc == rc_int) {
1130 // gpr -> gpr
1131 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1132 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1133 // 64-bit
1134 if (cbuf) {
1135 MacroAssembler _masm(cbuf);
1136 __ move(as_Register(Matcher::_regEncode[dst_first]),
1137 as_Register(Matcher::_regEncode[src_first]));
1138 #ifndef PRODUCT
1139 } else {
1140 if(!do_size){
1141 if (size != 0) st->print("\n\t");
1142 st->print("move(64bit) %s <-- %s\t# spill 10",
1143 Matcher::regName[dst_first],
1144 Matcher::regName[src_first]);
1145 }
1146 #endif
1147 }
1148 size += 4;
1149 return size;
1150 } else {
1151 // 32-bit
1152 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1153 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1154 if (cbuf) {
1155 MacroAssembler _masm(cbuf);
1156 if (this->ideal_reg() == Op_RegI)
1157 __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1158 else
1159 __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
1160 #ifndef PRODUCT
1161 } else {
1162 if (!do_size) {
1163 if (size != 0) st->print("\n\t");
1164 st->print("move(32-bit) %s <-- %s\t# spill 11",
1165 Matcher::regName[dst_first],
1166 Matcher::regName[src_first]);
1167 }
1168 #endif
1169 }
1170 size += 4;
1171 return size;
1172 }
1173 } else if (dst_first_rc == rc_float) {
1174 // gpr -> xmm
1175 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1176 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1177 // 64-bit
1178 if (cbuf) {
1179 MacroAssembler _masm(cbuf);
1180 __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
1181 #ifndef PRODUCT
1182 } else {
1183 if(!do_size){
1184 if (size != 0) st->print("\n\t");
1185 st->print("dmtc1 %s, %s\t# spill 12",
1186 Matcher::regName[dst_first],
1187 Matcher::regName[src_first]);
1188 }
1189 #endif
1190 }
1191 size += 4;
1192 } else {
1193 // 32-bit
1194 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1195 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1196 if (cbuf) {
1197 MacroAssembler _masm(cbuf);
1198 __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
1199 #ifndef PRODUCT
1200 } else {
1201 if(!do_size){
1202 if (size != 0) st->print("\n\t");
1203 st->print("mtc1 %s, %s\t# spill 13",
1204 Matcher::regName[dst_first],
1205 Matcher::regName[src_first]);
1206 }
1207 #endif
1208 }
1209 size += 4;
1210 }
1211 return size;
1212 }
1213 } else if (src_first_rc == rc_float) {
1214 // xmm ->
1215 if (dst_first_rc == rc_stack) {
1216 // xmm -> mem
1217 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1218 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1219 // 64-bit
1220 int offset = ra_->reg2offset(dst_first);
1221 if (cbuf) {
1222 MacroAssembler _masm(cbuf);
1223 __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
1224 #ifndef PRODUCT
1225 } else {
1226 if(!do_size){
1227 if (size != 0) st->print("\n\t");
1228 st->print("sdc1 %s, [SP + #%d]\t# spill 14",
1229 Matcher::regName[src_first],
1230 offset);
1231 }
1232 #endif
1233 }
1234 size += 4;
1235 } else {
1236 // 32-bit
1237 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1238 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1239 int offset = ra_->reg2offset(dst_first);
1240 if (cbuf) {
1241 MacroAssembler _masm(cbuf);
1242 __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
1243 #ifndef PRODUCT
1244 } else {
1245 if(!do_size){
1246 if (size != 0) st->print("\n\t");
1247 st->print("swc1 %s, [SP + #%d]\t# spill 15",
1248 Matcher::regName[src_first],
1249 offset);
1250 }
1251 #endif
1252 }
1253 size += 4;
1254 }
1255 return size;
1256 } else if (dst_first_rc == rc_int) {
1257 // xmm -> gpr
1258 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1259 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1260 // 64-bit
1261 if (cbuf) {
1262 MacroAssembler _masm(cbuf);
1263 __ dmfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1264 #ifndef PRODUCT
1265 } else {
1266 if(!do_size){
1267 if (size != 0) st->print("\n\t");
1268 st->print("dmfc1 %s, %s\t# spill 16",
1269 Matcher::regName[dst_first],
1270 Matcher::regName[src_first]);
1271 }
1272 #endif
1273 }
1274 size += 4;
1275 } else {
1276 // 32-bit
1277 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1278 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1279 if (cbuf) {
1280 MacroAssembler _masm(cbuf);
1281 __ mfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1282 #ifndef PRODUCT
1283 } else {
1284 if(!do_size){
1285 if (size != 0) st->print("\n\t");
1286 st->print("mfc1 %s, %s\t# spill 17",
1287 Matcher::regName[dst_first],
1288 Matcher::regName[src_first]);
1289 }
1290 #endif
1291 }
1292 size += 4;
1293 }
1294 return size;
1295 } else if (dst_first_rc == rc_float) {
1296 // xmm -> xmm
1297 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1298 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1299 // 64-bit
1300 if (cbuf) {
1301 MacroAssembler _masm(cbuf);
1302 __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1303 #ifndef PRODUCT
1304 } else {
1305 if(!do_size){
1306 if (size != 0) st->print("\n\t");
1307 st->print("mov_d %s <-- %s\t# spill 18",
1308 Matcher::regName[dst_first],
1309 Matcher::regName[src_first]);
1310 }
1311 #endif
1312 }
1313 size += 4;
1314 } else {
1315 // 32-bit
1316 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1317 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1318 if (cbuf) {
1319 MacroAssembler _masm(cbuf);
1320 __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1321 #ifndef PRODUCT
1322 } else {
1323 if(!do_size){
1324 if (size != 0) st->print("\n\t");
1325 st->print("mov_s %s <-- %s\t# spill 19",
1326 Matcher::regName[dst_first],
1327 Matcher::regName[src_first]);
1328 }
1329 #endif
1330 }
1331 size += 4;
1332 }
1333 return size;
1334 }
1335 }
1337 assert(0," foo ");
1338 Unimplemented();
1339 return size;
1341 }
1343 #ifndef PRODUCT
1344 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1345 implementation( NULL, ra_, false, st );
1346 }
1347 #endif
1349 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1350 implementation( &cbuf, ra_, false, NULL );
1351 }
1353 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1354 return implementation( NULL, ra_, true, NULL );
1355 }
1357 //=============================================================================
1358 #
1360 #ifndef PRODUCT
1361 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
1362 st->print("INT3");
1363 }
1364 #endif
1366 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
1367 MacroAssembler _masm(&cbuf);
1368 __ int3();
1369 }
1371 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
1372 return MachNode::size(ra_);
1373 }
1376 //=============================================================================
1377 #ifndef PRODUCT
1378 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1379 Compile *C = ra_->C;
1380 int framesize = C->frame_size_in_bytes();
1382 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1384 st->print_cr("daddiu SP, SP, %d # Rlease stack @ MachEpilogNode", framesize);
1385 st->print("\t");
1386 if (UseLoongsonISA) {
1387 st->print_cr("gslq RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
1388 } else {
1389 st->print_cr("ld RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
1390 st->print("\t");
1391 st->print_cr("ld FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
1392 }
1394 if( do_polling() && C->is_method_compilation() ) {
1395 st->print("\t");
1396 st->print_cr("Poll Safepoint # MachEpilogNode");
1397 }
1398 }
1399 #endif
1401 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1402 Compile *C = ra_->C;
1403 MacroAssembler _masm(&cbuf);
1404 int framesize = C->frame_size_in_bytes();
1406 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1408 __ daddiu(SP, SP, framesize);
1410 if (UseLoongsonISA) {
1411 __ gslq(RA, FP, SP, -wordSize*2);
1412 } else {
1413 __ ld(RA, SP, -wordSize );
1414 __ ld(FP, SP, -wordSize*2 );
1415 }
1417 if( do_polling() && C->is_method_compilation() ) {
1418 __ set64(AT, (long)os::get_polling_page());
1419 __ relocate(relocInfo::poll_return_type);
1420 __ lw(AT, AT, 0);
1421 }
1422 }
1424 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1425 return MachNode::size(ra_); // too many variables; just compute it the hard way fujie debug
1426 }
1428 int MachEpilogNode::reloc() const {
1429 return 0; // a large enough number
1430 }
1432 const Pipeline * MachEpilogNode::pipeline() const {
1433 return MachNode::pipeline_class();
1434 }
1436 int MachEpilogNode::safepoint_offset() const { return 0; }
1438 //=============================================================================
1440 #ifndef PRODUCT
1441 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1442 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1443 int reg = ra_->get_reg_first(this);
1444 st->print("ADDI %s, SP, %d @BoxLockNode",Matcher::regName[reg],offset);
1445 }
1446 #endif
1449 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1450 return 4;
1451 }
1453 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1454 MacroAssembler _masm(&cbuf);
1455 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1456 int reg = ra_->get_encode(this);
1458 __ addi(as_Register(reg), SP, offset);
1459 }
1462 //static int sizeof_FFree_Float_Stack_All = -1;
1464 int MachCallRuntimeNode::ret_addr_offset() {
1465 //lui
1466 //ori
1467 //dsll
1468 //ori
1469 //jalr
1470 //nop
1471 assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
1472 return NativeCall::instruction_size;
1473 }
1476 //=============================================================================
1477 #ifndef PRODUCT
1478 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
1479 st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
1480 }
1481 #endif
1483 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
1484 MacroAssembler _masm(&cbuf);
1485 int i = 0;
1486 for(i = 0; i < _count; i++)
1487 __ nop();
1488 }
1490 uint MachNopNode::size(PhaseRegAlloc *) const {
1491 return 4 * _count;
1492 }
1493 const Pipeline* MachNopNode::pipeline() const {
1494 return MachNode::pipeline_class();
1495 }
1497 //=============================================================================
1499 //=============================================================================
1500 #ifndef PRODUCT
1501 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1502 st->print_cr("load_klass(T9, T0)");
1503 st->print_cr("\tbeq(T9, iCache, L)");
1504 st->print_cr("\tnop");
1505 st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
1506 st->print_cr("\tnop");
1507 st->print_cr("\tnop");
1508 st->print_cr(" L:");
1509 }
1510 #endif
1513 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1514 MacroAssembler _masm(&cbuf);
1515 #ifdef ASSERT
1516 //uint code_size = cbuf.code_size();
1517 #endif
1518 int ic_reg = Matcher::inline_cache_reg_encode();
1519 Label L;
1520 Register receiver = T0;
1521 Register iCache = as_Register(ic_reg);
1522 __ load_klass(T9, receiver);
1523 __ beq(T9, iCache, L);
1524 __ delayed()->nop();
1526 __ relocate(relocInfo::runtime_call_type);
1527 __ patchable_jump((address)SharedRuntime::get_ic_miss_stub());
1529 /* WARNING these NOPs are critical so that verified entry point is properly
1530 * 8 bytes aligned for patching by NativeJump::patch_verified_entry() */
1531 __ align(CodeEntryAlignment);
1532 __ bind(L);
1533 }
1535 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1536 return MachNode::size(ra_);
1537 }
1541 //=============================================================================
1543 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
1545 int Compile::ConstantTable::calculate_table_base_offset() const {
1546 return 0; // absolute addressing, no offset
1547 }
1549 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1550 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1551 ShouldNotReachHere();
1552 }
1554 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1555 Compile* C = ra_->C;
1556 Compile::ConstantTable& constant_table = C->constant_table();
1557 MacroAssembler _masm(&cbuf);
1559 Register Rtoc = as_Register(ra_->get_encode(this));
1560 CodeSection* consts_section = __ code()->consts();
1561 int consts_size = consts_section->align_at_start(consts_section->size());
1562 assert(constant_table.size() == consts_size, "must be equal");
1564 if (consts_section->size()) {
1565 // Materialize the constant table base.
1566 address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
1567 // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
1568 __ relocate(relocInfo::internal_word_type);
1569 __ patchable_set48(Rtoc, (long)baseaddr);
1570 }
1571 }
1573 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1574 // patchable_set48 (4 insts)
1575 return 4 * 4;
1576 }
1578 #ifndef PRODUCT
1579 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1580 Register r = as_Register(ra_->get_encode(this));
1581 st->print("patchable_set48 %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
1582 }
1583 #endif
1586 //=============================================================================
1587 #ifndef PRODUCT
1588 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1589 Compile* C = ra_->C;
1591 int framesize = C->frame_size_in_bytes();
1592 int bangsize = C->bang_size_in_bytes();
1593 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1595 // Calls to C2R adapters often do not accept exceptional returns.
1596 // We require that their callers must bang for them. But be careful, because
1597 // some VM calls (such as call site linkage) can use several kilobytes of
1598 // stack. But the stack safety zone should account for that.
1599 // See bugs 4446381, 4468289, 4497237.
1600 if (C->need_stack_bang(bangsize)) {
1601 st->print_cr("# stack bang"); st->print("\t");
1602 }
1603 if (UseLoongsonISA) {
1604 st->print("gssq RA, FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1605 } else {
1606 st->print("sd RA, %d(SP) @ MachPrologNode\n\t", -wordSize);
1607 st->print("sd FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1608 }
1609 st->print("daddiu FP, SP, -%d \n\t", wordSize*2);
1610 st->print("daddiu SP, SP, -%d \t",framesize);
1611 }
1612 #endif
1615 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1616 Compile* C = ra_->C;
1617 MacroAssembler _masm(&cbuf);
1619 int framesize = C->frame_size_in_bytes();
1620 int bangsize = C->bang_size_in_bytes();
1622 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1624 if (C->need_stack_bang(bangsize)) {
1625 __ generate_stack_overflow_check(bangsize);
1626 }
1628 if (UseLoongsonISA) {
1629 __ gssq(RA, FP, SP, -wordSize*2);
1630 } else {
1631 __ sd(RA, SP, -wordSize);
1632 __ sd(FP, SP, -wordSize*2);
1633 }
1634 __ daddiu(FP, SP, -wordSize*2);
1635 __ daddiu(SP, SP, -framesize);
1636 __ nop(); // Make enough room for patch_verified_entry()
1637 __ nop();
1639 C->set_frame_complete(cbuf.insts_size());
1640 if (C->has_mach_constant_base_node()) {
1641 // NOTE: We set the table base offset here because users might be
1642 // emitted before MachConstantBaseNode.
1643 Compile::ConstantTable& constant_table = C->constant_table();
1644 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1645 }
1647 }
1650 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1651 return MachNode::size(ra_); // too many variables; just compute it the hard way
1652 }
1654 int MachPrologNode::reloc() const {
1655 return 0; // a large enough number
1656 }
1658 %}
1660 //----------ENCODING BLOCK-----------------------------------------------------
1661 // This block specifies the encoding classes used by the compiler to output
1662 // byte streams. Encoding classes generate functions which are called by
1663 // Machine Instruction Nodes in order to generate the bit encoding of the
1664 // instruction. Operands specify their base encoding interface with the
1665 // interface keyword. There are currently supported four interfaces,
1666 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
1667 // operand to generate a function which returns its register number when
1668 // queried. CONST_INTER causes an operand to generate a function which
1669 // returns the value of the constant when queried. MEMORY_INTER causes an
1670 // operand to generate four functions which return the Base Register, the
1671 // Index Register, the Scale Value, and the Offset Value of the operand when
1672 // queried. COND_INTER causes an operand to generate six functions which
1673 // return the encoding code (ie - encoding bits for the instruction)
1674 // associated with each basic boolean condition for a conditional instruction.
1675 // Instructions specify two basic values for encoding. They use the
1676 // ins_encode keyword to specify their encoding class (which must be one of
1677 // the class names specified in the encoding block), and they use the
1678 // opcode keyword to specify, in order, their primary, secondary, and
1679 // tertiary opcode. Only the opcode sections which a particular instruction
1680 // needs for encoding need to be specified.
1681 encode %{
1683 //Load byte signed
1684 enc_class load_B_enc (mRegI dst, memory mem) %{
1685 MacroAssembler _masm(&cbuf);
1686 int dst = $dst$$reg;
1687 int base = $mem$$base;
1688 int index = $mem$$index;
1689 int scale = $mem$$scale;
1690 int disp = $mem$$disp;
1692 if( index != 0 ) {
1693 if( Assembler::is_simm16(disp) ) {
1694 if( UseLoongsonISA ) {
1695 if (scale == 0) {
1696 __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
1697 } else {
1698 __ dsll(AT, as_Register(index), scale);
1699 __ gslbx(as_Register(dst), as_Register(base), AT, disp);
1700 }
1701 } else {
1702 if (scale == 0) {
1703 __ addu(AT, as_Register(base), as_Register(index));
1704 } else {
1705 __ dsll(AT, as_Register(index), scale);
1706 __ addu(AT, as_Register(base), AT);
1707 }
1708 __ lb(as_Register(dst), AT, disp);
1709 }
1710 } else {
1711 if (scale == 0) {
1712 __ addu(AT, as_Register(base), as_Register(index));
1713 } else {
1714 __ dsll(AT, as_Register(index), scale);
1715 __ addu(AT, as_Register(base), AT);
1716 }
1717 __ move(T9, disp);
1718 if( UseLoongsonISA ) {
1719 __ gslbx(as_Register(dst), AT, T9, 0);
1720 } else {
1721 __ addu(AT, AT, T9);
1722 __ lb(as_Register(dst), AT, 0);
1723 }
1724 }
1725 } else {
1726 if( Assembler::is_simm16(disp) ) {
1727 __ lb(as_Register(dst), as_Register(base), disp);
1728 } else {
1729 __ move(T9, disp);
1730 if( UseLoongsonISA ) {
1731 __ gslbx(as_Register(dst), as_Register(base), T9, 0);
1732 } else {
1733 __ addu(AT, as_Register(base), T9);
1734 __ lb(as_Register(dst), AT, 0);
1735 }
1736 }
1737 }
1738 %}
1740 //Load byte unsigned
1741 enc_class load_UB_enc (mRegI dst, memory mem) %{
1742 MacroAssembler _masm(&cbuf);
1743 int dst = $dst$$reg;
1744 int base = $mem$$base;
1745 int index = $mem$$index;
1746 int scale = $mem$$scale;
1747 int disp = $mem$$disp;
1749 if( index != 0 ) {
1750 if (scale == 0) {
1751 __ daddu(AT, as_Register(base), as_Register(index));
1752 } else {
1753 __ dsll(AT, as_Register(index), scale);
1754 __ daddu(AT, as_Register(base), AT);
1755 }
1756 if( Assembler::is_simm16(disp) ) {
1757 __ lbu(as_Register(dst), AT, disp);
1758 } else {
1759 __ move(T9, disp);
1760 __ daddu(AT, AT, T9);
1761 __ lbu(as_Register(dst), AT, 0);
1762 }
1763 } else {
1764 if( Assembler::is_simm16(disp) ) {
1765 __ lbu(as_Register(dst), as_Register(base), disp);
1766 } else {
1767 __ move(T9, disp);
1768 __ daddu(AT, as_Register(base), T9);
1769 __ lbu(as_Register(dst), AT, 0);
1770 }
1771 }
1772 %}
1774 enc_class store_B_reg_enc (memory mem, mRegI src) %{
1775 MacroAssembler _masm(&cbuf);
1776 int src = $src$$reg;
1777 int base = $mem$$base;
1778 int index = $mem$$index;
1779 int scale = $mem$$scale;
1780 int disp = $mem$$disp;
1782 if( index != 0 ) {
1783 if (scale == 0) {
1784 if( Assembler::is_simm(disp, 8) ) {
1785 if (UseLoongsonISA) {
1786 __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
1787 } else {
1788 __ addu(AT, as_Register(base), as_Register(index));
1789 __ sb(as_Register(src), AT, disp);
1790 }
1791 } else if( Assembler::is_simm16(disp) ) {
1792 __ addu(AT, as_Register(base), as_Register(index));
1793 __ sb(as_Register(src), AT, disp);
1794 } else {
1795 __ addu(AT, as_Register(base), as_Register(index));
1796 __ move(T9, disp);
1797 if (UseLoongsonISA) {
1798 __ gssbx(as_Register(src), AT, T9, 0);
1799 } else {
1800 __ addu(AT, AT, T9);
1801 __ sb(as_Register(src), AT, 0);
1802 }
1803 }
1804 } else {
1805 __ dsll(AT, as_Register(index), scale);
1806 if( Assembler::is_simm(disp, 8) ) {
1807 if (UseLoongsonISA) {
1808 __ gssbx(as_Register(src), AT, as_Register(base), disp);
1809 } else {
1810 __ addu(AT, as_Register(base), AT);
1811 __ sb(as_Register(src), AT, disp);
1812 }
1813 } else if( Assembler::is_simm16(disp) ) {
1814 __ addu(AT, as_Register(base), AT);
1815 __ sb(as_Register(src), AT, disp);
1816 } else {
1817 __ addu(AT, as_Register(base), AT);
1818 __ move(T9, disp);
1819 if (UseLoongsonISA) {
1820 __ gssbx(as_Register(src), AT, T9, 0);
1821 } else {
1822 __ addu(AT, AT, T9);
1823 __ sb(as_Register(src), AT, 0);
1824 }
1825 }
1826 }
1827 } else {
1828 if( Assembler::is_simm16(disp) ) {
1829 __ sb(as_Register(src), as_Register(base), disp);
1830 } else {
1831 __ move(T9, disp);
1832 if (UseLoongsonISA) {
1833 __ gssbx(as_Register(src), as_Register(base), T9, 0);
1834 } else {
1835 __ addu(AT, as_Register(base), T9);
1836 __ sb(as_Register(src), AT, 0);
1837 }
1838 }
1839 }
1840 %}
1842 enc_class store_B_immI_enc (memory mem, immI8 src) %{
1843 MacroAssembler _masm(&cbuf);
1844 int base = $mem$$base;
1845 int index = $mem$$index;
1846 int scale = $mem$$scale;
1847 int disp = $mem$$disp;
1848 int value = $src$$constant;
1850 if( index != 0 ) {
1851 if (!UseLoongsonISA) {
1852 if (scale == 0) {
1853 __ daddu(AT, as_Register(base), as_Register(index));
1854 } else {
1855 __ dsll(AT, as_Register(index), scale);
1856 __ daddu(AT, as_Register(base), AT);
1857 }
1858 if( Assembler::is_simm16(disp) ) {
1859 if (value == 0) {
1860 __ sb(R0, AT, disp);
1861 } else {
1862 __ move(T9, value);
1863 __ sb(T9, AT, disp);
1864 }
1865 } else {
1866 if (value == 0) {
1867 __ move(T9, disp);
1868 __ daddu(AT, AT, T9);
1869 __ sb(R0, AT, 0);
1870 } else {
1871 __ move(T9, disp);
1872 __ daddu(AT, AT, T9);
1873 __ move(T9, value);
1874 __ sb(T9, AT, 0);
1875 }
1876 }
1877 } else {
1879 if (scale == 0) {
1880 if( Assembler::is_simm(disp, 8) ) {
1881 if (value == 0) {
1882 __ gssbx(R0, as_Register(base), as_Register(index), disp);
1883 } else {
1884 __ move(T9, value);
1885 __ gssbx(T9, as_Register(base), as_Register(index), disp);
1886 }
1887 } else if( Assembler::is_simm16(disp) ) {
1888 __ daddu(AT, as_Register(base), as_Register(index));
1889 if (value == 0) {
1890 __ sb(R0, AT, disp);
1891 } else {
1892 __ move(T9, value);
1893 __ sb(T9, AT, disp);
1894 }
1895 } else {
1896 if (value == 0) {
1897 __ daddu(AT, as_Register(base), as_Register(index));
1898 __ move(T9, disp);
1899 __ gssbx(R0, AT, T9, 0);
1900 } else {
1901 __ move(AT, disp);
1902 __ move(T9, value);
1903 __ daddu(AT, as_Register(base), AT);
1904 __ gssbx(T9, AT, as_Register(index), 0);
1905 }
1906 }
1908 } else {
1910 if( Assembler::is_simm(disp, 8) ) {
1911 __ dsll(AT, as_Register(index), scale);
1912 if (value == 0) {
1913 __ gssbx(R0, as_Register(base), AT, disp);
1914 } else {
1915 __ move(T9, value);
1916 __ gssbx(T9, as_Register(base), AT, disp);
1917 }
1918 } else if( Assembler::is_simm16(disp) ) {
1919 __ dsll(AT, as_Register(index), scale);
1920 __ daddu(AT, as_Register(base), AT);
1921 if (value == 0) {
1922 __ sb(R0, AT, disp);
1923 } else {
1924 __ move(T9, value);
1925 __ sb(T9, AT, disp);
1926 }
1927 } else {
1928 __ dsll(AT, as_Register(index), scale);
1929 if (value == 0) {
1930 __ daddu(AT, as_Register(base), AT);
1931 __ move(T9, disp);
1932 __ gssbx(R0, AT, T9, 0);
1933 } else {
1934 __ move(T9, disp);
1935 __ daddu(AT, AT, T9);
1936 __ move(T9, value);
1937 __ gssbx(T9, as_Register(base), AT, 0);
1938 }
1939 }
1940 }
1941 }
1942 } else {
1943 if( Assembler::is_simm16(disp) ) {
1944 if (value == 0) {
1945 __ sb(R0, as_Register(base), disp);
1946 } else {
1947 __ move(AT, value);
1948 __ sb(AT, as_Register(base), disp);
1949 }
1950 } else {
1951 if (value == 0) {
1952 __ move(T9, disp);
1953 if (UseLoongsonISA) {
1954 __ gssbx(R0, as_Register(base), T9, 0);
1955 } else {
1956 __ daddu(AT, as_Register(base), T9);
1957 __ sb(R0, AT, 0);
1958 }
1959 } else {
1960 __ move(T9, disp);
1961 if (UseLoongsonISA) {
1962 __ move(AT, value);
1963 __ gssbx(AT, as_Register(base), T9, 0);
1964 } else {
1965 __ daddu(AT, as_Register(base), T9);
1966 __ move(T9, value);
1967 __ sb(T9, AT, 0);
1968 }
1969 }
1970 }
1971 }
1972 %}
1975 enc_class store_B_immI_enc_sync (memory mem, immI8 src) %{
1976 MacroAssembler _masm(&cbuf);
1977 int base = $mem$$base;
1978 int index = $mem$$index;
1979 int scale = $mem$$scale;
1980 int disp = $mem$$disp;
1981 int value = $src$$constant;
1983 if( index != 0 ) {
1984 if ( UseLoongsonISA ) {
1985 if ( Assembler::is_simm(disp,8) ) {
1986 if ( scale == 0 ) {
1987 if ( value == 0 ) {
1988 __ gssbx(R0, as_Register(base), as_Register(index), disp);
1989 } else {
1990 __ move(AT, value);
1991 __ gssbx(AT, as_Register(base), as_Register(index), disp);
1992 }
1993 } else {
1994 __ dsll(AT, as_Register(index), scale);
1995 if ( value == 0 ) {
1996 __ gssbx(R0, as_Register(base), AT, disp);
1997 } else {
1998 __ move(T9, value);
1999 __ gssbx(T9, as_Register(base), AT, disp);
2000 }
2001 }
2002 } else if ( Assembler::is_simm16(disp) ) {
2003 if ( scale == 0 ) {
2004 __ daddu(AT, as_Register(base), as_Register(index));
2005 if ( value == 0 ){
2006 __ sb(R0, AT, disp);
2007 } else {
2008 __ move(T9, value);
2009 __ sb(T9, AT, disp);
2010 }
2011 } else {
2012 __ dsll(AT, as_Register(index), scale);
2013 __ daddu(AT, as_Register(base), AT);
2014 if ( value == 0 ) {
2015 __ sb(R0, AT, disp);
2016 } else {
2017 __ move(T9, value);
2018 __ sb(T9, AT, disp);
2019 }
2020 }
2021 } else {
2022 if ( scale == 0 ) {
2023 __ move(AT, disp);
2024 __ daddu(AT, as_Register(index), AT);
2025 if ( value == 0 ) {
2026 __ gssbx(R0, as_Register(base), AT, 0);
2027 } else {
2028 __ move(T9, value);
2029 __ gssbx(T9, as_Register(base), AT, 0);
2030 }
2031 } else {
2032 __ dsll(AT, as_Register(index), scale);
2033 __ move(T9, disp);
2034 __ daddu(AT, AT, T9);
2035 if ( value == 0 ) {
2036 __ gssbx(R0, as_Register(base), AT, 0);
2037 } else {
2038 __ move(T9, value);
2039 __ gssbx(T9, as_Register(base), AT, 0);
2040 }
2041 }
2042 }
2043 } else { //not use loongson isa
2044 if (scale == 0) {
2045 __ daddu(AT, as_Register(base), as_Register(index));
2046 } else {
2047 __ dsll(AT, as_Register(index), scale);
2048 __ daddu(AT, as_Register(base), AT);
2049 }
2050 if( Assembler::is_simm16(disp) ) {
2051 if (value == 0) {
2052 __ sb(R0, AT, disp);
2053 } else {
2054 __ move(T9, value);
2055 __ sb(T9, AT, disp);
2056 }
2057 } else {
2058 if (value == 0) {
2059 __ move(T9, disp);
2060 __ daddu(AT, AT, T9);
2061 __ sb(R0, AT, 0);
2062 } else {
2063 __ move(T9, disp);
2064 __ daddu(AT, AT, T9);
2065 __ move(T9, value);
2066 __ sb(T9, AT, 0);
2067 }
2068 }
2069 }
2070 } else {
2071 if ( UseLoongsonISA ){
2072 if ( Assembler::is_simm16(disp) ){
2073 if ( value == 0 ) {
2074 __ sb(R0, as_Register(base), disp);
2075 } else {
2076 __ move(AT, value);
2077 __ sb(AT, as_Register(base), disp);
2078 }
2079 } else {
2080 __ move(AT, disp);
2081 if ( value == 0 ) {
2082 __ gssbx(R0, as_Register(base), AT, 0);
2083 } else {
2084 __ move(T9, value);
2085 __ gssbx(T9, as_Register(base), AT, 0);
2086 }
2087 }
2088 } else {
2089 if( Assembler::is_simm16(disp) ) {
2090 if (value == 0) {
2091 __ sb(R0, as_Register(base), disp);
2092 } else {
2093 __ move(AT, value);
2094 __ sb(AT, as_Register(base), disp);
2095 }
2096 } else {
2097 if (value == 0) {
2098 __ move(T9, disp);
2099 __ daddu(AT, as_Register(base), T9);
2100 __ sb(R0, AT, 0);
2101 } else {
2102 __ move(T9, disp);
2103 __ daddu(AT, as_Register(base), T9);
2104 __ move(T9, value);
2105 __ sb(T9, AT, 0);
2106 }
2107 }
2108 }
2109 }
2111 __ sync();
2112 %}
2114 // Load Short (16bit signed)
2115 enc_class load_S_enc (mRegI dst, memory mem) %{
2116 MacroAssembler _masm(&cbuf);
2117 int dst = $dst$$reg;
2118 int base = $mem$$base;
2119 int index = $mem$$index;
2120 int scale = $mem$$scale;
2121 int disp = $mem$$disp;
2123 if( index != 0 ) {
2124 if ( UseLoongsonISA ) {
2125 if ( Assembler::is_simm(disp, 8) ) {
2126 if (scale == 0) {
2127 __ gslhx(as_Register(dst), as_Register(base), as_Register(index), disp);
2128 } else {
2129 __ dsll(AT, as_Register(index), scale);
2130 __ gslhx(as_Register(dst), as_Register(base), AT, disp);
2131 }
2132 } else if ( Assembler::is_simm16(disp) ) {
2133 if (scale == 0) {
2134 __ daddu(AT, as_Register(base), as_Register(index));
2135 __ lh(as_Register(dst), AT, disp);
2136 } else {
2137 __ dsll(AT, as_Register(index), scale);
2138 __ daddu(AT, as_Register(base), AT);
2139 __ lh(as_Register(dst), AT, disp);
2140 }
2141 } else {
2142 if (scale == 0) {
2143 __ move(AT, disp);
2144 __ daddu(AT, as_Register(index), AT);
2145 __ gslhx(as_Register(dst), as_Register(base), AT, 0);
2146 } else {
2147 __ dsll(AT, as_Register(index), scale);
2148 __ move(T9, disp);
2149 __ daddu(AT, AT, T9);
2150 __ gslhx(as_Register(dst), as_Register(base), AT, 0);
2151 }
2152 }
2153 } else { // not use loongson isa
2154 if (scale == 0) {
2155 __ daddu(AT, as_Register(base), as_Register(index));
2156 } else {
2157 __ dsll(AT, as_Register(index), scale);
2158 __ daddu(AT, as_Register(base), AT);
2159 }
2160 if( Assembler::is_simm16(disp) ) {
2161 __ lh(as_Register(dst), AT, disp);
2162 } else {
2163 __ move(T9, disp);
2164 __ daddu(AT, AT, T9);
2165 __ lh(as_Register(dst), AT, 0);
2166 }
2167 }
2168 } else { // index is 0
2169 if ( UseLoongsonISA ) {
2170 if ( Assembler::is_simm16(disp) ) {
2171 __ lh(as_Register(dst), as_Register(base), disp);
2172 } else {
2173 __ move(T9, disp);
2174 __ gslhx(as_Register(dst), as_Register(base), T9, 0);
2175 }
2176 } else { //not use loongson isa
2177 if( Assembler::is_simm16(disp) ) {
2178 __ lh(as_Register(dst), as_Register(base), disp);
2179 } else {
2180 __ move(T9, disp);
2181 __ daddu(AT, as_Register(base), T9);
2182 __ lh(as_Register(dst), AT, 0);
2183 }
2184 }
2185 }
2186 %}
2188 // Load Char (16bit unsigned)
2189 enc_class load_C_enc (mRegI dst, memory mem) %{
2190 MacroAssembler _masm(&cbuf);
2191 int dst = $dst$$reg;
2192 int base = $mem$$base;
2193 int index = $mem$$index;
2194 int scale = $mem$$scale;
2195 int disp = $mem$$disp;
2197 if( index != 0 ) {
2198 if (scale == 0) {
2199 __ daddu(AT, as_Register(base), as_Register(index));
2200 } else {
2201 __ dsll(AT, as_Register(index), scale);
2202 __ daddu(AT, as_Register(base), AT);
2203 }
2204 if( Assembler::is_simm16(disp) ) {
2205 __ lhu(as_Register(dst), AT, disp);
2206 } else {
2207 __ move(T9, disp);
2208 __ addu(AT, AT, T9);
2209 __ lhu(as_Register(dst), AT, 0);
2210 }
2211 } else {
2212 if( Assembler::is_simm16(disp) ) {
2213 __ lhu(as_Register(dst), as_Register(base), disp);
2214 } else {
2215 __ move(T9, disp);
2216 __ daddu(AT, as_Register(base), T9);
2217 __ lhu(as_Register(dst), AT, 0);
2218 }
2219 }
2220 %}
2222 // Store Char (16bit unsigned)
2223 enc_class store_C_reg_enc (memory mem, mRegI src) %{
2224 MacroAssembler _masm(&cbuf);
2225 int src = $src$$reg;
2226 int base = $mem$$base;
2227 int index = $mem$$index;
2228 int scale = $mem$$scale;
2229 int disp = $mem$$disp;
2231 if( index != 0 ) {
2232 if( Assembler::is_simm16(disp) ) {
2233 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2234 if (scale == 0) {
2235 __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
2236 } else {
2237 __ dsll(AT, as_Register(index), scale);
2238 __ gsshx(as_Register(src), as_Register(base), AT, disp);
2239 }
2240 } else {
2241 if (scale == 0) {
2242 __ addu(AT, as_Register(base), as_Register(index));
2243 } else {
2244 __ dsll(AT, as_Register(index), scale);
2245 __ addu(AT, as_Register(base), AT);
2246 }
2247 __ sh(as_Register(src), AT, disp);
2248 }
2249 } else {
2250 if (scale == 0) {
2251 __ addu(AT, as_Register(base), as_Register(index));
2252 } else {
2253 __ dsll(AT, as_Register(index), scale);
2254 __ addu(AT, as_Register(base), AT);
2255 }
2256 __ move(T9, disp);
2257 if( UseLoongsonISA ) {
2258 __ gsshx(as_Register(src), AT, T9, 0);
2259 } else {
2260 __ addu(AT, AT, T9);
2261 __ sh(as_Register(src), AT, 0);
2262 }
2263 }
2264 } else {
2265 if( Assembler::is_simm16(disp) ) {
2266 __ sh(as_Register(src), as_Register(base), disp);
2267 } else {
2268 __ move(T9, disp);
2269 if( UseLoongsonISA ) {
2270 __ gsshx(as_Register(src), as_Register(base), T9, 0);
2271 } else {
2272 __ addu(AT, as_Register(base), T9);
2273 __ sh(as_Register(src), AT, 0);
2274 }
2275 }
2276 }
2277 %}
2279 enc_class store_C0_enc (memory mem) %{
2280 MacroAssembler _masm(&cbuf);
2281 int base = $mem$$base;
2282 int index = $mem$$index;
2283 int scale = $mem$$scale;
2284 int disp = $mem$$disp;
2286 if( index != 0 ) {
2287 if( Assembler::is_simm16(disp) ) {
2288 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2289 if (scale == 0) {
2290 __ gsshx(R0, as_Register(base), as_Register(index), disp);
2291 } else {
2292 __ dsll(AT, as_Register(index), scale);
2293 __ gsshx(R0, as_Register(base), AT, disp);
2294 }
2295 } else {
2296 if (scale == 0) {
2297 __ addu(AT, as_Register(base), as_Register(index));
2298 } else {
2299 __ dsll(AT, as_Register(index), scale);
2300 __ addu(AT, as_Register(base), AT);
2301 }
2302 __ sh(R0, AT, disp);
2303 }
2304 } else {
2305 if (scale == 0) {
2306 __ addu(AT, as_Register(base), as_Register(index));
2307 } else {
2308 __ dsll(AT, as_Register(index), scale);
2309 __ addu(AT, as_Register(base), AT);
2310 }
2311 __ move(T9, disp);
2312 if( UseLoongsonISA ) {
2313 __ gsshx(R0, AT, T9, 0);
2314 } else {
2315 __ addu(AT, AT, T9);
2316 __ sh(R0, AT, 0);
2317 }
2318 }
2319 } else {
2320 if( Assembler::is_simm16(disp) ) {
2321 __ sh(R0, as_Register(base), disp);
2322 } else {
2323 __ move(T9, disp);
2324 if( UseLoongsonISA ) {
2325 __ gsshx(R0, as_Register(base), T9, 0);
2326 } else {
2327 __ addu(AT, as_Register(base), T9);
2328 __ sh(R0, AT, 0);
2329 }
2330 }
2331 }
2332 %}
2334 enc_class load_I_enc (mRegI dst, memory mem) %{
2335 MacroAssembler _masm(&cbuf);
2336 int dst = $dst$$reg;
2337 int base = $mem$$base;
2338 int index = $mem$$index;
2339 int scale = $mem$$scale;
2340 int disp = $mem$$disp;
2342 if( index != 0 ) {
2343 if( Assembler::is_simm16(disp) ) {
2344 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2345 if (scale == 0) {
2346 __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
2347 } else {
2348 __ dsll(AT, as_Register(index), scale);
2349 __ gslwx(as_Register(dst), as_Register(base), AT, disp);
2350 }
2351 } else {
2352 if (scale == 0) {
2353 __ addu(AT, as_Register(base), as_Register(index));
2354 } else {
2355 __ dsll(AT, as_Register(index), scale);
2356 __ addu(AT, as_Register(base), AT);
2357 }
2358 __ lw(as_Register(dst), AT, disp);
2359 }
2360 } else {
2361 if (scale == 0) {
2362 __ addu(AT, as_Register(base), as_Register(index));
2363 } else {
2364 __ dsll(AT, as_Register(index), scale);
2365 __ addu(AT, as_Register(base), AT);
2366 }
2367 __ move(T9, disp);
2368 if( UseLoongsonISA ) {
2369 __ gslwx(as_Register(dst), AT, T9, 0);
2370 } else {
2371 __ addu(AT, AT, T9);
2372 __ lw(as_Register(dst), AT, 0);
2373 }
2374 }
2375 } else {
2376 if( Assembler::is_simm16(disp) ) {
2377 __ lw(as_Register(dst), as_Register(base), disp);
2378 } else {
2379 __ move(T9, disp);
2380 if( UseLoongsonISA ) {
2381 __ gslwx(as_Register(dst), as_Register(base), T9, 0);
2382 } else {
2383 __ addu(AT, as_Register(base), T9);
2384 __ lw(as_Register(dst), AT, 0);
2385 }
2386 }
2387 }
2388 %}
2390 enc_class store_I_reg_enc (memory mem, mRegI src) %{
2391 MacroAssembler _masm(&cbuf);
2392 int src = $src$$reg;
2393 int base = $mem$$base;
2394 int index = $mem$$index;
2395 int scale = $mem$$scale;
2396 int disp = $mem$$disp;
2398 if( index != 0 ) {
2399 if( Assembler::is_simm16(disp) ) {
2400 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2401 if (scale == 0) {
2402 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
2403 } else {
2404 __ dsll(AT, as_Register(index), scale);
2405 __ gsswx(as_Register(src), as_Register(base), AT, disp);
2406 }
2407 } else {
2408 if (scale == 0) {
2409 __ addu(AT, as_Register(base), as_Register(index));
2410 } else {
2411 __ dsll(AT, as_Register(index), scale);
2412 __ addu(AT, as_Register(base), AT);
2413 }
2414 __ sw(as_Register(src), AT, disp);
2415 }
2416 } else {
2417 if (scale == 0) {
2418 __ addu(AT, as_Register(base), as_Register(index));
2419 } else {
2420 __ dsll(AT, as_Register(index), scale);
2421 __ addu(AT, as_Register(base), AT);
2422 }
2423 __ move(T9, disp);
2424 if( UseLoongsonISA ) {
2425 __ gsswx(as_Register(src), AT, T9, 0);
2426 } else {
2427 __ addu(AT, AT, T9);
2428 __ sw(as_Register(src), AT, 0);
2429 }
2430 }
2431 } else {
2432 if( Assembler::is_simm16(disp) ) {
2433 __ sw(as_Register(src), as_Register(base), disp);
2434 } else {
2435 __ move(T9, disp);
2436 if( UseLoongsonISA ) {
2437 __ gsswx(as_Register(src), as_Register(base), T9, 0);
2438 } else {
2439 __ addu(AT, as_Register(base), T9);
2440 __ sw(as_Register(src), AT, 0);
2441 }
2442 }
2443 }
2444 %}
2446 enc_class store_I_immI_enc (memory mem, immI src) %{
2447 MacroAssembler _masm(&cbuf);
2448 int base = $mem$$base;
2449 int index = $mem$$index;
2450 int scale = $mem$$scale;
2451 int disp = $mem$$disp;
2452 int value = $src$$constant;
2454 if( index != 0 ) {
2455 if ( UseLoongsonISA ) {
2456 if ( Assembler::is_simm(disp, 8) ) {
2457 if ( scale == 0 ) {
2458 if ( value == 0 ) {
2459 __ gsswx(R0, as_Register(base), as_Register(index), disp);
2460 } else {
2461 __ move(T9, value);
2462 __ gsswx(T9, as_Register(base), as_Register(index), disp);
2463 }
2464 } else {
2465 __ dsll(AT, as_Register(index), scale);
2466 if ( value == 0 ) {
2467 __ gsswx(R0, as_Register(base), AT, disp);
2468 } else {
2469 __ move(T9, value);
2470 __ gsswx(T9, as_Register(base), AT, disp);
2471 }
2472 }
2473 } else if ( Assembler::is_simm16(disp) ) {
2474 if ( scale == 0 ) {
2475 __ daddu(AT, as_Register(base), as_Register(index));
2476 if ( value == 0 ) {
2477 __ sw(R0, AT, disp);
2478 } else {
2479 __ move(T9, value);
2480 __ sw(T9, AT, disp);
2481 }
2482 } else {
2483 __ dsll(AT, as_Register(index), scale);
2484 __ daddu(AT, as_Register(base), AT);
2485 if ( value == 0 ) {
2486 __ sw(R0, AT, disp);
2487 } else {
2488 __ move(T9, value);
2489 __ sw(T9, AT, disp);
2490 }
2491 }
2492 } else {
2493 if ( scale == 0 ) {
2494 __ move(T9, disp);
2495 __ daddu(AT, as_Register(index), T9);
2496 if ( value ==0 ) {
2497 __ gsswx(R0, as_Register(base), AT, 0);
2498 } else {
2499 __ move(T9, value);
2500 __ gsswx(T9, as_Register(base), AT, 0);
2501 }
2502 } else {
2503 __ dsll(AT, as_Register(index), scale);
2504 __ move(T9, disp);
2505 __ daddu(AT, AT, T9);
2506 if ( value == 0 ) {
2507 __ gsswx(R0, as_Register(base), AT, 0);
2508 } else {
2509 __ move(T9, value);
2510 __ gsswx(T9, as_Register(base), AT, 0);
2511 }
2512 }
2513 }
2514 } else { //not use loongson isa
2515 if (scale == 0) {
2516 __ daddu(AT, as_Register(base), as_Register(index));
2517 } else {
2518 __ dsll(AT, as_Register(index), scale);
2519 __ daddu(AT, as_Register(base), AT);
2520 }
2521 if( Assembler::is_simm16(disp) ) {
2522 if (value == 0) {
2523 __ sw(R0, AT, disp);
2524 } else {
2525 __ move(T9, value);
2526 __ sw(T9, AT, disp);
2527 }
2528 } else {
2529 if (value == 0) {
2530 __ move(T9, disp);
2531 __ daddu(AT, AT, T9);
2532 __ sw(R0, AT, 0);
2533 } else {
2534 __ move(T9, disp);
2535 __ daddu(AT, AT, T9);
2536 __ move(T9, value);
2537 __ sw(T9, AT, 0);
2538 }
2539 }
2540 }
2541 } else {
2542 if ( UseLoongsonISA ) {
2543 if ( Assembler::is_simm16(disp) ) {
2544 if ( value == 0 ) {
2545 __ sw(R0, as_Register(base), disp);
2546 } else {
2547 __ move(AT, value);
2548 __ sw(AT, as_Register(base), disp);
2549 }
2550 } else {
2551 __ move(T9, disp);
2552 if ( value == 0 ) {
2553 __ gsswx(R0, as_Register(base), T9, 0);
2554 } else {
2555 __ move(AT, value);
2556 __ gsswx(AT, as_Register(base), T9, 0);
2557 }
2558 }
2559 } else {
2560 if( Assembler::is_simm16(disp) ) {
2561 if (value == 0) {
2562 __ sw(R0, as_Register(base), disp);
2563 } else {
2564 __ move(AT, value);
2565 __ sw(AT, as_Register(base), disp);
2566 }
2567 } else {
2568 if (value == 0) {
2569 __ move(T9, disp);
2570 __ daddu(AT, as_Register(base), T9);
2571 __ sw(R0, AT, 0);
2572 } else {
2573 __ move(T9, disp);
2574 __ daddu(AT, as_Register(base), T9);
2575 __ move(T9, value);
2576 __ sw(T9, AT, 0);
2577 }
2578 }
2579 }
2580 }
2581 %}
2583 enc_class load_N_enc (mRegN dst, memory mem) %{
2584 MacroAssembler _masm(&cbuf);
2585 int dst = $dst$$reg;
2586 int base = $mem$$base;
2587 int index = $mem$$index;
2588 int scale = $mem$$scale;
2589 int disp = $mem$$disp;
2590 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2591 assert(disp_reloc == relocInfo::none, "cannot have disp");
2593 if( index != 0 ) {
2594 if (scale == 0) {
2595 __ daddu(AT, as_Register(base), as_Register(index));
2596 } else {
2597 __ dsll(AT, as_Register(index), scale);
2598 __ daddu(AT, as_Register(base), AT);
2599 }
2600 if( Assembler::is_simm16(disp) ) {
2601 __ lwu(as_Register(dst), AT, disp);
2602 } else {
2603 __ set64(T9, disp);
2604 __ daddu(AT, AT, T9);
2605 __ lwu(as_Register(dst), AT, 0);
2606 }
2607 } else {
2608 if( Assembler::is_simm16(disp) ) {
2609 __ lwu(as_Register(dst), as_Register(base), disp);
2610 } else {
2611 __ set64(T9, disp);
2612 __ daddu(AT, as_Register(base), T9);
2613 __ lwu(as_Register(dst), AT, 0);
2614 }
2615 }
2616 %}
2619 enc_class load_P_enc (mRegP dst, memory mem) %{
2620 MacroAssembler _masm(&cbuf);
2621 int dst = $dst$$reg;
2622 int base = $mem$$base;
2623 int index = $mem$$index;
2624 int scale = $mem$$scale;
2625 int disp = $mem$$disp;
2626 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2627 assert(disp_reloc == relocInfo::none, "cannot have disp");
2629 if( index != 0 ) {
2630 if ( UseLoongsonISA ) {
2631 if ( Assembler::is_simm(disp, 8) ) {
2632 if ( scale != 0 ) {
2633 __ dsll(AT, as_Register(index), scale);
2634 __ gsldx(as_Register(dst), as_Register(base), AT, disp);
2635 } else {
2636 __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
2637 }
2638 } else if ( Assembler::is_simm16(disp) ){
2639 if ( scale != 0 ) {
2640 __ dsll(AT, as_Register(index), scale);
2641 __ daddu(AT, AT, as_Register(base));
2642 } else {
2643 __ daddu(AT, as_Register(index), as_Register(base));
2644 }
2645 __ ld(as_Register(dst), AT, disp);
2646 } else {
2647 if ( scale != 0 ) {
2648 __ dsll(AT, as_Register(index), scale);
2649 __ move(T9, disp);
2650 __ daddu(AT, AT, T9);
2651 } else {
2652 __ move(T9, disp);
2653 __ daddu(AT, as_Register(index), T9);
2654 }
2655 __ gsldx(as_Register(dst), as_Register(base), AT, 0);
2656 }
2657 } else { //not use loongson isa
2658 if (scale == 0) {
2659 __ daddu(AT, as_Register(base), as_Register(index));
2660 } else {
2661 __ dsll(AT, as_Register(index), scale);
2662 __ daddu(AT, as_Register(base), AT);
2663 }
2664 if( Assembler::is_simm16(disp) ) {
2665 __ ld(as_Register(dst), AT, disp);
2666 } else {
2667 __ set64(T9, disp);
2668 __ daddu(AT, AT, T9);
2669 __ ld(as_Register(dst), AT, 0);
2670 }
2671 }
2672 } else {
2673 if ( UseLoongsonISA ) {
2674 if ( Assembler::is_simm16(disp) ){
2675 __ ld(as_Register(dst), as_Register(base), disp);
2676 } else {
2677 __ set64(T9, disp);
2678 __ gsldx(as_Register(dst), as_Register(base), T9, 0);
2679 }
2680 } else { //not use loongson isa
2681 if( Assembler::is_simm16(disp) ) {
2682 __ ld(as_Register(dst), as_Register(base), disp);
2683 } else {
2684 __ set64(T9, disp);
2685 __ daddu(AT, as_Register(base), T9);
2686 __ ld(as_Register(dst), AT, 0);
2687 }
2688 }
2689 }
2690 %}
2692 enc_class store_P_reg_enc (memory mem, mRegP src) %{
2693 MacroAssembler _masm(&cbuf);
2694 int src = $src$$reg;
2695 int base = $mem$$base;
2696 int index = $mem$$index;
2697 int scale = $mem$$scale;
2698 int disp = $mem$$disp;
2700 if( index != 0 ) {
2701 if ( UseLoongsonISA ){
2702 if ( Assembler::is_simm(disp, 8) ) {
2703 if ( scale == 0 ) {
2704 __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
2705 } else {
2706 __ dsll(AT, as_Register(index), scale);
2707 __ gssdx(as_Register(src), as_Register(base), AT, disp);
2708 }
2709 } else if ( Assembler::is_simm16(disp) ) {
2710 if ( scale == 0 ) {
2711 __ daddu(AT, as_Register(base), as_Register(index));
2712 } else {
2713 __ dsll(AT, as_Register(index), scale);
2714 __ daddu(AT, as_Register(base), AT);
2715 }
2716 __ sd(as_Register(src), AT, disp);
2717 } else {
2718 if ( scale == 0 ) {
2719 __ move(T9, disp);
2720 __ daddu(AT, as_Register(index), T9);
2721 } else {
2722 __ dsll(AT, as_Register(index), scale);
2723 __ move(T9, disp);
2724 __ daddu(AT, AT, T9);
2725 }
2726 __ gssdx(as_Register(src), as_Register(base), AT, 0);
2727 }
2728 } else { //not use loongson isa
2729 if (scale == 0) {
2730 __ daddu(AT, as_Register(base), as_Register(index));
2731 } else {
2732 __ dsll(AT, as_Register(index), scale);
2733 __ daddu(AT, as_Register(base), AT);
2734 }
2735 if( Assembler::is_simm16(disp) ) {
2736 __ sd(as_Register(src), AT, disp);
2737 } else {
2738 __ move(T9, disp);
2739 __ daddu(AT, AT, T9);
2740 __ sd(as_Register(src), AT, 0);
2741 }
2742 }
2743 } else {
2744 if ( UseLoongsonISA ) {
2745 if ( Assembler::is_simm16(disp) ) {
2746 __ sd(as_Register(src), as_Register(base), disp);
2747 } else {
2748 __ move(T9, disp);
2749 __ gssdx(as_Register(src), as_Register(base), T9, 0);
2750 }
2751 } else {
2752 if( Assembler::is_simm16(disp) ) {
2753 __ sd(as_Register(src), as_Register(base), disp);
2754 } else {
2755 __ move(T9, disp);
2756 __ daddu(AT, as_Register(base), T9);
2757 __ sd(as_Register(src), AT, 0);
2758 }
2759 }
2760 }
2761 %}
2763 enc_class store_N_reg_enc (memory mem, mRegN src) %{
2764 MacroAssembler _masm(&cbuf);
2765 int src = $src$$reg;
2766 int base = $mem$$base;
2767 int index = $mem$$index;
2768 int scale = $mem$$scale;
2769 int disp = $mem$$disp;
2771 if( index != 0 ) {
2772 if ( UseLoongsonISA ){
2773 if ( Assembler::is_simm(disp, 8) ) {
2774 if ( scale == 0 ) {
2775 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
2776 } else {
2777 __ dsll(AT, as_Register(index), scale);
2778 __ gsswx(as_Register(src), as_Register(base), AT, disp);
2779 }
2780 } else if ( Assembler::is_simm16(disp) ) {
2781 if ( scale == 0 ) {
2782 __ daddu(AT, as_Register(base), as_Register(index));
2783 } else {
2784 __ dsll(AT, as_Register(index), scale);
2785 __ daddu(AT, as_Register(base), AT);
2786 }
2787 __ sw(as_Register(src), AT, disp);
2788 } else {
2789 if ( scale == 0 ) {
2790 __ move(T9, disp);
2791 __ daddu(AT, as_Register(index), T9);
2792 } else {
2793 __ dsll(AT, as_Register(index), scale);
2794 __ move(T9, disp);
2795 __ daddu(AT, AT, T9);
2796 }
2797 __ gsswx(as_Register(src), as_Register(base), AT, 0);
2798 }
2799 } else { //not use loongson isa
2800 if (scale == 0) {
2801 __ daddu(AT, as_Register(base), as_Register(index));
2802 } else {
2803 __ dsll(AT, as_Register(index), scale);
2804 __ daddu(AT, as_Register(base), AT);
2805 }
2806 if( Assembler::is_simm16(disp) ) {
2807 __ sw(as_Register(src), AT, disp);
2808 } else {
2809 __ move(T9, disp);
2810 __ daddu(AT, AT, T9);
2811 __ sw(as_Register(src), AT, 0);
2812 }
2813 }
2814 } else {
2815 if ( UseLoongsonISA ) {
2816 if ( Assembler::is_simm16(disp) ) {
2817 __ sw(as_Register(src), as_Register(base), disp);
2818 } else {
2819 __ move(T9, disp);
2820 __ gsswx(as_Register(src), as_Register(base), T9, 0);
2821 }
2822 } else {
2823 if( Assembler::is_simm16(disp) ) {
2824 __ sw(as_Register(src), as_Register(base), disp);
2825 } else {
2826 __ move(T9, disp);
2827 __ daddu(AT, as_Register(base), T9);
2828 __ sw(as_Register(src), AT, 0);
2829 }
2830 }
2831 }
2832 %}
2834 enc_class store_P_immP0_enc (memory mem) %{
2835 MacroAssembler _masm(&cbuf);
2836 int base = $mem$$base;
2837 int index = $mem$$index;
2838 int scale = $mem$$scale;
2839 int disp = $mem$$disp;
2841 if( index != 0 ) {
2842 if (scale == 0) {
2843 if( Assembler::is_simm16(disp) ) {
2844 if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
2845 __ gssdx(R0, as_Register(base), as_Register(index), disp);
2846 } else {
2847 __ daddu(AT, as_Register(base), as_Register(index));
2848 __ sd(R0, AT, disp);
2849 }
2850 } else {
2851 __ daddu(AT, as_Register(base), as_Register(index));
2852 __ move(T9, disp);
2853 if(UseLoongsonISA) {
2854 __ gssdx(R0, AT, T9, 0);
2855 } else {
2856 __ daddu(AT, AT, T9);
2857 __ sd(R0, AT, 0);
2858 }
2859 }
2860 } else {
2861 __ dsll(AT, as_Register(index), scale);
2862 if( Assembler::is_simm16(disp) ) {
2863 if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
2864 __ gssdx(R0, as_Register(base), AT, disp);
2865 } else {
2866 __ daddu(AT, as_Register(base), AT);
2867 __ sd(R0, AT, disp);
2868 }
2869 } else {
2870 __ daddu(AT, as_Register(base), AT);
2871 __ move(T9, disp);
2872 if (UseLoongsonISA) {
2873 __ gssdx(R0, AT, T9, 0);
2874 } else {
2875 __ daddu(AT, AT, T9);
2876 __ sd(R0, AT, 0);
2877 }
2878 }
2879 }
2880 } else {
2881 if( Assembler::is_simm16(disp) ) {
2882 __ sd(R0, as_Register(base), disp);
2883 } else {
2884 __ move(T9, disp);
2885 if (UseLoongsonISA) {
2886 __ gssdx(R0, as_Register(base), T9, 0);
2887 } else {
2888 __ daddu(AT, as_Register(base), T9);
2889 __ sd(R0, AT, 0);
2890 }
2891 }
2892 }
2893 %}
2895 enc_class storeImmN0_enc(memory mem, ImmN0 src) %{
2896 MacroAssembler _masm(&cbuf);
2897 int base = $mem$$base;
2898 int index = $mem$$index;
2899 int scale = $mem$$scale;
2900 int disp = $mem$$disp;
2902 if(index!=0){
2903 if (scale == 0) {
2904 __ daddu(AT, as_Register(base), as_Register(index));
2905 } else {
2906 __ dsll(AT, as_Register(index), scale);
2907 __ daddu(AT, as_Register(base), AT);
2908 }
2910 if( Assembler::is_simm16(disp) ) {
2911 __ sw(R0, AT, disp);
2912 } else {
2913 __ move(T9, disp);
2914 __ daddu(AT, AT, T9);
2915 __ sw(R0, AT, 0);
2916 }
2917 } else {
2918 if( Assembler::is_simm16(disp) ) {
2919 __ sw(R0, as_Register(base), disp);
2920 } else {
2921 __ move(T9, disp);
2922 __ daddu(AT, as_Register(base), T9);
2923 __ sw(R0, AT, 0);
2924 }
2925 }
2926 %}
2928 enc_class load_L_enc (mRegL dst, memory mem) %{
2929 MacroAssembler _masm(&cbuf);
2930 int base = $mem$$base;
2931 int index = $mem$$index;
2932 int scale = $mem$$scale;
2933 int disp = $mem$$disp;
2934 Register dst_reg = as_Register($dst$$reg);
2936 if( index != 0 ) {
2937 if (scale == 0) {
2938 __ daddu(AT, as_Register(base), as_Register(index));
2939 } else {
2940 __ dsll(AT, as_Register(index), scale);
2941 __ daddu(AT, as_Register(base), AT);
2942 }
2943 if( Assembler::is_simm16(disp) ) {
2944 __ ld(dst_reg, AT, disp);
2945 } else {
2946 __ move(T9, disp);
2947 __ daddu(AT, AT, T9);
2948 __ ld(dst_reg, AT, 0);
2949 }
2950 } else {
2951 if( Assembler::is_simm16(disp) ) {
2952 __ ld(dst_reg, as_Register(base), disp);
2953 } else {
2954 __ move(T9, disp);
2955 __ daddu(AT, as_Register(base), T9);
2956 __ ld(dst_reg, AT, 0);
2957 }
2958 }
2959 %}
2961 enc_class store_L_reg_enc (memory mem, mRegL src) %{
2962 MacroAssembler _masm(&cbuf);
2963 int base = $mem$$base;
2964 int index = $mem$$index;
2965 int scale = $mem$$scale;
2966 int disp = $mem$$disp;
2967 Register src_reg = as_Register($src$$reg);
2969 if( index != 0 ) {
2970 if (scale == 0) {
2971 __ daddu(AT, as_Register(base), as_Register(index));
2972 } else {
2973 __ dsll(AT, as_Register(index), scale);
2974 __ daddu(AT, as_Register(base), AT);
2975 }
2976 if( Assembler::is_simm16(disp) ) {
2977 __ sd(src_reg, AT, disp);
2978 } else {
2979 __ move(T9, disp);
2980 __ daddu(AT, AT, T9);
2981 __ sd(src_reg, AT, 0);
2982 }
2983 } else {
2984 if( Assembler::is_simm16(disp) ) {
2985 __ sd(src_reg, as_Register(base), disp);
2986 } else {
2987 __ move(T9, disp);
2988 __ daddu(AT, as_Register(base), T9);
2989 __ sd(src_reg, AT, 0);
2990 }
2991 }
2992 %}
2994 enc_class store_L_immL0_enc (memory mem, immL0 src) %{
2995 MacroAssembler _masm(&cbuf);
2996 int base = $mem$$base;
2997 int index = $mem$$index;
2998 int scale = $mem$$scale;
2999 int disp = $mem$$disp;
3001 if( index != 0 ) {
3002 if (scale == 0) {
3003 __ daddu(AT, as_Register(base), as_Register(index));
3004 } else {
3005 __ dsll(AT, as_Register(index), scale);
3006 __ daddu(AT, as_Register(base), AT);
3007 }
3008 if( Assembler::is_simm16(disp) ) {
3009 __ sd(R0, AT, disp);
3010 } else {
3011 __ move(T9, disp);
3012 __ addu(AT, AT, T9);
3013 __ sd(R0, AT, 0);
3014 }
3015 } else {
3016 if( Assembler::is_simm16(disp) ) {
3017 __ sd(R0, as_Register(base), disp);
3018 } else {
3019 __ move(T9, disp);
3020 __ addu(AT, as_Register(base), T9);
3021 __ sd(R0, AT, 0);
3022 }
3023 }
3024 %}
3026 enc_class store_L_immL_enc (memory mem, immL src) %{
3027 MacroAssembler _masm(&cbuf);
3028 int base = $mem$$base;
3029 int index = $mem$$index;
3030 int scale = $mem$$scale;
3031 int disp = $mem$$disp;
3032 long imm = $src$$constant;
3034 if( index != 0 ) {
3035 if (scale == 0) {
3036 __ daddu(AT, as_Register(base), as_Register(index));
3037 } else {
3038 __ dsll(AT, as_Register(index), scale);
3039 __ daddu(AT, as_Register(base), AT);
3040 }
3041 if( Assembler::is_simm16(disp) ) {
3042 __ set64(T9, imm);
3043 __ sd(T9, AT, disp);
3044 } else {
3045 __ move(T9, disp);
3046 __ addu(AT, AT, T9);
3047 __ set64(T9, imm);
3048 __ sd(T9, AT, 0);
3049 }
3050 } else {
3051 if( Assembler::is_simm16(disp) ) {
3052 __ move(AT, as_Register(base));
3053 __ set64(T9, imm);
3054 __ sd(T9, AT, disp);
3055 } else {
3056 __ move(T9, disp);
3057 __ addu(AT, as_Register(base), T9);
3058 __ set64(T9, imm);
3059 __ sd(T9, AT, 0);
3060 }
3061 }
3062 %}
3064 enc_class load_F_enc (regF dst, memory mem) %{
3065 MacroAssembler _masm(&cbuf);
3066 int base = $mem$$base;
3067 int index = $mem$$index;
3068 int scale = $mem$$scale;
3069 int disp = $mem$$disp;
3070 FloatRegister dst = $dst$$FloatRegister;
3072 if( index != 0 ) {
3073 if( Assembler::is_simm16(disp) ) {
3074 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3075 if (scale == 0) {
3076 __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
3077 } else {
3078 __ dsll(AT, as_Register(index), scale);
3079 __ gslwxc1(dst, as_Register(base), AT, disp);
3080 }
3081 } else {
3082 if (scale == 0) {
3083 __ daddu(AT, as_Register(base), as_Register(index));
3084 } else {
3085 __ dsll(AT, as_Register(index), scale);
3086 __ daddu(AT, as_Register(base), AT);
3087 }
3088 __ lwc1(dst, AT, disp);
3089 }
3090 } else {
3091 if (scale == 0) {
3092 __ daddu(AT, as_Register(base), as_Register(index));
3093 } else {
3094 __ dsll(AT, as_Register(index), scale);
3095 __ daddu(AT, as_Register(base), AT);
3096 }
3097 __ move(T9, disp);
3098 if( UseLoongsonISA ) {
3099 __ gslwxc1(dst, AT, T9, 0);
3100 } else {
3101 __ daddu(AT, AT, T9);
3102 __ lwc1(dst, AT, 0);
3103 }
3104 }
3105 } else {
3106 if( Assembler::is_simm16(disp) ) {
3107 __ lwc1(dst, as_Register(base), disp);
3108 } else {
3109 __ move(T9, disp);
3110 if( UseLoongsonISA ) {
3111 __ gslwxc1(dst, as_Register(base), T9, 0);
3112 } else {
3113 __ daddu(AT, as_Register(base), T9);
3114 __ lwc1(dst, AT, 0);
3115 }
3116 }
3117 }
3118 %}
3120 enc_class store_F_reg_enc (memory mem, regF src) %{
3121 MacroAssembler _masm(&cbuf);
3122 int base = $mem$$base;
3123 int index = $mem$$index;
3124 int scale = $mem$$scale;
3125 int disp = $mem$$disp;
3126 FloatRegister src = $src$$FloatRegister;
3128 if( index != 0 ) {
3129 if( Assembler::is_simm16(disp) ) {
3130 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3131 if (scale == 0) {
3132 __ gsswxc1(src, as_Register(base), as_Register(index), disp);
3133 } else {
3134 __ dsll(AT, as_Register(index), scale);
3135 __ gsswxc1(src, as_Register(base), AT, disp);
3136 }
3137 } else {
3138 if (scale == 0) {
3139 __ daddu(AT, as_Register(base), as_Register(index));
3140 } else {
3141 __ dsll(AT, as_Register(index), scale);
3142 __ daddu(AT, as_Register(base), AT);
3143 }
3144 __ swc1(src, AT, disp);
3145 }
3146 } else {
3147 if (scale == 0) {
3148 __ daddu(AT, as_Register(base), as_Register(index));
3149 } else {
3150 __ dsll(AT, as_Register(index), scale);
3151 __ daddu(AT, as_Register(base), AT);
3152 }
3153 __ move(T9, disp);
3154 if( UseLoongsonISA ) {
3155 __ gsswxc1(src, AT, T9, 0);
3156 } else {
3157 __ daddu(AT, AT, T9);
3158 __ swc1(src, AT, 0);
3159 }
3160 }
3161 } else {
3162 if( Assembler::is_simm16(disp) ) {
3163 __ swc1(src, as_Register(base), disp);
3164 } else {
3165 __ move(T9, disp);
3166 if( UseLoongsonISA ) {
3167 __ gsswxc1(src, as_Register(base), T9, 0);
3168 } else {
3169 __ daddu(AT, as_Register(base), T9);
3170 __ swc1(src, AT, 0);
3171 }
3172 }
3173 }
3174 %}
3176 enc_class load_D_enc (regD dst, memory mem) %{
3177 MacroAssembler _masm(&cbuf);
3178 int base = $mem$$base;
3179 int index = $mem$$index;
3180 int scale = $mem$$scale;
3181 int disp = $mem$$disp;
3182 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3184 if( index != 0 ) {
3185 if( Assembler::is_simm16(disp) ) {
3186 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3187 if (scale == 0) {
3188 __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
3189 } else {
3190 __ dsll(AT, as_Register(index), scale);
3191 __ gsldxc1(dst_reg, as_Register(base), AT, disp);
3192 }
3193 } else {
3194 if (scale == 0) {
3195 __ daddu(AT, as_Register(base), as_Register(index));
3196 } else {
3197 __ dsll(AT, as_Register(index), scale);
3198 __ daddu(AT, as_Register(base), AT);
3199 }
3200 __ ldc1(dst_reg, AT, disp);
3201 }
3202 } else {
3203 if (scale == 0) {
3204 __ daddu(AT, as_Register(base), as_Register(index));
3205 } else {
3206 __ dsll(AT, as_Register(index), scale);
3207 __ daddu(AT, as_Register(base), AT);
3208 }
3209 __ move(T9, disp);
3210 if( UseLoongsonISA ) {
3211 __ gsldxc1(dst_reg, AT, T9, 0);
3212 } else {
3213 __ addu(AT, AT, T9);
3214 __ ldc1(dst_reg, AT, 0);
3215 }
3216 }
3217 } else {
3218 if( Assembler::is_simm16(disp) ) {
3219 __ ldc1(dst_reg, as_Register(base), disp);
3220 } else {
3221 __ move(T9, disp);
3222 if( UseLoongsonISA ) {
3223 __ gsldxc1(dst_reg, as_Register(base), T9, 0);
3224 } else {
3225 __ addu(AT, as_Register(base), T9);
3226 __ ldc1(dst_reg, AT, 0);
3227 }
3228 }
3229 }
3230 %}
3232 enc_class store_D_reg_enc (memory mem, regD src) %{
3233 MacroAssembler _masm(&cbuf);
3234 int base = $mem$$base;
3235 int index = $mem$$index;
3236 int scale = $mem$$scale;
3237 int disp = $mem$$disp;
3238 FloatRegister src_reg = as_FloatRegister($src$$reg);
3240 if( index != 0 ) {
3241 if( Assembler::is_simm16(disp) ) {
3242 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3243 if (scale == 0) {
3244 __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
3245 } else {
3246 __ dsll(AT, as_Register(index), scale);
3247 __ gssdxc1(src_reg, as_Register(base), AT, disp);
3248 }
3249 } else {
3250 if (scale == 0) {
3251 __ daddu(AT, as_Register(base), as_Register(index));
3252 } else {
3253 __ dsll(AT, as_Register(index), scale);
3254 __ daddu(AT, as_Register(base), AT);
3255 }
3256 __ sdc1(src_reg, AT, disp);
3257 }
3258 } else {
3259 if (scale == 0) {
3260 __ daddu(AT, as_Register(base), as_Register(index));
3261 } else {
3262 __ dsll(AT, as_Register(index), scale);
3263 __ daddu(AT, as_Register(base), AT);
3264 }
3265 __ move(T9, disp);
3266 if( UseLoongsonISA ) {
3267 __ gssdxc1(src_reg, AT, T9, 0);
3268 } else {
3269 __ addu(AT, AT, T9);
3270 __ sdc1(src_reg, AT, 0);
3271 }
3272 }
3273 } else {
3274 if( Assembler::is_simm16(disp) ) {
3275 __ sdc1(src_reg, as_Register(base), disp);
3276 } else {
3277 __ move(T9, disp);
3278 if( UseLoongsonISA ) {
3279 __ gssdxc1(src_reg, as_Register(base), T9, 0);
3280 } else {
3281 __ addu(AT, as_Register(base), T9);
3282 __ sdc1(src_reg, AT, 0);
3283 }
3284 }
3285 }
3286 %}
3288 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf
3289 MacroAssembler _masm(&cbuf);
3290 // This is the instruction starting address for relocation info.
3291 __ block_comment("Java_To_Runtime");
3292 cbuf.set_insts_mark();
3293 __ relocate(relocInfo::runtime_call_type);
3295 __ patchable_call((address)$meth$$method);
3296 %}
3298 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
3299 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
3300 // who we intended to call.
3301 MacroAssembler _masm(&cbuf);
3302 cbuf.set_insts_mark();
3304 if ( !_method ) {
3305 __ relocate(relocInfo::runtime_call_type);
3306 } else if(_optimized_virtual) {
3307 __ relocate(relocInfo::opt_virtual_call_type);
3308 } else {
3309 __ relocate(relocInfo::static_call_type);
3310 }
3312 __ patchable_call((address)($meth$$method));
3313 if( _method ) { // Emit stub for static call
3314 emit_java_to_interp(cbuf);
3315 }
3316 %}
3319 /*
3320 * [Ref: LIR_Assembler::ic_call() ]
3321 */
3322 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL
3323 MacroAssembler _masm(&cbuf);
3324 __ block_comment("Java_Dynamic_Call");
3325 __ ic_call((address)$meth$$method);
3326 %}
3329 enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
3330 Register flags = $cr$$Register;
3331 Label L;
3333 MacroAssembler _masm(&cbuf);
3335 __ addu(flags, R0, R0);
3336 __ beq(AT, R0, L);
3337 __ delayed()->nop();
3338 __ move(flags, 0xFFFFFFFF);
3339 __ bind(L);
3340 %}
3342 enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
3343 Register result = $result$$Register;
3344 Register sub = $sub$$Register;
3345 Register super = $super$$Register;
3346 Register length = $tmp$$Register;
3347 Register tmp = T9;
3348 Label miss;
3350 // result may be the same as sub
3351 // 47c B40: # B21 B41 <- B20 Freq: 0.155379
3352 // 47c partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
3353 // 4bc mov S2, NULL #@loadConP
3354 // 4c0 beq S1, S2, B21 #@branchConP P=0.999999 C=-1.000000
3355 //
3356 MacroAssembler _masm(&cbuf);
3357 Label done;
3358 __ check_klass_subtype_slow_path(sub, super, length, tmp,
3359 NULL, &miss,
3360 /*set_cond_codes:*/ true);
3361 // Refer to X86_64's RDI
3362 __ move(result, 0);
3363 __ b(done);
3364 __ delayed()->nop();
3366 __ bind(miss);
3367 __ move(result, 1);
3368 __ bind(done);
3369 %}
3371 %}
3374 //---------MIPS FRAME--------------------------------------------------------------
3375 // Definition of frame structure and management information.
3376 //
3377 // S T A C K L A Y O U T Allocators stack-slot number
3378 // | (to get allocators register number
3379 // G Owned by | | v add SharedInfo::stack0)
3380 // r CALLER | |
3381 // o | +--------+ pad to even-align allocators stack-slot
3382 // w V | pad0 | numbers; owned by CALLER
3383 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
3384 // h ^ | in | 5
3385 // | | args | 4 Holes in incoming args owned by SELF
3386 // | | old | | 3
3387 // | | SP-+--------+----> Matcher::_old_SP, even aligned
3388 // v | | ret | 3 return address
3389 // Owned by +--------+
3390 // Self | pad2 | 2 pad to align old SP
3391 // | +--------+ 1
3392 // | | locks | 0
3393 // | +--------+----> SharedInfo::stack0, even aligned
3394 // | | pad1 | 11 pad to align new SP
3395 // | +--------+
3396 // | | | 10
3397 // | | spills | 9 spills
3398 // V | | 8 (pad0 slot for callee)
3399 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
3400 // ^ | out | 7
3401 // | | args | 6 Holes in outgoing args owned by CALLEE
3402 // Owned by new | |
3403 // Callee SP-+--------+----> Matcher::_new_SP, even aligned
3404 // | |
3405 //
3406 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
3407 // known from SELF's arguments and the Java calling convention.
3408 // Region 6-7 is determined per call site.
3409 // Note 2: If the calling convention leaves holes in the incoming argument
3410 // area, those holes are owned by SELF. Holes in the outgoing area
3411 // are owned by the CALLEE. Holes should not be nessecary in the
3412 // incoming area, as the Java calling convention is completely under
3413 // the control of the AD file. Doubles can be sorted and packed to
3414 // avoid holes. Holes in the outgoing arguments may be nessecary for
3415 // varargs C calling conventions.
3416 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
3417 // even aligned with pad0 as needed.
3418 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
3419 // region 6-11 is even aligned; it may be padded out more so that
3420 // the region from SP to FP meets the minimum stack alignment.
3421 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3422 // alignment. Region 11, pad1, may be dynamically extended so that
3423 // SP meets the minimum alignment.
3426 frame %{
3428 stack_direction(TOWARDS_LOW);
3430 // These two registers define part of the calling convention
3431 // between compiled code and the interpreter.
3432 // SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention
3433 // for more information.
3435 inline_cache_reg(T1); // Inline Cache Register
3436 interpreter_method_oop_reg(S3); // Method Oop Register when calling interpreter
3438 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
3439 cisc_spilling_operand_name(indOffset32);
3441 // Number of stack slots consumed by locking an object
3442 // generate Compile::sync_stack_slots
3443 #ifdef _LP64
3444 sync_stack_slots(2);
3445 #else
3446 sync_stack_slots(1);
3447 #endif
3449 frame_pointer(SP);
3451 // Interpreter stores its frame pointer in a register which is
3452 // stored to the stack by I2CAdaptors.
3453 // I2CAdaptors convert from interpreted java to compiled java.
3455 interpreter_frame_pointer(FP);
3457 // generate Matcher::stack_alignment
3458 stack_alignment(StackAlignmentInBytes); //wordSize = sizeof(char*);
3460 // Number of stack slots between incoming argument block and the start of
3461 // a new frame. The PROLOG must add this many slots to the stack. The
3462 // EPILOG must remove this many slots. Intel needs one slot for
3463 // return address.
3464 // generate Matcher::in_preserve_stack_slots
3465 //in_preserve_stack_slots(VerifyStackAtCalls + 2); //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
3466 in_preserve_stack_slots(4); //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
3468 // Number of outgoing stack slots killed above the out_preserve_stack_slots
3469 // for calls to C. Supports the var-args backing area for register parms.
3470 varargs_C_out_slots_killed(0);
3472 // The after-PROLOG location of the return address. Location of
3473 // return address specifies a type (REG or STACK) and a number
3474 // representing the register number (i.e. - use a register name) or
3475 // stack slot.
3476 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3477 // Otherwise, it is above the locks and verification slot and alignment word
3478 //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
3479 return_addr(REG RA);
3481 // Body of function which returns an integer array locating
3482 // arguments either in registers or in stack slots. Passed an array
3483 // of ideal registers called "sig" and a "length" count. Stack-slot
3484 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3485 // arguments for a CALLEE. Incoming stack arguments are
3486 // automatically biased by the preserve_stack_slots field above.
3489 // will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
3490 // StartNode::calling_convention call this.
3491 calling_convention %{
3492 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3493 %}
3498 // Body of function which returns an integer array locating
3499 // arguments either in registers or in stack slots. Passed an array
3500 // of ideal registers called "sig" and a "length" count. Stack-slot
3501 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3502 // arguments for a CALLEE. Incoming stack arguments are
3503 // automatically biased by the preserve_stack_slots field above.
3506 // SEE CallRuntimeNode::calling_convention for more information.
3507 c_calling_convention %{
3508 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
3509 %}
3512 // Location of C & interpreter return values
3513 // register(s) contain(s) return value for Op_StartI2C and Op_StartOSR.
3514 // SEE Matcher::match.
3515 c_return_value %{
3516 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3517 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
3518 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
3519 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num };
3520 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3521 %}
3523 // Location of return values
3524 // register(s) contain(s) return value for Op_StartC2I and Op_Start.
3525 // SEE Matcher::match.
3527 return_value %{
3528 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3529 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
3530 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
3531 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num};
3532 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3533 %}
3535 %}
3537 //----------ATTRIBUTES---------------------------------------------------------
3538 //----------Operand Attributes-------------------------------------------------
3539 op_attrib op_cost(0); // Required cost attribute
3541 //----------Instruction Attributes---------------------------------------------
3542 ins_attrib ins_cost(100); // Required cost attribute
3543 ins_attrib ins_size(32); // Required size attribute (in bits)
3544 ins_attrib ins_pc_relative(0); // Required PC Relative flag
3545 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
3546 // non-matching short branch variant of some
3547 // long branch?
3548 ins_attrib ins_alignment(4); // Required alignment attribute (must be a power of 2)
3549 // specifies the alignment that some part of the instruction (not
3550 // necessarily the start) requires. If > 1, a compute_padding()
3551 // function must be provided for the instruction
3553 //----------OPERANDS-----------------------------------------------------------
3554 // Operand definitions must precede instruction definitions for correct parsing
3555 // in the ADLC because operands constitute user defined types which are used in
3556 // instruction definitions.
3558 // Vectors
3559 operand vecD() %{
3560 constraint(ALLOC_IN_RC(dbl_reg));
3561 match(VecD);
3563 format %{ %}
3564 interface(REG_INTER);
3565 %}
3567 // Flags register, used as output of compare instructions
3568 operand FlagsReg() %{
3569 constraint(ALLOC_IN_RC(mips_flags));
3570 match(RegFlags);
3572 format %{ "AT" %}
3573 interface(REG_INTER);
3574 %}
3576 //----------Simple Operands----------------------------------------------------
3577 //TODO: Should we need to define some more special immediate number ?
3578 // Immediate Operands
3579 // Integer Immediate
3580 operand immI() %{
3581 match(ConI);
3582 //TODO: should not match immI8 here LEE
3583 match(immI8);
3585 op_cost(20);
3586 format %{ %}
3587 interface(CONST_INTER);
3588 %}
3590 // Long Immediate 8-bit
3591 operand immL8()
3592 %{
3593 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3594 match(ConL);
3596 op_cost(5);
3597 format %{ %}
3598 interface(CONST_INTER);
3599 %}
3601 // Constant for test vs zero
3602 operand immI0() %{
3603 predicate(n->get_int() == 0);
3604 match(ConI);
3606 op_cost(0);
3607 format %{ %}
3608 interface(CONST_INTER);
3609 %}
3611 // Constant for increment
3612 operand immI1() %{
3613 predicate(n->get_int() == 1);
3614 match(ConI);
3616 op_cost(0);
3617 format %{ %}
3618 interface(CONST_INTER);
3619 %}
3621 // Constant for decrement
3622 operand immI_M1() %{
3623 predicate(n->get_int() == -1);
3624 match(ConI);
3626 op_cost(0);
3627 format %{ %}
3628 interface(CONST_INTER);
3629 %}
3631 operand immI_MaxI() %{
3632 predicate(n->get_int() == 2147483647);
3633 match(ConI);
3635 op_cost(0);
3636 format %{ %}
3637 interface(CONST_INTER);
3638 %}
3640 // Valid scale values for addressing modes
3641 operand immI2() %{
3642 predicate(0 <= n->get_int() && (n->get_int() <= 3));
3643 match(ConI);
3645 format %{ %}
3646 interface(CONST_INTER);
3647 %}
3649 operand immI8() %{
3650 predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
3651 match(ConI);
3653 op_cost(5);
3654 format %{ %}
3655 interface(CONST_INTER);
3656 %}
3658 operand immI16() %{
3659 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
3660 match(ConI);
3662 op_cost(10);
3663 format %{ %}
3664 interface(CONST_INTER);
3665 %}
3667 // Constant for long shifts
3668 operand immI_32() %{
3669 predicate( n->get_int() == 32 );
3670 match(ConI);
3672 op_cost(0);
3673 format %{ %}
3674 interface(CONST_INTER);
3675 %}
3677 operand immI_63() %{
3678 predicate( n->get_int() == 63 );
3679 match(ConI);
3681 op_cost(0);
3682 format %{ %}
3683 interface(CONST_INTER);
3684 %}
3686 operand immI_0_31() %{
3687 predicate( n->get_int() >= 0 && n->get_int() <= 31 );
3688 match(ConI);
3690 op_cost(0);
3691 format %{ %}
3692 interface(CONST_INTER);
3693 %}
3695 // Operand for non-negtive integer mask
3696 operand immI_nonneg_mask() %{
3697 predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
3698 match(ConI);
3700 op_cost(0);
3701 format %{ %}
3702 interface(CONST_INTER);
3703 %}
3705 operand immI_32_63() %{
3706 predicate( n->get_int() >= 32 && n->get_int() <= 63 );
3707 match(ConI);
3708 op_cost(0);
3710 format %{ %}
3711 interface(CONST_INTER);
3712 %}
3714 operand immI16_sub() %{
3715 predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
3716 match(ConI);
3718 op_cost(10);
3719 format %{ %}
3720 interface(CONST_INTER);
3721 %}
3723 operand immI_0_32767() %{
3724 predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
3725 match(ConI);
3726 op_cost(0);
3728 format %{ %}
3729 interface(CONST_INTER);
3730 %}
3732 operand immI_0_65535() %{
3733 predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
3734 match(ConI);
3735 op_cost(0);
3737 format %{ %}
3738 interface(CONST_INTER);
3739 %}
3741 operand immI_1() %{
3742 predicate( n->get_int() == 1 );
3743 match(ConI);
3745 op_cost(0);
3746 format %{ %}
3747 interface(CONST_INTER);
3748 %}
3750 operand immI_2() %{
3751 predicate( n->get_int() == 2 );
3752 match(ConI);
3754 op_cost(0);
3755 format %{ %}
3756 interface(CONST_INTER);
3757 %}
3759 operand immI_3() %{
3760 predicate( n->get_int() == 3 );
3761 match(ConI);
3763 op_cost(0);
3764 format %{ %}
3765 interface(CONST_INTER);
3766 %}
3768 operand immI_7() %{
3769 predicate( n->get_int() == 7 );
3770 match(ConI);
3772 format %{ %}
3773 interface(CONST_INTER);
3774 %}
3776 // Immediates for special shifts (sign extend)
3778 // Constants for increment
3779 operand immI_16() %{
3780 predicate( n->get_int() == 16 );
3781 match(ConI);
3783 format %{ %}
3784 interface(CONST_INTER);
3785 %}
3787 operand immI_24() %{
3788 predicate( n->get_int() == 24 );
3789 match(ConI);
3791 format %{ %}
3792 interface(CONST_INTER);
3793 %}
3795 // Constant for byte-wide masking
3796 operand immI_255() %{
3797 predicate( n->get_int() == 255 );
3798 match(ConI);
3800 op_cost(0);
3801 format %{ %}
3802 interface(CONST_INTER);
3803 %}
3805 operand immI_65535() %{
3806 predicate( n->get_int() == 65535 );
3807 match(ConI);
3809 op_cost(5);
3810 format %{ %}
3811 interface(CONST_INTER);
3812 %}
3814 operand immI_65536() %{
3815 predicate( n->get_int() == 65536 );
3816 match(ConI);
3818 op_cost(5);
3819 format %{ %}
3820 interface(CONST_INTER);
3821 %}
3823 operand immI_M65536() %{
3824 predicate( n->get_int() == -65536 );
3825 match(ConI);
3827 op_cost(5);
3828 format %{ %}
3829 interface(CONST_INTER);
3830 %}
3832 // Pointer Immediate
3833 operand immP() %{
3834 match(ConP);
3836 op_cost(10);
3837 format %{ %}
3838 interface(CONST_INTER);
3839 %}
3841 // NULL Pointer Immediate
3842 operand immP0() %{
3843 predicate( n->get_ptr() == 0 );
3844 match(ConP);
3845 op_cost(0);
3847 format %{ %}
3848 interface(CONST_INTER);
3849 %}
3851 // Pointer Immediate: 64-bit
3852 operand immP_set() %{
3853 match(ConP);
3855 op_cost(5);
3856 // formats are generated automatically for constants and base registers
3857 format %{ %}
3858 interface(CONST_INTER);
3859 %}
3861 // Pointer Immediate: 64-bit
3862 operand immP_load() %{
3863 predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
3864 match(ConP);
3866 op_cost(5);
3867 // formats are generated automatically for constants and base registers
3868 format %{ %}
3869 interface(CONST_INTER);
3870 %}
3872 // Pointer Immediate: 64-bit
3873 operand immP_no_oop_cheap() %{
3874 predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
3875 match(ConP);
3877 op_cost(5);
3878 // formats are generated automatically for constants and base registers
3879 format %{ %}
3880 interface(CONST_INTER);
3881 %}
3883 // Pointer for polling page
3884 operand immP_poll() %{
3885 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
3886 match(ConP);
3887 op_cost(5);
3889 format %{ %}
3890 interface(CONST_INTER);
3891 %}
3893 // Pointer Immediate
3894 operand immN() %{
3895 match(ConN);
3897 op_cost(10);
3898 format %{ %}
3899 interface(CONST_INTER);
3900 %}
3902 operand immNKlass() %{
3903 match(ConNKlass);
3905 op_cost(10);
3906 format %{ %}
3907 interface(CONST_INTER);
3908 %}
3910 // NULL Pointer Immediate
3911 operand immN0() %{
3912 predicate(n->get_narrowcon() == 0);
3913 match(ConN);
3915 op_cost(5);
3916 format %{ %}
3917 interface(CONST_INTER);
3918 %}
3920 // Long Immediate
3921 operand immL() %{
3922 match(ConL);
3924 op_cost(20);
3925 format %{ %}
3926 interface(CONST_INTER);
3927 %}
3929 // Long Immediate zero
3930 operand immL0() %{
3931 predicate( n->get_long() == 0L );
3932 match(ConL);
3933 op_cost(0);
3935 format %{ %}
3936 interface(CONST_INTER);
3937 %}
3939 operand immL7() %{
3940 predicate( n->get_long() == 7L );
3941 match(ConL);
3942 op_cost(0);
3944 format %{ %}
3945 interface(CONST_INTER);
3946 %}
3948 operand immL_M1() %{
3949 predicate( n->get_long() == -1L );
3950 match(ConL);
3951 op_cost(0);
3953 format %{ %}
3954 interface(CONST_INTER);
3955 %}
3957 // bit 0..2 zero
3958 operand immL_M8() %{
3959 predicate( n->get_long() == -8L );
3960 match(ConL);
3961 op_cost(0);
3963 format %{ %}
3964 interface(CONST_INTER);
3965 %}
3967 // bit 2 zero
3968 operand immL_M5() %{
3969 predicate( n->get_long() == -5L );
3970 match(ConL);
3971 op_cost(0);
3973 format %{ %}
3974 interface(CONST_INTER);
3975 %}
3977 // bit 1..2 zero
3978 operand immL_M7() %{
3979 predicate( n->get_long() == -7L );
3980 match(ConL);
3981 op_cost(0);
3983 format %{ %}
3984 interface(CONST_INTER);
3985 %}
3987 // bit 0..1 zero
3988 operand immL_M4() %{
3989 predicate( n->get_long() == -4L );
3990 match(ConL);
3991 op_cost(0);
3993 format %{ %}
3994 interface(CONST_INTER);
3995 %}
3997 // bit 3..6 zero
3998 operand immL_M121() %{
3999 predicate( n->get_long() == -121L );
4000 match(ConL);
4001 op_cost(0);
4003 format %{ %}
4004 interface(CONST_INTER);
4005 %}
4007 // Long immediate from 0 to 127.
4008 // Used for a shorter form of long mul by 10.
4009 operand immL_127() %{
4010 predicate((0 <= n->get_long()) && (n->get_long() <= 127));
4011 match(ConL);
4012 op_cost(0);
4014 format %{ %}
4015 interface(CONST_INTER);
4016 %}
4018 // Operand for non-negtive long mask
4019 operand immL_nonneg_mask() %{
4020 predicate( (n->get_long() >= 0) && (Assembler::is_jlong_mask(n->get_long()) != -1) );
4021 match(ConL);
4023 op_cost(0);
4024 format %{ %}
4025 interface(CONST_INTER);
4026 %}
4028 operand immL_0_65535() %{
4029 predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
4030 match(ConL);
4031 op_cost(0);
4033 format %{ %}
4034 interface(CONST_INTER);
4035 %}
4037 // Long Immediate: cheap (materialize in <= 3 instructions)
4038 operand immL_cheap() %{
4039 predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
4040 match(ConL);
4041 op_cost(0);
4043 format %{ %}
4044 interface(CONST_INTER);
4045 %}
4047 // Long Immediate: expensive (materialize in > 3 instructions)
4048 operand immL_expensive() %{
4049 predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
4050 match(ConL);
4051 op_cost(0);
4053 format %{ %}
4054 interface(CONST_INTER);
4055 %}
4057 operand immL16() %{
4058 predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
4059 match(ConL);
4061 op_cost(10);
4062 format %{ %}
4063 interface(CONST_INTER);
4064 %}
4066 operand immL16_sub() %{
4067 predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
4068 match(ConL);
4070 op_cost(10);
4071 format %{ %}
4072 interface(CONST_INTER);
4073 %}
4075 // Long Immediate: low 32-bit mask
4076 operand immL_32bits() %{
4077 predicate(n->get_long() == 0xFFFFFFFFL);
4078 match(ConL);
4079 op_cost(20);
4081 format %{ %}
4082 interface(CONST_INTER);
4083 %}
4085 // Long Immediate 32-bit signed
4086 operand immL32()
4087 %{
4088 predicate(n->get_long() == (int) (n->get_long()));
4089 match(ConL);
4091 op_cost(15);
4092 format %{ %}
4093 interface(CONST_INTER);
4094 %}
4097 //single-precision floating-point zero
4098 operand immF0() %{
4099 predicate(jint_cast(n->getf()) == 0);
4100 match(ConF);
4102 op_cost(5);
4103 format %{ %}
4104 interface(CONST_INTER);
4105 %}
4107 //single-precision floating-point immediate
4108 operand immF() %{
4109 match(ConF);
4111 op_cost(20);
4112 format %{ %}
4113 interface(CONST_INTER);
4114 %}
4116 //double-precision floating-point zero
4117 operand immD0() %{
4118 predicate(jlong_cast(n->getd()) == 0);
4119 match(ConD);
4121 op_cost(5);
4122 format %{ %}
4123 interface(CONST_INTER);
4124 %}
4126 //double-precision floating-point immediate
4127 operand immD() %{
4128 match(ConD);
4130 op_cost(20);
4131 format %{ %}
4132 interface(CONST_INTER);
4133 %}
4135 // Register Operands
4136 // Integer Register
4137 operand mRegI() %{
4138 constraint(ALLOC_IN_RC(int_reg));
4139 match(RegI);
4141 format %{ %}
4142 interface(REG_INTER);
4143 %}
4145 operand no_Ax_mRegI() %{
4146 constraint(ALLOC_IN_RC(no_Ax_int_reg));
4147 match(RegI);
4148 match(mRegI);
4150 format %{ %}
4151 interface(REG_INTER);
4152 %}
4154 operand mS0RegI() %{
4155 constraint(ALLOC_IN_RC(s0_reg));
4156 match(RegI);
4157 match(mRegI);
4159 format %{ "S0" %}
4160 interface(REG_INTER);
4161 %}
4163 operand mS1RegI() %{
4164 constraint(ALLOC_IN_RC(s1_reg));
4165 match(RegI);
4166 match(mRegI);
4168 format %{ "S1" %}
4169 interface(REG_INTER);
4170 %}
4172 operand mS2RegI() %{
4173 constraint(ALLOC_IN_RC(s2_reg));
4174 match(RegI);
4175 match(mRegI);
4177 format %{ "S2" %}
4178 interface(REG_INTER);
4179 %}
4181 operand mS3RegI() %{
4182 constraint(ALLOC_IN_RC(s3_reg));
4183 match(RegI);
4184 match(mRegI);
4186 format %{ "S3" %}
4187 interface(REG_INTER);
4188 %}
4190 operand mS4RegI() %{
4191 constraint(ALLOC_IN_RC(s4_reg));
4192 match(RegI);
4193 match(mRegI);
4195 format %{ "S4" %}
4196 interface(REG_INTER);
4197 %}
4199 operand mS5RegI() %{
4200 constraint(ALLOC_IN_RC(s5_reg));
4201 match(RegI);
4202 match(mRegI);
4204 format %{ "S5" %}
4205 interface(REG_INTER);
4206 %}
4208 operand mS6RegI() %{
4209 constraint(ALLOC_IN_RC(s6_reg));
4210 match(RegI);
4211 match(mRegI);
4213 format %{ "S6" %}
4214 interface(REG_INTER);
4215 %}
4217 operand mS7RegI() %{
4218 constraint(ALLOC_IN_RC(s7_reg));
4219 match(RegI);
4220 match(mRegI);
4222 format %{ "S7" %}
4223 interface(REG_INTER);
4224 %}
4227 operand mT0RegI() %{
4228 constraint(ALLOC_IN_RC(t0_reg));
4229 match(RegI);
4230 match(mRegI);
4232 format %{ "T0" %}
4233 interface(REG_INTER);
4234 %}
4236 operand mT1RegI() %{
4237 constraint(ALLOC_IN_RC(t1_reg));
4238 match(RegI);
4239 match(mRegI);
4241 format %{ "T1" %}
4242 interface(REG_INTER);
4243 %}
4245 operand mT2RegI() %{
4246 constraint(ALLOC_IN_RC(t2_reg));
4247 match(RegI);
4248 match(mRegI);
4250 format %{ "T2" %}
4251 interface(REG_INTER);
4252 %}
4254 operand mT3RegI() %{
4255 constraint(ALLOC_IN_RC(t3_reg));
4256 match(RegI);
4257 match(mRegI);
4259 format %{ "T3" %}
4260 interface(REG_INTER);
4261 %}
4263 operand mT8RegI() %{
4264 constraint(ALLOC_IN_RC(t8_reg));
4265 match(RegI);
4266 match(mRegI);
4268 format %{ "T8" %}
4269 interface(REG_INTER);
4270 %}
4272 operand mT9RegI() %{
4273 constraint(ALLOC_IN_RC(t9_reg));
4274 match(RegI);
4275 match(mRegI);
4277 format %{ "T9" %}
4278 interface(REG_INTER);
4279 %}
4281 operand mA0RegI() %{
4282 constraint(ALLOC_IN_RC(a0_reg));
4283 match(RegI);
4284 match(mRegI);
4286 format %{ "A0" %}
4287 interface(REG_INTER);
4288 %}
4290 operand mA1RegI() %{
4291 constraint(ALLOC_IN_RC(a1_reg));
4292 match(RegI);
4293 match(mRegI);
4295 format %{ "A1" %}
4296 interface(REG_INTER);
4297 %}
4299 operand mA2RegI() %{
4300 constraint(ALLOC_IN_RC(a2_reg));
4301 match(RegI);
4302 match(mRegI);
4304 format %{ "A2" %}
4305 interface(REG_INTER);
4306 %}
4308 operand mA3RegI() %{
4309 constraint(ALLOC_IN_RC(a3_reg));
4310 match(RegI);
4311 match(mRegI);
4313 format %{ "A3" %}
4314 interface(REG_INTER);
4315 %}
4317 operand mA4RegI() %{
4318 constraint(ALLOC_IN_RC(a4_reg));
4319 match(RegI);
4320 match(mRegI);
4322 format %{ "A4" %}
4323 interface(REG_INTER);
4324 %}
4326 operand mA5RegI() %{
4327 constraint(ALLOC_IN_RC(a5_reg));
4328 match(RegI);
4329 match(mRegI);
4331 format %{ "A5" %}
4332 interface(REG_INTER);
4333 %}
4335 operand mA6RegI() %{
4336 constraint(ALLOC_IN_RC(a6_reg));
4337 match(RegI);
4338 match(mRegI);
4340 format %{ "A6" %}
4341 interface(REG_INTER);
4342 %}
4344 operand mA7RegI() %{
4345 constraint(ALLOC_IN_RC(a7_reg));
4346 match(RegI);
4347 match(mRegI);
4349 format %{ "A7" %}
4350 interface(REG_INTER);
4351 %}
4353 operand mV0RegI() %{
4354 constraint(ALLOC_IN_RC(v0_reg));
4355 match(RegI);
4356 match(mRegI);
4358 format %{ "V0" %}
4359 interface(REG_INTER);
4360 %}
4362 operand mV1RegI() %{
4363 constraint(ALLOC_IN_RC(v1_reg));
4364 match(RegI);
4365 match(mRegI);
4367 format %{ "V1" %}
4368 interface(REG_INTER);
4369 %}
4371 operand mRegN() %{
4372 constraint(ALLOC_IN_RC(int_reg));
4373 match(RegN);
4375 format %{ %}
4376 interface(REG_INTER);
4377 %}
4379 operand t0_RegN() %{
4380 constraint(ALLOC_IN_RC(t0_reg));
4381 match(RegN);
4382 match(mRegN);
4384 format %{ %}
4385 interface(REG_INTER);
4386 %}
4388 operand t1_RegN() %{
4389 constraint(ALLOC_IN_RC(t1_reg));
4390 match(RegN);
4391 match(mRegN);
4393 format %{ %}
4394 interface(REG_INTER);
4395 %}
4397 operand t2_RegN() %{
4398 constraint(ALLOC_IN_RC(t2_reg));
4399 match(RegN);
4400 match(mRegN);
4402 format %{ %}
4403 interface(REG_INTER);
4404 %}
4406 operand t3_RegN() %{
4407 constraint(ALLOC_IN_RC(t3_reg));
4408 match(RegN);
4409 match(mRegN);
4411 format %{ %}
4412 interface(REG_INTER);
4413 %}
4415 operand t8_RegN() %{
4416 constraint(ALLOC_IN_RC(t8_reg));
4417 match(RegN);
4418 match(mRegN);
4420 format %{ %}
4421 interface(REG_INTER);
4422 %}
4424 operand t9_RegN() %{
4425 constraint(ALLOC_IN_RC(t9_reg));
4426 match(RegN);
4427 match(mRegN);
4429 format %{ %}
4430 interface(REG_INTER);
4431 %}
4433 operand a0_RegN() %{
4434 constraint(ALLOC_IN_RC(a0_reg));
4435 match(RegN);
4436 match(mRegN);
4438 format %{ %}
4439 interface(REG_INTER);
4440 %}
4442 operand a1_RegN() %{
4443 constraint(ALLOC_IN_RC(a1_reg));
4444 match(RegN);
4445 match(mRegN);
4447 format %{ %}
4448 interface(REG_INTER);
4449 %}
4451 operand a2_RegN() %{
4452 constraint(ALLOC_IN_RC(a2_reg));
4453 match(RegN);
4454 match(mRegN);
4456 format %{ %}
4457 interface(REG_INTER);
4458 %}
4460 operand a3_RegN() %{
4461 constraint(ALLOC_IN_RC(a3_reg));
4462 match(RegN);
4463 match(mRegN);
4465 format %{ %}
4466 interface(REG_INTER);
4467 %}
4469 operand a4_RegN() %{
4470 constraint(ALLOC_IN_RC(a4_reg));
4471 match(RegN);
4472 match(mRegN);
4474 format %{ %}
4475 interface(REG_INTER);
4476 %}
4478 operand a5_RegN() %{
4479 constraint(ALLOC_IN_RC(a5_reg));
4480 match(RegN);
4481 match(mRegN);
4483 format %{ %}
4484 interface(REG_INTER);
4485 %}
4487 operand a6_RegN() %{
4488 constraint(ALLOC_IN_RC(a6_reg));
4489 match(RegN);
4490 match(mRegN);
4492 format %{ %}
4493 interface(REG_INTER);
4494 %}
4496 operand a7_RegN() %{
4497 constraint(ALLOC_IN_RC(a7_reg));
4498 match(RegN);
4499 match(mRegN);
4501 format %{ %}
4502 interface(REG_INTER);
4503 %}
4505 operand s0_RegN() %{
4506 constraint(ALLOC_IN_RC(s0_reg));
4507 match(RegN);
4508 match(mRegN);
4510 format %{ %}
4511 interface(REG_INTER);
4512 %}
4514 operand s1_RegN() %{
4515 constraint(ALLOC_IN_RC(s1_reg));
4516 match(RegN);
4517 match(mRegN);
4519 format %{ %}
4520 interface(REG_INTER);
4521 %}
4523 operand s2_RegN() %{
4524 constraint(ALLOC_IN_RC(s2_reg));
4525 match(RegN);
4526 match(mRegN);
4528 format %{ %}
4529 interface(REG_INTER);
4530 %}
4532 operand s3_RegN() %{
4533 constraint(ALLOC_IN_RC(s3_reg));
4534 match(RegN);
4535 match(mRegN);
4537 format %{ %}
4538 interface(REG_INTER);
4539 %}
4541 operand s4_RegN() %{
4542 constraint(ALLOC_IN_RC(s4_reg));
4543 match(RegN);
4544 match(mRegN);
4546 format %{ %}
4547 interface(REG_INTER);
4548 %}
4550 operand s5_RegN() %{
4551 constraint(ALLOC_IN_RC(s5_reg));
4552 match(RegN);
4553 match(mRegN);
4555 format %{ %}
4556 interface(REG_INTER);
4557 %}
4559 operand s6_RegN() %{
4560 constraint(ALLOC_IN_RC(s6_reg));
4561 match(RegN);
4562 match(mRegN);
4564 format %{ %}
4565 interface(REG_INTER);
4566 %}
4568 operand s7_RegN() %{
4569 constraint(ALLOC_IN_RC(s7_reg));
4570 match(RegN);
4571 match(mRegN);
4573 format %{ %}
4574 interface(REG_INTER);
4575 %}
4577 operand v0_RegN() %{
4578 constraint(ALLOC_IN_RC(v0_reg));
4579 match(RegN);
4580 match(mRegN);
4582 format %{ %}
4583 interface(REG_INTER);
4584 %}
4586 operand v1_RegN() %{
4587 constraint(ALLOC_IN_RC(v1_reg));
4588 match(RegN);
4589 match(mRegN);
4591 format %{ %}
4592 interface(REG_INTER);
4593 %}
4595 // Pointer Register
4596 operand mRegP() %{
4597 constraint(ALLOC_IN_RC(p_reg));
4598 match(RegP);
4599 match(a0_RegP);
4601 format %{ %}
4602 interface(REG_INTER);
4603 %}
4605 operand no_T8_mRegP() %{
4606 constraint(ALLOC_IN_RC(no_T8_p_reg));
4607 match(RegP);
4608 match(mRegP);
4610 format %{ %}
4611 interface(REG_INTER);
4612 %}
4614 operand s0_RegP()
4615 %{
4616 constraint(ALLOC_IN_RC(s0_long_reg));
4617 match(RegP);
4618 match(mRegP);
4619 match(no_T8_mRegP);
4621 format %{ %}
4622 interface(REG_INTER);
4623 %}
4625 operand s1_RegP()
4626 %{
4627 constraint(ALLOC_IN_RC(s1_long_reg));
4628 match(RegP);
4629 match(mRegP);
4630 match(no_T8_mRegP);
4632 format %{ %}
4633 interface(REG_INTER);
4634 %}
4636 operand s2_RegP()
4637 %{
4638 constraint(ALLOC_IN_RC(s2_long_reg));
4639 match(RegP);
4640 match(mRegP);
4641 match(no_T8_mRegP);
4643 format %{ %}
4644 interface(REG_INTER);
4645 %}
4647 operand s3_RegP()
4648 %{
4649 constraint(ALLOC_IN_RC(s3_long_reg));
4650 match(RegP);
4651 match(mRegP);
4652 match(no_T8_mRegP);
4654 format %{ %}
4655 interface(REG_INTER);
4656 %}
4658 operand s4_RegP()
4659 %{
4660 constraint(ALLOC_IN_RC(s4_long_reg));
4661 match(RegP);
4662 match(mRegP);
4663 match(no_T8_mRegP);
4665 format %{ %}
4666 interface(REG_INTER);
4667 %}
4669 operand s5_RegP()
4670 %{
4671 constraint(ALLOC_IN_RC(s5_long_reg));
4672 match(RegP);
4673 match(mRegP);
4674 match(no_T8_mRegP);
4676 format %{ %}
4677 interface(REG_INTER);
4678 %}
4680 operand s6_RegP()
4681 %{
4682 constraint(ALLOC_IN_RC(s6_long_reg));
4683 match(RegP);
4684 match(mRegP);
4685 match(no_T8_mRegP);
4687 format %{ %}
4688 interface(REG_INTER);
4689 %}
4691 operand s7_RegP()
4692 %{
4693 constraint(ALLOC_IN_RC(s7_long_reg));
4694 match(RegP);
4695 match(mRegP);
4696 match(no_T8_mRegP);
4698 format %{ %}
4699 interface(REG_INTER);
4700 %}
4702 operand t0_RegP()
4703 %{
4704 constraint(ALLOC_IN_RC(t0_long_reg));
4705 match(RegP);
4706 match(mRegP);
4707 match(no_T8_mRegP);
4709 format %{ %}
4710 interface(REG_INTER);
4711 %}
4713 operand t1_RegP()
4714 %{
4715 constraint(ALLOC_IN_RC(t1_long_reg));
4716 match(RegP);
4717 match(mRegP);
4718 match(no_T8_mRegP);
4720 format %{ %}
4721 interface(REG_INTER);
4722 %}
4724 operand t2_RegP()
4725 %{
4726 constraint(ALLOC_IN_RC(t2_long_reg));
4727 match(RegP);
4728 match(mRegP);
4729 match(no_T8_mRegP);
4731 format %{ %}
4732 interface(REG_INTER);
4733 %}
4735 operand t3_RegP()
4736 %{
4737 constraint(ALLOC_IN_RC(t3_long_reg));
4738 match(RegP);
4739 match(mRegP);
4740 match(no_T8_mRegP);
4742 format %{ %}
4743 interface(REG_INTER);
4744 %}
4746 operand t8_RegP()
4747 %{
4748 constraint(ALLOC_IN_RC(t8_long_reg));
4749 match(RegP);
4750 match(mRegP);
4752 format %{ %}
4753 interface(REG_INTER);
4754 %}
4756 operand t9_RegP()
4757 %{
4758 constraint(ALLOC_IN_RC(t9_long_reg));
4759 match(RegP);
4760 match(mRegP);
4761 match(no_T8_mRegP);
4763 format %{ %}
4764 interface(REG_INTER);
4765 %}
4767 operand a0_RegP()
4768 %{
4769 constraint(ALLOC_IN_RC(a0_long_reg));
4770 match(RegP);
4771 match(mRegP);
4772 match(no_T8_mRegP);
4774 format %{ %}
4775 interface(REG_INTER);
4776 %}
4778 operand a1_RegP()
4779 %{
4780 constraint(ALLOC_IN_RC(a1_long_reg));
4781 match(RegP);
4782 match(mRegP);
4783 match(no_T8_mRegP);
4785 format %{ %}
4786 interface(REG_INTER);
4787 %}
4789 operand a2_RegP()
4790 %{
4791 constraint(ALLOC_IN_RC(a2_long_reg));
4792 match(RegP);
4793 match(mRegP);
4794 match(no_T8_mRegP);
4796 format %{ %}
4797 interface(REG_INTER);
4798 %}
4800 operand a3_RegP()
4801 %{
4802 constraint(ALLOC_IN_RC(a3_long_reg));
4803 match(RegP);
4804 match(mRegP);
4805 match(no_T8_mRegP);
4807 format %{ %}
4808 interface(REG_INTER);
4809 %}
4811 operand a4_RegP()
4812 %{
4813 constraint(ALLOC_IN_RC(a4_long_reg));
4814 match(RegP);
4815 match(mRegP);
4816 match(no_T8_mRegP);
4818 format %{ %}
4819 interface(REG_INTER);
4820 %}
4823 operand a5_RegP()
4824 %{
4825 constraint(ALLOC_IN_RC(a5_long_reg));
4826 match(RegP);
4827 match(mRegP);
4828 match(no_T8_mRegP);
4830 format %{ %}
4831 interface(REG_INTER);
4832 %}
4834 operand a6_RegP()
4835 %{
4836 constraint(ALLOC_IN_RC(a6_long_reg));
4837 match(RegP);
4838 match(mRegP);
4839 match(no_T8_mRegP);
4841 format %{ %}
4842 interface(REG_INTER);
4843 %}
4845 operand a7_RegP()
4846 %{
4847 constraint(ALLOC_IN_RC(a7_long_reg));
4848 match(RegP);
4849 match(mRegP);
4850 match(no_T8_mRegP);
4852 format %{ %}
4853 interface(REG_INTER);
4854 %}
4856 operand v0_RegP()
4857 %{
4858 constraint(ALLOC_IN_RC(v0_long_reg));
4859 match(RegP);
4860 match(mRegP);
4861 match(no_T8_mRegP);
4863 format %{ %}
4864 interface(REG_INTER);
4865 %}
4867 operand v1_RegP()
4868 %{
4869 constraint(ALLOC_IN_RC(v1_long_reg));
4870 match(RegP);
4871 match(mRegP);
4872 match(no_T8_mRegP);
4874 format %{ %}
4875 interface(REG_INTER);
4876 %}
4878 /*
4879 operand mSPRegP(mRegP reg) %{
4880 constraint(ALLOC_IN_RC(sp_reg));
4881 match(reg);
4883 format %{ "SP" %}
4884 interface(REG_INTER);
4885 %}
4887 operand mFPRegP(mRegP reg) %{
4888 constraint(ALLOC_IN_RC(fp_reg));
4889 match(reg);
4891 format %{ "FP" %}
4892 interface(REG_INTER);
4893 %}
4894 */
4896 operand mRegL() %{
4897 constraint(ALLOC_IN_RC(long_reg));
4898 match(RegL);
4900 format %{ %}
4901 interface(REG_INTER);
4902 %}
4904 operand v0RegL() %{
4905 constraint(ALLOC_IN_RC(v0_long_reg));
4906 match(RegL);
4907 match(mRegL);
4909 format %{ %}
4910 interface(REG_INTER);
4911 %}
4913 operand v1RegL() %{
4914 constraint(ALLOC_IN_RC(v1_long_reg));
4915 match(RegL);
4916 match(mRegL);
4918 format %{ %}
4919 interface(REG_INTER);
4920 %}
4922 operand a0RegL() %{
4923 constraint(ALLOC_IN_RC(a0_long_reg));
4924 match(RegL);
4925 match(mRegL);
4927 format %{ "A0" %}
4928 interface(REG_INTER);
4929 %}
4931 operand a1RegL() %{
4932 constraint(ALLOC_IN_RC(a1_long_reg));
4933 match(RegL);
4934 match(mRegL);
4936 format %{ %}
4937 interface(REG_INTER);
4938 %}
4940 operand a2RegL() %{
4941 constraint(ALLOC_IN_RC(a2_long_reg));
4942 match(RegL);
4943 match(mRegL);
4945 format %{ %}
4946 interface(REG_INTER);
4947 %}
4949 operand a3RegL() %{
4950 constraint(ALLOC_IN_RC(a3_long_reg));
4951 match(RegL);
4952 match(mRegL);
4954 format %{ %}
4955 interface(REG_INTER);
4956 %}
4958 operand t0RegL() %{
4959 constraint(ALLOC_IN_RC(t0_long_reg));
4960 match(RegL);
4961 match(mRegL);
4963 format %{ %}
4964 interface(REG_INTER);
4965 %}
4967 operand t1RegL() %{
4968 constraint(ALLOC_IN_RC(t1_long_reg));
4969 match(RegL);
4970 match(mRegL);
4972 format %{ %}
4973 interface(REG_INTER);
4974 %}
4976 operand t2RegL() %{
4977 constraint(ALLOC_IN_RC(t2_long_reg));
4978 match(RegL);
4979 match(mRegL);
4981 format %{ %}
4982 interface(REG_INTER);
4983 %}
4985 operand t3RegL() %{
4986 constraint(ALLOC_IN_RC(t3_long_reg));
4987 match(RegL);
4988 match(mRegL);
4990 format %{ %}
4991 interface(REG_INTER);
4992 %}
4994 operand t8RegL() %{
4995 constraint(ALLOC_IN_RC(t8_long_reg));
4996 match(RegL);
4997 match(mRegL);
4999 format %{ %}
5000 interface(REG_INTER);
5001 %}
5003 operand a4RegL() %{
5004 constraint(ALLOC_IN_RC(a4_long_reg));
5005 match(RegL);
5006 match(mRegL);
5008 format %{ %}
5009 interface(REG_INTER);
5010 %}
5012 operand a5RegL() %{
5013 constraint(ALLOC_IN_RC(a5_long_reg));
5014 match(RegL);
5015 match(mRegL);
5017 format %{ %}
5018 interface(REG_INTER);
5019 %}
5021 operand a6RegL() %{
5022 constraint(ALLOC_IN_RC(a6_long_reg));
5023 match(RegL);
5024 match(mRegL);
5026 format %{ %}
5027 interface(REG_INTER);
5028 %}
5030 operand a7RegL() %{
5031 constraint(ALLOC_IN_RC(a7_long_reg));
5032 match(RegL);
5033 match(mRegL);
5035 format %{ %}
5036 interface(REG_INTER);
5037 %}
5039 operand s0RegL() %{
5040 constraint(ALLOC_IN_RC(s0_long_reg));
5041 match(RegL);
5042 match(mRegL);
5044 format %{ %}
5045 interface(REG_INTER);
5046 %}
5048 operand s1RegL() %{
5049 constraint(ALLOC_IN_RC(s1_long_reg));
5050 match(RegL);
5051 match(mRegL);
5053 format %{ %}
5054 interface(REG_INTER);
5055 %}
5057 operand s2RegL() %{
5058 constraint(ALLOC_IN_RC(s2_long_reg));
5059 match(RegL);
5060 match(mRegL);
5062 format %{ %}
5063 interface(REG_INTER);
5064 %}
5066 operand s3RegL() %{
5067 constraint(ALLOC_IN_RC(s3_long_reg));
5068 match(RegL);
5069 match(mRegL);
5071 format %{ %}
5072 interface(REG_INTER);
5073 %}
5075 operand s4RegL() %{
5076 constraint(ALLOC_IN_RC(s4_long_reg));
5077 match(RegL);
5078 match(mRegL);
5080 format %{ %}
5081 interface(REG_INTER);
5082 %}
5084 operand s7RegL() %{
5085 constraint(ALLOC_IN_RC(s7_long_reg));
5086 match(RegL);
5087 match(mRegL);
5089 format %{ %}
5090 interface(REG_INTER);
5091 %}
5093 // Floating register operands
5094 operand regF() %{
5095 constraint(ALLOC_IN_RC(flt_reg));
5096 match(RegF);
5098 format %{ %}
5099 interface(REG_INTER);
5100 %}
5102 //Double Precision Floating register operands
5103 operand regD() %{
5104 constraint(ALLOC_IN_RC(dbl_reg));
5105 match(RegD);
5107 format %{ %}
5108 interface(REG_INTER);
5109 %}
5111 //----------Memory Operands----------------------------------------------------
5112 // Indirect Memory Operand
5113 operand indirect(mRegP reg) %{
5114 constraint(ALLOC_IN_RC(p_reg));
5115 match(reg);
5117 format %{ "[$reg] @ indirect" %}
5118 interface(MEMORY_INTER) %{
5119 base($reg);
5120 index(0x0); /* NO_INDEX */
5121 scale(0x0);
5122 disp(0x0);
5123 %}
5124 %}
5126 // Indirect Memory Plus Short Offset Operand
5127 operand indOffset8(mRegP reg, immL8 off)
5128 %{
5129 constraint(ALLOC_IN_RC(p_reg));
5130 match(AddP reg off);
5132 op_cost(10);
5133 format %{ "[$reg + $off (8-bit)] @ indOffset8" %}
5134 interface(MEMORY_INTER) %{
5135 base($reg);
5136 index(0x0); /* NO_INDEX */
5137 scale(0x0);
5138 disp($off);
5139 %}
5140 %}
5142 // Indirect Memory Times Scale Plus Index Register
5143 operand indIndexScale(mRegP reg, mRegL lreg, immI2 scale)
5144 %{
5145 constraint(ALLOC_IN_RC(p_reg));
5146 match(AddP reg (LShiftL lreg scale));
5148 op_cost(10);
5149 format %{"[$reg + $lreg << $scale] @ indIndexScale" %}
5150 interface(MEMORY_INTER) %{
5151 base($reg);
5152 index($lreg);
5153 scale($scale);
5154 disp(0x0);
5155 %}
5156 %}
5159 // [base + index + offset]
5160 operand baseIndexOffset8(mRegP base, mRegL index, immL8 off)
5161 %{
5162 constraint(ALLOC_IN_RC(p_reg));
5163 op_cost(5);
5164 match(AddP (AddP base index) off);
5166 format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8" %}
5167 interface(MEMORY_INTER) %{
5168 base($base);
5169 index($index);
5170 scale(0x0);
5171 disp($off);
5172 %}
5173 %}
5175 // [base + index + offset]
5176 operand baseIndexOffset8_convI2L(mRegP base, mRegI index, immL8 off)
5177 %{
5178 constraint(ALLOC_IN_RC(p_reg));
5179 op_cost(5);
5180 match(AddP (AddP base (ConvI2L index)) off);
5182 format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8_convI2L" %}
5183 interface(MEMORY_INTER) %{
5184 base($base);
5185 index($index);
5186 scale(0x0);
5187 disp($off);
5188 %}
5189 %}
5191 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5192 operand indIndexScaleOffset8(mRegP reg, immL8 off, mRegL lreg, immI2 scale)
5193 %{
5194 constraint(ALLOC_IN_RC(p_reg));
5195 match(AddP (AddP reg (LShiftL lreg scale)) off);
5197 op_cost(10);
5198 format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffset8" %}
5199 interface(MEMORY_INTER) %{
5200 base($reg);
5201 index($lreg);
5202 scale($scale);
5203 disp($off);
5204 %}
5205 %}
5207 operand indIndexScaleOffset8_convI2L(mRegP reg, immL8 off, mRegI ireg, immI2 scale)
5208 %{
5209 constraint(ALLOC_IN_RC(p_reg));
5210 match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
5212 op_cost(10);
5213 format %{"[$reg + $off + $ireg << $scale] @ indIndexScaleOffset8_convI2L" %}
5214 interface(MEMORY_INTER) %{
5215 base($reg);
5216 index($ireg);
5217 scale($scale);
5218 disp($off);
5219 %}
5220 %}
5222 // [base + index<<scale + offset]
5223 operand basePosIndexScaleOffset8(mRegP base, mRegI index, immL8 off, immI_0_31 scale)
5224 %{
5225 constraint(ALLOC_IN_RC(p_reg));
5226 //predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5227 op_cost(10);
5228 match(AddP (AddP base (LShiftL (ConvI2L index) scale)) off);
5230 format %{ "[$base + $index << $scale + $off (8-bit)] @ basePosIndexScaleOffset8" %}
5231 interface(MEMORY_INTER) %{
5232 base($base);
5233 index($index);
5234 scale($scale);
5235 disp($off);
5236 %}
5237 %}
5239 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5240 operand indIndexScaleOffsetNarrow(mRegN reg, immL8 off, mRegL lreg, immI2 scale)
5241 %{
5242 predicate(Universe::narrow_oop_shift() == 0);
5243 constraint(ALLOC_IN_RC(p_reg));
5244 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
5246 op_cost(10);
5247 format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffsetNarrow" %}
5248 interface(MEMORY_INTER) %{
5249 base($reg);
5250 index($lreg);
5251 scale($scale);
5252 disp($off);
5253 %}
5254 %}
5256 // [base + index<<scale + offset] for compressd Oops
5257 operand indPosIndexI2LScaleOffset8Narrow(mRegN base, mRegI index, immL8 off, immI_0_31 scale)
5258 %{
5259 constraint(ALLOC_IN_RC(p_reg));
5260 //predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5261 predicate(Universe::narrow_oop_shift() == 0);
5262 op_cost(10);
5263 match(AddP (AddP (DecodeN base) (LShiftL (ConvI2L index) scale)) off);
5265 format %{ "[$base + $index << $scale + $off (8-bit)] @ indPosIndexI2LScaleOffset8Narrow" %}
5266 interface(MEMORY_INTER) %{
5267 base($base);
5268 index($index);
5269 scale($scale);
5270 disp($off);
5271 %}
5272 %}
5274 //FIXME: I think it's better to limit the immI to be 16-bit at most!
5275 // Indirect Memory Plus Long Offset Operand
5276 operand indOffset32(mRegP reg, immL32 off) %{
5277 constraint(ALLOC_IN_RC(p_reg));
5278 op_cost(20);
5279 match(AddP reg off);
5281 format %{ "[$reg + $off (32-bit)] @ indOffset32" %}
5282 interface(MEMORY_INTER) %{
5283 base($reg);
5284 index(0x0); /* NO_INDEX */
5285 scale(0x0);
5286 disp($off);
5287 %}
5288 %}
5290 // Indirect Memory Plus Index Register
5291 operand indIndex(mRegP addr, mRegL index) %{
5292 constraint(ALLOC_IN_RC(p_reg));
5293 match(AddP addr index);
5295 op_cost(20);
5296 format %{"[$addr + $index] @ indIndex" %}
5297 interface(MEMORY_INTER) %{
5298 base($addr);
5299 index($index);
5300 scale(0x0);
5301 disp(0x0);
5302 %}
5303 %}
5305 operand indirectNarrowKlass(mRegN reg)
5306 %{
5307 predicate(Universe::narrow_klass_shift() == 0);
5308 constraint(ALLOC_IN_RC(p_reg));
5309 op_cost(10);
5310 match(DecodeNKlass reg);
5312 format %{ "[$reg] @ indirectNarrowKlass" %}
5313 interface(MEMORY_INTER) %{
5314 base($reg);
5315 index(0x0);
5316 scale(0x0);
5317 disp(0x0);
5318 %}
5319 %}
5321 operand indOffset8NarrowKlass(mRegN reg, immL8 off)
5322 %{
5323 predicate(Universe::narrow_klass_shift() == 0);
5324 constraint(ALLOC_IN_RC(p_reg));
5325 op_cost(10);
5326 match(AddP (DecodeNKlass reg) off);
5328 format %{ "[$reg + $off (8-bit)] @ indOffset8NarrowKlass" %}
5329 interface(MEMORY_INTER) %{
5330 base($reg);
5331 index(0x0);
5332 scale(0x0);
5333 disp($off);
5334 %}
5335 %}
5337 operand indOffset32NarrowKlass(mRegN reg, immL32 off)
5338 %{
5339 predicate(Universe::narrow_klass_shift() == 0);
5340 constraint(ALLOC_IN_RC(p_reg));
5341 op_cost(10);
5342 match(AddP (DecodeNKlass reg) off);
5344 format %{ "[$reg + $off (32-bit)] @ indOffset32NarrowKlass" %}
5345 interface(MEMORY_INTER) %{
5346 base($reg);
5347 index(0x0);
5348 scale(0x0);
5349 disp($off);
5350 %}
5351 %}
5353 operand indIndexOffsetNarrowKlass(mRegN reg, mRegL lreg, immL32 off)
5354 %{
5355 predicate(Universe::narrow_klass_shift() == 0);
5356 constraint(ALLOC_IN_RC(p_reg));
5357 match(AddP (AddP (DecodeNKlass reg) lreg) off);
5359 op_cost(10);
5360 format %{"[$reg + $off + $lreg] @ indIndexOffsetNarrowKlass" %}
5361 interface(MEMORY_INTER) %{
5362 base($reg);
5363 index($lreg);
5364 scale(0x0);
5365 disp($off);
5366 %}
5367 %}
5369 operand indIndexNarrowKlass(mRegN reg, mRegL lreg)
5370 %{
5371 predicate(Universe::narrow_klass_shift() == 0);
5372 constraint(ALLOC_IN_RC(p_reg));
5373 match(AddP (DecodeNKlass reg) lreg);
5375 op_cost(10);
5376 format %{"[$reg + $lreg] @ indIndexNarrowKlass" %}
5377 interface(MEMORY_INTER) %{
5378 base($reg);
5379 index($lreg);
5380 scale(0x0);
5381 disp(0x0);
5382 %}
5383 %}
5385 // Indirect Memory Operand
5386 operand indirectNarrow(mRegN reg)
5387 %{
5388 predicate(Universe::narrow_oop_shift() == 0);
5389 constraint(ALLOC_IN_RC(p_reg));
5390 op_cost(10);
5391 match(DecodeN reg);
5393 format %{ "[$reg] @ indirectNarrow" %}
5394 interface(MEMORY_INTER) %{
5395 base($reg);
5396 index(0x0);
5397 scale(0x0);
5398 disp(0x0);
5399 %}
5400 %}
5402 // Indirect Memory Plus Short Offset Operand
5403 operand indOffset8Narrow(mRegN reg, immL8 off)
5404 %{
5405 predicate(Universe::narrow_oop_shift() == 0);
5406 constraint(ALLOC_IN_RC(p_reg));
5407 op_cost(10);
5408 match(AddP (DecodeN reg) off);
5410 format %{ "[$reg + $off (8-bit)] @ indOffset8Narrow" %}
5411 interface(MEMORY_INTER) %{
5412 base($reg);
5413 index(0x0);
5414 scale(0x0);
5415 disp($off);
5416 %}
5417 %}
5419 // Indirect Memory Plus Index Register Plus Offset Operand
5420 operand indIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
5421 %{
5422 predicate(Universe::narrow_oop_shift() == 0);
5423 constraint(ALLOC_IN_RC(p_reg));
5424 match(AddP (AddP (DecodeN reg) lreg) off);
5426 op_cost(10);
5427 format %{"[$reg + $off + $lreg] @ indIndexOffset8Narrow" %}
5428 interface(MEMORY_INTER) %{
5429 base($reg);
5430 index($lreg);
5431 scale(0x0);
5432 disp($off);
5433 %}
5434 %}
5436 //----------Load Long Memory Operands------------------------------------------
5437 // The load-long idiom will use it's address expression again after loading
5438 // the first word of the long. If the load-long destination overlaps with
5439 // registers used in the addressing expression, the 2nd half will be loaded
5440 // from a clobbered address. Fix this by requiring that load-long use
5441 // address registers that do not overlap with the load-long target.
5443 // load-long support
5444 operand load_long_RegP() %{
5445 constraint(ALLOC_IN_RC(p_reg));
5446 match(RegP);
5447 match(mRegP);
5448 op_cost(100);
5449 format %{ %}
5450 interface(REG_INTER);
5451 %}
5453 // Indirect Memory Operand Long
5454 operand load_long_indirect(load_long_RegP reg) %{
5455 constraint(ALLOC_IN_RC(p_reg));
5456 match(reg);
5458 format %{ "[$reg]" %}
5459 interface(MEMORY_INTER) %{
5460 base($reg);
5461 index(0x0);
5462 scale(0x0);
5463 disp(0x0);
5464 %}
5465 %}
5467 // Indirect Memory Plus Long Offset Operand
5468 operand load_long_indOffset32(load_long_RegP reg, immL32 off) %{
5469 match(AddP reg off);
5471 format %{ "[$reg + $off]" %}
5472 interface(MEMORY_INTER) %{
5473 base($reg);
5474 index(0x0);
5475 scale(0x0);
5476 disp($off);
5477 %}
5478 %}
5480 //----------Conditional Branch Operands----------------------------------------
5481 // Comparison Op - This is the operation of the comparison, and is limited to
5482 // the following set of codes:
5483 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5484 //
5485 // Other attributes of the comparison, such as unsignedness, are specified
5486 // by the comparison instruction that sets a condition code flags register.
5487 // That result is represented by a flags operand whose subtype is appropriate
5488 // to the unsignedness (etc.) of the comparison.
5489 //
5490 // Later, the instruction which matches both the Comparison Op (a Bool) and
5491 // the flags (produced by the Cmp) specifies the coding of the comparison op
5492 // by matching a specific subtype of Bool operand below, such as cmpOpU.
5494 // Comparision Code
5495 operand cmpOp() %{
5496 match(Bool);
5498 format %{ "" %}
5499 interface(COND_INTER) %{
5500 equal(0x01);
5501 not_equal(0x02);
5502 greater(0x03);
5503 greater_equal(0x04);
5504 less(0x05);
5505 less_equal(0x06);
5506 overflow(0x7);
5507 no_overflow(0x8);
5508 %}
5509 %}
5512 // Comparision Code
5513 // Comparison Code, unsigned compare. Used by FP also, with
5514 // C2 (unordered) turned into GT or LT already. The other bits
5515 // C0 and C3 are turned into Carry & Zero flags.
5516 operand cmpOpU() %{
5517 match(Bool);
5519 format %{ "" %}
5520 interface(COND_INTER) %{
5521 equal(0x01);
5522 not_equal(0x02);
5523 greater(0x03);
5524 greater_equal(0x04);
5525 less(0x05);
5526 less_equal(0x06);
5527 overflow(0x7);
5528 no_overflow(0x8);
5529 %}
5530 %}
5533 //----------Special Memory Operands--------------------------------------------
5534 // Stack Slot Operand - This operand is used for loading and storing temporary
5535 // values on the stack where a match requires a value to
5536 // flow through memory.
5537 operand stackSlotP(sRegP reg) %{
5538 constraint(ALLOC_IN_RC(stack_slots));
5539 // No match rule because this operand is only generated in matching
5540 op_cost(50);
5541 format %{ "[$reg]" %}
5542 interface(MEMORY_INTER) %{
5543 base(0x1d); // SP
5544 index(0x0); // No Index
5545 scale(0x0); // No Scale
5546 disp($reg); // Stack Offset
5547 %}
5548 %}
5550 operand stackSlotI(sRegI reg) %{
5551 constraint(ALLOC_IN_RC(stack_slots));
5552 // No match rule because this operand is only generated in matching
5553 op_cost(50);
5554 format %{ "[$reg]" %}
5555 interface(MEMORY_INTER) %{
5556 base(0x1d); // SP
5557 index(0x0); // No Index
5558 scale(0x0); // No Scale
5559 disp($reg); // Stack Offset
5560 %}
5561 %}
5563 operand stackSlotF(sRegF reg) %{
5564 constraint(ALLOC_IN_RC(stack_slots));
5565 // No match rule because this operand is only generated in matching
5566 op_cost(50);
5567 format %{ "[$reg]" %}
5568 interface(MEMORY_INTER) %{
5569 base(0x1d); // SP
5570 index(0x0); // No Index
5571 scale(0x0); // No Scale
5572 disp($reg); // Stack Offset
5573 %}
5574 %}
5576 operand stackSlotD(sRegD reg) %{
5577 constraint(ALLOC_IN_RC(stack_slots));
5578 // No match rule because this operand is only generated in matching
5579 op_cost(50);
5580 format %{ "[$reg]" %}
5581 interface(MEMORY_INTER) %{
5582 base(0x1d); // SP
5583 index(0x0); // No Index
5584 scale(0x0); // No Scale
5585 disp($reg); // Stack Offset
5586 %}
5587 %}
5589 operand stackSlotL(sRegL reg) %{
5590 constraint(ALLOC_IN_RC(stack_slots));
5591 // No match rule because this operand is only generated in matching
5592 op_cost(50);
5593 format %{ "[$reg]" %}
5594 interface(MEMORY_INTER) %{
5595 base(0x1d); // SP
5596 index(0x0); // No Index
5597 scale(0x0); // No Scale
5598 disp($reg); // Stack Offset
5599 %}
5600 %}
5603 //------------------------OPERAND CLASSES--------------------------------------
5604 //opclass memory( direct, indirect, indOffset16, indOffset32, indOffset32X, indIndexOffset );
5605 opclass memory( indirect, indirectNarrow, indOffset8, indOffset32, indIndex, indIndexScale, load_long_indirect, load_long_indOffset32, baseIndexOffset8, baseIndexOffset8_convI2L, indIndexScaleOffset8, indIndexScaleOffset8_convI2L, basePosIndexScaleOffset8, indIndexScaleOffsetNarrow, indPosIndexI2LScaleOffset8Narrow, indOffset8Narrow, indIndexOffset8Narrow);
5608 //----------PIPELINE-----------------------------------------------------------
5609 // Rules which define the behavior of the target architectures pipeline.
5611 pipeline %{
5613 //----------ATTRIBUTES---------------------------------------------------------
5614 attributes %{
5615 fixed_size_instructions; // Fixed size instructions
5616 branch_has_delay_slot; // branch have delay slot in gs2
5617 max_instructions_per_bundle = 1; // 1 instruction per bundle
5618 max_bundles_per_cycle = 4; // Up to 4 bundles per cycle
5619 bundle_unit_size=4;
5620 instruction_unit_size = 4; // An instruction is 4 bytes long
5621 instruction_fetch_unit_size = 16; // The processor fetches one line
5622 instruction_fetch_units = 1; // of 16 bytes
5624 // List of nop instructions
5625 nops( MachNop );
5626 %}
5628 //----------RESOURCES----------------------------------------------------------
5629 // Resources are the functional units available to the machine
5631 resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4, ALU1, ALU2, ALU = ALU1 | ALU2, FPU1, FPU2, FPU = FPU1 | FPU2, MEM, BR);
5633 //----------PIPELINE DESCRIPTION-----------------------------------------------
5634 // Pipeline Description specifies the stages in the machine's pipeline
5636 // IF: fetch
5637 // ID: decode
5638 // RD: read
5639 // CA: caculate
5640 // WB: write back
5641 // CM: commit
5643 pipe_desc(IF, ID, RD, CA, WB, CM);
5646 //----------PIPELINE CLASSES---------------------------------------------------
5647 // Pipeline Classes describe the stages in which input and output are
5648 // referenced by the hardware pipeline.
5650 //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
5651 pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
5652 single_instruction;
5653 src1 : RD(read);
5654 src2 : RD(read);
5655 dst : WB(write)+1;
5656 DECODE : ID;
5657 ALU : CA;
5658 %}
5660 //No.19 Integer mult operation : dst <-- reg1 mult reg2
5661 pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
5662 src1 : RD(read);
5663 src2 : RD(read);
5664 dst : WB(write)+5;
5665 DECODE : ID;
5666 ALU2 : CA;
5667 %}
5669 pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
5670 src1 : RD(read);
5671 src2 : RD(read);
5672 dst : WB(write)+10;
5673 DECODE : ID;
5674 ALU2 : CA;
5675 %}
5677 //No.19 Integer div operation : dst <-- reg1 div reg2
5678 pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
5679 src1 : RD(read);
5680 src2 : RD(read);
5681 dst : WB(write)+10;
5682 DECODE : ID;
5683 ALU2 : CA;
5684 %}
5686 //No.19 Integer mod operation : dst <-- reg1 mod reg2
5687 pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
5688 instruction_count(2);
5689 src1 : RD(read);
5690 src2 : RD(read);
5691 dst : WB(write)+10;
5692 DECODE : ID;
5693 ALU2 : CA;
5694 %}
5696 //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
5697 pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
5698 instruction_count(2);
5699 src1 : RD(read);
5700 src2 : RD(read);
5701 dst : WB(write);
5702 DECODE : ID;
5703 ALU : CA;
5704 %}
5706 //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
5707 pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
5708 instruction_count(2);
5709 src : RD(read);
5710 dst : WB(write);
5711 DECODE : ID;
5712 ALU : CA;
5713 %}
5715 //no.16 load Long from memory :
5716 pipe_class ialu_loadL(mRegL dst, memory mem) %{
5717 instruction_count(2);
5718 mem : RD(read);
5719 dst : WB(write)+5;
5720 DECODE : ID;
5721 MEM : RD;
5722 %}
5724 //No.17 Store Long to Memory :
5725 pipe_class ialu_storeL(mRegL src, memory mem) %{
5726 instruction_count(2);
5727 mem : RD(read);
5728 src : RD(read);
5729 DECODE : ID;
5730 MEM : RD;
5731 %}
5733 //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
5734 pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
5735 single_instruction;
5736 src : RD(read);
5737 dst : WB(write);
5738 DECODE : ID;
5739 ALU : CA;
5740 %}
5742 //No.3 Integer move operation : dst <-- reg
5743 pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
5744 src : RD(read);
5745 dst : WB(write);
5746 DECODE : ID;
5747 ALU : CA;
5748 %}
5750 //No.4 No instructions : do nothing
5751 pipe_class empty( ) %{
5752 instruction_count(0);
5753 %}
5755 //No.5 UnConditional branch :
5756 pipe_class pipe_jump( label labl ) %{
5757 multiple_bundles;
5758 DECODE : ID;
5759 BR : RD;
5760 %}
5762 //No.6 ALU Conditional branch :
5763 pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
5764 multiple_bundles;
5765 src1 : RD(read);
5766 src2 : RD(read);
5767 DECODE : ID;
5768 BR : RD;
5769 %}
5771 //no.7 load integer from memory :
5772 pipe_class ialu_loadI(mRegI dst, memory mem) %{
5773 mem : RD(read);
5774 dst : WB(write)+3;
5775 DECODE : ID;
5776 MEM : RD;
5777 %}
5779 //No.8 Store Integer to Memory :
5780 pipe_class ialu_storeI(mRegI src, memory mem) %{
5781 mem : RD(read);
5782 src : RD(read);
5783 DECODE : ID;
5784 MEM : RD;
5785 %}
5788 //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
5789 pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
5790 src1 : RD(read);
5791 src2 : RD(read);
5792 dst : WB(write);
5793 DECODE : ID;
5794 FPU : CA;
5795 %}
5797 //No.22 Floating div operation : dst <-- reg1 div reg2
5798 pipe_class fpu_div(regF dst, regF src1, regF src2) %{
5799 src1 : RD(read);
5800 src2 : RD(read);
5801 dst : WB(write);
5802 DECODE : ID;
5803 FPU2 : CA;
5804 %}
5806 pipe_class fcvt_I2D(regD dst, mRegI src) %{
5807 src : RD(read);
5808 dst : WB(write);
5809 DECODE : ID;
5810 FPU1 : CA;
5811 %}
5813 pipe_class fcvt_D2I(mRegI dst, regD src) %{
5814 src : RD(read);
5815 dst : WB(write);
5816 DECODE : ID;
5817 FPU1 : CA;
5818 %}
5820 pipe_class pipe_mfc1(mRegI dst, regD src) %{
5821 src : RD(read);
5822 dst : WB(write);
5823 DECODE : ID;
5824 MEM : RD;
5825 %}
5827 pipe_class pipe_mtc1(regD dst, mRegI src) %{
5828 src : RD(read);
5829 dst : WB(write);
5830 DECODE : ID;
5831 MEM : RD(5);
5832 %}
5834 //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
5835 pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
5836 multiple_bundles;
5837 src1 : RD(read);
5838 src2 : RD(read);
5839 dst : WB(write);
5840 DECODE : ID;
5841 FPU2 : CA;
5842 %}
5844 //No.11 Load Floating from Memory :
5845 pipe_class fpu_loadF(regF dst, memory mem) %{
5846 instruction_count(1);
5847 mem : RD(read);
5848 dst : WB(write)+3;
5849 DECODE : ID;
5850 MEM : RD;
5851 %}
5853 //No.12 Store Floating to Memory :
5854 pipe_class fpu_storeF(regF src, memory mem) %{
5855 instruction_count(1);
5856 mem : RD(read);
5857 src : RD(read);
5858 DECODE : ID;
5859 MEM : RD;
5860 %}
5862 //No.13 FPU Conditional branch :
5863 pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
5864 multiple_bundles;
5865 src1 : RD(read);
5866 src2 : RD(read);
5867 DECODE : ID;
5868 BR : RD;
5869 %}
5871 //No.14 Floating FPU reg operation : dst <-- op reg
5872 pipe_class fpu1_regF(regF dst, regF src) %{
5873 src : RD(read);
5874 dst : WB(write);
5875 DECODE : ID;
5876 FPU : CA;
5877 %}
5879 pipe_class long_memory_op() %{
5880 instruction_count(10); multiple_bundles; force_serialization;
5881 fixed_latency(30);
5882 %}
5884 pipe_class simple_call() %{
5885 instruction_count(10); multiple_bundles; force_serialization;
5886 fixed_latency(200);
5887 BR : RD;
5888 %}
5890 pipe_class call() %{
5891 instruction_count(10); multiple_bundles; force_serialization;
5892 fixed_latency(200);
5893 %}
5895 //FIXME:
5896 //No.9 Piple slow : for multi-instructions
5897 pipe_class pipe_slow( ) %{
5898 instruction_count(20);
5899 force_serialization;
5900 multiple_bundles;
5901 fixed_latency(50);
5902 %}
5904 %}
5908 //----------INSTRUCTIONS-------------------------------------------------------
5909 //
5910 // match -- States which machine-independent subtree may be replaced
5911 // by this instruction.
5912 // ins_cost -- The estimated cost of this instruction is used by instruction
5913 // selection to identify a minimum cost tree of machine
5914 // instructions that matches a tree of machine-independent
5915 // instructions.
5916 // format -- A string providing the disassembly for this instruction.
5917 // The value of an instruction's operand may be inserted
5918 // by referring to it with a '$' prefix.
5919 // opcode -- Three instruction opcodes may be provided. These are referred
5920 // to within an encode class as $primary, $secondary, and $tertiary
5921 // respectively. The primary opcode is commonly used to
5922 // indicate the type of machine instruction, while secondary
5923 // and tertiary are often used for prefix options or addressing
5924 // modes.
5925 // ins_encode -- A list of encode classes with parameters. The encode class
5926 // name must have been defined in an 'enc_class' specification
5927 // in the encode section of the architecture description.
5930 // Load Integer
5931 instruct loadI(mRegI dst, memory mem) %{
5932 match(Set dst (LoadI mem));
5934 ins_cost(125);
5935 format %{ "lw $dst, $mem #@loadI" %}
5936 ins_encode (load_I_enc(dst, mem));
5937 ins_pipe( ialu_loadI );
5938 %}
5940 instruct loadI_convI2L(mRegL dst, memory mem) %{
5941 match(Set dst (ConvI2L (LoadI mem)));
5943 ins_cost(125);
5944 format %{ "lw $dst, $mem #@loadI_convI2L" %}
5945 ins_encode (load_I_enc(dst, mem));
5946 ins_pipe( ialu_loadI );
5947 %}
5949 // Load Integer (32 bit signed) to Byte (8 bit signed)
5950 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
5951 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
5953 ins_cost(125);
5954 format %{ "lb $dst, $mem\t# int -> byte #@loadI2B" %}
5955 ins_encode(load_B_enc(dst, mem));
5956 ins_pipe(ialu_loadI);
5957 %}
5959 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
5960 instruct loadI2UB(mRegI dst, memory mem, immI_255 mask) %{
5961 match(Set dst (AndI (LoadI mem) mask));
5963 ins_cost(125);
5964 format %{ "lbu $dst, $mem\t# int -> ubyte #@loadI2UB" %}
5965 ins_encode(load_UB_enc(dst, mem));
5966 ins_pipe(ialu_loadI);
5967 %}
5969 // Load Integer (32 bit signed) to Short (16 bit signed)
5970 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
5971 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
5973 ins_cost(125);
5974 format %{ "lh $dst, $mem\t# int -> short #@loadI2S" %}
5975 ins_encode(load_S_enc(dst, mem));
5976 ins_pipe(ialu_loadI);
5977 %}
5979 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
5980 instruct loadI2US(mRegI dst, memory mem, immI_65535 mask) %{
5981 match(Set dst (AndI (LoadI mem) mask));
5983 ins_cost(125);
5984 format %{ "lhu $dst, $mem\t# int -> ushort/char #@loadI2US" %}
5985 ins_encode(load_C_enc(dst, mem));
5986 ins_pipe(ialu_loadI);
5987 %}
5989 // Load Long.
5990 instruct loadL(mRegL dst, memory mem) %{
5991 // predicate(!((LoadLNode*)n)->require_atomic_access());
5992 match(Set dst (LoadL mem));
5994 ins_cost(250);
5995 format %{ "ld $dst, $mem #@loadL" %}
5996 ins_encode(load_L_enc(dst, mem));
5997 ins_pipe( ialu_loadL );
5998 %}
6000 // Load Long - UNaligned
6001 instruct loadL_unaligned(mRegL dst, memory mem) %{
6002 match(Set dst (LoadL_unaligned mem));
6004 // FIXME: Need more effective ldl/ldr
6005 ins_cost(450);
6006 format %{ "ld $dst, $mem #@loadL_unaligned\n\t" %}
6007 ins_encode(load_L_enc(dst, mem));
6008 ins_pipe( ialu_loadL );
6009 %}
6011 // Store Long
6012 instruct storeL_reg(memory mem, mRegL src) %{
6013 match(Set mem (StoreL mem src));
6015 ins_cost(200);
6016 format %{ "sd $mem, $src #@storeL_reg\n" %}
6017 ins_encode(store_L_reg_enc(mem, src));
6018 ins_pipe( ialu_storeL );
6019 %}
6021 instruct storeL_immL0(memory mem, immL0 zero) %{
6022 match(Set mem (StoreL mem zero));
6024 ins_cost(180);
6025 format %{ "sd zero, $mem #@storeL_immL0" %}
6026 ins_encode(store_L_immL0_enc(mem, zero));
6027 ins_pipe( ialu_storeL );
6028 %}
6030 instruct storeL_imm(memory mem, immL src) %{
6031 match(Set mem (StoreL mem src));
6033 ins_cost(200);
6034 format %{ "sd $src, $mem #@storeL_imm" %}
6035 ins_encode(store_L_immL_enc(mem, src));
6036 ins_pipe( ialu_storeL );
6037 %}
6039 // Load Compressed Pointer
6040 instruct loadN(mRegN dst, memory mem)
6041 %{
6042 match(Set dst (LoadN mem));
6044 ins_cost(125); // XXX
6045 format %{ "lwu $dst, $mem\t# compressed ptr @ loadN" %}
6046 ins_encode (load_N_enc(dst, mem));
6047 ins_pipe( ialu_loadI ); // XXX
6048 %}
6050 instruct loadN2P(mRegP dst, memory mem)
6051 %{
6052 match(Set dst (DecodeN (LoadN mem)));
6053 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6055 ins_cost(125); // XXX
6056 format %{ "lwu $dst, $mem\t# @ loadN2P" %}
6057 ins_encode (load_N_enc(dst, mem));
6058 ins_pipe( ialu_loadI ); // XXX
6059 %}
6061 // Load Pointer
6062 instruct loadP(mRegP dst, memory mem) %{
6063 match(Set dst (LoadP mem));
6065 ins_cost(125);
6066 format %{ "ld $dst, $mem #@loadP" %}
6067 ins_encode (load_P_enc(dst, mem));
6068 ins_pipe( ialu_loadI );
6069 %}
6071 // Load Klass Pointer
6072 instruct loadKlass(mRegP dst, memory mem) %{
6073 match(Set dst (LoadKlass mem));
6075 ins_cost(125);
6076 format %{ "MOV $dst,$mem @ loadKlass" %}
6077 ins_encode (load_P_enc(dst, mem));
6078 ins_pipe( ialu_loadI );
6079 %}
6081 // Load narrow Klass Pointer
6082 instruct loadNKlass(mRegN dst, memory mem)
6083 %{
6084 match(Set dst (LoadNKlass mem));
6086 ins_cost(125); // XXX
6087 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
6088 ins_encode (load_N_enc(dst, mem));
6089 ins_pipe( ialu_loadI ); // XXX
6090 %}
6092 instruct loadN2PKlass(mRegP dst, memory mem)
6093 %{
6094 match(Set dst (DecodeNKlass (LoadNKlass mem)));
6095 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
6097 ins_cost(125); // XXX
6098 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
6099 ins_encode (load_N_enc(dst, mem));
6100 ins_pipe( ialu_loadI ); // XXX
6101 %}
6103 // Load Constant
6104 instruct loadConI(mRegI dst, immI src) %{
6105 match(Set dst src);
6107 ins_cost(150);
6108 format %{ "mov $dst, $src #@loadConI" %}
6109 ins_encode %{
6110 Register dst = $dst$$Register;
6111 int value = $src$$constant;
6112 __ move(dst, value);
6113 %}
6114 ins_pipe( ialu_regI_regI );
6115 %}
6118 instruct loadConL_set64(mRegL dst, immL src) %{
6119 match(Set dst src);
6120 ins_cost(120);
6121 format %{ "li $dst, $src @ loadConL_set64" %}
6122 ins_encode %{
6123 __ set64($dst$$Register, $src$$constant);
6124 %}
6125 ins_pipe(ialu_regL_regL);
6126 %}
6128 /*
6129 // Load long value from constant table (predicated by immL_expensive).
6130 instruct loadConL_load(mRegL dst, immL_expensive src) %{
6131 match(Set dst src);
6132 ins_cost(150);
6133 format %{ "ld $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
6134 ins_encode %{
6135 int con_offset = $constantoffset($src);
6137 if (Assembler::is_simm16(con_offset)) {
6138 __ ld($dst$$Register, $constanttablebase, con_offset);
6139 } else {
6140 __ set64(AT, con_offset);
6141 if (UseLoongsonISA) {
6142 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
6143 } else {
6144 __ daddu(AT, $constanttablebase, AT);
6145 __ ld($dst$$Register, AT, 0);
6146 }
6147 }
6148 %}
6149 ins_pipe(ialu_loadI);
6150 %}
6151 */
6153 instruct loadConL16(mRegL dst, immL16 src) %{
6154 match(Set dst src);
6155 ins_cost(105);
6156 format %{ "mov $dst, $src #@loadConL16" %}
6157 ins_encode %{
6158 Register dst_reg = as_Register($dst$$reg);
6159 int value = $src$$constant;
6160 __ daddiu(dst_reg, R0, value);
6161 %}
6162 ins_pipe( ialu_regL_regL );
6163 %}
6166 instruct loadConL0(mRegL dst, immL0 src) %{
6167 match(Set dst src);
6168 ins_cost(100);
6169 format %{ "mov $dst, zero #@loadConL0" %}
6170 ins_encode %{
6171 Register dst_reg = as_Register($dst$$reg);
6172 __ daddu(dst_reg, R0, R0);
6173 %}
6174 ins_pipe( ialu_regL_regL );
6175 %}
6177 // Load Range
6178 instruct loadRange(mRegI dst, memory mem) %{
6179 match(Set dst (LoadRange mem));
6181 ins_cost(125);
6182 format %{ "MOV $dst,$mem @ loadRange" %}
6183 ins_encode(load_I_enc(dst, mem));
6184 ins_pipe( ialu_loadI );
6185 %}
6188 instruct storeP(memory mem, mRegP src ) %{
6189 match(Set mem (StoreP mem src));
6191 ins_cost(125);
6192 format %{ "sd $src, $mem #@storeP" %}
6193 ins_encode(store_P_reg_enc(mem, src));
6194 ins_pipe( ialu_storeI );
6195 %}
6197 // Store NULL Pointer, mark word, or other simple pointer constant.
6198 instruct storeImmP0(memory mem, immP0 zero) %{
6199 match(Set mem (StoreP mem zero));
6201 ins_cost(125);
6202 format %{ "mov $mem, $zero #@storeImmP0" %}
6203 ins_encode(store_P_immP0_enc(mem));
6204 ins_pipe( ialu_storeI );
6205 %}
6207 // Store Byte Immediate
6208 instruct storeImmB(memory mem, immI8 src) %{
6209 match(Set mem (StoreB mem src));
6211 ins_cost(150);
6212 format %{ "movb $mem, $src #@storeImmB" %}
6213 ins_encode(store_B_immI_enc(mem, src));
6214 ins_pipe( ialu_storeI );
6215 %}
6217 // Store Compressed Pointer
6218 instruct storeN(memory mem, mRegN src)
6219 %{
6220 match(Set mem (StoreN mem src));
6222 ins_cost(125); // XXX
6223 format %{ "sw $mem, $src\t# compressed ptr @ storeN" %}
6224 ins_encode(store_N_reg_enc(mem, src));
6225 ins_pipe( ialu_storeI );
6226 %}
6228 instruct storeP2N(memory mem, mRegP src)
6229 %{
6230 match(Set mem (StoreN mem (EncodeP src)));
6231 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6233 ins_cost(125); // XXX
6234 format %{ "sw $mem, $src\t# @ storeP2N" %}
6235 ins_encode(store_N_reg_enc(mem, src));
6236 ins_pipe( ialu_storeI );
6237 %}
6239 instruct storeNKlass(memory mem, mRegN src)
6240 %{
6241 match(Set mem (StoreNKlass mem src));
6243 ins_cost(125); // XXX
6244 format %{ "sw $mem, $src\t# compressed klass ptr @ storeNKlass" %}
6245 ins_encode(store_N_reg_enc(mem, src));
6246 ins_pipe( ialu_storeI );
6247 %}
6249 instruct storeP2NKlass(memory mem, mRegP src)
6250 %{
6251 match(Set mem (StoreNKlass mem (EncodePKlass src)));
6252 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
6254 ins_cost(125); // XXX
6255 format %{ "sw $mem, $src\t# @ storeP2NKlass" %}
6256 ins_encode(store_N_reg_enc(mem, src));
6257 ins_pipe( ialu_storeI );
6258 %}
6260 instruct storeImmN0(memory mem, immN0 zero)
6261 %{
6262 match(Set mem (StoreN mem zero));
6264 ins_cost(125); // XXX
6265 format %{ "storeN0 zero, $mem\t# compressed ptr" %}
6266 ins_encode(storeImmN0_enc(mem, zero));
6267 ins_pipe( ialu_storeI );
6268 %}
6270 // Store Byte
6271 instruct storeB(memory mem, mRegI src) %{
6272 match(Set mem (StoreB mem src));
6274 ins_cost(125);
6275 format %{ "sb $src, $mem #@storeB" %}
6276 ins_encode(store_B_reg_enc(mem, src));
6277 ins_pipe( ialu_storeI );
6278 %}
6280 instruct storeB_convL2I(memory mem, mRegL src) %{
6281 match(Set mem (StoreB mem (ConvL2I src)));
6283 ins_cost(125);
6284 format %{ "sb $src, $mem #@storeB_convL2I" %}
6285 ins_encode(store_B_reg_enc(mem, src));
6286 ins_pipe( ialu_storeI );
6287 %}
6289 // Load Byte (8bit signed)
6290 instruct loadB(mRegI dst, memory mem) %{
6291 match(Set dst (LoadB mem));
6293 ins_cost(125);
6294 format %{ "lb $dst, $mem #@loadB" %}
6295 ins_encode(load_B_enc(dst, mem));
6296 ins_pipe( ialu_loadI );
6297 %}
6299 instruct loadB_convI2L(mRegL dst, memory mem) %{
6300 match(Set dst (ConvI2L (LoadB mem)));
6302 ins_cost(125);
6303 format %{ "lb $dst, $mem #@loadB_convI2L" %}
6304 ins_encode(load_B_enc(dst, mem));
6305 ins_pipe( ialu_loadI );
6306 %}
6308 // Load Byte (8bit UNsigned)
6309 instruct loadUB(mRegI dst, memory mem) %{
6310 match(Set dst (LoadUB mem));
6312 ins_cost(125);
6313 format %{ "lbu $dst, $mem #@loadUB" %}
6314 ins_encode(load_UB_enc(dst, mem));
6315 ins_pipe( ialu_loadI );
6316 %}
6318 instruct loadUB_convI2L(mRegL dst, memory mem) %{
6319 match(Set dst (ConvI2L (LoadUB mem)));
6321 ins_cost(125);
6322 format %{ "lbu $dst, $mem #@loadUB_convI2L" %}
6323 ins_encode(load_UB_enc(dst, mem));
6324 ins_pipe( ialu_loadI );
6325 %}
6327 // Load Short (16bit signed)
6328 instruct loadS(mRegI dst, memory mem) %{
6329 match(Set dst (LoadS mem));
6331 ins_cost(125);
6332 format %{ "lh $dst, $mem #@loadS" %}
6333 ins_encode(load_S_enc(dst, mem));
6334 ins_pipe( ialu_loadI );
6335 %}
6337 // Load Short (16 bit signed) to Byte (8 bit signed)
6338 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
6339 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
6341 ins_cost(125);
6342 format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
6343 ins_encode(load_B_enc(dst, mem));
6344 ins_pipe(ialu_loadI);
6345 %}
6347 instruct loadS_convI2L(mRegL dst, memory mem) %{
6348 match(Set dst (ConvI2L (LoadS mem)));
6350 ins_cost(125);
6351 format %{ "lh $dst, $mem #@loadS_convI2L" %}
6352 ins_encode(load_S_enc(dst, mem));
6353 ins_pipe( ialu_loadI );
6354 %}
6356 // Store Integer Immediate
6357 instruct storeImmI(memory mem, immI src) %{
6358 match(Set mem (StoreI mem src));
6360 ins_cost(150);
6361 format %{ "mov $mem, $src #@storeImmI" %}
6362 ins_encode(store_I_immI_enc(mem, src));
6363 ins_pipe( ialu_storeI );
6364 %}
6366 // Store Integer
6367 instruct storeI(memory mem, mRegI src) %{
6368 match(Set mem (StoreI mem src));
6370 ins_cost(125);
6371 format %{ "sw $mem, $src #@storeI" %}
6372 ins_encode(store_I_reg_enc(mem, src));
6373 ins_pipe( ialu_storeI );
6374 %}
6376 instruct storeI_convL2I(memory mem, mRegL src) %{
6377 match(Set mem (StoreI mem (ConvL2I src)));
6379 ins_cost(125);
6380 format %{ "sw $mem, $src #@storeI_convL2I" %}
6381 ins_encode(store_I_reg_enc(mem, src));
6382 ins_pipe( ialu_storeI );
6383 %}
6385 // Load Float
6386 instruct loadF(regF dst, memory mem) %{
6387 match(Set dst (LoadF mem));
6389 ins_cost(150);
6390 format %{ "loadF $dst, $mem #@loadF" %}
6391 ins_encode(load_F_enc(dst, mem));
6392 ins_pipe( ialu_loadI );
6393 %}
6395 instruct loadConP_general(mRegP dst, immP src) %{
6396 match(Set dst src);
6398 ins_cost(120);
6399 format %{ "li $dst, $src #@loadConP_general" %}
6401 ins_encode %{
6402 Register dst = $dst$$Register;
6403 long* value = (long*)$src$$constant;
6405 if($src->constant_reloc() == relocInfo::metadata_type){
6406 int klass_index = __ oop_recorder()->find_index((Klass*)value);
6407 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
6409 __ relocate(rspec);
6410 __ patchable_set48(dst, (long)value);
6411 }else if($src->constant_reloc() == relocInfo::oop_type){
6412 int oop_index = __ oop_recorder()->find_index((jobject)value);
6413 RelocationHolder rspec = oop_Relocation::spec(oop_index);
6415 __ relocate(rspec);
6416 __ patchable_set48(dst, (long)value);
6417 } else if ($src->constant_reloc() == relocInfo::none) {
6418 __ set64(dst, (long)value);
6419 }
6420 %}
6422 ins_pipe( ialu_regI_regI );
6423 %}
6425 /*
6426 instruct loadConP_load(mRegP dst, immP_load src) %{
6427 match(Set dst src);
6429 ins_cost(100);
6430 format %{ "ld $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
6432 ins_encode %{
6434 int con_offset = $constantoffset($src);
6436 if (Assembler::is_simm16(con_offset)) {
6437 __ ld($dst$$Register, $constanttablebase, con_offset);
6438 } else {
6439 __ set64(AT, con_offset);
6440 if (UseLoongsonISA) {
6441 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
6442 } else {
6443 __ daddu(AT, $constanttablebase, AT);
6444 __ ld($dst$$Register, AT, 0);
6445 }
6446 }
6447 %}
6449 ins_pipe(ialu_loadI);
6450 %}
6451 */
6453 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
6454 match(Set dst src);
6456 ins_cost(80);
6457 format %{ "li $dst, $src @ loadConP_no_oop_cheap" %}
6459 ins_encode %{
6460 __ set64($dst$$Register, $src$$constant);
6461 %}
6463 ins_pipe(ialu_regI_regI);
6464 %}
6467 instruct loadConP_poll(mRegP dst, immP_poll src) %{
6468 match(Set dst src);
6470 ins_cost(50);
6471 format %{ "li $dst, $src #@loadConP_poll" %}
6473 ins_encode %{
6474 Register dst = $dst$$Register;
6475 intptr_t value = (intptr_t)$src$$constant;
6477 __ set64(dst, (jlong)value);
6478 %}
6480 ins_pipe( ialu_regI_regI );
6481 %}
6483 instruct loadConP0(mRegP dst, immP0 src)
6484 %{
6485 match(Set dst src);
6487 ins_cost(50);
6488 format %{ "mov $dst, R0\t# ptr" %}
6489 ins_encode %{
6490 Register dst_reg = $dst$$Register;
6491 __ daddu(dst_reg, R0, R0);
6492 %}
6493 ins_pipe( ialu_regI_regI );
6494 %}
6496 instruct loadConN0(mRegN dst, immN0 src) %{
6497 match(Set dst src);
6498 format %{ "move $dst, R0\t# compressed NULL ptr" %}
6499 ins_encode %{
6500 __ move($dst$$Register, R0);
6501 %}
6502 ins_pipe( ialu_regI_regI );
6503 %}
6505 instruct loadConN(mRegN dst, immN src) %{
6506 match(Set dst src);
6508 ins_cost(125);
6509 format %{ "li $dst, $src\t# compressed ptr @ loadConN" %}
6510 ins_encode %{
6511 Register dst = $dst$$Register;
6512 __ set_narrow_oop(dst, (jobject)$src$$constant);
6513 %}
6514 ins_pipe( ialu_regI_regI ); // XXX
6515 %}
6517 instruct loadConNKlass(mRegN dst, immNKlass src) %{
6518 match(Set dst src);
6520 ins_cost(125);
6521 format %{ "li $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
6522 ins_encode %{
6523 Register dst = $dst$$Register;
6524 __ set_narrow_klass(dst, (Klass*)$src$$constant);
6525 %}
6526 ins_pipe( ialu_regI_regI ); // XXX
6527 %}
6529 //FIXME
6530 // Tail Call; Jump from runtime stub to Java code.
6531 // Also known as an 'interprocedural jump'.
6532 // Target of jump will eventually return to caller.
6533 // TailJump below removes the return address.
6534 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
6535 match(TailCall jump_target method_oop );
6536 ins_cost(300);
6537 format %{ "JMP $jump_target \t# @TailCalljmpInd" %}
6539 ins_encode %{
6540 Register target = $jump_target$$Register;
6541 Register oop = $method_oop$$Register;
6543 // RA will be used in generate_forward_exception()
6544 __ push(RA);
6546 __ move(S3, oop);
6547 __ jr(target);
6548 __ delayed()->nop();
6549 %}
6551 ins_pipe( pipe_jump );
6552 %}
6554 // Create exception oop: created by stack-crawling runtime code.
6555 // Created exception is now available to this handler, and is setup
6556 // just prior to jumping to this handler. No code emitted.
6557 instruct CreateException( a0_RegP ex_oop )
6558 %{
6559 match(Set ex_oop (CreateEx));
6561 // use the following format syntax
6562 format %{ "# exception oop is in A0; no code emitted @CreateException" %}
6563 ins_encode %{
6564 // X86 leaves this function empty
6565 __ block_comment("CreateException is empty in MIPS");
6566 %}
6567 ins_pipe( empty );
6568 // ins_pipe( pipe_jump );
6569 %}
6572 /* The mechanism of exception handling is clear now.
6574 - Common try/catch:
6575 [stubGenerator_mips.cpp] generate_forward_exception()
6576 |- V0, V1 are created
6577 |- T9 <= SharedRuntime::exception_handler_for_return_address
6578 `- jr T9
6579 `- the caller's exception_handler
6580 `- jr OptoRuntime::exception_blob
6581 `- here
6582 - Rethrow(e.g. 'unwind'):
6583 * The callee:
6584 |- an exception is triggered during execution
6585 `- exits the callee method through RethrowException node
6586 |- The callee pushes exception_oop(T0) and exception_pc(RA)
6587 `- The callee jumps to OptoRuntime::rethrow_stub()
6588 * In OptoRuntime::rethrow_stub:
6589 |- The VM calls _rethrow_Java to determine the return address in the caller method
6590 `- exits the stub with tailjmpInd
6591 |- pops exception_oop(V0) and exception_pc(V1)
6592 `- jumps to the return address(usually an exception_handler)
6593 * The caller:
6594 `- continues processing the exception_blob with V0/V1
6595 */
6597 /*
6598 Disassembling OptoRuntime::rethrow_stub()
6600 ; locals
6601 0x2d3bf320: addiu sp, sp, 0xfffffff8
6602 0x2d3bf324: sw ra, 0x4(sp)
6603 0x2d3bf328: sw fp, 0x0(sp)
6604 0x2d3bf32c: addu fp, sp, zero
6605 0x2d3bf330: addiu sp, sp, 0xfffffff0
6606 0x2d3bf334: sw ra, 0x8(sp)
6607 0x2d3bf338: sw t0, 0x4(sp)
6608 0x2d3bf33c: sw sp, 0x0(sp)
6610 ; get_thread(S2)
6611 0x2d3bf340: addu s2, sp, zero
6612 0x2d3bf344: srl s2, s2, 12
6613 0x2d3bf348: sll s2, s2, 2
6614 0x2d3bf34c: lui at, 0x2c85
6615 0x2d3bf350: addu at, at, s2
6616 0x2d3bf354: lw s2, 0xffffcc80(at)
6618 0x2d3bf358: lw s0, 0x0(sp)
6619 0x2d3bf35c: sw s0, 0x118(s2) // last_sp -> threa
6620 0x2d3bf360: sw s2, 0xc(sp)
6622 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
6623 0x2d3bf364: lw a0, 0x4(sp)
6624 0x2d3bf368: lw a1, 0xc(sp)
6625 0x2d3bf36c: lw a2, 0x8(sp)
6626 ;; Java_To_Runtime
6627 0x2d3bf370: lui t9, 0x2c34
6628 0x2d3bf374: addiu t9, t9, 0xffff8a48
6629 0x2d3bf378: jalr t9
6630 0x2d3bf37c: nop
6632 0x2d3bf380: addu s3, v0, zero ; S3: SharedRuntime::raw_exception_handler_for_return_address()
6634 0x2d3bf384: lw s0, 0xc(sp)
6635 0x2d3bf388: sw zero, 0x118(s0)
6636 0x2d3bf38c: sw zero, 0x11c(s0)
6637 0x2d3bf390: lw s1, 0x144(s0) ; ex_oop: S1
6638 0x2d3bf394: addu s2, s0, zero
6639 0x2d3bf398: sw zero, 0x144(s2)
6640 0x2d3bf39c: lw s0, 0x4(s2)
6641 0x2d3bf3a0: addiu s4, zero, 0x0
6642 0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
6643 0x2d3bf3a8: nop
6644 0x2d3bf3ac: addiu sp, sp, 0x10
6645 0x2d3bf3b0: addiu sp, sp, 0x8
6646 0x2d3bf3b4: lw ra, 0xfffffffc(sp)
6647 0x2d3bf3b8: lw fp, 0xfffffff8(sp)
6648 0x2d3bf3bc: lui at, 0x2b48
6649 0x2d3bf3c0: lw at, 0x100(at)
6651 ; tailjmpInd: Restores exception_oop & exception_pc
6652 0x2d3bf3c4: addu v1, ra, zero
6653 0x2d3bf3c8: addu v0, s1, zero
6654 0x2d3bf3cc: jr s3
6655 0x2d3bf3d0: nop
6656 ; Exception:
6657 0x2d3bf3d4: lui s1, 0x2cc8 ; generate_forward_exception()
6658 0x2d3bf3d8: addiu s1, s1, 0x40
6659 0x2d3bf3dc: addiu s2, zero, 0x0
6660 0x2d3bf3e0: addiu sp, sp, 0x10
6661 0x2d3bf3e4: addiu sp, sp, 0x8
6662 0x2d3bf3e8: lw ra, 0xfffffffc(sp)
6663 0x2d3bf3ec: lw fp, 0xfffffff8(sp)
6664 0x2d3bf3f0: lui at, 0x2b48
6665 0x2d3bf3f4: lw at, 0x100(at)
6666 ; TailCalljmpInd
6667 __ push(RA); ; to be used in generate_forward_exception()
6668 0x2d3bf3f8: addu t7, s2, zero
6669 0x2d3bf3fc: jr s1
6670 0x2d3bf400: nop
6671 */
6672 // Rethrow exception:
6673 // The exception oop will come in the first argument position.
6674 // Then JUMP (not call) to the rethrow stub code.
6675 instruct RethrowException()
6676 %{
6677 match(Rethrow);
6679 // use the following format syntax
6680 format %{ "JMP rethrow_stub #@RethrowException" %}
6681 ins_encode %{
6682 __ block_comment("@ RethrowException");
6684 cbuf.set_insts_mark();
6685 cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
6687 // call OptoRuntime::rethrow_stub to get the exception handler in parent method
6688 __ patchable_jump((address)OptoRuntime::rethrow_stub());
6689 %}
6690 ins_pipe( pipe_jump );
6691 %}
6693 // ============================================================================
6694 // Branch Instructions --- long offset versions
6696 // Jump Direct
6697 instruct jmpDir_long(label labl) %{
6698 match(Goto);
6699 effect(USE labl);
6701 ins_cost(300);
6702 format %{ "JMP $labl #@jmpDir_long" %}
6704 ins_encode %{
6705 Label* L = $labl$$label;
6706 __ jmp_far(*L);
6707 %}
6709 ins_pipe( pipe_jump );
6710 //ins_pc_relative(1);
6711 %}
6713 // Jump Direct Conditional - Label defines a relative address from Jcc+1
6714 instruct jmpLoopEnd_long(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
6715 match(CountedLoopEnd cop (CmpI src1 src2));
6716 effect(USE labl);
6718 ins_cost(300);
6719 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_long" %}
6720 ins_encode %{
6721 Register op1 = $src1$$Register;
6722 Register op2 = $src2$$Register;
6723 Label* L = $labl$$label;
6724 int flag = $cop$$cmpcode;
6726 switch(flag) {
6727 case 0x01: //equal
6728 __ beq_long(op1, op2, *L);
6729 break;
6730 case 0x02: //not_equal
6731 __ bne_long(op1, op2, *L);
6732 break;
6733 case 0x03: //above
6734 __ slt(AT, op2, op1);
6735 __ bne_long(AT, R0, *L);
6736 break;
6737 case 0x04: //above_equal
6738 __ slt(AT, op1, op2);
6739 __ beq_long(AT, R0, *L);
6740 break;
6741 case 0x05: //below
6742 __ slt(AT, op1, op2);
6743 __ bne_long(AT, R0, *L);
6744 break;
6745 case 0x06: //below_equal
6746 __ slt(AT, op2, op1);
6747 __ beq_long(AT, R0, *L);
6748 break;
6749 default:
6750 Unimplemented();
6751 }
6752 %}
6753 ins_pipe( pipe_jump );
6754 ins_pc_relative(1);
6755 %}
6757 instruct jmpLoopEnd_reg_immI_long(cmpOp cop, mRegI src1, immI src2, label labl) %{
6758 match(CountedLoopEnd cop (CmpI src1 src2));
6759 effect(USE labl);
6761 ins_cost(300);
6762 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_immI_long" %}
6763 ins_encode %{
6764 Register op1 = $src1$$Register;
6765 Register op2 = AT;
6766 Label* L = $labl$$label;
6767 int flag = $cop$$cmpcode;
6769 __ move(op2, $src2$$constant);
6771 switch(flag) {
6772 case 0x01: //equal
6773 __ beq_long(op1, op2, *L);
6774 break;
6775 case 0x02: //not_equal
6776 __ bne_long(op1, op2, *L);
6777 break;
6778 case 0x03: //above
6779 __ slt(AT, op2, op1);
6780 __ bne_long(AT, R0, *L);
6781 break;
6782 case 0x04: //above_equal
6783 __ slt(AT, op1, op2);
6784 __ beq_long(AT, R0, *L);
6785 break;
6786 case 0x05: //below
6787 __ slt(AT, op1, op2);
6788 __ bne_long(AT, R0, *L);
6789 break;
6790 case 0x06: //below_equal
6791 __ slt(AT, op2, op1);
6792 __ beq_long(AT, R0, *L);
6793 break;
6794 default:
6795 Unimplemented();
6796 }
6797 %}
6798 ins_pipe( pipe_jump );
6799 ins_pc_relative(1);
6800 %}
6803 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
6804 instruct jmpCon_flags_long(cmpOp cop, FlagsReg cr, label labl) %{
6805 match(If cop cr);
6806 effect(USE labl);
6808 ins_cost(300);
6809 format %{ "J$cop $labl #mips uses AT as eflag @jmpCon_flags_long" %}
6811 ins_encode %{
6812 Label* L = $labl$$label;
6813 switch($cop$$cmpcode) {
6814 case 0x01: //equal
6815 __ bne_long(AT, R0, *L);
6816 break;
6817 case 0x02: //not equal
6818 __ beq_long(AT, R0, *L);
6819 break;
6820 default:
6821 Unimplemented();
6822 }
6823 %}
6825 ins_pipe( pipe_jump );
6826 ins_pc_relative(1);
6827 %}
6829 // Conditional jumps
6830 instruct branchConP_zero_long(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
6831 match(If cmp (CmpP op1 zero));
6832 effect(USE labl);
6834 ins_cost(180);
6835 format %{ "b$cmp $op1, R0, $labl #@branchConP_zero_long" %}
6837 ins_encode %{
6838 Register op1 = $op1$$Register;
6839 Register op2 = R0;
6840 Label* L = $labl$$label;
6841 int flag = $cmp$$cmpcode;
6843 switch(flag) {
6844 case 0x01: //equal
6845 __ beq_long(op1, op2, *L);
6846 break;
6847 case 0x02: //not_equal
6848 __ bne_long(op1, op2, *L);
6849 break;
6850 default:
6851 Unimplemented();
6852 }
6853 %}
6855 ins_pc_relative(1);
6856 ins_pipe( pipe_alu_branch );
6857 %}
6859 instruct branchConN2P_zero_long(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
6860 match(If cmp (CmpP (DecodeN op1) zero));
6861 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6862 effect(USE labl);
6864 ins_cost(180);
6865 format %{ "b$cmp $op1, R0, $labl #@branchConN2P_zero_long" %}
6867 ins_encode %{
6868 Register op1 = $op1$$Register;
6869 Register op2 = R0;
6870 Label* L = $labl$$label;
6871 int flag = $cmp$$cmpcode;
6873 switch(flag)
6874 {
6875 case 0x01: //equal
6876 __ beq_long(op1, op2, *L);
6877 break;
6878 case 0x02: //not_equal
6879 __ bne_long(op1, op2, *L);
6880 break;
6881 default:
6882 Unimplemented();
6883 }
6884 %}
6886 ins_pc_relative(1);
6887 ins_pipe( pipe_alu_branch );
6888 %}
6891 instruct branchConP_long(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
6892 match(If cmp (CmpP op1 op2));
6893 // predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
6894 effect(USE labl);
6896 ins_cost(200);
6897 format %{ "b$cmp $op1, $op2, $labl #@branchConP_long" %}
6899 ins_encode %{
6900 Register op1 = $op1$$Register;
6901 Register op2 = $op2$$Register;
6902 Label* L = $labl$$label;
6903 int flag = $cmp$$cmpcode;
6905 switch(flag) {
6906 case 0x01: //equal
6907 __ beq_long(op1, op2, *L);
6908 break;
6909 case 0x02: //not_equal
6910 __ bne_long(op1, op2, *L);
6911 break;
6912 case 0x03: //above
6913 __ sltu(AT, op2, op1);
6914 __ bne_long(R0, AT, *L);
6915 break;
6916 case 0x04: //above_equal
6917 __ sltu(AT, op1, op2);
6918 __ beq_long(AT, R0, *L);
6919 break;
6920 case 0x05: //below
6921 __ sltu(AT, op1, op2);
6922 __ bne_long(R0, AT, *L);
6923 break;
6924 case 0x06: //below_equal
6925 __ sltu(AT, op2, op1);
6926 __ beq_long(AT, R0, *L);
6927 break;
6928 default:
6929 Unimplemented();
6930 }
6931 %}
6933 ins_pc_relative(1);
6934 ins_pipe( pipe_alu_branch );
6935 %}
6937 instruct cmpN_null_branch_long(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
6938 match(If cmp (CmpN op1 null));
6939 effect(USE labl);
6941 ins_cost(180);
6942 format %{ "CMP $op1,0\t! compressed ptr\n\t"
6943 "BP$cmp $labl @ cmpN_null_branch_long" %}
6944 ins_encode %{
6945 Register op1 = $op1$$Register;
6946 Register op2 = R0;
6947 Label* L = $labl$$label;
6948 int flag = $cmp$$cmpcode;
6950 switch(flag) {
6951 case 0x01: //equal
6952 __ beq_long(op1, op2, *L);
6953 break;
6954 case 0x02: //not_equal
6955 __ bne_long(op1, op2, *L);
6956 break;
6957 default:
6958 Unimplemented();
6959 }
6960 %}
6961 //TODO: pipe_branchP or create pipe_branchN LEE
6962 ins_pc_relative(1);
6963 ins_pipe( pipe_alu_branch );
6964 %}
6966 instruct cmpN_reg_branch_long(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
6967 match(If cmp (CmpN op1 op2));
6968 effect(USE labl);
6970 ins_cost(180);
6971 format %{ "CMP $op1,$op2\t! compressed ptr\n\t"
6972 "BP$cmp $labl @ cmpN_reg_branch_long" %}
6973 ins_encode %{
6974 Register op1_reg = $op1$$Register;
6975 Register op2_reg = $op2$$Register;
6976 Label* L = $labl$$label;
6977 int flag = $cmp$$cmpcode;
6979 switch(flag) {
6980 case 0x01: //equal
6981 __ beq_long(op1_reg, op2_reg, *L);
6982 break;
6983 case 0x02: //not_equal
6984 __ bne_long(op1_reg, op2_reg, *L);
6985 break;
6986 case 0x03: //above
6987 __ sltu(AT, op2_reg, op1_reg);
6988 __ bne_long(R0, AT, *L);
6989 break;
6990 case 0x04: //above_equal
6991 __ sltu(AT, op1_reg, op2_reg);
6992 __ beq_long(AT, R0, *L);
6993 break;
6994 case 0x05: //below
6995 __ sltu(AT, op1_reg, op2_reg);
6996 __ bne_long(R0, AT, *L);
6997 break;
6998 case 0x06: //below_equal
6999 __ sltu(AT, op2_reg, op1_reg);
7000 __ beq_long(AT, R0, *L);
7001 break;
7002 default:
7003 Unimplemented();
7004 }
7005 %}
7006 ins_pc_relative(1);
7007 ins_pipe( pipe_alu_branch );
7008 %}
7010 instruct branchConIU_reg_reg_long(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
7011 match( If cmp (CmpU src1 src2) );
7012 effect(USE labl);
7013 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_reg_long" %}
7015 ins_encode %{
7016 Register op1 = $src1$$Register;
7017 Register op2 = $src2$$Register;
7018 Label* L = $labl$$label;
7019 int flag = $cmp$$cmpcode;
7021 switch(flag) {
7022 case 0x01: //equal
7023 __ beq_long(op1, op2, *L);
7024 break;
7025 case 0x02: //not_equal
7026 __ bne_long(op1, op2, *L);
7027 break;
7028 case 0x03: //above
7029 __ sltu(AT, op2, op1);
7030 __ bne_long(AT, R0, *L);
7031 break;
7032 case 0x04: //above_equal
7033 __ sltu(AT, op1, op2);
7034 __ beq_long(AT, R0, *L);
7035 break;
7036 case 0x05: //below
7037 __ sltu(AT, op1, op2);
7038 __ bne_long(AT, R0, *L);
7039 break;
7040 case 0x06: //below_equal
7041 __ sltu(AT, op2, op1);
7042 __ beq_long(AT, R0, *L);
7043 break;
7044 default:
7045 Unimplemented();
7046 }
7047 %}
7049 ins_pc_relative(1);
7050 ins_pipe( pipe_alu_branch );
7051 %}
7054 instruct branchConIU_reg_imm_long(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
7055 match( If cmp (CmpU src1 src2) );
7056 effect(USE labl);
7057 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_imm_long" %}
7059 ins_encode %{
7060 Register op1 = $src1$$Register;
7061 int val = $src2$$constant;
7062 Label* L = $labl$$label;
7063 int flag = $cmp$$cmpcode;
7065 __ move(AT, val);
7066 switch(flag) {
7067 case 0x01: //equal
7068 __ beq_long(op1, AT, *L);
7069 break;
7070 case 0x02: //not_equal
7071 __ bne_long(op1, AT, *L);
7072 break;
7073 case 0x03: //above
7074 __ sltu(AT, AT, op1);
7075 __ bne_long(R0, AT, *L);
7076 break;
7077 case 0x04: //above_equal
7078 __ sltu(AT, op1, AT);
7079 __ beq_long(AT, R0, *L);
7080 break;
7081 case 0x05: //below
7082 __ sltu(AT, op1, AT);
7083 __ bne_long(R0, AT, *L);
7084 break;
7085 case 0x06: //below_equal
7086 __ sltu(AT, AT, op1);
7087 __ beq_long(AT, R0, *L);
7088 break;
7089 default:
7090 Unimplemented();
7091 }
7092 %}
7094 ins_pc_relative(1);
7095 ins_pipe( pipe_alu_branch );
7096 %}
7098 instruct branchConI_reg_reg_long(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
7099 match( If cmp (CmpI src1 src2) );
7100 effect(USE labl);
7101 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_reg_long" %}
7103 ins_encode %{
7104 Register op1 = $src1$$Register;
7105 Register op2 = $src2$$Register;
7106 Label* L = $labl$$label;
7107 int flag = $cmp$$cmpcode;
7109 switch(flag) {
7110 case 0x01: //equal
7111 __ beq_long(op1, op2, *L);
7112 break;
7113 case 0x02: //not_equal
7114 __ bne_long(op1, op2, *L);
7115 break;
7116 case 0x03: //above
7117 __ slt(AT, op2, op1);
7118 __ bne_long(R0, AT, *L);
7119 break;
7120 case 0x04: //above_equal
7121 __ slt(AT, op1, op2);
7122 __ beq_long(AT, R0, *L);
7123 break;
7124 case 0x05: //below
7125 __ slt(AT, op1, op2);
7126 __ bne_long(R0, AT, *L);
7127 break;
7128 case 0x06: //below_equal
7129 __ slt(AT, op2, op1);
7130 __ beq_long(AT, R0, *L);
7131 break;
7132 default:
7133 Unimplemented();
7134 }
7135 %}
7137 ins_pc_relative(1);
7138 ins_pipe( pipe_alu_branch );
7139 %}
7141 instruct branchConI_reg_imm0_long(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
7142 match( If cmp (CmpI src1 src2) );
7143 effect(USE labl);
7144 ins_cost(170);
7145 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm0_long" %}
7147 ins_encode %{
7148 Register op1 = $src1$$Register;
7149 Label* L = $labl$$label;
7150 int flag = $cmp$$cmpcode;
7152 switch(flag) {
7153 case 0x01: //equal
7154 __ beq_long(op1, R0, *L);
7155 break;
7156 case 0x02: //not_equal
7157 __ bne_long(op1, R0, *L);
7158 break;
7159 case 0x03: //greater
7160 __ slt(AT, R0, op1);
7161 __ bne_long(R0, AT, *L);
7162 break;
7163 case 0x04: //greater_equal
7164 __ slt(AT, op1, R0);
7165 __ beq_long(AT, R0, *L);
7166 break;
7167 case 0x05: //less
7168 __ slt(AT, op1, R0);
7169 __ bne_long(R0, AT, *L);
7170 break;
7171 case 0x06: //less_equal
7172 __ slt(AT, R0, op1);
7173 __ beq_long(AT, R0, *L);
7174 break;
7175 default:
7176 Unimplemented();
7177 }
7178 %}
7180 ins_pc_relative(1);
7181 ins_pipe( pipe_alu_branch );
7182 %}
7184 instruct branchConI_reg_imm_long(cmpOp cmp, mRegI src1, immI src2, label labl) %{
7185 match( If cmp (CmpI src1 src2) );
7186 effect(USE labl);
7187 ins_cost(200);
7188 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm_long" %}
7190 ins_encode %{
7191 Register op1 = $src1$$Register;
7192 int val = $src2$$constant;
7193 Label* L = $labl$$label;
7194 int flag = $cmp$$cmpcode;
7196 __ move(AT, val);
7197 switch(flag) {
7198 case 0x01: //equal
7199 __ beq_long(op1, AT, *L);
7200 break;
7201 case 0x02: //not_equal
7202 __ bne_long(op1, AT, *L);
7203 break;
7204 case 0x03: //greater
7205 __ slt(AT, AT, op1);
7206 __ bne_long(R0, AT, *L);
7207 break;
7208 case 0x04: //greater_equal
7209 __ slt(AT, op1, AT);
7210 __ beq_long(AT, R0, *L);
7211 break;
7212 case 0x05: //less
7213 __ slt(AT, op1, AT);
7214 __ bne_long(R0, AT, *L);
7215 break;
7216 case 0x06: //less_equal
7217 __ slt(AT, AT, op1);
7218 __ beq_long(AT, R0, *L);
7219 break;
7220 default:
7221 Unimplemented();
7222 }
7223 %}
7225 ins_pc_relative(1);
7226 ins_pipe( pipe_alu_branch );
7227 %}
7229 instruct branchConIU_reg_imm0_long(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
7230 match( If cmp (CmpU src1 zero) );
7231 effect(USE labl);
7232 format %{ "BR$cmp $src1, zero, $labl #@branchConIU_reg_imm0_long" %}
7234 ins_encode %{
7235 Register op1 = $src1$$Register;
7236 Label* L = $labl$$label;
7237 int flag = $cmp$$cmpcode;
7239 switch(flag) {
7240 case 0x01: //equal
7241 __ beq_long(op1, R0, *L);
7242 break;
7243 case 0x02: //not_equal
7244 __ bne_long(op1, R0, *L);
7245 break;
7246 case 0x03: //above
7247 __ bne_long(R0, op1, *L);
7248 break;
7249 case 0x04: //above_equal
7250 __ beq_long(R0, R0, *L);
7251 break;
7252 case 0x05: //below
7253 return;
7254 break;
7255 case 0x06: //below_equal
7256 __ beq_long(op1, R0, *L);
7257 break;
7258 default:
7259 Unimplemented();
7260 }
7261 %}
7263 ins_pc_relative(1);
7264 ins_pipe( pipe_alu_branch );
7265 %}
7268 instruct branchConIU_reg_immI16_long(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
7269 match( If cmp (CmpU src1 src2) );
7270 effect(USE labl);
7271 ins_cost(180);
7272 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_immI16_long" %}
7274 ins_encode %{
7275 Register op1 = $src1$$Register;
7276 int val = $src2$$constant;
7277 Label* L = $labl$$label;
7278 int flag = $cmp$$cmpcode;
7280 switch(flag) {
7281 case 0x01: //equal
7282 __ move(AT, val);
7283 __ beq_long(op1, AT, *L);
7284 break;
7285 case 0x02: //not_equal
7286 __ move(AT, val);
7287 __ bne_long(op1, AT, *L);
7288 break;
7289 case 0x03: //above
7290 __ move(AT, val);
7291 __ sltu(AT, AT, op1);
7292 __ bne_long(R0, AT, *L);
7293 break;
7294 case 0x04: //above_equal
7295 __ sltiu(AT, op1, val);
7296 __ beq_long(AT, R0, *L);
7297 break;
7298 case 0x05: //below
7299 __ sltiu(AT, op1, val);
7300 __ bne_long(R0, AT, *L);
7301 break;
7302 case 0x06: //below_equal
7303 __ move(AT, val);
7304 __ sltu(AT, AT, op1);
7305 __ beq_long(AT, R0, *L);
7306 break;
7307 default:
7308 Unimplemented();
7309 }
7310 %}
7312 ins_pc_relative(1);
7313 ins_pipe( pipe_alu_branch );
7314 %}
7317 instruct branchConL_regL_regL_long(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
7318 match( If cmp (CmpL src1 src2) );
7319 effect(USE labl);
7320 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_regL_long" %}
7321 ins_cost(250);
7323 ins_encode %{
7324 Register opr1_reg = as_Register($src1$$reg);
7325 Register opr2_reg = as_Register($src2$$reg);
7327 Label* target = $labl$$label;
7328 int flag = $cmp$$cmpcode;
7330 switch(flag) {
7331 case 0x01: //equal
7332 __ beq_long(opr1_reg, opr2_reg, *target);
7333 break;
7335 case 0x02: //not_equal
7336 __ bne_long(opr1_reg, opr2_reg, *target);
7337 break;
7339 case 0x03: //greater
7340 __ slt(AT, opr2_reg, opr1_reg);
7341 __ bne_long(AT, R0, *target);
7342 break;
7344 case 0x04: //greater_equal
7345 __ slt(AT, opr1_reg, opr2_reg);
7346 __ beq_long(AT, R0, *target);
7347 break;
7349 case 0x05: //less
7350 __ slt(AT, opr1_reg, opr2_reg);
7351 __ bne_long(AT, R0, *target);
7352 break;
7354 case 0x06: //less_equal
7355 __ slt(AT, opr2_reg, opr1_reg);
7356 __ beq_long(AT, R0, *target);
7357 break;
7359 default:
7360 Unimplemented();
7361 }
7362 %}
7365 ins_pc_relative(1);
7366 ins_pipe( pipe_alu_branch );
7367 %}
7369 instruct branchConL_regL_immL0_long(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
7370 match( If cmp (CmpL src1 zero) );
7371 effect(USE labl);
7372 format %{ "BR$cmp $src1, zero, $labl #@branchConL_regL_immL0_long" %}
7373 ins_cost(150);
7375 ins_encode %{
7376 Register opr1_reg = as_Register($src1$$reg);
7377 Register opr2_reg = R0;
7379 Label* target = $labl$$label;
7380 int flag = $cmp$$cmpcode;
7382 switch(flag) {
7383 case 0x01: //equal
7384 __ beq_long(opr1_reg, opr2_reg, *target);
7385 break;
7387 case 0x02: //not_equal
7388 __ bne_long(opr1_reg, opr2_reg, *target);
7389 break;
7391 case 0x03: //greater
7392 __ slt(AT, opr2_reg, opr1_reg);
7393 __ bne_long(AT, R0, *target);
7394 break;
7396 case 0x04: //greater_equal
7397 __ slt(AT, opr1_reg, opr2_reg);
7398 __ beq_long(AT, R0, *target);
7399 break;
7401 case 0x05: //less
7402 __ slt(AT, opr1_reg, opr2_reg);
7403 __ bne_long(AT, R0, *target);
7404 break;
7406 case 0x06: //less_equal
7407 __ slt(AT, opr2_reg, opr1_reg);
7408 __ beq_long(AT, R0, *target);
7409 break;
7411 default:
7412 Unimplemented();
7413 }
7414 %}
7417 ins_pc_relative(1);
7418 ins_pipe( pipe_alu_branch );
7419 %}
7421 instruct branchConL_regL_immL_long(cmpOp cmp, mRegL src1, immL src2, label labl) %{
7422 match( If cmp (CmpL src1 src2) );
7423 effect(USE labl);
7424 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_immL_long" %}
7425 ins_cost(180);
7427 ins_encode %{
7428 Register opr1_reg = as_Register($src1$$reg);
7429 Register opr2_reg = AT;
7431 Label* target = $labl$$label;
7432 int flag = $cmp$$cmpcode;
7434 __ set64(opr2_reg, $src2$$constant);
7436 switch(flag) {
7437 case 0x01: //equal
7438 __ beq_long(opr1_reg, opr2_reg, *target);
7439 break;
7441 case 0x02: //not_equal
7442 __ bne_long(opr1_reg, opr2_reg, *target);
7443 break;
7445 case 0x03: //greater
7446 __ slt(AT, opr2_reg, opr1_reg);
7447 __ bne_long(AT, R0, *target);
7448 break;
7450 case 0x04: //greater_equal
7451 __ slt(AT, opr1_reg, opr2_reg);
7452 __ beq_long(AT, R0, *target);
7453 break;
7455 case 0x05: //less
7456 __ slt(AT, opr1_reg, opr2_reg);
7457 __ bne_long(AT, R0, *target);
7458 break;
7460 case 0x06: //less_equal
7461 __ slt(AT, opr2_reg, opr1_reg);
7462 __ beq_long(AT, R0, *target);
7463 break;
7465 default:
7466 Unimplemented();
7467 }
7468 %}
7471 ins_pc_relative(1);
7472 ins_pipe( pipe_alu_branch );
7473 %}
7476 //FIXME
7477 instruct branchConF_reg_reg_long(cmpOp cmp, regF src1, regF src2, label labl) %{
7478 match( If cmp (CmpF src1 src2) );
7479 effect(USE labl);
7480 format %{ "BR$cmp $src1, $src2, $labl #@branchConF_reg_reg_long" %}
7482 ins_encode %{
7483 FloatRegister reg_op1 = $src1$$FloatRegister;
7484 FloatRegister reg_op2 = $src2$$FloatRegister;
7485 Label* L = $labl$$label;
7486 int flag = $cmp$$cmpcode;
7488 switch(flag) {
7489 case 0x01: //equal
7490 __ c_eq_s(reg_op1, reg_op2);
7491 __ bc1t_long(*L);
7492 break;
7493 case 0x02: //not_equal
7494 __ c_eq_s(reg_op1, reg_op2);
7495 __ bc1f_long(*L);
7496 break;
7497 case 0x03: //greater
7498 __ c_ule_s(reg_op1, reg_op2);
7499 __ bc1f_long(*L);
7500 break;
7501 case 0x04: //greater_equal
7502 __ c_ult_s(reg_op1, reg_op2);
7503 __ bc1f_long(*L);
7504 break;
7505 case 0x05: //less
7506 __ c_ult_s(reg_op1, reg_op2);
7507 __ bc1t_long(*L);
7508 break;
7509 case 0x06: //less_equal
7510 __ c_ule_s(reg_op1, reg_op2);
7511 __ bc1t_long(*L);
7512 break;
7513 default:
7514 Unimplemented();
7515 }
7516 %}
7518 ins_pc_relative(1);
7519 ins_pipe(pipe_slow);
7520 %}
7522 instruct branchConD_reg_reg_long(cmpOp cmp, regD src1, regD src2, label labl) %{
7523 match( If cmp (CmpD src1 src2) );
7524 effect(USE labl);
7525 format %{ "BR$cmp $src1, $src2, $labl #@branchConD_reg_reg_long" %}
7527 ins_encode %{
7528 FloatRegister reg_op1 = $src1$$FloatRegister;
7529 FloatRegister reg_op2 = $src2$$FloatRegister;
7530 Label* L = $labl$$label;
7531 int flag = $cmp$$cmpcode;
7533 switch(flag) {
7534 case 0x01: //equal
7535 __ c_eq_d(reg_op1, reg_op2);
7536 __ bc1t_long(*L);
7537 break;
7538 case 0x02: //not_equal
7539 // c_ueq_d cannot distinguish NaN from equal. Double.isNaN(Double) is implemented by 'f != f', so the use of c_ueq_d causes bugs.
7540 __ c_eq_d(reg_op1, reg_op2);
7541 __ bc1f_long(*L);
7542 break;
7543 case 0x03: //greater
7544 __ c_ule_d(reg_op1, reg_op2);
7545 __ bc1f_long(*L);
7546 break;
7547 case 0x04: //greater_equal
7548 __ c_ult_d(reg_op1, reg_op2);
7549 __ bc1f_long(*L);
7550 break;
7551 case 0x05: //less
7552 __ c_ult_d(reg_op1, reg_op2);
7553 __ bc1t_long(*L);
7554 break;
7555 case 0x06: //less_equal
7556 __ c_ule_d(reg_op1, reg_op2);
7557 __ bc1t_long(*L);
7558 break;
7559 default:
7560 Unimplemented();
7561 }
7562 %}
7564 ins_pc_relative(1);
7565 ins_pipe(pipe_slow);
7566 %}
7569 // ============================================================================
7570 // Branch Instructions -- short offset versions
7572 // Jump Direct
7573 instruct jmpDir_short(label labl) %{
7574 match(Goto);
7575 effect(USE labl);
7577 ins_cost(300);
7578 format %{ "JMP $labl #@jmpDir_short" %}
7580 ins_encode %{
7581 Label &L = *($labl$$label);
7582 if(&L)
7583 __ b(L);
7584 else
7585 __ b(int(0));
7586 __ delayed()->nop();
7587 %}
7589 ins_pipe( pipe_jump );
7590 ins_pc_relative(1);
7591 ins_short_branch(1);
7592 %}
7594 // Jump Direct Conditional - Label defines a relative address from Jcc+1
7595 instruct jmpLoopEnd_short(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
7596 match(CountedLoopEnd cop (CmpI src1 src2));
7597 effect(USE labl);
7599 ins_cost(300);
7600 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_short" %}
7601 ins_encode %{
7602 Register op1 = $src1$$Register;
7603 Register op2 = $src2$$Register;
7604 Label &L = *($labl$$label);
7605 int flag = $cop$$cmpcode;
7607 switch(flag) {
7608 case 0x01: //equal
7609 if (&L)
7610 __ beq(op1, op2, L);
7611 else
7612 __ beq(op1, op2, (int)0);
7613 break;
7614 case 0x02: //not_equal
7615 if (&L)
7616 __ bne(op1, op2, L);
7617 else
7618 __ bne(op1, op2, (int)0);
7619 break;
7620 case 0x03: //above
7621 __ slt(AT, op2, op1);
7622 if(&L)
7623 __ bne(AT, R0, L);
7624 else
7625 __ bne(AT, R0, (int)0);
7626 break;
7627 case 0x04: //above_equal
7628 __ slt(AT, op1, op2);
7629 if(&L)
7630 __ beq(AT, R0, L);
7631 else
7632 __ beq(AT, R0, (int)0);
7633 break;
7634 case 0x05: //below
7635 __ slt(AT, op1, op2);
7636 if(&L)
7637 __ bne(AT, R0, L);
7638 else
7639 __ bne(AT, R0, (int)0);
7640 break;
7641 case 0x06: //below_equal
7642 __ slt(AT, op2, op1);
7643 if(&L)
7644 __ beq(AT, R0, L);
7645 else
7646 __ beq(AT, R0, (int)0);
7647 break;
7648 default:
7649 Unimplemented();
7650 }
7651 __ delayed()->nop();
7652 %}
7653 ins_pipe( pipe_jump );
7654 ins_pc_relative(1);
7655 ins_short_branch(1);
7656 %}
7658 instruct jmpLoopEnd_reg_immI_short(cmpOp cop, mRegI src1, immI src2, label labl) %{
7659 match(CountedLoopEnd cop (CmpI src1 src2));
7660 effect(USE labl);
7662 ins_cost(300);
7663 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_immI_short" %}
7664 ins_encode %{
7665 Register op1 = $src1$$Register;
7666 Register op2 = AT;
7667 Label &L = *($labl$$label);
7668 int flag = $cop$$cmpcode;
7670 __ move(op2, $src2$$constant);
7672 switch(flag) {
7673 case 0x01: //equal
7674 if (&L)
7675 __ beq(op1, op2, L);
7676 else
7677 __ beq(op1, op2, (int)0);
7678 break;
7679 case 0x02: //not_equal
7680 if (&L)
7681 __ bne(op1, op2, L);
7682 else
7683 __ bne(op1, op2, (int)0);
7684 break;
7685 case 0x03: //above
7686 __ slt(AT, op2, op1);
7687 if(&L)
7688 __ bne(AT, R0, L);
7689 else
7690 __ bne(AT, R0, (int)0);
7691 break;
7692 case 0x04: //above_equal
7693 __ slt(AT, op1, op2);
7694 if(&L)
7695 __ beq(AT, R0, L);
7696 else
7697 __ beq(AT, R0, (int)0);
7698 break;
7699 case 0x05: //below
7700 __ slt(AT, op1, op2);
7701 if(&L)
7702 __ bne(AT, R0, L);
7703 else
7704 __ bne(AT, R0, (int)0);
7705 break;
7706 case 0x06: //below_equal
7707 __ slt(AT, op2, op1);
7708 if(&L)
7709 __ beq(AT, R0, L);
7710 else
7711 __ beq(AT, R0, (int)0);
7712 break;
7713 default:
7714 Unimplemented();
7715 }
7716 __ delayed()->nop();
7717 %}
7718 ins_pipe( pipe_jump );
7719 ins_pc_relative(1);
7720 ins_short_branch(1);
7721 %}
7724 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
7725 instruct jmpCon_flags_short(cmpOp cop, FlagsReg cr, label labl) %{
7726 match(If cop cr);
7727 effect(USE labl);
7729 ins_cost(300);
7730 format %{ "J$cop $labl #mips uses AT as eflag @jmpCon_flags_short" %}
7732 ins_encode %{
7733 Label &L = *($labl$$label);
7734 switch($cop$$cmpcode) {
7735 case 0x01: //equal
7736 if (&L)
7737 __ bne(AT, R0, L);
7738 else
7739 __ bne(AT, R0, (int)0);
7740 break;
7741 case 0x02: //not equal
7742 if (&L)
7743 __ beq(AT, R0, L);
7744 else
7745 __ beq(AT, R0, (int)0);
7746 break;
7747 default:
7748 Unimplemented();
7749 }
7750 __ delayed()->nop();
7751 %}
7753 ins_pipe( pipe_jump );
7754 ins_pc_relative(1);
7755 ins_short_branch(1);
7756 %}
7758 // Conditional jumps
7759 instruct branchConP_zero_short(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
7760 match(If cmp (CmpP op1 zero));
7761 effect(USE labl);
7763 ins_cost(180);
7764 format %{ "b$cmp $op1, R0, $labl #@branchConP_zero_short" %}
7766 ins_encode %{
7767 Register op1 = $op1$$Register;
7768 Register op2 = R0;
7769 Label &L = *($labl$$label);
7770 int flag = $cmp$$cmpcode;
7772 switch(flag) {
7773 case 0x01: //equal
7774 if (&L)
7775 __ beq(op1, op2, L);
7776 else
7777 __ beq(op1, op2, (int)0);
7778 break;
7779 case 0x02: //not_equal
7780 if (&L)
7781 __ bne(op1, op2, L);
7782 else
7783 __ bne(op1, op2, (int)0);
7784 break;
7785 default:
7786 Unimplemented();
7787 }
7788 __ delayed()->nop();
7789 %}
7791 ins_pc_relative(1);
7792 ins_pipe( pipe_alu_branch );
7793 ins_short_branch(1);
7794 %}
7796 instruct branchConN2P_zero_short(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
7797 match(If cmp (CmpP (DecodeN op1) zero));
7798 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
7799 effect(USE labl);
7801 ins_cost(180);
7802 format %{ "b$cmp $op1, R0, $labl #@branchConN2P_zero_short" %}
7804 ins_encode %{
7805 Register op1 = $op1$$Register;
7806 Register op2 = R0;
7807 Label &L = *($labl$$label);
7808 int flag = $cmp$$cmpcode;
7810 switch(flag)
7811 {
7812 case 0x01: //equal
7813 if (&L)
7814 __ beq(op1, op2, L);
7815 else
7816 __ beq(op1, op2, (int)0);
7817 break;
7818 case 0x02: //not_equal
7819 if (&L)
7820 __ bne(op1, op2, L);
7821 else
7822 __ bne(op1, op2, (int)0);
7823 break;
7824 default:
7825 Unimplemented();
7826 }
7827 __ delayed()->nop();
7828 %}
7830 ins_pc_relative(1);
7831 ins_pipe( pipe_alu_branch );
7832 ins_short_branch(1);
7833 %}
7836 instruct branchConP_short(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
7837 match(If cmp (CmpP op1 op2));
7838 // predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
7839 effect(USE labl);
7841 ins_cost(200);
7842 format %{ "b$cmp $op1, $op2, $labl #@branchConP_short" %}
7844 ins_encode %{
7845 Register op1 = $op1$$Register;
7846 Register op2 = $op2$$Register;
7847 Label &L = *($labl$$label);
7848 int flag = $cmp$$cmpcode;
7850 switch(flag) {
7851 case 0x01: //equal
7852 if (&L)
7853 __ beq(op1, op2, L);
7854 else
7855 __ beq(op1, op2, (int)0);
7856 break;
7857 case 0x02: //not_equal
7858 if (&L)
7859 __ bne(op1, op2, L);
7860 else
7861 __ bne(op1, op2, (int)0);
7862 break;
7863 case 0x03: //above
7864 __ sltu(AT, op2, op1);
7865 if(&L)
7866 __ bne(R0, AT, L);
7867 else
7868 __ bne(R0, AT, (int)0);
7869 break;
7870 case 0x04: //above_equal
7871 __ sltu(AT, op1, op2);
7872 if(&L)
7873 __ beq(AT, R0, L);
7874 else
7875 __ beq(AT, R0, (int)0);
7876 break;
7877 case 0x05: //below
7878 __ sltu(AT, op1, op2);
7879 if(&L)
7880 __ bne(R0, AT, L);
7881 else
7882 __ bne(R0, AT, (int)0);
7883 break;
7884 case 0x06: //below_equal
7885 __ sltu(AT, op2, op1);
7886 if(&L)
7887 __ beq(AT, R0, L);
7888 else
7889 __ beq(AT, R0, (int)0);
7890 break;
7891 default:
7892 Unimplemented();
7893 }
7894 __ delayed()->nop();
7895 %}
7897 ins_pc_relative(1);
7898 ins_pipe( pipe_alu_branch );
7899 ins_short_branch(1);
7900 %}
7902 instruct cmpN_null_branch_short(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
7903 match(If cmp (CmpN op1 null));
7904 effect(USE labl);
7906 ins_cost(180);
7907 format %{ "CMP $op1,0\t! compressed ptr\n\t"
7908 "BP$cmp $labl @ cmpN_null_branch_short" %}
7909 ins_encode %{
7910 Register op1 = $op1$$Register;
7911 Register op2 = R0;
7912 Label &L = *($labl$$label);
7913 int flag = $cmp$$cmpcode;
7915 switch(flag) {
7916 case 0x01: //equal
7917 if (&L)
7918 __ beq(op1, op2, L);
7919 else
7920 __ beq(op1, op2, (int)0);
7921 break;
7922 case 0x02: //not_equal
7923 if (&L)
7924 __ bne(op1, op2, L);
7925 else
7926 __ bne(op1, op2, (int)0);
7927 break;
7928 default:
7929 Unimplemented();
7930 }
7931 __ delayed()->nop();
7932 %}
7933 //TODO: pipe_branchP or create pipe_branchN LEE
7934 ins_pc_relative(1);
7935 ins_pipe( pipe_alu_branch );
7936 ins_short_branch(1);
7937 %}
7939 instruct cmpN_reg_branch_short(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
7940 match(If cmp (CmpN op1 op2));
7941 effect(USE labl);
7943 ins_cost(180);
7944 format %{ "CMP $op1,$op2\t! compressed ptr\n\t"
7945 "BP$cmp $labl @ cmpN_reg_branch_short" %}
7946 ins_encode %{
7947 Register op1_reg = $op1$$Register;
7948 Register op2_reg = $op2$$Register;
7949 Label &L = *($labl$$label);
7950 int flag = $cmp$$cmpcode;
7952 switch(flag) {
7953 case 0x01: //equal
7954 if (&L)
7955 __ beq(op1_reg, op2_reg, L);
7956 else
7957 __ beq(op1_reg, op2_reg, (int)0);
7958 break;
7959 case 0x02: //not_equal
7960 if (&L)
7961 __ bne(op1_reg, op2_reg, L);
7962 else
7963 __ bne(op1_reg, op2_reg, (int)0);
7964 break;
7965 case 0x03: //above
7966 __ sltu(AT, op2_reg, op1_reg);
7967 if(&L)
7968 __ bne(R0, AT, L);
7969 else
7970 __ bne(R0, AT, (int)0);
7971 break;
7972 case 0x04: //above_equal
7973 __ sltu(AT, op1_reg, op2_reg);
7974 if(&L)
7975 __ beq(AT, R0, L);
7976 else
7977 __ beq(AT, R0, (int)0);
7978 break;
7979 case 0x05: //below
7980 __ sltu(AT, op1_reg, op2_reg);
7981 if(&L)
7982 __ bne(R0, AT, L);
7983 else
7984 __ bne(R0, AT, (int)0);
7985 break;
7986 case 0x06: //below_equal
7987 __ sltu(AT, op2_reg, op1_reg);
7988 if(&L)
7989 __ beq(AT, R0, L);
7990 else
7991 __ beq(AT, R0, (int)0);
7992 break;
7993 default:
7994 Unimplemented();
7995 }
7996 __ delayed()->nop();
7997 %}
7998 ins_pc_relative(1);
7999 ins_pipe( pipe_alu_branch );
8000 ins_short_branch(1);
8001 %}
8003 instruct branchConIU_reg_reg_short(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
8004 match( If cmp (CmpU src1 src2) );
8005 effect(USE labl);
8006 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_reg_short" %}
8008 ins_encode %{
8009 Register op1 = $src1$$Register;
8010 Register op2 = $src2$$Register;
8011 Label &L = *($labl$$label);
8012 int flag = $cmp$$cmpcode;
8014 switch(flag) {
8015 case 0x01: //equal
8016 if (&L)
8017 __ beq(op1, op2, L);
8018 else
8019 __ beq(op1, op2, (int)0);
8020 break;
8021 case 0x02: //not_equal
8022 if (&L)
8023 __ bne(op1, op2, L);
8024 else
8025 __ bne(op1, op2, (int)0);
8026 break;
8027 case 0x03: //above
8028 __ sltu(AT, op2, op1);
8029 if(&L)
8030 __ bne(AT, R0, L);
8031 else
8032 __ bne(AT, R0, (int)0);
8033 break;
8034 case 0x04: //above_equal
8035 __ sltu(AT, op1, op2);
8036 if(&L)
8037 __ beq(AT, R0, L);
8038 else
8039 __ beq(AT, R0, (int)0);
8040 break;
8041 case 0x05: //below
8042 __ sltu(AT, op1, op2);
8043 if(&L)
8044 __ bne(AT, R0, L);
8045 else
8046 __ bne(AT, R0, (int)0);
8047 break;
8048 case 0x06: //below_equal
8049 __ sltu(AT, op2, op1);
8050 if(&L)
8051 __ beq(AT, R0, L);
8052 else
8053 __ beq(AT, R0, (int)0);
8054 break;
8055 default:
8056 Unimplemented();
8057 }
8058 __ delayed()->nop();
8059 %}
8061 ins_pc_relative(1);
8062 ins_pipe( pipe_alu_branch );
8063 ins_short_branch(1);
8064 %}
8067 instruct branchConIU_reg_imm_short(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
8068 match( If cmp (CmpU src1 src2) );
8069 effect(USE labl);
8070 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_imm_short" %}
8072 ins_encode %{
8073 Register op1 = $src1$$Register;
8074 int val = $src2$$constant;
8075 Label &L = *($labl$$label);
8076 int flag = $cmp$$cmpcode;
8078 __ move(AT, val);
8079 switch(flag) {
8080 case 0x01: //equal
8081 if (&L)
8082 __ beq(op1, AT, L);
8083 else
8084 __ beq(op1, AT, (int)0);
8085 break;
8086 case 0x02: //not_equal
8087 if (&L)
8088 __ bne(op1, AT, L);
8089 else
8090 __ bne(op1, AT, (int)0);
8091 break;
8092 case 0x03: //above
8093 __ sltu(AT, AT, op1);
8094 if(&L)
8095 __ bne(R0, AT, L);
8096 else
8097 __ bne(R0, AT, (int)0);
8098 break;
8099 case 0x04: //above_equal
8100 __ sltu(AT, op1, AT);
8101 if(&L)
8102 __ beq(AT, R0, L);
8103 else
8104 __ beq(AT, R0, (int)0);
8105 break;
8106 case 0x05: //below
8107 __ sltu(AT, op1, AT);
8108 if(&L)
8109 __ bne(R0, AT, L);
8110 else
8111 __ bne(R0, AT, (int)0);
8112 break;
8113 case 0x06: //below_equal
8114 __ sltu(AT, AT, op1);
8115 if(&L)
8116 __ beq(AT, R0, L);
8117 else
8118 __ beq(AT, R0, (int)0);
8119 break;
8120 default:
8121 Unimplemented();
8122 }
8123 __ delayed()->nop();
8124 %}
8126 ins_pc_relative(1);
8127 ins_pipe( pipe_alu_branch );
8128 ins_short_branch(1);
8129 %}
8131 instruct branchConI_reg_reg_short(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
8132 match( If cmp (CmpI src1 src2) );
8133 effect(USE labl);
8134 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_reg_short" %}
8136 ins_encode %{
8137 Register op1 = $src1$$Register;
8138 Register op2 = $src2$$Register;
8139 Label &L = *($labl$$label);
8140 int flag = $cmp$$cmpcode;
8142 switch(flag) {
8143 case 0x01: //equal
8144 if (&L)
8145 __ beq(op1, op2, L);
8146 else
8147 __ beq(op1, op2, (int)0);
8148 break;
8149 case 0x02: //not_equal
8150 if (&L)
8151 __ bne(op1, op2, L);
8152 else
8153 __ bne(op1, op2, (int)0);
8154 break;
8155 case 0x03: //above
8156 __ slt(AT, op2, op1);
8157 if(&L)
8158 __ bne(R0, AT, L);
8159 else
8160 __ bne(R0, AT, (int)0);
8161 break;
8162 case 0x04: //above_equal
8163 __ slt(AT, op1, op2);
8164 if(&L)
8165 __ beq(AT, R0, L);
8166 else
8167 __ beq(AT, R0, (int)0);
8168 break;
8169 case 0x05: //below
8170 __ slt(AT, op1, op2);
8171 if(&L)
8172 __ bne(R0, AT, L);
8173 else
8174 __ bne(R0, AT, (int)0);
8175 break;
8176 case 0x06: //below_equal
8177 __ slt(AT, op2, op1);
8178 if(&L)
8179 __ beq(AT, R0, L);
8180 else
8181 __ beq(AT, R0, (int)0);
8182 break;
8183 default:
8184 Unimplemented();
8185 }
8186 __ delayed()->nop();
8187 %}
8189 ins_pc_relative(1);
8190 ins_pipe( pipe_alu_branch );
8191 ins_short_branch(1);
8192 %}
8194 instruct branchConI_reg_imm0_short(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
8195 match( If cmp (CmpI src1 src2) );
8196 effect(USE labl);
8197 ins_cost(170);
8198 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm0_short" %}
8200 ins_encode %{
8201 Register op1 = $src1$$Register;
8202 Label &L = *($labl$$label);
8203 int flag = $cmp$$cmpcode;
8205 switch(flag) {
8206 case 0x01: //equal
8207 if (&L)
8208 __ beq(op1, R0, L);
8209 else
8210 __ beq(op1, R0, (int)0);
8211 break;
8212 case 0x02: //not_equal
8213 if (&L)
8214 __ bne(op1, R0, L);
8215 else
8216 __ bne(op1, R0, (int)0);
8217 break;
8218 case 0x03: //greater
8219 if(&L)
8220 __ bgtz(op1, L);
8221 else
8222 __ bgtz(op1, (int)0);
8223 break;
8224 case 0x04: //greater_equal
8225 if(&L)
8226 __ bgez(op1, L);
8227 else
8228 __ bgez(op1, (int)0);
8229 break;
8230 case 0x05: //less
8231 if(&L)
8232 __ bltz(op1, L);
8233 else
8234 __ bltz(op1, (int)0);
8235 break;
8236 case 0x06: //less_equal
8237 if(&L)
8238 __ blez(op1, L);
8239 else
8240 __ blez(op1, (int)0);
8241 break;
8242 default:
8243 Unimplemented();
8244 }
8245 __ delayed()->nop();
8246 %}
8248 ins_pc_relative(1);
8249 ins_pipe( pipe_alu_branch );
8250 ins_short_branch(1);
8251 %}
8254 instruct branchConI_reg_imm_short(cmpOp cmp, mRegI src1, immI src2, label labl) %{
8255 match( If cmp (CmpI src1 src2) );
8256 effect(USE labl);
8257 ins_cost(200);
8258 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm_short" %}
8260 ins_encode %{
8261 Register op1 = $src1$$Register;
8262 int val = $src2$$constant;
8263 Label &L = *($labl$$label);
8264 int flag = $cmp$$cmpcode;
8266 __ move(AT, val);
8267 switch(flag) {
8268 case 0x01: //equal
8269 if (&L)
8270 __ beq(op1, AT, L);
8271 else
8272 __ beq(op1, AT, (int)0);
8273 break;
8274 case 0x02: //not_equal
8275 if (&L)
8276 __ bne(op1, AT, L);
8277 else
8278 __ bne(op1, AT, (int)0);
8279 break;
8280 case 0x03: //greater
8281 __ slt(AT, AT, op1);
8282 if(&L)
8283 __ bne(R0, AT, L);
8284 else
8285 __ bne(R0, AT, (int)0);
8286 break;
8287 case 0x04: //greater_equal
8288 __ slt(AT, op1, AT);
8289 if(&L)
8290 __ beq(AT, R0, L);
8291 else
8292 __ beq(AT, R0, (int)0);
8293 break;
8294 case 0x05: //less
8295 __ slt(AT, op1, AT);
8296 if(&L)
8297 __ bne(R0, AT, L);
8298 else
8299 __ bne(R0, AT, (int)0);
8300 break;
8301 case 0x06: //less_equal
8302 __ slt(AT, AT, op1);
8303 if(&L)
8304 __ beq(AT, R0, L);
8305 else
8306 __ beq(AT, R0, (int)0);
8307 break;
8308 default:
8309 Unimplemented();
8310 }
8311 __ delayed()->nop();
8312 %}
8314 ins_pc_relative(1);
8315 ins_pipe( pipe_alu_branch );
8316 ins_short_branch(1);
8317 %}
8319 instruct branchConIU_reg_imm0_short(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
8320 match( If cmp (CmpU src1 zero) );
8321 effect(USE labl);
8322 format %{ "BR$cmp $src1, zero, $labl #@branchConIU_reg_imm0_short" %}
8324 ins_encode %{
8325 Register op1 = $src1$$Register;
8326 Label &L = *($labl$$label);
8327 int flag = $cmp$$cmpcode;
8329 switch(flag) {
8330 case 0x01: //equal
8331 if (&L)
8332 __ beq(op1, R0, L);
8333 else
8334 __ beq(op1, R0, (int)0);
8335 break;
8336 case 0x02: //not_equal
8337 if (&L)
8338 __ bne(op1, R0, L);
8339 else
8340 __ bne(op1, R0, (int)0);
8341 break;
8342 case 0x03: //above
8343 if(&L)
8344 __ bne(R0, op1, L);
8345 else
8346 __ bne(R0, op1, (int)0);
8347 break;
8348 case 0x04: //above_equal
8349 if(&L)
8350 __ beq(R0, R0, L);
8351 else
8352 __ beq(R0, R0, (int)0);
8353 break;
8354 case 0x05: //below
8355 return;
8356 break;
8357 case 0x06: //below_equal
8358 if(&L)
8359 __ beq(op1, R0, L);
8360 else
8361 __ beq(op1, R0, (int)0);
8362 break;
8363 default:
8364 Unimplemented();
8365 }
8366 __ delayed()->nop();
8367 %}
8369 ins_pc_relative(1);
8370 ins_pipe( pipe_alu_branch );
8371 ins_short_branch(1);
8372 %}
8375 instruct branchConIU_reg_immI16_short(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
8376 match( If cmp (CmpU src1 src2) );
8377 effect(USE labl);
8378 ins_cost(180);
8379 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_immI16_short" %}
8381 ins_encode %{
8382 Register op1 = $src1$$Register;
8383 int val = $src2$$constant;
8384 Label &L = *($labl$$label);
8385 int flag = $cmp$$cmpcode;
8387 switch(flag) {
8388 case 0x01: //equal
8389 __ move(AT, val);
8390 if (&L)
8391 __ beq(op1, AT, L);
8392 else
8393 __ beq(op1, AT, (int)0);
8394 break;
8395 case 0x02: //not_equal
8396 __ move(AT, val);
8397 if (&L)
8398 __ bne(op1, AT, L);
8399 else
8400 __ bne(op1, AT, (int)0);
8401 break;
8402 case 0x03: //above
8403 __ move(AT, val);
8404 __ sltu(AT, AT, op1);
8405 if(&L)
8406 __ bne(R0, AT, L);
8407 else
8408 __ bne(R0, AT, (int)0);
8409 break;
8410 case 0x04: //above_equal
8411 __ sltiu(AT, op1, val);
8412 if(&L)
8413 __ beq(AT, R0, L);
8414 else
8415 __ beq(AT, R0, (int)0);
8416 break;
8417 case 0x05: //below
8418 __ sltiu(AT, op1, val);
8419 if(&L)
8420 __ bne(R0, AT, L);
8421 else
8422 __ bne(R0, AT, (int)0);
8423 break;
8424 case 0x06: //below_equal
8425 __ move(AT, val);
8426 __ sltu(AT, AT, op1);
8427 if(&L)
8428 __ beq(AT, R0, L);
8429 else
8430 __ beq(AT, R0, (int)0);
8431 break;
8432 default:
8433 Unimplemented();
8434 }
8435 __ delayed()->nop();
8436 %}
8438 ins_pc_relative(1);
8439 ins_pipe( pipe_alu_branch );
8440 ins_short_branch(1);
8441 %}
8444 instruct branchConL_regL_regL_short(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
8445 match( If cmp (CmpL src1 src2) );
8446 effect(USE labl);
8447 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_regL_short" %}
8448 ins_cost(250);
8450 ins_encode %{
8451 Register opr1_reg = as_Register($src1$$reg);
8452 Register opr2_reg = as_Register($src2$$reg);
8454 Label &target = *($labl$$label);
8455 int flag = $cmp$$cmpcode;
8457 switch(flag) {
8458 case 0x01: //equal
8459 if (&target)
8460 __ beq(opr1_reg, opr2_reg, target);
8461 else
8462 __ beq(opr1_reg, opr2_reg, (int)0);
8463 __ delayed()->nop();
8464 break;
8466 case 0x02: //not_equal
8467 if(&target)
8468 __ bne(opr1_reg, opr2_reg, target);
8469 else
8470 __ bne(opr1_reg, opr2_reg, (int)0);
8471 __ delayed()->nop();
8472 break;
8474 case 0x03: //greater
8475 __ slt(AT, opr2_reg, opr1_reg);
8476 if(&target)
8477 __ bne(AT, R0, target);
8478 else
8479 __ bne(AT, R0, (int)0);
8480 __ delayed()->nop();
8481 break;
8483 case 0x04: //greater_equal
8484 __ slt(AT, opr1_reg, opr2_reg);
8485 if(&target)
8486 __ beq(AT, R0, target);
8487 else
8488 __ beq(AT, R0, (int)0);
8489 __ delayed()->nop();
8491 break;
8493 case 0x05: //less
8494 __ slt(AT, opr1_reg, opr2_reg);
8495 if(&target)
8496 __ bne(AT, R0, target);
8497 else
8498 __ bne(AT, R0, (int)0);
8499 __ delayed()->nop();
8501 break;
8503 case 0x06: //less_equal
8504 __ slt(AT, opr2_reg, opr1_reg);
8506 if(&target)
8507 __ beq(AT, R0, target);
8508 else
8509 __ beq(AT, R0, (int)0);
8510 __ delayed()->nop();
8512 break;
8514 default:
8515 Unimplemented();
8516 }
8517 %}
8520 ins_pc_relative(1);
8521 ins_pipe( pipe_alu_branch );
8522 ins_short_branch(1);
8523 %}
8526 instruct branchConL_regL_immL0_short(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
8527 match( If cmp (CmpL src1 zero) );
8528 effect(USE labl);
8529 format %{ "BR$cmp $src1, zero, $labl #@branchConL_regL_immL0_short" %}
8530 ins_cost(150);
8532 ins_encode %{
8533 Register opr1_reg = as_Register($src1$$reg);
8534 Label &target = *($labl$$label);
8535 int flag = $cmp$$cmpcode;
8537 switch(flag) {
8538 case 0x01: //equal
8539 if (&target)
8540 __ beq(opr1_reg, R0, target);
8541 else
8542 __ beq(opr1_reg, R0, int(0));
8543 break;
8545 case 0x02: //not_equal
8546 if(&target)
8547 __ bne(opr1_reg, R0, target);
8548 else
8549 __ bne(opr1_reg, R0, (int)0);
8550 break;
8552 case 0x03: //greater
8553 if(&target)
8554 __ bgtz(opr1_reg, target);
8555 else
8556 __ bgtz(opr1_reg, (int)0);
8557 break;
8559 case 0x04: //greater_equal
8560 if(&target)
8561 __ bgez(opr1_reg, target);
8562 else
8563 __ bgez(opr1_reg, (int)0);
8564 break;
8566 case 0x05: //less
8567 __ slt(AT, opr1_reg, R0);
8568 if(&target)
8569 __ bne(AT, R0, target);
8570 else
8571 __ bne(AT, R0, (int)0);
8572 break;
8574 case 0x06: //less_equal
8575 if (&target)
8576 __ blez(opr1_reg, target);
8577 else
8578 __ blez(opr1_reg, int(0));
8579 break;
8581 default:
8582 Unimplemented();
8583 }
8584 __ delayed()->nop();
8585 %}
8588 ins_pc_relative(1);
8589 ins_pipe( pipe_alu_branch );
8590 ins_short_branch(1);
8591 %}
8593 instruct branchConL_regL_immL_short(cmpOp cmp, mRegL src1, immL src2, label labl) %{
8594 match( If cmp (CmpL src1 src2) );
8595 effect(USE labl);
8596 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_immL_short" %}
8597 ins_cost(180);
8599 ins_encode %{
8600 Register opr1_reg = as_Register($src1$$reg);
8601 Register opr2_reg = AT;
8603 Label &target = *($labl$$label);
8604 int flag = $cmp$$cmpcode;
8606 __ set64(opr2_reg, $src2$$constant);
8608 switch(flag) {
8609 case 0x01: //equal
8610 if (&target)
8611 __ beq(opr1_reg, opr2_reg, target);
8612 else
8613 __ beq(opr1_reg, opr2_reg, (int)0);
8614 break;
8616 case 0x02: //not_equal
8617 if(&target)
8618 __ bne(opr1_reg, opr2_reg, target);
8619 else
8620 __ bne(opr1_reg, opr2_reg, (int)0);
8621 break;
8623 case 0x03: //greater
8624 __ slt(AT, opr2_reg, opr1_reg);
8625 if(&target)
8626 __ bne(AT, R0, target);
8627 else
8628 __ bne(AT, R0, (int)0);
8629 break;
8631 case 0x04: //greater_equal
8632 __ slt(AT, opr1_reg, opr2_reg);
8633 if(&target)
8634 __ beq(AT, R0, target);
8635 else
8636 __ beq(AT, R0, (int)0);
8637 break;
8639 case 0x05: //less
8640 __ slt(AT, opr1_reg, opr2_reg);
8641 if(&target)
8642 __ bne(AT, R0, target);
8643 else
8644 __ bne(AT, R0, (int)0);
8645 break;
8647 case 0x06: //less_equal
8648 __ slt(AT, opr2_reg, opr1_reg);
8649 if(&target)
8650 __ beq(AT, R0, target);
8651 else
8652 __ beq(AT, R0, (int)0);
8653 break;
8655 default:
8656 Unimplemented();
8657 }
8658 __ delayed()->nop();
8659 %}
8662 ins_pc_relative(1);
8663 ins_pipe( pipe_alu_branch );
8664 ins_short_branch(1);
8665 %}
8668 //FIXME
8669 instruct branchConF_reg_reg_short(cmpOp cmp, regF src1, regF src2, label labl) %{
8670 match( If cmp (CmpF src1 src2) );
8671 effect(USE labl);
8672 format %{ "BR$cmp $src1, $src2, $labl #@branchConF_reg_reg_short" %}
8674 ins_encode %{
8675 FloatRegister reg_op1 = $src1$$FloatRegister;
8676 FloatRegister reg_op2 = $src2$$FloatRegister;
8677 Label &L = *($labl$$label);
8678 int flag = $cmp$$cmpcode;
8680 switch(flag) {
8681 case 0x01: //equal
8682 __ c_eq_s(reg_op1, reg_op2);
8683 if (&L)
8684 __ bc1t(L);
8685 else
8686 __ bc1t((int)0);
8687 break;
8688 case 0x02: //not_equal
8689 __ c_eq_s(reg_op1, reg_op2);
8690 if (&L)
8691 __ bc1f(L);
8692 else
8693 __ bc1f((int)0);
8694 break;
8695 case 0x03: //greater
8696 __ c_ule_s(reg_op1, reg_op2);
8697 if(&L)
8698 __ bc1f(L);
8699 else
8700 __ bc1f((int)0);
8701 break;
8702 case 0x04: //greater_equal
8703 __ c_ult_s(reg_op1, reg_op2);
8704 if(&L)
8705 __ bc1f(L);
8706 else
8707 __ bc1f((int)0);
8708 break;
8709 case 0x05: //less
8710 __ c_ult_s(reg_op1, reg_op2);
8711 if(&L)
8712 __ bc1t(L);
8713 else
8714 __ bc1t((int)0);
8715 break;
8716 case 0x06: //less_equal
8717 __ c_ule_s(reg_op1, reg_op2);
8718 if(&L)
8719 __ bc1t(L);
8720 else
8721 __ bc1t((int)0);
8722 break;
8723 default:
8724 Unimplemented();
8725 }
8726 __ delayed()->nop();
8727 %}
8729 ins_pc_relative(1);
8730 ins_pipe(pipe_slow);
8731 ins_short_branch(1);
8732 %}
8734 instruct branchConD_reg_reg_short(cmpOp cmp, regD src1, regD src2, label labl) %{
8735 match( If cmp (CmpD src1 src2) );
8736 effect(USE labl);
8737 format %{ "BR$cmp $src1, $src2, $labl #@branchConD_reg_reg_short" %}
8739 ins_encode %{
8740 FloatRegister reg_op1 = $src1$$FloatRegister;
8741 FloatRegister reg_op2 = $src2$$FloatRegister;
8742 Label &L = *($labl$$label);
8743 int flag = $cmp$$cmpcode;
8745 switch(flag) {
8746 case 0x01: //equal
8747 __ c_eq_d(reg_op1, reg_op2);
8748 if (&L)
8749 __ bc1t(L);
8750 else
8751 __ bc1t((int)0);
8752 break;
8753 case 0x02: //not_equal
8754 // c_ueq_d cannot distinguish NaN from equal. Double.isNaN(Double) is implemented by 'f != f', so the use of c_ueq_d causes bugs.
8755 __ c_eq_d(reg_op1, reg_op2);
8756 if (&L)
8757 __ bc1f(L);
8758 else
8759 __ bc1f((int)0);
8760 break;
8761 case 0x03: //greater
8762 __ c_ule_d(reg_op1, reg_op2);
8763 if(&L)
8764 __ bc1f(L);
8765 else
8766 __ bc1f((int)0);
8767 break;
8768 case 0x04: //greater_equal
8769 __ c_ult_d(reg_op1, reg_op2);
8770 if(&L)
8771 __ bc1f(L);
8772 else
8773 __ bc1f((int)0);
8774 break;
8775 case 0x05: //less
8776 __ c_ult_d(reg_op1, reg_op2);
8777 if(&L)
8778 __ bc1t(L);
8779 else
8780 __ bc1t((int)0);
8781 break;
8782 case 0x06: //less_equal
8783 __ c_ule_d(reg_op1, reg_op2);
8784 if(&L)
8785 __ bc1t(L);
8786 else
8787 __ bc1t((int)0);
8788 break;
8789 default:
8790 Unimplemented();
8791 }
8792 __ delayed()->nop();
8793 %}
8795 ins_pc_relative(1);
8796 ins_pipe(pipe_slow);
8797 ins_short_branch(1);
8798 %}
8800 // =================== End of branch instructions ==========================
8802 // Call Runtime Instruction
8803 instruct CallRuntimeDirect(method meth) %{
8804 match(CallRuntime );
8805 effect(USE meth);
8807 ins_cost(300);
8808 format %{ "CALL,runtime #@CallRuntimeDirect" %}
8809 ins_encode( Java_To_Runtime( meth ) );
8810 ins_pipe( pipe_slow );
8811 ins_alignment(16);
8812 %}
8816 //------------------------MemBar Instructions-------------------------------
8817 //Memory barrier flavors
8819 instruct membar_acquire() %{
8820 match(MemBarAcquire);
8821 ins_cost(400);
8823 format %{ "MEMBAR-acquire @ membar_acquire" %}
8824 ins_encode %{
8825 __ sync();
8826 %}
8827 ins_pipe(empty);
8828 %}
8830 instruct load_fence() %{
8831 match(LoadFence);
8832 ins_cost(400);
8834 format %{ "MEMBAR @ load_fence" %}
8835 ins_encode %{
8836 __ sync();
8837 %}
8838 ins_pipe(pipe_slow);
8839 %}
8841 instruct membar_acquire_lock()
8842 %{
8843 match(MemBarAcquireLock);
8844 ins_cost(0);
8846 size(0);
8847 format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
8848 ins_encode();
8849 ins_pipe(empty);
8850 %}
8852 instruct membar_release() %{
8853 match(MemBarRelease);
8854 ins_cost(400);
8856 format %{ "MEMBAR-release @ membar_release" %}
8858 ins_encode %{
8859 // Attention: DO NOT DELETE THIS GUY!
8860 __ sync();
8861 %}
8863 ins_pipe(pipe_slow);
8864 %}
8866 instruct store_fence() %{
8867 match(StoreFence);
8868 ins_cost(400);
8870 format %{ "MEMBAR @ store_fence" %}
8872 ins_encode %{
8873 __ sync();
8874 %}
8876 ins_pipe(pipe_slow);
8877 %}
8879 instruct membar_release_lock()
8880 %{
8881 match(MemBarReleaseLock);
8882 ins_cost(0);
8884 size(0);
8885 format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
8886 ins_encode();
8887 ins_pipe(empty);
8888 %}
8891 instruct membar_volatile() %{
8892 match(MemBarVolatile);
8893 ins_cost(400);
8895 format %{ "MEMBAR-volatile" %}
8896 ins_encode %{
8897 if( !os::is_MP() ) return; // Not needed on single CPU
8898 __ sync();
8900 %}
8901 ins_pipe(pipe_slow);
8902 %}
8904 instruct unnecessary_membar_volatile() %{
8905 match(MemBarVolatile);
8906 predicate(Matcher::post_store_load_barrier(n));
8907 ins_cost(0);
8909 size(0);
8910 format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
8911 ins_encode( );
8912 ins_pipe(empty);
8913 %}
8915 instruct membar_storestore() %{
8916 match(MemBarStoreStore);
8918 ins_cost(400);
8919 format %{ "MEMBAR-storestore @ membar_storestore" %}
8920 ins_encode %{
8921 __ sync();
8922 %}
8923 ins_pipe(empty);
8924 %}
8926 //----------Move Instructions--------------------------------------------------
8927 instruct castX2P(mRegP dst, mRegL src) %{
8928 match(Set dst (CastX2P src));
8929 format %{ "castX2P $dst, $src @ castX2P" %}
8930 ins_encode %{
8931 Register src = $src$$Register;
8932 Register dst = $dst$$Register;
8934 if(src != dst)
8935 __ move(dst, src);
8936 %}
8937 ins_cost(10);
8938 ins_pipe( ialu_regI_mov );
8939 %}
8941 instruct castP2X(mRegL dst, mRegP src ) %{
8942 match(Set dst (CastP2X src));
8944 format %{ "mov $dst, $src\t #@castP2X" %}
8945 ins_encode %{
8946 Register src = $src$$Register;
8947 Register dst = $dst$$Register;
8949 if(src != dst)
8950 __ move(dst, src);
8951 %}
8952 ins_pipe( ialu_regI_mov );
8953 %}
8955 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
8956 match(Set dst (MoveF2I src));
8957 effect(DEF dst, USE src);
8958 ins_cost(85);
8959 format %{ "MoveF2I $dst, $src @ MoveF2I_reg_reg" %}
8960 ins_encode %{
8961 Register dst = as_Register($dst$$reg);
8962 FloatRegister src = as_FloatRegister($src$$reg);
8964 __ mfc1(dst, src);
8965 %}
8966 ins_pipe( pipe_slow );
8967 %}
8969 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
8970 match(Set dst (MoveI2F src));
8971 effect(DEF dst, USE src);
8972 ins_cost(85);
8973 format %{ "MoveI2F $dst, $src @ MoveI2F_reg_reg" %}
8974 ins_encode %{
8975 Register src = as_Register($src$$reg);
8976 FloatRegister dst = as_FloatRegister($dst$$reg);
8978 __ mtc1(src, dst);
8979 %}
8980 ins_pipe( pipe_slow );
8981 %}
8983 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
8984 match(Set dst (MoveD2L src));
8985 effect(DEF dst, USE src);
8986 ins_cost(85);
8987 format %{ "MoveD2L $dst, $src @ MoveD2L_reg_reg" %}
8988 ins_encode %{
8989 Register dst = as_Register($dst$$reg);
8990 FloatRegister src = as_FloatRegister($src$$reg);
8992 __ dmfc1(dst, src);
8993 %}
8994 ins_pipe( pipe_slow );
8995 %}
8997 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
8998 match(Set dst (MoveL2D src));
8999 effect(DEF dst, USE src);
9000 ins_cost(85);
9001 format %{ "MoveL2D $dst, $src @ MoveL2D_reg_reg" %}
9002 ins_encode %{
9003 FloatRegister dst = as_FloatRegister($dst$$reg);
9004 Register src = as_Register($src$$reg);
9006 __ dmtc1(src, dst);
9007 %}
9008 ins_pipe( pipe_slow );
9009 %}
9011 //----------Conditional Move---------------------------------------------------
9012 // Conditional move
9013 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9014 match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9015 ins_cost(80);
9016 format %{
9017 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpI_reg_reg\n"
9018 "\tCMOV $dst,$src \t @cmovI_cmpI_reg_reg"
9019 %}
9021 ins_encode %{
9022 Register op1 = $tmp1$$Register;
9023 Register op2 = $tmp2$$Register;
9024 Register dst = $dst$$Register;
9025 Register src = $src$$Register;
9026 int flag = $cop$$cmpcode;
9028 switch(flag) {
9029 case 0x01: //equal
9030 __ subu32(AT, op1, op2);
9031 __ movz(dst, src, AT);
9032 break;
9034 case 0x02: //not_equal
9035 __ subu32(AT, op1, op2);
9036 __ movn(dst, src, AT);
9037 break;
9039 case 0x03: //great
9040 __ slt(AT, op2, op1);
9041 __ movn(dst, src, AT);
9042 break;
9044 case 0x04: //great_equal
9045 __ slt(AT, op1, op2);
9046 __ movz(dst, src, AT);
9047 break;
9049 case 0x05: //less
9050 __ slt(AT, op1, op2);
9051 __ movn(dst, src, AT);
9052 break;
9054 case 0x06: //less_equal
9055 __ slt(AT, op2, op1);
9056 __ movz(dst, src, AT);
9057 break;
9059 default:
9060 Unimplemented();
9061 }
9062 %}
9064 ins_pipe( pipe_slow );
9065 %}
9067 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9068 match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9069 ins_cost(80);
9070 format %{
9071 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
9072 "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
9073 %}
9074 ins_encode %{
9075 Register op1 = $tmp1$$Register;
9076 Register op2 = $tmp2$$Register;
9077 Register dst = $dst$$Register;
9078 Register src = $src$$Register;
9079 int flag = $cop$$cmpcode;
9081 switch(flag) {
9082 case 0x01: //equal
9083 __ subu(AT, op1, op2);
9084 __ movz(dst, src, AT);
9085 break;
9087 case 0x02: //not_equal
9088 __ subu(AT, op1, op2);
9089 __ movn(dst, src, AT);
9090 break;
9092 case 0x03: //above
9093 __ sltu(AT, op2, op1);
9094 __ movn(dst, src, AT);
9095 break;
9097 case 0x04: //above_equal
9098 __ sltu(AT, op1, op2);
9099 __ movz(dst, src, AT);
9100 break;
9102 case 0x05: //below
9103 __ sltu(AT, op1, op2);
9104 __ movn(dst, src, AT);
9105 break;
9107 case 0x06: //below_equal
9108 __ sltu(AT, op2, op1);
9109 __ movz(dst, src, AT);
9110 break;
9112 default:
9113 Unimplemented();
9114 }
9115 %}
9117 ins_pipe( pipe_slow );
9118 %}
9120 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
9121 match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
9122 ins_cost(80);
9123 format %{
9124 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
9125 "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
9126 %}
9127 ins_encode %{
9128 Register op1 = $tmp1$$Register;
9129 Register op2 = $tmp2$$Register;
9130 Register dst = $dst$$Register;
9131 Register src = $src$$Register;
9132 int flag = $cop$$cmpcode;
9134 switch(flag) {
9135 case 0x01: //equal
9136 __ subu32(AT, op1, op2);
9137 __ movz(dst, src, AT);
9138 break;
9140 case 0x02: //not_equal
9141 __ subu32(AT, op1, op2);
9142 __ movn(dst, src, AT);
9143 break;
9145 case 0x03: //above
9146 __ sltu(AT, op2, op1);
9147 __ movn(dst, src, AT);
9148 break;
9150 case 0x04: //above_equal
9151 __ sltu(AT, op1, op2);
9152 __ movz(dst, src, AT);
9153 break;
9155 case 0x05: //below
9156 __ sltu(AT, op1, op2);
9157 __ movn(dst, src, AT);
9158 break;
9160 case 0x06: //below_equal
9161 __ sltu(AT, op2, op1);
9162 __ movz(dst, src, AT);
9163 break;
9165 default:
9166 Unimplemented();
9167 }
9168 %}
9170 ins_pipe( pipe_slow );
9171 %}
9173 instruct cmovP_cmpU_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
9174 match(Set dst (CMoveP (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
9175 ins_cost(80);
9176 format %{
9177 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpU_reg_reg\n\t"
9178 "CMOV $dst,$src\t @cmovP_cmpU_reg_reg"
9179 %}
9180 ins_encode %{
9181 Register op1 = $tmp1$$Register;
9182 Register op2 = $tmp2$$Register;
9183 Register dst = $dst$$Register;
9184 Register src = $src$$Register;
9185 int flag = $cop$$cmpcode;
9187 switch(flag) {
9188 case 0x01: //equal
9189 __ subu32(AT, op1, op2);
9190 __ movz(dst, src, AT);
9191 break;
9193 case 0x02: //not_equal
9194 __ subu32(AT, op1, op2);
9195 __ movn(dst, src, AT);
9196 break;
9198 case 0x03: //above
9199 __ sltu(AT, op2, op1);
9200 __ movn(dst, src, AT);
9201 break;
9203 case 0x04: //above_equal
9204 __ sltu(AT, op1, op2);
9205 __ movz(dst, src, AT);
9206 break;
9208 case 0x05: //below
9209 __ sltu(AT, op1, op2);
9210 __ movn(dst, src, AT);
9211 break;
9213 case 0x06: //below_equal
9214 __ sltu(AT, op2, op1);
9215 __ movz(dst, src, AT);
9216 break;
9218 default:
9219 Unimplemented();
9220 }
9221 %}
9223 ins_pipe( pipe_slow );
9224 %}
9226 instruct cmovP_cmpF_reg_reg(mRegP dst, mRegP src, regF tmp1, regF tmp2, cmpOp cop ) %{
9227 match(Set dst (CMoveP (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
9228 ins_cost(80);
9229 format %{
9230 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpF_reg_reg\n"
9231 "\tCMOV $dst,$src \t @cmovP_cmpF_reg_reg"
9232 %}
9234 ins_encode %{
9235 FloatRegister reg_op1 = $tmp1$$FloatRegister;
9236 FloatRegister reg_op2 = $tmp2$$FloatRegister;
9237 Register dst = $dst$$Register;
9238 Register src = $src$$Register;
9239 int flag = $cop$$cmpcode;
9241 switch(flag) {
9242 case 0x01: //equal
9243 __ c_eq_s(reg_op1, reg_op2);
9244 __ movt(dst, src);
9245 break;
9246 case 0x02: //not_equal
9247 __ c_eq_s(reg_op1, reg_op2);
9248 __ movf(dst, src);
9249 break;
9250 case 0x03: //greater
9251 __ c_ole_s(reg_op1, reg_op2);
9252 __ movf(dst, src);
9253 break;
9254 case 0x04: //greater_equal
9255 __ c_olt_s(reg_op1, reg_op2);
9256 __ movf(dst, src);
9257 break;
9258 case 0x05: //less
9259 __ c_ult_s(reg_op1, reg_op2);
9260 __ movt(dst, src);
9261 break;
9262 case 0x06: //less_equal
9263 __ c_ule_s(reg_op1, reg_op2);
9264 __ movt(dst, src);
9265 break;
9266 default:
9267 Unimplemented();
9268 }
9269 %}
9270 ins_pipe( pipe_slow );
9271 %}
9273 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
9274 match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
9275 ins_cost(80);
9276 format %{
9277 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
9278 "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
9279 %}
9280 ins_encode %{
9281 Register op1 = $tmp1$$Register;
9282 Register op2 = $tmp2$$Register;
9283 Register dst = $dst$$Register;
9284 Register src = $src$$Register;
9285 int flag = $cop$$cmpcode;
9287 switch(flag) {
9288 case 0x01: //equal
9289 __ subu32(AT, op1, op2);
9290 __ movz(dst, src, AT);
9291 break;
9293 case 0x02: //not_equal
9294 __ subu32(AT, op1, op2);
9295 __ movn(dst, src, AT);
9296 break;
9298 case 0x03: //above
9299 __ sltu(AT, op2, op1);
9300 __ movn(dst, src, AT);
9301 break;
9303 case 0x04: //above_equal
9304 __ sltu(AT, op1, op2);
9305 __ movz(dst, src, AT);
9306 break;
9308 case 0x05: //below
9309 __ sltu(AT, op1, op2);
9310 __ movn(dst, src, AT);
9311 break;
9313 case 0x06: //below_equal
9314 __ sltu(AT, op2, op1);
9315 __ movz(dst, src, AT);
9316 break;
9318 default:
9319 Unimplemented();
9320 }
9321 %}
9323 ins_pipe( pipe_slow );
9324 %}
9326 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9327 match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9328 ins_cost(80);
9329 format %{
9330 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
9331 "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
9332 %}
9333 ins_encode %{
9334 Register op1 = $tmp1$$Register;
9335 Register op2 = $tmp2$$Register;
9336 Register dst = $dst$$Register;
9337 Register src = $src$$Register;
9338 int flag = $cop$$cmpcode;
9340 switch(flag) {
9341 case 0x01: //equal
9342 __ subu(AT, op1, op2);
9343 __ movz(dst, src, AT);
9344 break;
9346 case 0x02: //not_equal
9347 __ subu(AT, op1, op2);
9348 __ movn(dst, src, AT);
9349 break;
9351 case 0x03: //above
9352 __ sltu(AT, op2, op1);
9353 __ movn(dst, src, AT);
9354 break;
9356 case 0x04: //above_equal
9357 __ sltu(AT, op1, op2);
9358 __ movz(dst, src, AT);
9359 break;
9361 case 0x05: //below
9362 __ sltu(AT, op1, op2);
9363 __ movn(dst, src, AT);
9364 break;
9366 case 0x06: //below_equal
9367 __ sltu(AT, op2, op1);
9368 __ movz(dst, src, AT);
9369 break;
9371 default:
9372 Unimplemented();
9373 }
9374 %}
9376 ins_pipe( pipe_slow );
9377 %}
9379 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
9380 match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
9381 ins_cost(80);
9382 format %{
9383 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpD_reg_reg\n"
9384 "\tCMOV $dst,$src \t @cmovP_cmpD_reg_reg"
9385 %}
9386 ins_encode %{
9387 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
9388 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
9389 Register dst = as_Register($dst$$reg);
9390 Register src = as_Register($src$$reg);
9392 int flag = $cop$$cmpcode;
9394 switch(flag) {
9395 case 0x01: //equal
9396 __ c_eq_d(reg_op1, reg_op2);
9397 __ movt(dst, src);
9398 break;
9399 case 0x02: //not_equal
9400 __ c_eq_d(reg_op1, reg_op2);
9401 __ movf(dst, src);
9402 break;
9403 case 0x03: //greater
9404 __ c_ole_d(reg_op1, reg_op2);
9405 __ movf(dst, src);
9406 break;
9407 case 0x04: //greater_equal
9408 __ c_olt_d(reg_op1, reg_op2);
9409 __ movf(dst, src);
9410 break;
9411 case 0x05: //less
9412 __ c_ult_d(reg_op1, reg_op2);
9413 __ movt(dst, src);
9414 break;
9415 case 0x06: //less_equal
9416 __ c_ule_d(reg_op1, reg_op2);
9417 __ movt(dst, src);
9418 break;
9419 default:
9420 Unimplemented();
9421 }
9422 %}
9424 ins_pipe( pipe_slow );
9425 %}
9428 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
9429 match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
9430 ins_cost(80);
9431 format %{
9432 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
9433 "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
9434 %}
9435 ins_encode %{
9436 Register op1 = $tmp1$$Register;
9437 Register op2 = $tmp2$$Register;
9438 Register dst = $dst$$Register;
9439 Register src = $src$$Register;
9440 int flag = $cop$$cmpcode;
9442 switch(flag) {
9443 case 0x01: //equal
9444 __ subu32(AT, op1, op2);
9445 __ movz(dst, src, AT);
9446 break;
9448 case 0x02: //not_equal
9449 __ subu32(AT, op1, op2);
9450 __ movn(dst, src, AT);
9451 break;
9453 case 0x03: //above
9454 __ sltu(AT, op2, op1);
9455 __ movn(dst, src, AT);
9456 break;
9458 case 0x04: //above_equal
9459 __ sltu(AT, op1, op2);
9460 __ movz(dst, src, AT);
9461 break;
9463 case 0x05: //below
9464 __ sltu(AT, op1, op2);
9465 __ movn(dst, src, AT);
9466 break;
9468 case 0x06: //below_equal
9469 __ sltu(AT, op2, op1);
9470 __ movz(dst, src, AT);
9471 break;
9473 default:
9474 Unimplemented();
9475 }
9476 %}
9478 ins_pipe( pipe_slow );
9479 %}
9482 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
9483 match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
9484 ins_cost(80);
9485 format %{
9486 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
9487 "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
9488 %}
9489 ins_encode %{
9490 Register op1 = $tmp1$$Register;
9491 Register op2 = $tmp2$$Register;
9492 Register dst = $dst$$Register;
9493 Register src = $src$$Register;
9494 int flag = $cop$$cmpcode;
9496 switch(flag) {
9497 case 0x01: //equal
9498 __ subu(AT, op1, op2);
9499 __ movz(dst, src, AT);
9500 break;
9502 case 0x02: //not_equal
9503 __ subu(AT, op1, op2);
9504 __ movn(dst, src, AT);
9505 break;
9507 case 0x03: //above
9508 __ sltu(AT, op2, op1);
9509 __ movn(dst, src, AT);
9510 break;
9512 case 0x04: //above_equal
9513 __ sltu(AT, op1, op2);
9514 __ movz(dst, src, AT);
9515 break;
9517 case 0x05: //below
9518 __ sltu(AT, op1, op2);
9519 __ movn(dst, src, AT);
9520 break;
9522 case 0x06: //below_equal
9523 __ sltu(AT, op2, op1);
9524 __ movz(dst, src, AT);
9525 break;
9527 default:
9528 Unimplemented();
9529 }
9530 %}
9532 ins_pipe( pipe_slow );
9533 %}
9535 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
9536 match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
9537 ins_cost(80);
9538 format %{
9539 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpL_reg_reg\n"
9540 "\tCMOV $dst,$src \t @cmovI_cmpL_reg_reg"
9541 %}
9542 ins_encode %{
9543 Register opr1 = as_Register($tmp1$$reg);
9544 Register opr2 = as_Register($tmp2$$reg);
9545 Register dst = $dst$$Register;
9546 Register src = $src$$Register;
9547 int flag = $cop$$cmpcode;
9549 switch(flag) {
9550 case 0x01: //equal
9551 __ subu(AT, opr1, opr2);
9552 __ movz(dst, src, AT);
9553 break;
9555 case 0x02: //not_equal
9556 __ subu(AT, opr1, opr2);
9557 __ movn(dst, src, AT);
9558 break;
9560 case 0x03: //greater
9561 __ slt(AT, opr2, opr1);
9562 __ movn(dst, src, AT);
9563 break;
9565 case 0x04: //greater_equal
9566 __ slt(AT, opr1, opr2);
9567 __ movz(dst, src, AT);
9568 break;
9570 case 0x05: //less
9571 __ slt(AT, opr1, opr2);
9572 __ movn(dst, src, AT);
9573 break;
9575 case 0x06: //less_equal
9576 __ slt(AT, opr2, opr1);
9577 __ movz(dst, src, AT);
9578 break;
9580 default:
9581 Unimplemented();
9582 }
9583 %}
9585 ins_pipe( pipe_slow );
9586 %}
9588 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
9589 match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
9590 ins_cost(80);
9591 format %{
9592 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpL_reg_reg\n"
9593 "\tCMOV $dst,$src \t @cmovP_cmpL_reg_reg"
9594 %}
9595 ins_encode %{
9596 Register opr1 = as_Register($tmp1$$reg);
9597 Register opr2 = as_Register($tmp2$$reg);
9598 Register dst = $dst$$Register;
9599 Register src = $src$$Register;
9600 int flag = $cop$$cmpcode;
9602 switch(flag) {
9603 case 0x01: //equal
9604 __ subu(AT, opr1, opr2);
9605 __ movz(dst, src, AT);
9606 break;
9608 case 0x02: //not_equal
9609 __ subu(AT, opr1, opr2);
9610 __ movn(dst, src, AT);
9611 break;
9613 case 0x03: //greater
9614 __ slt(AT, opr2, opr1);
9615 __ movn(dst, src, AT);
9616 break;
9618 case 0x04: //greater_equal
9619 __ slt(AT, opr1, opr2);
9620 __ movz(dst, src, AT);
9621 break;
9623 case 0x05: //less
9624 __ slt(AT, opr1, opr2);
9625 __ movn(dst, src, AT);
9626 break;
9628 case 0x06: //less_equal
9629 __ slt(AT, opr2, opr1);
9630 __ movz(dst, src, AT);
9631 break;
9633 default:
9634 Unimplemented();
9635 }
9636 %}
9638 ins_pipe( pipe_slow );
9639 %}
9641 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
9642 match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
9643 ins_cost(80);
9644 format %{
9645 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpD_reg_reg\n"
9646 "\tCMOV $dst,$src \t @cmovI_cmpD_reg_reg"
9647 %}
9648 ins_encode %{
9649 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
9650 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
9651 Register dst = as_Register($dst$$reg);
9652 Register src = as_Register($src$$reg);
9654 int flag = $cop$$cmpcode;
9656 switch(flag) {
9657 case 0x01: //equal
9658 __ c_eq_d(reg_op1, reg_op2);
9659 __ movt(dst, src);
9660 break;
9661 case 0x02: //not_equal
9662 // See instruct branchConD_reg_reg. The change in branchConD_reg_reg fixed a bug. It seems similar here, so I made thesame change.
9663 __ c_eq_d(reg_op1, reg_op2);
9664 __ movf(dst, src);
9665 break;
9666 case 0x03: //greater
9667 __ c_ole_d(reg_op1, reg_op2);
9668 __ movf(dst, src);
9669 break;
9670 case 0x04: //greater_equal
9671 __ c_olt_d(reg_op1, reg_op2);
9672 __ movf(dst, src);
9673 break;
9674 case 0x05: //less
9675 __ c_ult_d(reg_op1, reg_op2);
9676 __ movt(dst, src);
9677 break;
9678 case 0x06: //less_equal
9679 __ c_ule_d(reg_op1, reg_op2);
9680 __ movt(dst, src);
9681 break;
9682 default:
9683 Unimplemented();
9684 }
9685 %}
9687 ins_pipe( pipe_slow );
9688 %}
9691 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9692 match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9693 ins_cost(80);
9694 format %{
9695 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
9696 "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
9697 %}
9698 ins_encode %{
9699 Register op1 = $tmp1$$Register;
9700 Register op2 = $tmp2$$Register;
9701 Register dst = $dst$$Register;
9702 Register src = $src$$Register;
9703 int flag = $cop$$cmpcode;
9705 switch(flag) {
9706 case 0x01: //equal
9707 __ subu(AT, op1, op2);
9708 __ movz(dst, src, AT);
9709 break;
9711 case 0x02: //not_equal
9712 __ subu(AT, op1, op2);
9713 __ movn(dst, src, AT);
9714 break;
9716 case 0x03: //above
9717 __ sltu(AT, op2, op1);
9718 __ movn(dst, src, AT);
9719 break;
9721 case 0x04: //above_equal
9722 __ sltu(AT, op1, op2);
9723 __ movz(dst, src, AT);
9724 break;
9726 case 0x05: //below
9727 __ sltu(AT, op1, op2);
9728 __ movn(dst, src, AT);
9729 break;
9731 case 0x06: //below_equal
9732 __ sltu(AT, op2, op1);
9733 __ movz(dst, src, AT);
9734 break;
9736 default:
9737 Unimplemented();
9738 }
9739 %}
9741 ins_pipe( pipe_slow );
9742 %}
9744 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9745 match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9746 ins_cost(80);
9747 format %{
9748 "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
9749 "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
9750 %}
9751 ins_encode %{
9752 Register op1 = $tmp1$$Register;
9753 Register op2 = $tmp2$$Register;
9754 Register dst = $dst$$Register;
9755 Register src = $src$$Register;
9756 int flag = $cop$$cmpcode;
9758 switch(flag) {
9759 case 0x01: //equal
9760 __ subu32(AT, op1, op2);
9761 __ movz(dst, src, AT);
9762 break;
9764 case 0x02: //not_equal
9765 __ subu32(AT, op1, op2);
9766 __ movn(dst, src, AT);
9767 break;
9769 case 0x03: //above
9770 __ slt(AT, op2, op1);
9771 __ movn(dst, src, AT);
9772 break;
9774 case 0x04: //above_equal
9775 __ slt(AT, op1, op2);
9776 __ movz(dst, src, AT);
9777 break;
9779 case 0x05: //below
9780 __ slt(AT, op1, op2);
9781 __ movn(dst, src, AT);
9782 break;
9784 case 0x06: //below_equal
9785 __ slt(AT, op2, op1);
9786 __ movz(dst, src, AT);
9787 break;
9789 default:
9790 Unimplemented();
9791 }
9792 %}
9794 ins_pipe( pipe_slow );
9795 %}
9797 instruct cmovL_cmpP_reg_reg(mRegL dst, mRegL src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9798 match(Set dst (CMoveL (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9799 ins_cost(80);
9800 format %{
9801 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpP_reg_reg\n\t"
9802 "CMOV $dst,$src\t @cmovL_cmpP_reg_reg"
9803 %}
9804 ins_encode %{
9805 Register op1 = $tmp1$$Register;
9806 Register op2 = $tmp2$$Register;
9807 Register dst = $dst$$Register;
9808 Register src = $src$$Register;
9809 int flag = $cop$$cmpcode;
9811 switch(flag) {
9812 case 0x01: //equal
9813 __ subu(AT, op1, op2);
9814 __ movz(dst, src, AT);
9815 break;
9817 case 0x02: //not_equal
9818 __ subu(AT, op1, op2);
9819 __ movn(dst, src, AT);
9820 break;
9822 case 0x03: //above
9823 __ sltu(AT, op2, op1);
9824 __ movn(dst, src, AT);
9825 break;
9827 case 0x04: //above_equal
9828 __ sltu(AT, op1, op2);
9829 __ movz(dst, src, AT);
9830 break;
9832 case 0x05: //below
9833 __ sltu(AT, op1, op2);
9834 __ movn(dst, src, AT);
9835 break;
9837 case 0x06: //below_equal
9838 __ sltu(AT, op2, op1);
9839 __ movz(dst, src, AT);
9840 break;
9842 default:
9843 Unimplemented();
9844 }
9845 %}
9847 ins_pipe( pipe_slow );
9848 %}
9850 instruct cmovN_cmpL_reg_reg(mRegN dst, mRegN src, mRegL tmp1, mRegL tmp2, cmpOp cop) %{
9851 match(Set dst (CMoveN (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
9852 ins_cost(80);
9853 format %{
9854 "CMP$cop $tmp1, $tmp2\t @cmovN_cmpL_reg_reg\n"
9855 "\tCMOV $dst,$src \t @cmovN_cmpL_reg_reg"
9856 %}
9857 ins_encode %{
9858 Register opr1 = as_Register($tmp1$$reg);
9859 Register opr2 = as_Register($tmp2$$reg);
9860 Register dst = $dst$$Register;
9861 Register src = $src$$Register;
9862 int flag = $cop$$cmpcode;
9864 switch(flag) {
9865 case 0x01: //equal
9866 __ subu(AT, opr1, opr2);
9867 __ movz(dst, src, AT);
9868 break;
9870 case 0x02: //not_equal
9871 __ subu(AT, opr1, opr2);
9872 __ movn(dst, src, AT);
9873 break;
9875 case 0x03: //greater
9876 __ slt(AT, opr2, opr1);
9877 __ movn(dst, src, AT);
9878 break;
9880 case 0x04: //greater_equal
9881 __ slt(AT, opr1, opr2);
9882 __ movz(dst, src, AT);
9883 break;
9885 case 0x05: //less
9886 __ slt(AT, opr1, opr2);
9887 __ movn(dst, src, AT);
9888 break;
9890 case 0x06: //less_equal
9891 __ slt(AT, opr2, opr1);
9892 __ movz(dst, src, AT);
9893 break;
9895 default:
9896 Unimplemented();
9897 }
9898 %}
9900 ins_pipe( pipe_slow );
9901 %}
9903 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9904 match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9905 ins_cost(80);
9906 format %{
9907 "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
9908 "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
9909 %}
9910 ins_encode %{
9911 Register op1 = $tmp1$$Register;
9912 Register op2 = $tmp2$$Register;
9913 Register dst = $dst$$Register;
9914 Register src = $src$$Register;
9915 int flag = $cop$$cmpcode;
9917 switch(flag) {
9918 case 0x01: //equal
9919 __ subu32(AT, op1, op2);
9920 __ movz(dst, src, AT);
9921 break;
9923 case 0x02: //not_equal
9924 __ subu32(AT, op1, op2);
9925 __ movn(dst, src, AT);
9926 break;
9928 case 0x03: //above
9929 __ slt(AT, op2, op1);
9930 __ movn(dst, src, AT);
9931 break;
9933 case 0x04: //above_equal
9934 __ slt(AT, op1, op2);
9935 __ movz(dst, src, AT);
9936 break;
9938 case 0x05: //below
9939 __ slt(AT, op1, op2);
9940 __ movn(dst, src, AT);
9941 break;
9943 case 0x06: //below_equal
9944 __ slt(AT, op2, op1);
9945 __ movz(dst, src, AT);
9946 break;
9948 default:
9949 Unimplemented();
9950 }
9951 %}
9953 ins_pipe( pipe_slow );
9954 %}
9956 instruct cmovL_cmpU_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
9957 match(Set dst (CMoveL (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
9958 ins_cost(80);
9959 format %{
9960 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpU_reg_reg\n\t"
9961 "CMOV $dst,$src\t @cmovL_cmpU_reg_reg"
9962 %}
9963 ins_encode %{
9964 Register op1 = $tmp1$$Register;
9965 Register op2 = $tmp2$$Register;
9966 Register dst = $dst$$Register;
9967 Register src = $src$$Register;
9968 int flag = $cop$$cmpcode;
9970 switch(flag) {
9971 case 0x01: //equal
9972 __ subu32(AT, op1, op2);
9973 __ movz(dst, src, AT);
9974 break;
9976 case 0x02: //not_equal
9977 __ subu32(AT, op1, op2);
9978 __ movn(dst, src, AT);
9979 break;
9981 case 0x03: //above
9982 __ sltu(AT, op2, op1);
9983 __ movn(dst, src, AT);
9984 break;
9986 case 0x04: //above_equal
9987 __ sltu(AT, op1, op2);
9988 __ movz(dst, src, AT);
9989 break;
9991 case 0x05: //below
9992 __ sltu(AT, op1, op2);
9993 __ movn(dst, src, AT);
9994 break;
9996 case 0x06: //below_equal
9997 __ sltu(AT, op2, op1);
9998 __ movz(dst, src, AT);
9999 break;
10001 default:
10002 Unimplemented();
10003 }
10004 %}
10006 ins_pipe( pipe_slow );
10007 %}
10009 instruct cmovL_cmpF_reg_reg(mRegL dst, mRegL src, regF tmp1, regF tmp2, cmpOp cop ) %{
10010 match(Set dst (CMoveL (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
10011 ins_cost(80);
10012 format %{
10013 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpF_reg_reg\n"
10014 "\tCMOV $dst,$src \t @cmovL_cmpF_reg_reg"
10015 %}
10017 ins_encode %{
10018 FloatRegister reg_op1 = $tmp1$$FloatRegister;
10019 FloatRegister reg_op2 = $tmp2$$FloatRegister;
10020 Register dst = $dst$$Register;
10021 Register src = $src$$Register;
10022 int flag = $cop$$cmpcode;
10024 switch(flag) {
10025 case 0x01: //equal
10026 __ c_eq_s(reg_op1, reg_op2);
10027 __ movt(dst, src);
10028 break;
10029 case 0x02: //not_equal
10030 __ c_eq_s(reg_op1, reg_op2);
10031 __ movf(dst, src);
10032 break;
10033 case 0x03: //greater
10034 __ c_ole_s(reg_op1, reg_op2);
10035 __ movf(dst, src);
10036 break;
10037 case 0x04: //greater_equal
10038 __ c_olt_s(reg_op1, reg_op2);
10039 __ movf(dst, src);
10040 break;
10041 case 0x05: //less
10042 __ c_ult_s(reg_op1, reg_op2);
10043 __ movt(dst, src);
10044 break;
10045 case 0x06: //less_equal
10046 __ c_ule_s(reg_op1, reg_op2);
10047 __ movt(dst, src);
10048 break;
10049 default:
10050 Unimplemented();
10051 }
10052 %}
10053 ins_pipe( pipe_slow );
10054 %}
10056 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10057 match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10058 ins_cost(80);
10059 format %{
10060 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpI_reg_reg\n"
10061 "\tCMOV $dst,$src \t @cmovL_cmpI_reg_reg"
10062 %}
10064 ins_encode %{
10065 Register op1 = $tmp1$$Register;
10066 Register op2 = $tmp2$$Register;
10067 Register dst = as_Register($dst$$reg);
10068 Register src = as_Register($src$$reg);
10069 int flag = $cop$$cmpcode;
10071 switch(flag)
10072 {
10073 case 0x01: //equal
10074 __ subu32(AT, op1, op2);
10075 __ movz(dst, src, AT);
10076 break;
10078 case 0x02: //not_equal
10079 __ subu32(AT, op1, op2);
10080 __ movn(dst, src, AT);
10081 break;
10083 case 0x03: //great
10084 __ slt(AT, op2, op1);
10085 __ movn(dst, src, AT);
10086 break;
10088 case 0x04: //great_equal
10089 __ slt(AT, op1, op2);
10090 __ movz(dst, src, AT);
10091 break;
10093 case 0x05: //less
10094 __ slt(AT, op1, op2);
10095 __ movn(dst, src, AT);
10096 break;
10098 case 0x06: //less_equal
10099 __ slt(AT, op2, op1);
10100 __ movz(dst, src, AT);
10101 break;
10103 default:
10104 Unimplemented();
10105 }
10106 %}
10108 ins_pipe( pipe_slow );
10109 %}
10111 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
10112 match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
10113 ins_cost(80);
10114 format %{
10115 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpL_reg_reg\n"
10116 "\tCMOV $dst,$src \t @cmovL_cmpL_reg_reg"
10117 %}
10118 ins_encode %{
10119 Register opr1 = as_Register($tmp1$$reg);
10120 Register opr2 = as_Register($tmp2$$reg);
10121 Register dst = as_Register($dst$$reg);
10122 Register src = as_Register($src$$reg);
10123 int flag = $cop$$cmpcode;
10125 switch(flag) {
10126 case 0x01: //equal
10127 __ subu(AT, opr1, opr2);
10128 __ movz(dst, src, AT);
10129 break;
10131 case 0x02: //not_equal
10132 __ subu(AT, opr1, opr2);
10133 __ movn(dst, src, AT);
10134 break;
10136 case 0x03: //greater
10137 __ slt(AT, opr2, opr1);
10138 __ movn(dst, src, AT);
10139 break;
10141 case 0x04: //greater_equal
10142 __ slt(AT, opr1, opr2);
10143 __ movz(dst, src, AT);
10144 break;
10146 case 0x05: //less
10147 __ slt(AT, opr1, opr2);
10148 __ movn(dst, src, AT);
10149 break;
10151 case 0x06: //less_equal
10152 __ slt(AT, opr2, opr1);
10153 __ movz(dst, src, AT);
10154 break;
10156 default:
10157 Unimplemented();
10158 }
10159 %}
10161 ins_pipe( pipe_slow );
10162 %}
10164 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
10165 match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
10166 ins_cost(80);
10167 format %{
10168 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
10169 "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
10170 %}
10171 ins_encode %{
10172 Register op1 = $tmp1$$Register;
10173 Register op2 = $tmp2$$Register;
10174 Register dst = $dst$$Register;
10175 Register src = $src$$Register;
10176 int flag = $cop$$cmpcode;
10178 switch(flag) {
10179 case 0x01: //equal
10180 __ subu32(AT, op1, op2);
10181 __ movz(dst, src, AT);
10182 break;
10184 case 0x02: //not_equal
10185 __ subu32(AT, op1, op2);
10186 __ movn(dst, src, AT);
10187 break;
10189 case 0x03: //above
10190 __ sltu(AT, op2, op1);
10191 __ movn(dst, src, AT);
10192 break;
10194 case 0x04: //above_equal
10195 __ sltu(AT, op1, op2);
10196 __ movz(dst, src, AT);
10197 break;
10199 case 0x05: //below
10200 __ sltu(AT, op1, op2);
10201 __ movn(dst, src, AT);
10202 break;
10204 case 0x06: //below_equal
10205 __ sltu(AT, op2, op1);
10206 __ movz(dst, src, AT);
10207 break;
10209 default:
10210 Unimplemented();
10211 }
10212 %}
10214 ins_pipe( pipe_slow );
10215 %}
10218 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
10219 match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
10220 ins_cost(80);
10221 format %{
10222 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpD_reg_reg\n"
10223 "\tCMOV $dst,$src \t @cmovL_cmpD_reg_reg"
10224 %}
10225 ins_encode %{
10226 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
10227 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
10228 Register dst = as_Register($dst$$reg);
10229 Register src = as_Register($src$$reg);
10231 int flag = $cop$$cmpcode;
10233 switch(flag) {
10234 case 0x01: //equal
10235 __ c_eq_d(reg_op1, reg_op2);
10236 __ movt(dst, src);
10237 break;
10238 case 0x02: //not_equal
10239 __ c_eq_d(reg_op1, reg_op2);
10240 __ movf(dst, src);
10241 break;
10242 case 0x03: //greater
10243 __ c_ole_d(reg_op1, reg_op2);
10244 __ movf(dst, src);
10245 break;
10246 case 0x04: //greater_equal
10247 __ c_olt_d(reg_op1, reg_op2);
10248 __ movf(dst, src);
10249 break;
10250 case 0x05: //less
10251 __ c_ult_d(reg_op1, reg_op2);
10252 __ movt(dst, src);
10253 break;
10254 case 0x06: //less_equal
10255 __ c_ule_d(reg_op1, reg_op2);
10256 __ movt(dst, src);
10257 break;
10258 default:
10259 Unimplemented();
10260 }
10261 %}
10263 ins_pipe( pipe_slow );
10264 %}
10266 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
10267 match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
10268 ins_cost(200);
10269 format %{
10270 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpD_reg_reg\n"
10271 "\tCMOV $dst,$src \t @cmovD_cmpD_reg_reg"
10272 %}
10273 ins_encode %{
10274 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
10275 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
10276 FloatRegister dst = as_FloatRegister($dst$$reg);
10277 FloatRegister src = as_FloatRegister($src$$reg);
10279 int flag = $cop$$cmpcode;
10281 switch(flag) {
10282 case 0x01: //equal
10283 __ c_eq_d(reg_op1, reg_op2);
10284 __ movt_d(dst, src);
10285 break;
10286 case 0x02: //not_equal
10287 __ c_eq_d(reg_op1, reg_op2);
10288 __ movf_d(dst, src);
10289 break;
10290 case 0x03: //greater
10291 __ c_ole_d(reg_op1, reg_op2);
10292 __ movf_d(dst, src);
10293 break;
10294 case 0x04: //greater_equal
10295 __ c_olt_d(reg_op1, reg_op2);
10296 __ movf_d(dst, src);
10297 break;
10298 case 0x05: //less
10299 __ c_ult_d(reg_op1, reg_op2);
10300 __ movt_d(dst, src);
10301 break;
10302 case 0x06: //less_equal
10303 __ c_ule_d(reg_op1, reg_op2);
10304 __ movt_d(dst, src);
10305 break;
10306 default:
10307 Unimplemented();
10308 }
10309 %}
10311 ins_pipe( pipe_slow );
10312 %}
10314 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10315 match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10316 ins_cost(200);
10317 format %{
10318 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpI_reg_reg\n"
10319 "\tCMOV $dst, $src \t @cmovF_cmpI_reg_reg"
10320 %}
10322 ins_encode %{
10323 Register op1 = $tmp1$$Register;
10324 Register op2 = $tmp2$$Register;
10325 FloatRegister dst = as_FloatRegister($dst$$reg);
10326 FloatRegister src = as_FloatRegister($src$$reg);
10327 int flag = $cop$$cmpcode;
10328 Label L;
10330 switch(flag) {
10331 case 0x01: //equal
10332 __ bne(op1, op2, L);
10333 __ delayed()->nop();
10334 __ mov_s(dst, src);
10335 __ bind(L);
10336 break;
10337 case 0x02: //not_equal
10338 __ beq(op1, op2, L);
10339 __ delayed()->nop();
10340 __ mov_s(dst, src);
10341 __ bind(L);
10342 break;
10343 case 0x03: //great
10344 __ slt(AT, op2, op1);
10345 __ beq(AT, R0, L);
10346 __ delayed()->nop();
10347 __ mov_s(dst, src);
10348 __ bind(L);
10349 break;
10350 case 0x04: //great_equal
10351 __ slt(AT, op1, op2);
10352 __ bne(AT, R0, L);
10353 __ delayed()->nop();
10354 __ mov_s(dst, src);
10355 __ bind(L);
10356 break;
10357 case 0x05: //less
10358 __ slt(AT, op1, op2);
10359 __ beq(AT, R0, L);
10360 __ delayed()->nop();
10361 __ mov_s(dst, src);
10362 __ bind(L);
10363 break;
10364 case 0x06: //less_equal
10365 __ slt(AT, op2, op1);
10366 __ bne(AT, R0, L);
10367 __ delayed()->nop();
10368 __ mov_s(dst, src);
10369 __ bind(L);
10370 break;
10371 default:
10372 Unimplemented();
10373 }
10374 %}
10376 ins_pipe( pipe_slow );
10377 %}
10379 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10380 match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10381 ins_cost(200);
10382 format %{
10383 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpI_reg_reg\n"
10384 "\tCMOV $dst, $src \t @cmovD_cmpI_reg_reg"
10385 %}
10387 ins_encode %{
10388 Register op1 = $tmp1$$Register;
10389 Register op2 = $tmp2$$Register;
10390 FloatRegister dst = as_FloatRegister($dst$$reg);
10391 FloatRegister src = as_FloatRegister($src$$reg);
10392 int flag = $cop$$cmpcode;
10393 Label L;
10395 switch(flag) {
10396 case 0x01: //equal
10397 __ bne(op1, op2, L);
10398 __ delayed()->nop();
10399 __ mov_d(dst, src);
10400 __ bind(L);
10401 break;
10402 case 0x02: //not_equal
10403 __ beq(op1, op2, L);
10404 __ delayed()->nop();
10405 __ mov_d(dst, src);
10406 __ bind(L);
10407 break;
10408 case 0x03: //great
10409 __ slt(AT, op2, op1);
10410 __ beq(AT, R0, L);
10411 __ delayed()->nop();
10412 __ mov_d(dst, src);
10413 __ bind(L);
10414 break;
10415 case 0x04: //great_equal
10416 __ slt(AT, op1, op2);
10417 __ bne(AT, R0, L);
10418 __ delayed()->nop();
10419 __ mov_d(dst, src);
10420 __ bind(L);
10421 break;
10422 case 0x05: //less
10423 __ slt(AT, op1, op2);
10424 __ beq(AT, R0, L);
10425 __ delayed()->nop();
10426 __ mov_d(dst, src);
10427 __ bind(L);
10428 break;
10429 case 0x06: //less_equal
10430 __ slt(AT, op2, op1);
10431 __ bne(AT, R0, L);
10432 __ delayed()->nop();
10433 __ mov_d(dst, src);
10434 __ bind(L);
10435 break;
10436 default:
10437 Unimplemented();
10438 }
10439 %}
10441 ins_pipe( pipe_slow );
10442 %}
10444 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
10445 match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
10446 ins_cost(200);
10447 format %{
10448 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpP_reg_reg\n"
10449 "\tCMOV $dst, $src \t @cmovD_cmpP_reg_reg"
10450 %}
10452 ins_encode %{
10453 Register op1 = $tmp1$$Register;
10454 Register op2 = $tmp2$$Register;
10455 FloatRegister dst = as_FloatRegister($dst$$reg);
10456 FloatRegister src = as_FloatRegister($src$$reg);
10457 int flag = $cop$$cmpcode;
10458 Label L;
10460 switch(flag) {
10461 case 0x01: //equal
10462 __ bne(op1, op2, L);
10463 __ delayed()->nop();
10464 __ mov_d(dst, src);
10465 __ bind(L);
10466 break;
10467 case 0x02: //not_equal
10468 __ beq(op1, op2, L);
10469 __ delayed()->nop();
10470 __ mov_d(dst, src);
10471 __ bind(L);
10472 break;
10473 case 0x03: //great
10474 __ slt(AT, op2, op1);
10475 __ beq(AT, R0, L);
10476 __ delayed()->nop();
10477 __ mov_d(dst, src);
10478 __ bind(L);
10479 break;
10480 case 0x04: //great_equal
10481 __ slt(AT, op1, op2);
10482 __ bne(AT, R0, L);
10483 __ delayed()->nop();
10484 __ mov_d(dst, src);
10485 __ bind(L);
10486 break;
10487 case 0x05: //less
10488 __ slt(AT, op1, op2);
10489 __ beq(AT, R0, L);
10490 __ delayed()->nop();
10491 __ mov_d(dst, src);
10492 __ bind(L);
10493 break;
10494 case 0x06: //less_equal
10495 __ slt(AT, op2, op1);
10496 __ bne(AT, R0, L);
10497 __ delayed()->nop();
10498 __ mov_d(dst, src);
10499 __ bind(L);
10500 break;
10501 default:
10502 Unimplemented();
10503 }
10504 %}
10506 ins_pipe( pipe_slow );
10507 %}
10509 //FIXME
10510 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
10511 match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
10512 ins_cost(80);
10513 format %{
10514 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpF_reg_reg\n"
10515 "\tCMOV $dst,$src \t @cmovI_cmpF_reg_reg"
10516 %}
10518 ins_encode %{
10519 FloatRegister reg_op1 = $tmp1$$FloatRegister;
10520 FloatRegister reg_op2 = $tmp2$$FloatRegister;
10521 Register dst = $dst$$Register;
10522 Register src = $src$$Register;
10523 int flag = $cop$$cmpcode;
10525 switch(flag) {
10526 case 0x01: //equal
10527 __ c_eq_s(reg_op1, reg_op2);
10528 __ movt(dst, src);
10529 break;
10530 case 0x02: //not_equal
10531 __ c_eq_s(reg_op1, reg_op2);
10532 __ movf(dst, src);
10533 break;
10534 case 0x03: //greater
10535 __ c_ole_s(reg_op1, reg_op2);
10536 __ movf(dst, src);
10537 break;
10538 case 0x04: //greater_equal
10539 __ c_olt_s(reg_op1, reg_op2);
10540 __ movf(dst, src);
10541 break;
10542 case 0x05: //less
10543 __ c_ult_s(reg_op1, reg_op2);
10544 __ movt(dst, src);
10545 break;
10546 case 0x06: //less_equal
10547 __ c_ule_s(reg_op1, reg_op2);
10548 __ movt(dst, src);
10549 break;
10550 default:
10551 Unimplemented();
10552 }
10553 %}
10554 ins_pipe( pipe_slow );
10555 %}
10557 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
10558 match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
10559 ins_cost(200);
10560 format %{
10561 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpF_reg_reg\n"
10562 "\tCMOV $dst,$src \t @cmovF_cmpF_reg_reg"
10563 %}
10565 ins_encode %{
10566 FloatRegister reg_op1 = $tmp1$$FloatRegister;
10567 FloatRegister reg_op2 = $tmp2$$FloatRegister;
10568 FloatRegister dst = $dst$$FloatRegister;
10569 FloatRegister src = $src$$FloatRegister;
10570 int flag = $cop$$cmpcode;
10572 switch(flag) {
10573 case 0x01: //equal
10574 __ c_eq_s(reg_op1, reg_op2);
10575 __ movt_s(dst, src);
10576 break;
10577 case 0x02: //not_equal
10578 __ c_eq_s(reg_op1, reg_op2);
10579 __ movf_s(dst, src);
10580 break;
10581 case 0x03: //greater
10582 __ c_ole_s(reg_op1, reg_op2);
10583 __ movf_s(dst, src);
10584 break;
10585 case 0x04: //greater_equal
10586 __ c_olt_s(reg_op1, reg_op2);
10587 __ movf_s(dst, src);
10588 break;
10589 case 0x05: //less
10590 __ c_ult_s(reg_op1, reg_op2);
10591 __ movt_s(dst, src);
10592 break;
10593 case 0x06: //less_equal
10594 __ c_ule_s(reg_op1, reg_op2);
10595 __ movt_s(dst, src);
10596 break;
10597 default:
10598 Unimplemented();
10599 }
10600 %}
10601 ins_pipe( pipe_slow );
10602 %}
10604 // Manifest a CmpL result in an integer register. Very painful.
10605 // This is the test to avoid.
10606 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
10607 match(Set dst (CmpL3 src1 src2));
10608 ins_cost(1000);
10609 format %{ "cmpL3 $dst, $src1, $src2 @ cmpL3_reg_reg" %}
10610 ins_encode %{
10611 Register opr1 = as_Register($src1$$reg);
10612 Register opr2 = as_Register($src2$$reg);
10613 Register dst = as_Register($dst$$reg);
10615 Label Done;
10617 __ subu(AT, opr1, opr2);
10618 __ bltz(AT, Done);
10619 __ delayed()->daddiu(dst, R0, -1);
10621 __ move(dst, 1);
10622 __ movz(dst, R0, AT);
10624 __ bind(Done);
10625 %}
10626 ins_pipe( pipe_slow );
10627 %}
10629 //
10630 // less_rsult = -1
10631 // greater_result = 1
10632 // equal_result = 0
10633 // nan_result = -1
10634 //
10635 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
10636 match(Set dst (CmpF3 src1 src2));
10637 ins_cost(1000);
10638 format %{ "cmpF3 $dst, $src1, $src2 @ cmpF3_reg_reg" %}
10639 ins_encode %{
10640 FloatRegister src1 = as_FloatRegister($src1$$reg);
10641 FloatRegister src2 = as_FloatRegister($src2$$reg);
10642 Register dst = as_Register($dst$$reg);
10644 Label Done;
10646 __ c_ult_s(src1, src2);
10647 __ bc1t(Done);
10648 __ delayed()->daddiu(dst, R0, -1);
10650 __ c_eq_s(src1, src2);
10651 __ move(dst, 1);
10652 __ movt(dst, R0);
10654 __ bind(Done);
10655 %}
10656 ins_pipe( pipe_slow );
10657 %}
10659 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
10660 match(Set dst (CmpD3 src1 src2));
10661 ins_cost(1000);
10662 format %{ "cmpD3 $dst, $src1, $src2 @ cmpD3_reg_reg" %}
10663 ins_encode %{
10664 FloatRegister src1 = as_FloatRegister($src1$$reg);
10665 FloatRegister src2 = as_FloatRegister($src2$$reg);
10666 Register dst = as_Register($dst$$reg);
10668 Label Done;
10670 __ c_ult_d(src1, src2);
10671 __ bc1t(Done);
10672 __ delayed()->daddiu(dst, R0, -1);
10674 __ c_eq_d(src1, src2);
10675 __ move(dst, 1);
10676 __ movt(dst, R0);
10678 __ bind(Done);
10679 %}
10680 ins_pipe( pipe_slow );
10681 %}
10683 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
10684 match(Set dummy (ClearArray cnt base));
10685 format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
10686 ins_encode %{
10687 //Assume cnt is the number of bytes in an array to be cleared,
10688 //and base points to the starting address of the array.
10689 Register base = $base$$Register;
10690 Register num = $cnt$$Register;
10691 Label Loop, done;
10693 __ beq(num, R0, done);
10694 __ delayed()->daddu(AT, base, R0);
10696 __ move(T9, num); /* T9 = words */
10698 __ bind(Loop);
10699 __ sd(R0, AT, 0);
10700 __ daddi(T9, T9, -1);
10701 __ bne(T9, R0, Loop);
10702 __ delayed()->daddi(AT, AT, wordSize);
10704 __ bind(done);
10705 %}
10706 ins_pipe( pipe_slow );
10707 %}
10709 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2, mA7RegI cnt2, no_Ax_mRegI result) %{
10710 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
10711 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
10713 format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
10714 ins_encode %{
10715 // Get the first character position in both strings
10716 // [8] char array, [12] offset, [16] count
10717 Register str1 = $str1$$Register;
10718 Register str2 = $str2$$Register;
10719 Register cnt1 = $cnt1$$Register;
10720 Register cnt2 = $cnt2$$Register;
10721 Register result = $result$$Register;
10723 Label L, Loop, haveResult, done;
10725 // compute the and difference of lengths (in result)
10726 __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
10728 // compute the shorter length (in cnt1)
10729 __ slt(AT, cnt2, cnt1);
10730 __ movn(cnt1, cnt2, AT);
10732 // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
10733 __ bind(Loop); // Loop begin
10734 __ beq(cnt1, R0, done);
10735 __ delayed()->lhu(AT, str1, 0);;
10737 // compare current character
10738 __ lhu(cnt2, str2, 0);
10739 __ bne(AT, cnt2, haveResult);
10740 __ delayed()->addi(str1, str1, 2);
10741 __ addi(str2, str2, 2);
10742 __ b(Loop);
10743 __ delayed()->addi(cnt1, cnt1, -1); // Loop end
10745 __ bind(haveResult);
10746 __ subu(result, AT, cnt2);
10748 __ bind(done);
10749 %}
10751 ins_pipe( pipe_slow );
10752 %}
10754 // intrinsic optimization
10755 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
10756 match(Set result (StrEquals (Binary str1 str2) cnt));
10757 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
10759 format %{ "String Equal $str1, $str2, len:$cnt tmp:$temp -> $result @ string_equals" %}
10760 ins_encode %{
10761 // Get the first character position in both strings
10762 // [8] char array, [12] offset, [16] count
10763 Register str1 = $str1$$Register;
10764 Register str2 = $str2$$Register;
10765 Register cnt = $cnt$$Register;
10766 Register tmp = $temp$$Register;
10767 Register result = $result$$Register;
10769 Label Loop, done;
10772 __ beq(str1, str2, done); // same char[] ?
10773 __ delayed()->daddiu(result, R0, 1);
10775 __ bind(Loop); // Loop begin
10776 __ beq(cnt, R0, done);
10777 __ delayed()->daddiu(result, R0, 1); // count == 0
10779 // compare current character
10780 __ lhu(AT, str1, 0);;
10781 __ lhu(tmp, str2, 0);
10782 __ bne(AT, tmp, done);
10783 __ delayed()->daddi(result, R0, 0);
10784 __ addi(str1, str1, 2);
10785 __ addi(str2, str2, 2);
10786 __ b(Loop);
10787 __ delayed()->addi(cnt, cnt, -1); // Loop end
10789 __ bind(done);
10790 %}
10792 ins_pipe( pipe_slow );
10793 %}
10795 //----------Arithmetic Instructions-------------------------------------------
10796 //----------Addition Instructions---------------------------------------------
10797 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10798 match(Set dst (AddI src1 src2));
10800 format %{ "add $dst, $src1, $src2 #@addI_Reg_Reg" %}
10801 ins_encode %{
10802 Register dst = $dst$$Register;
10803 Register src1 = $src1$$Register;
10804 Register src2 = $src2$$Register;
10805 __ addu32(dst, src1, src2);
10806 %}
10807 ins_pipe( ialu_regI_regI );
10808 %}
10810 instruct addI_Reg_imm(mRegI dst, mRegI src1, immI src2) %{
10811 match(Set dst (AddI src1 src2));
10813 format %{ "add $dst, $src1, $src2 #@addI_Reg_imm" %}
10814 ins_encode %{
10815 Register dst = $dst$$Register;
10816 Register src1 = $src1$$Register;
10817 int imm = $src2$$constant;
10819 if(Assembler::is_simm16(imm)) {
10820 __ addiu32(dst, src1, imm);
10821 } else {
10822 __ move(AT, imm);
10823 __ addu32(dst, src1, AT);
10824 }
10825 %}
10826 ins_pipe( ialu_regI_regI );
10827 %}
10829 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
10830 match(Set dst (AddP src1 src2));
10832 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg" %}
10834 ins_encode %{
10835 Register dst = $dst$$Register;
10836 Register src1 = $src1$$Register;
10837 Register src2 = $src2$$Register;
10838 __ daddu(dst, src1, src2);
10839 %}
10841 ins_pipe( ialu_regI_regI );
10842 %}
10844 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
10845 match(Set dst (AddP src1 (ConvI2L src2)));
10847 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
10849 ins_encode %{
10850 Register dst = $dst$$Register;
10851 Register src1 = $src1$$Register;
10852 Register src2 = $src2$$Register;
10853 __ daddu(dst, src1, src2);
10854 %}
10856 ins_pipe( ialu_regI_regI );
10857 %}
10859 instruct addP_reg_imm(mRegP dst, mRegP src1, immL src2) %{
10860 match(Set dst (AddP src1 src2));
10862 format %{ "daddi $dst, $src1, $src2 #@addP_reg_imm" %}
10863 ins_encode %{
10864 Register src1 = $src1$$Register;
10865 long src2 = $src2$$constant;
10866 Register dst = $dst$$Register;
10868 if(Assembler::is_simm16(src2)) {
10869 __ daddiu(dst, src1, src2);
10870 } else {
10871 __ set64(AT, src2);
10872 __ daddu(dst, src1, AT);
10873 }
10874 %}
10875 ins_pipe( ialu_regI_imm16 );
10876 %}
10878 // Add Long Register with Register
10879 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10880 match(Set dst (AddL src1 src2));
10881 ins_cost(200);
10882 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
10884 ins_encode %{
10885 Register dst_reg = as_Register($dst$$reg);
10886 Register src1_reg = as_Register($src1$$reg);
10887 Register src2_reg = as_Register($src2$$reg);
10889 __ daddu(dst_reg, src1_reg, src2_reg);
10890 %}
10892 ins_pipe( ialu_regL_regL );
10893 %}
10895 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
10896 %{
10897 match(Set dst (AddL src1 src2));
10899 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_imm " %}
10900 ins_encode %{
10901 Register dst_reg = as_Register($dst$$reg);
10902 Register src1_reg = as_Register($src1$$reg);
10903 int src2_imm = $src2$$constant;
10905 __ daddiu(dst_reg, src1_reg, src2_imm);
10906 %}
10908 ins_pipe( ialu_regL_regL );
10909 %}
10911 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
10912 %{
10913 match(Set dst (AddL (ConvI2L src1) src2));
10915 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_imm " %}
10916 ins_encode %{
10917 Register dst_reg = as_Register($dst$$reg);
10918 Register src1_reg = as_Register($src1$$reg);
10919 int src2_imm = $src2$$constant;
10921 __ daddiu(dst_reg, src1_reg, src2_imm);
10922 %}
10924 ins_pipe( ialu_regL_regL );
10925 %}
10927 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
10928 match(Set dst (AddL (ConvI2L src1) src2));
10929 ins_cost(200);
10930 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
10932 ins_encode %{
10933 Register dst_reg = as_Register($dst$$reg);
10934 Register src1_reg = as_Register($src1$$reg);
10935 Register src2_reg = as_Register($src2$$reg);
10937 __ daddu(dst_reg, src1_reg, src2_reg);
10938 %}
10940 ins_pipe( ialu_regL_regL );
10941 %}
10943 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
10944 match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
10945 ins_cost(200);
10946 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
10948 ins_encode %{
10949 Register dst_reg = as_Register($dst$$reg);
10950 Register src1_reg = as_Register($src1$$reg);
10951 Register src2_reg = as_Register($src2$$reg);
10953 __ daddu(dst_reg, src1_reg, src2_reg);
10954 %}
10956 ins_pipe( ialu_regL_regL );
10957 %}
10959 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
10960 match(Set dst (AddL src1 (ConvI2L src2)));
10961 ins_cost(200);
10962 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
10964 ins_encode %{
10965 Register dst_reg = as_Register($dst$$reg);
10966 Register src1_reg = as_Register($src1$$reg);
10967 Register src2_reg = as_Register($src2$$reg);
10969 __ daddu(dst_reg, src1_reg, src2_reg);
10970 %}
10972 ins_pipe( ialu_regL_regL );
10973 %}
10975 //----------Subtraction Instructions-------------------------------------------
10976 // Integer Subtraction Instructions
10977 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10978 match(Set dst (SubI src1 src2));
10979 ins_cost(100);
10981 format %{ "sub $dst, $src1, $src2 #@subI_Reg_Reg" %}
10982 ins_encode %{
10983 Register dst = $dst$$Register;
10984 Register src1 = $src1$$Register;
10985 Register src2 = $src2$$Register;
10986 __ subu32(dst, src1, src2);
10987 %}
10988 ins_pipe( ialu_regI_regI );
10989 %}
10991 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1, immI16_sub src2) %{
10992 match(Set dst (SubI src1 src2));
10993 ins_cost(80);
10995 format %{ "sub $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
10996 ins_encode %{
10997 Register dst = $dst$$Register;
10998 Register src1 = $src1$$Register;
10999 __ addiu32(dst, src1, -1 * $src2$$constant);
11000 %}
11001 ins_pipe( ialu_regI_regI );
11002 %}
11004 instruct negI_Reg(mRegI dst, immI0 zero, mRegI src) %{
11005 match(Set dst (SubI zero src));
11006 ins_cost(80);
11008 format %{ "neg $dst, $src #@negI_Reg" %}
11009 ins_encode %{
11010 Register dst = $dst$$Register;
11011 Register src = $src$$Register;
11012 __ subu32(dst, R0, src);
11013 %}
11014 ins_pipe( ialu_regI_regI );
11015 %}
11017 instruct negL_Reg(mRegL dst, immL0 zero, mRegL src) %{
11018 match(Set dst (SubL zero src));
11019 ins_cost(80);
11021 format %{ "neg $dst, $src #@negL_Reg" %}
11022 ins_encode %{
11023 Register dst = $dst$$Register;
11024 Register src = $src$$Register;
11025 __ subu(dst, R0, src);
11026 %}
11027 ins_pipe( ialu_regI_regI );
11028 %}
11030 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1, immL16_sub src2) %{
11031 match(Set dst (SubL src1 src2));
11032 ins_cost(80);
11034 format %{ "sub $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
11035 ins_encode %{
11036 Register dst = $dst$$Register;
11037 Register src1 = $src1$$Register;
11038 __ daddiu(dst, src1, -1 * $src2$$constant);
11039 %}
11040 ins_pipe( ialu_regI_regI );
11041 %}
11043 // Subtract Long Register with Register.
11044 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11045 match(Set dst (SubL src1 src2));
11046 ins_cost(100);
11047 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_Reg" %}
11048 ins_encode %{
11049 Register dst = as_Register($dst$$reg);
11050 Register src1 = as_Register($src1$$reg);
11051 Register src2 = as_Register($src2$$reg);
11053 __ subu(dst, src1, src2);
11054 %}
11055 ins_pipe( ialu_regL_regL );
11056 %}
11058 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
11059 match(Set dst (SubL src1 (ConvI2L src2)));
11060 ins_cost(100);
11061 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
11062 ins_encode %{
11063 Register dst = as_Register($dst$$reg);
11064 Register src1 = as_Register($src1$$reg);
11065 Register src2 = as_Register($src2$$reg);
11067 __ subu(dst, src1, src2);
11068 %}
11069 ins_pipe( ialu_regL_regL );
11070 %}
11072 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
11073 match(Set dst (SubL (ConvI2L src1) src2));
11074 ins_cost(200);
11075 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
11076 ins_encode %{
11077 Register dst = as_Register($dst$$reg);
11078 Register src1 = as_Register($src1$$reg);
11079 Register src2 = as_Register($src2$$reg);
11081 __ subu(dst, src1, src2);
11082 %}
11083 ins_pipe( ialu_regL_regL );
11084 %}
11086 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
11087 match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
11088 ins_cost(200);
11089 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
11090 ins_encode %{
11091 Register dst = as_Register($dst$$reg);
11092 Register src1 = as_Register($src1$$reg);
11093 Register src2 = as_Register($src2$$reg);
11095 __ subu(dst, src1, src2);
11096 %}
11097 ins_pipe( ialu_regL_regL );
11098 %}
11100 // Integer MOD with Register
11101 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11102 match(Set dst (ModI src1 src2));
11103 ins_cost(300);
11104 format %{ "modi $dst, $src1, $src2 @ modI_Reg_Reg" %}
11105 ins_encode %{
11106 Register dst = $dst$$Register;
11107 Register src1 = $src1$$Register;
11108 Register src2 = $src2$$Register;
11110 //if (UseLoongsonISA) {
11111 if (0) {
11112 // 2016.08.10
11113 // Experiments show that gsmod is slower that div+mfhi.
11114 // So I just disable it here.
11115 __ gsmod(dst, src1, src2);
11116 } else {
11117 __ div(src1, src2);
11118 __ mfhi(dst);
11119 }
11120 %}
11122 //ins_pipe( ialu_mod );
11123 ins_pipe( ialu_regI_regI );
11124 %}
11126 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11127 match(Set dst (ModL src1 src2));
11128 format %{ "modL $dst, $src1, $src2 @modL_reg_reg" %}
11130 ins_encode %{
11131 Register dst = as_Register($dst$$reg);
11132 Register op1 = as_Register($src1$$reg);
11133 Register op2 = as_Register($src2$$reg);
11135 if (UseLoongsonISA) {
11136 __ gsdmod(dst, op1, op2);
11137 } else {
11138 __ ddiv(op1, op2);
11139 __ mfhi(dst);
11140 }
11141 %}
11142 ins_pipe( pipe_slow );
11143 %}
11145 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11146 match(Set dst (MulI src1 src2));
11148 ins_cost(300);
11149 format %{ "mul $dst, $src1, $src2 @ mulI_Reg_Reg" %}
11150 ins_encode %{
11151 Register src1 = $src1$$Register;
11152 Register src2 = $src2$$Register;
11153 Register dst = $dst$$Register;
11155 __ mul(dst, src1, src2);
11156 %}
11157 ins_pipe( ialu_mult );
11158 %}
11160 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
11161 match(Set dst (AddI (MulI src1 src2) src3));
11163 ins_cost(999);
11164 format %{ "madd $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
11165 ins_encode %{
11166 Register src1 = $src1$$Register;
11167 Register src2 = $src2$$Register;
11168 Register src3 = $src3$$Register;
11169 Register dst = $dst$$Register;
11171 __ mtlo(src3);
11172 __ madd(src1, src2);
11173 __ mflo(dst);
11174 %}
11175 ins_pipe( ialu_mult );
11176 %}
11178 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11179 match(Set dst (DivI src1 src2));
11181 ins_cost(300);
11182 format %{ "div $dst, $src1, $src2 @ divI_Reg_Reg" %}
11183 ins_encode %{
11184 Register src1 = $src1$$Register;
11185 Register src2 = $src2$$Register;
11186 Register dst = $dst$$Register;
11188 // In MIPS, div does not cause exception.
11189 // We must trap an exception manually.
11190 __ teq(R0, src2, 0x7);
11192 if (UseLoongsonISA) {
11193 __ gsdiv(dst, src1, src2);
11194 } else {
11195 __ div(src1, src2);
11197 __ nop();
11198 __ nop();
11199 __ mflo(dst);
11200 }
11201 %}
11202 ins_pipe( ialu_mod );
11203 %}
11205 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
11206 match(Set dst (DivF src1 src2));
11208 ins_cost(300);
11209 format %{ "divF $dst, $src1, $src2 @ divF_Reg_Reg" %}
11210 ins_encode %{
11211 FloatRegister src1 = $src1$$FloatRegister;
11212 FloatRegister src2 = $src2$$FloatRegister;
11213 FloatRegister dst = $dst$$FloatRegister;
11215 /* Here do we need to trap an exception manually ? */
11216 __ div_s(dst, src1, src2);
11217 %}
11218 ins_pipe( pipe_slow );
11219 %}
11221 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
11222 match(Set dst (DivD src1 src2));
11224 ins_cost(300);
11225 format %{ "divD $dst, $src1, $src2 @ divD_Reg_Reg" %}
11226 ins_encode %{
11227 FloatRegister src1 = $src1$$FloatRegister;
11228 FloatRegister src2 = $src2$$FloatRegister;
11229 FloatRegister dst = $dst$$FloatRegister;
11231 /* Here do we need to trap an exception manually ? */
11232 __ div_d(dst, src1, src2);
11233 %}
11234 ins_pipe( pipe_slow );
11235 %}
11237 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11238 match(Set dst (MulL src1 src2));
11239 format %{ "mulL $dst, $src1, $src2 @mulL_reg_reg" %}
11240 ins_encode %{
11241 Register dst = as_Register($dst$$reg);
11242 Register op1 = as_Register($src1$$reg);
11243 Register op2 = as_Register($src2$$reg);
11245 if (UseLoongsonISA) {
11246 __ gsdmult(dst, op1, op2);
11247 } else {
11248 __ dmult(op1, op2);
11249 __ mflo(dst);
11250 }
11251 %}
11252 ins_pipe( pipe_slow );
11253 %}
11255 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
11256 match(Set dst (MulL src1 (ConvI2L src2)));
11257 format %{ "mulL $dst, $src1, $src2 @mulL_reg_regI2L" %}
11258 ins_encode %{
11259 Register dst = as_Register($dst$$reg);
11260 Register op1 = as_Register($src1$$reg);
11261 Register op2 = as_Register($src2$$reg);
11263 if (UseLoongsonISA) {
11264 __ gsdmult(dst, op1, op2);
11265 } else {
11266 __ dmult(op1, op2);
11267 __ mflo(dst);
11268 }
11269 %}
11270 ins_pipe( pipe_slow );
11271 %}
11273 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11274 match(Set dst (DivL src1 src2));
11275 format %{ "divL $dst, $src1, $src2 @divL_reg_reg" %}
11277 ins_encode %{
11278 Register dst = as_Register($dst$$reg);
11279 Register op1 = as_Register($src1$$reg);
11280 Register op2 = as_Register($src2$$reg);
11282 if (UseLoongsonISA) {
11283 __ gsddiv(dst, op1, op2);
11284 } else {
11285 __ ddiv(op1, op2);
11286 __ mflo(dst);
11287 }
11288 %}
11289 ins_pipe( pipe_slow );
11290 %}
11292 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
11293 match(Set dst (AddF src1 src2));
11294 format %{ "AddF $dst, $src1, $src2 @addF_reg_reg" %}
11295 ins_encode %{
11296 FloatRegister src1 = as_FloatRegister($src1$$reg);
11297 FloatRegister src2 = as_FloatRegister($src2$$reg);
11298 FloatRegister dst = as_FloatRegister($dst$$reg);
11300 __ add_s(dst, src1, src2);
11301 %}
11302 ins_pipe( fpu_regF_regF );
11303 %}
11305 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
11306 match(Set dst (SubF src1 src2));
11307 format %{ "SubF $dst, $src1, $src2 @subF_reg_reg" %}
11308 ins_encode %{
11309 FloatRegister src1 = as_FloatRegister($src1$$reg);
11310 FloatRegister src2 = as_FloatRegister($src2$$reg);
11311 FloatRegister dst = as_FloatRegister($dst$$reg);
11313 __ sub_s(dst, src1, src2);
11314 %}
11315 ins_pipe( fpu_regF_regF );
11316 %}
11317 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
11318 match(Set dst (AddD src1 src2));
11319 format %{ "AddD $dst, $src1, $src2 @addD_reg_reg" %}
11320 ins_encode %{
11321 FloatRegister src1 = as_FloatRegister($src1$$reg);
11322 FloatRegister src2 = as_FloatRegister($src2$$reg);
11323 FloatRegister dst = as_FloatRegister($dst$$reg);
11325 __ add_d(dst, src1, src2);
11326 %}
11327 ins_pipe( fpu_regF_regF );
11328 %}
11330 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
11331 match(Set dst (SubD src1 src2));
11332 format %{ "SubD $dst, $src1, $src2 @subD_reg_reg" %}
11333 ins_encode %{
11334 FloatRegister src1 = as_FloatRegister($src1$$reg);
11335 FloatRegister src2 = as_FloatRegister($src2$$reg);
11336 FloatRegister dst = as_FloatRegister($dst$$reg);
11338 __ sub_d(dst, src1, src2);
11339 %}
11340 ins_pipe( fpu_regF_regF );
11341 %}
11343 instruct negF_reg(regF dst, regF src) %{
11344 match(Set dst (NegF src));
11345 format %{ "negF $dst, $src @negF_reg" %}
11346 ins_encode %{
11347 FloatRegister src = as_FloatRegister($src$$reg);
11348 FloatRegister dst = as_FloatRegister($dst$$reg);
11350 __ neg_s(dst, src);
11351 %}
11352 ins_pipe( fpu_regF_regF );
11353 %}
11355 instruct negD_reg(regD dst, regD src) %{
11356 match(Set dst (NegD src));
11357 format %{ "negD $dst, $src @negD_reg" %}
11358 ins_encode %{
11359 FloatRegister src = as_FloatRegister($src$$reg);
11360 FloatRegister dst = as_FloatRegister($dst$$reg);
11362 __ neg_d(dst, src);
11363 %}
11364 ins_pipe( fpu_regF_regF );
11365 %}
11368 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
11369 match(Set dst (MulF src1 src2));
11370 format %{ "MULF $dst, $src1, $src2 @mulF_reg_reg" %}
11371 ins_encode %{
11372 FloatRegister src1 = $src1$$FloatRegister;
11373 FloatRegister src2 = $src2$$FloatRegister;
11374 FloatRegister dst = $dst$$FloatRegister;
11376 __ mul_s(dst, src1, src2);
11377 %}
11378 ins_pipe( fpu_regF_regF );
11379 %}
11381 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
11382 match(Set dst (AddF (MulF src1 src2) src3));
11383 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
11384 ins_cost(44444);
11385 format %{ "maddF $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
11386 ins_encode %{
11387 FloatRegister src1 = $src1$$FloatRegister;
11388 FloatRegister src2 = $src2$$FloatRegister;
11389 FloatRegister src3 = $src3$$FloatRegister;
11390 FloatRegister dst = $dst$$FloatRegister;
11392 __ madd_s(dst, src1, src2, src3);
11393 %}
11394 ins_pipe( fpu_regF_regF );
11395 %}
11397 // Mul two double precision floating piont number
11398 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
11399 match(Set dst (MulD src1 src2));
11400 format %{ "MULD $dst, $src1, $src2 @mulD_reg_reg" %}
11401 ins_encode %{
11402 FloatRegister src1 = $src1$$FloatRegister;
11403 FloatRegister src2 = $src2$$FloatRegister;
11404 FloatRegister dst = $dst$$FloatRegister;
11406 __ mul_d(dst, src1, src2);
11407 %}
11408 ins_pipe( fpu_regF_regF );
11409 %}
11411 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
11412 match(Set dst (AddD (MulD src1 src2) src3));
11413 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
11414 ins_cost(44444);
11415 format %{ "maddD $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
11416 ins_encode %{
11417 FloatRegister src1 = $src1$$FloatRegister;
11418 FloatRegister src2 = $src2$$FloatRegister;
11419 FloatRegister src3 = $src3$$FloatRegister;
11420 FloatRegister dst = $dst$$FloatRegister;
11422 __ madd_d(dst, src1, src2, src3);
11423 %}
11424 ins_pipe( fpu_regF_regF );
11425 %}
11427 instruct absF_reg(regF dst, regF src) %{
11428 match(Set dst (AbsF src));
11429 ins_cost(100);
11430 format %{ "absF $dst, $src @absF_reg" %}
11431 ins_encode %{
11432 FloatRegister src = as_FloatRegister($src$$reg);
11433 FloatRegister dst = as_FloatRegister($dst$$reg);
11435 __ abs_s(dst, src);
11436 %}
11437 ins_pipe( fpu_regF_regF );
11438 %}
11441 // intrinsics for math_native.
11442 // AbsD SqrtD CosD SinD TanD LogD Log10D
11444 instruct absD_reg(regD dst, regD src) %{
11445 match(Set dst (AbsD src));
11446 ins_cost(100);
11447 format %{ "absD $dst, $src @absD_reg" %}
11448 ins_encode %{
11449 FloatRegister src = as_FloatRegister($src$$reg);
11450 FloatRegister dst = as_FloatRegister($dst$$reg);
11452 __ abs_d(dst, src);
11453 %}
11454 ins_pipe( fpu_regF_regF );
11455 %}
11457 instruct sqrtD_reg(regD dst, regD src) %{
11458 match(Set dst (SqrtD src));
11459 ins_cost(100);
11460 format %{ "SqrtD $dst, $src @sqrtD_reg" %}
11461 ins_encode %{
11462 FloatRegister src = as_FloatRegister($src$$reg);
11463 FloatRegister dst = as_FloatRegister($dst$$reg);
11465 __ sqrt_d(dst, src);
11466 %}
11467 ins_pipe( fpu_regF_regF );
11468 %}
11470 instruct sqrtF_reg(regF dst, regF src) %{
11471 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
11472 ins_cost(100);
11473 format %{ "SqrtF $dst, $src @sqrtF_reg" %}
11474 ins_encode %{
11475 FloatRegister src = as_FloatRegister($src$$reg);
11476 FloatRegister dst = as_FloatRegister($dst$$reg);
11478 __ sqrt_s(dst, src);
11479 %}
11480 ins_pipe( fpu_regF_regF );
11481 %}
11482 //----------------------------------Logical Instructions----------------------
11483 //__________________________________Integer Logical Instructions-------------
11485 //And Instuctions
11486 // And Register with Immediate
11487 instruct andI_Reg_immI(mRegI dst, mRegI src1, immI src2) %{
11488 match(Set dst (AndI src1 src2));
11490 format %{ "and $dst, $src1, $src2 #@andI_Reg_immI" %}
11491 ins_encode %{
11492 Register dst = $dst$$Register;
11493 Register src = $src1$$Register;
11494 int val = $src2$$constant;
11496 __ move(AT, val);
11497 __ andr(dst, src, AT);
11498 %}
11499 ins_pipe( ialu_regI_regI );
11500 %}
11502 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
11503 match(Set dst (AndI src1 src2));
11504 ins_cost(60);
11506 format %{ "and $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
11507 ins_encode %{
11508 Register dst = $dst$$Register;
11509 Register src = $src1$$Register;
11510 int val = $src2$$constant;
11512 __ andi(dst, src, val);
11513 %}
11514 ins_pipe( ialu_regI_regI );
11515 %}
11517 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1, immI_nonneg_mask mask) %{
11518 match(Set dst (AndI src1 mask));
11519 ins_cost(60);
11521 format %{ "and $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
11522 ins_encode %{
11523 Register dst = $dst$$Register;
11524 Register src = $src1$$Register;
11525 int size = Assembler::is_int_mask($mask$$constant);
11527 __ ext(dst, src, 0, size);
11528 %}
11529 ins_pipe( ialu_regI_regI );
11530 %}
11532 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1, immL_nonneg_mask mask) %{
11533 match(Set dst (AndL src1 mask));
11534 ins_cost(60);
11536 format %{ "and $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
11537 ins_encode %{
11538 Register dst = $dst$$Register;
11539 Register src = $src1$$Register;
11540 int size = Assembler::is_jlong_mask($mask$$constant);
11542 __ dext(dst, src, 0, size);
11543 %}
11544 ins_pipe( ialu_regI_regI );
11545 %}
11547 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
11548 match(Set dst (XorI src1 src2));
11549 ins_cost(60);
11551 format %{ "xori $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
11552 ins_encode %{
11553 Register dst = $dst$$Register;
11554 Register src = $src1$$Register;
11555 int val = $src2$$constant;
11557 __ xori(dst, src, val);
11558 %}
11559 ins_pipe( ialu_regI_regI );
11560 %}
11562 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1, immI_M1 M1) %{
11563 match(Set dst (XorI src1 M1));
11564 predicate(UseLoongsonISA && Use3A2000);
11565 ins_cost(60);
11567 format %{ "xor $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
11568 ins_encode %{
11569 Register dst = $dst$$Register;
11570 Register src = $src1$$Register;
11572 __ gsorn(dst, R0, src);
11573 %}
11574 ins_pipe( ialu_regI_regI );
11575 %}
11577 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1, immI_M1 M1) %{
11578 match(Set dst (XorI (ConvL2I src1) M1));
11579 predicate(UseLoongsonISA && Use3A2000);
11580 ins_cost(60);
11582 format %{ "xor $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
11583 ins_encode %{
11584 Register dst = $dst$$Register;
11585 Register src = $src1$$Register;
11587 __ gsorn(dst, R0, src);
11588 %}
11589 ins_pipe( ialu_regI_regI );
11590 %}
11592 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
11593 match(Set dst (XorL src1 src2));
11594 ins_cost(60);
11596 format %{ "xori $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
11597 ins_encode %{
11598 Register dst = $dst$$Register;
11599 Register src = $src1$$Register;
11600 int val = $src2$$constant;
11602 __ xori(dst, src, val);
11603 %}
11604 ins_pipe( ialu_regI_regI );
11605 %}
11607 /*
11608 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1, immL_M1 M1) %{
11609 match(Set dst (XorL src1 M1));
11610 predicate(UseLoongsonISA);
11611 ins_cost(60);
11613 format %{ "xor $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
11614 ins_encode %{
11615 Register dst = $dst$$Register;
11616 Register src = $src1$$Register;
11618 __ gsorn(dst, R0, src);
11619 %}
11620 ins_pipe( ialu_regI_regI );
11621 %}
11622 */
11624 instruct lbu_and_lmask(mRegI dst, memory mem, immI_255 mask) %{
11625 match(Set dst (AndI mask (LoadB mem)));
11626 ins_cost(60);
11628 format %{ "lhu $dst, $mem #@lbu_and_lmask" %}
11629 ins_encode(load_UB_enc(dst, mem));
11630 ins_pipe( ialu_loadI );
11631 %}
11633 instruct lbu_and_rmask(mRegI dst, memory mem, immI_255 mask) %{
11634 match(Set dst (AndI (LoadB mem) mask));
11635 ins_cost(60);
11637 format %{ "lhu $dst, $mem #@lbu_and_rmask" %}
11638 ins_encode(load_UB_enc(dst, mem));
11639 ins_pipe( ialu_loadI );
11640 %}
11642 instruct andI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11643 match(Set dst (AndI src1 src2));
11645 format %{ "and $dst, $src1, $src2 #@andI_Reg_Reg" %}
11646 ins_encode %{
11647 Register dst = $dst$$Register;
11648 Register src1 = $src1$$Register;
11649 Register src2 = $src2$$Register;
11650 __ andr(dst, src1, src2);
11651 %}
11652 ins_pipe( ialu_regI_regI );
11653 %}
11655 instruct andnI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11656 match(Set dst (AndI src1 (XorI src2 M1)));
11657 predicate(UseLoongsonISA && Use3A2000);
11659 format %{ "andn $dst, $src1, $src2 #@andnI_Reg_nReg" %}
11660 ins_encode %{
11661 Register dst = $dst$$Register;
11662 Register src1 = $src1$$Register;
11663 Register src2 = $src2$$Register;
11665 __ gsandn(dst, src1, src2);
11666 %}
11667 ins_pipe( ialu_regI_regI );
11668 %}
11670 instruct ornI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11671 match(Set dst (OrI src1 (XorI src2 M1)));
11672 predicate(UseLoongsonISA && Use3A2000);
11674 format %{ "orn $dst, $src1, $src2 #@ornI_Reg_nReg" %}
11675 ins_encode %{
11676 Register dst = $dst$$Register;
11677 Register src1 = $src1$$Register;
11678 Register src2 = $src2$$Register;
11680 __ gsorn(dst, src1, src2);
11681 %}
11682 ins_pipe( ialu_regI_regI );
11683 %}
11685 instruct andnI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11686 match(Set dst (AndI (XorI src1 M1) src2));
11687 predicate(UseLoongsonISA && Use3A2000);
11689 format %{ "andn $dst, $src2, $src1 #@andnI_nReg_Reg" %}
11690 ins_encode %{
11691 Register dst = $dst$$Register;
11692 Register src1 = $src1$$Register;
11693 Register src2 = $src2$$Register;
11695 __ gsandn(dst, src2, src1);
11696 %}
11697 ins_pipe( ialu_regI_regI );
11698 %}
11700 instruct ornI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11701 match(Set dst (OrI (XorI src1 M1) src2));
11702 predicate(UseLoongsonISA && Use3A2000);
11704 format %{ "orn $dst, $src2, $src1 #@ornI_nReg_Reg" %}
11705 ins_encode %{
11706 Register dst = $dst$$Register;
11707 Register src1 = $src1$$Register;
11708 Register src2 = $src2$$Register;
11710 __ gsorn(dst, src2, src1);
11711 %}
11712 ins_pipe( ialu_regI_regI );
11713 %}
11715 // And Long Register with Register
11716 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11717 match(Set dst (AndL src1 src2));
11718 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
11719 ins_encode %{
11720 Register dst_reg = as_Register($dst$$reg);
11721 Register src1_reg = as_Register($src1$$reg);
11722 Register src2_reg = as_Register($src2$$reg);
11724 __ andr(dst_reg, src1_reg, src2_reg);
11725 %}
11726 ins_pipe( ialu_regL_regL );
11727 %}
11729 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
11730 match(Set dst (AndL src1 (ConvI2L src2)));
11731 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
11732 ins_encode %{
11733 Register dst_reg = as_Register($dst$$reg);
11734 Register src1_reg = as_Register($src1$$reg);
11735 Register src2_reg = as_Register($src2$$reg);
11737 __ andr(dst_reg, src1_reg, src2_reg);
11738 %}
11739 ins_pipe( ialu_regL_regL );
11740 %}
11742 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
11743 match(Set dst (AndL src1 src2));
11744 ins_cost(60);
11746 format %{ "and $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
11747 ins_encode %{
11748 Register dst = $dst$$Register;
11749 Register src = $src1$$Register;
11750 long val = $src2$$constant;
11752 __ andi(dst, src, val);
11753 %}
11754 ins_pipe( ialu_regI_regI );
11755 %}
11757 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1, immL_0_65535 src2) %{
11758 match(Set dst (ConvL2I (AndL src1 src2)));
11759 ins_cost(60);
11761 format %{ "and $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
11762 ins_encode %{
11763 Register dst = $dst$$Register;
11764 Register src = $src1$$Register;
11765 long val = $src2$$constant;
11767 __ andi(dst, src, val);
11768 %}
11769 ins_pipe( ialu_regI_regI );
11770 %}
11772 /*
11773 instruct andnL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11774 match(Set dst (AndL src1 (XorL src2 M1)));
11775 predicate(UseLoongsonISA);
11777 format %{ "andn $dst, $src1, $src2 #@andnL_Reg_nReg" %}
11778 ins_encode %{
11779 Register dst = $dst$$Register;
11780 Register src1 = $src1$$Register;
11781 Register src2 = $src2$$Register;
11783 __ gsandn(dst, src1, src2);
11784 %}
11785 ins_pipe( ialu_regI_regI );
11786 %}
11787 */
11789 /*
11790 instruct ornL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11791 match(Set dst (OrL src1 (XorL src2 M1)));
11792 predicate(UseLoongsonISA);
11794 format %{ "orn $dst, $src1, $src2 #@ornL_Reg_nReg" %}
11795 ins_encode %{
11796 Register dst = $dst$$Register;
11797 Register src1 = $src1$$Register;
11798 Register src2 = $src2$$Register;
11800 __ gsorn(dst, src1, src2);
11801 %}
11802 ins_pipe( ialu_regI_regI );
11803 %}
11804 */
11806 /*
11807 instruct andnL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11808 match(Set dst (AndL (XorL src1 M1) src2));
11809 predicate(UseLoongsonISA);
11811 format %{ "andn $dst, $src2, $src1 #@andnL_nReg_Reg" %}
11812 ins_encode %{
11813 Register dst = $dst$$Register;
11814 Register src1 = $src1$$Register;
11815 Register src2 = $src2$$Register;
11817 __ gsandn(dst, src2, src1);
11818 %}
11819 ins_pipe( ialu_regI_regI );
11820 %}
11821 */
11823 /*
11824 instruct ornL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11825 match(Set dst (OrL (XorL src1 M1) src2));
11826 predicate(UseLoongsonISA);
11828 format %{ "orn $dst, $src2, $src1 #@ornL_nReg_Reg" %}
11829 ins_encode %{
11830 Register dst = $dst$$Register;
11831 Register src1 = $src1$$Register;
11832 Register src2 = $src2$$Register;
11834 __ gsorn(dst, src2, src1);
11835 %}
11836 ins_pipe( ialu_regI_regI );
11837 %}
11838 */
11840 instruct andL_Reg_immL_M8(mRegL dst, immL_M8 M8) %{
11841 match(Set dst (AndL dst M8));
11842 ins_cost(60);
11844 format %{ "and $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
11845 ins_encode %{
11846 Register dst = $dst$$Register;
11848 __ dins(dst, R0, 0, 3);
11849 %}
11850 ins_pipe( ialu_regI_regI );
11851 %}
11853 instruct andL_Reg_immL_M5(mRegL dst, immL_M5 M5) %{
11854 match(Set dst (AndL dst M5));
11855 ins_cost(60);
11857 format %{ "and $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
11858 ins_encode %{
11859 Register dst = $dst$$Register;
11861 __ dins(dst, R0, 2, 1);
11862 %}
11863 ins_pipe( ialu_regI_regI );
11864 %}
11866 instruct andL_Reg_immL_M7(mRegL dst, immL_M7 M7) %{
11867 match(Set dst (AndL dst M7));
11868 ins_cost(60);
11870 format %{ "and $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
11871 ins_encode %{
11872 Register dst = $dst$$Register;
11874 __ dins(dst, R0, 1, 2);
11875 %}
11876 ins_pipe( ialu_regI_regI );
11877 %}
11879 instruct andL_Reg_immL_M4(mRegL dst, immL_M4 M4) %{
11880 match(Set dst (AndL dst M4));
11881 ins_cost(60);
11883 format %{ "and $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
11884 ins_encode %{
11885 Register dst = $dst$$Register;
11887 __ dins(dst, R0, 0, 2);
11888 %}
11889 ins_pipe( ialu_regI_regI );
11890 %}
11892 instruct andL_Reg_immL_M121(mRegL dst, immL_M121 M121) %{
11893 match(Set dst (AndL dst M121));
11894 ins_cost(60);
11896 format %{ "and $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
11897 ins_encode %{
11898 Register dst = $dst$$Register;
11900 __ dins(dst, R0, 3, 4);
11901 %}
11902 ins_pipe( ialu_regI_regI );
11903 %}
11905 // Or Long Register with Register
11906 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11907 match(Set dst (OrL src1 src2));
11908 format %{ "OR $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
11909 ins_encode %{
11910 Register dst_reg = $dst$$Register;
11911 Register src1_reg = $src1$$Register;
11912 Register src2_reg = $src2$$Register;
11914 __ orr(dst_reg, src1_reg, src2_reg);
11915 %}
11916 ins_pipe( ialu_regL_regL );
11917 %}
11919 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
11920 match(Set dst (OrL (CastP2X src1) src2));
11921 format %{ "OR $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
11922 ins_encode %{
11923 Register dst_reg = $dst$$Register;
11924 Register src1_reg = $src1$$Register;
11925 Register src2_reg = $src2$$Register;
11927 __ orr(dst_reg, src1_reg, src2_reg);
11928 %}
11929 ins_pipe( ialu_regL_regL );
11930 %}
11932 // Xor Long Register with Register
11933 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11934 match(Set dst (XorL src1 src2));
11935 format %{ "XOR $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
11936 ins_encode %{
11937 Register dst_reg = as_Register($dst$$reg);
11938 Register src1_reg = as_Register($src1$$reg);
11939 Register src2_reg = as_Register($src2$$reg);
11941 __ xorr(dst_reg, src1_reg, src2_reg);
11942 %}
11943 ins_pipe( ialu_regL_regL );
11944 %}
11946 // Shift Left by 8-bit immediate
11947 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
11948 match(Set dst (LShiftI src shift));
11950 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm" %}
11951 ins_encode %{
11952 Register src = $src$$Register;
11953 Register dst = $dst$$Register;
11954 int shamt = $shift$$constant;
11956 __ sll(dst, src, shamt);
11957 %}
11958 ins_pipe( ialu_regI_regI );
11959 %}
11961 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
11962 match(Set dst (LShiftI (ConvL2I src) shift));
11964 format %{ "SHL $dst, $src, $shift #@salL2I_Reg_imm" %}
11965 ins_encode %{
11966 Register src = $src$$Register;
11967 Register dst = $dst$$Register;
11968 int shamt = $shift$$constant;
11970 __ sll(dst, src, shamt);
11971 %}
11972 ins_pipe( ialu_regI_regI );
11973 %}
11975 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
11976 match(Set dst (AndI (LShiftI src shift) mask));
11978 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
11979 ins_encode %{
11980 Register src = $src$$Register;
11981 Register dst = $dst$$Register;
11983 __ sll(dst, src, 16);
11984 %}
11985 ins_pipe( ialu_regI_regI );
11986 %}
11988 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
11989 %{
11990 match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
11992 format %{ "andi $dst, $src, 7\t# @land7_2_s" %}
11993 ins_encode %{
11994 Register src = $src$$Register;
11995 Register dst = $dst$$Register;
11997 __ andi(dst, src, 7);
11998 %}
11999 ins_pipe(ialu_regI_regI);
12000 %}
12002 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
12003 %{
12004 match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
12006 format %{ "ori $dst, $src1, $src2\t# @ori2s" %}
12007 ins_encode %{
12008 Register src = $src1$$Register;
12009 int val = $src2$$constant;
12010 Register dst = $dst$$Register;
12012 __ ori(dst, src, val);
12013 %}
12014 ins_pipe(ialu_regI_regI);
12015 %}
12017 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
12018 // This idiom is used by the compiler the i2s bytecode.
12019 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
12020 %{
12021 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
12023 format %{ "i2s $dst, $src\t# @i2s" %}
12024 ins_encode %{
12025 Register src = $src$$Register;
12026 Register dst = $dst$$Register;
12028 __ seh(dst, src);
12029 %}
12030 ins_pipe(ialu_regI_regI);
12031 %}
12033 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
12034 // This idiom is used by the compiler for the i2b bytecode.
12035 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
12036 %{
12037 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
12039 format %{ "i2b $dst, $src\t# @i2b" %}
12040 ins_encode %{
12041 Register src = $src$$Register;
12042 Register dst = $dst$$Register;
12044 __ seb(dst, src);
12045 %}
12046 ins_pipe(ialu_regI_regI);
12047 %}
12050 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
12051 match(Set dst (LShiftI (ConvL2I src) shift));
12053 format %{ "SHL $dst, $src, $shift #@salI_RegL2I_imm" %}
12054 ins_encode %{
12055 Register src = $src$$Register;
12056 Register dst = $dst$$Register;
12057 int shamt = $shift$$constant;
12059 __ sll(dst, src, shamt);
12060 %}
12061 ins_pipe( ialu_regI_regI );
12062 %}
12064 // Shift Left by 8-bit immediate
12065 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12066 match(Set dst (LShiftI src shift));
12068 format %{ "SHL $dst, $src, $shift #@salI_Reg_Reg" %}
12069 ins_encode %{
12070 Register src = $src$$Register;
12071 Register dst = $dst$$Register;
12072 Register shamt = $shift$$Register;
12073 __ sllv(dst, src, shamt);
12074 %}
12075 ins_pipe( ialu_regI_regI );
12076 %}
12079 // Shift Left Long
12080 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
12081 //predicate(UseNewLongLShift);
12082 match(Set dst (LShiftL src shift));
12083 ins_cost(100);
12084 format %{ "salL $dst, $src, $shift @ salL_Reg_imm" %}
12085 ins_encode %{
12086 Register src_reg = as_Register($src$$reg);
12087 Register dst_reg = as_Register($dst$$reg);
12088 int shamt = $shift$$constant;
12090 if (__ is_simm(shamt, 5))
12091 __ dsll(dst_reg, src_reg, shamt);
12092 else {
12093 int sa = Assembler::low(shamt, 6);
12094 if (sa < 32) {
12095 __ dsll(dst_reg, src_reg, sa);
12096 } else {
12097 __ dsll32(dst_reg, src_reg, sa - 32);
12098 }
12099 }
12100 %}
12101 ins_pipe( ialu_regL_regL );
12102 %}
12104 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
12105 //predicate(UseNewLongLShift);
12106 match(Set dst (LShiftL (ConvI2L src) shift));
12107 ins_cost(100);
12108 format %{ "salL $dst, $src, $shift @ salL_RegI2L_imm" %}
12109 ins_encode %{
12110 Register src_reg = as_Register($src$$reg);
12111 Register dst_reg = as_Register($dst$$reg);
12112 int shamt = $shift$$constant;
12114 if (__ is_simm(shamt, 5))
12115 __ dsll(dst_reg, src_reg, shamt);
12116 else {
12117 int sa = Assembler::low(shamt, 6);
12118 if (sa < 32) {
12119 __ dsll(dst_reg, src_reg, sa);
12120 } else {
12121 __ dsll32(dst_reg, src_reg, sa - 32);
12122 }
12123 }
12124 %}
12125 ins_pipe( ialu_regL_regL );
12126 %}
12128 // Shift Left Long
12129 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12130 //predicate(UseNewLongLShift);
12131 match(Set dst (LShiftL src shift));
12132 ins_cost(100);
12133 format %{ "salL $dst, $src, $shift @ salL_Reg_Reg" %}
12134 ins_encode %{
12135 Register src_reg = as_Register($src$$reg);
12136 Register dst_reg = as_Register($dst$$reg);
12138 __ dsllv(dst_reg, src_reg, $shift$$Register);
12139 %}
12140 ins_pipe( ialu_regL_regL );
12141 %}
12143 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
12144 match(Set dst (LShiftL (ConvI2L src) shift));
12145 ins_cost(100);
12146 format %{ "salL $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
12147 ins_encode %{
12148 Register src_reg = as_Register($src$$reg);
12149 Register dst_reg = as_Register($dst$$reg);
12150 int shamt = $shift$$constant;
12152 if (__ is_simm(shamt, 5)) {
12153 __ dsll(dst_reg, src_reg, shamt);
12154 } else {
12155 int sa = Assembler::low(shamt, 6);
12156 if (sa < 32) {
12157 __ dsll(dst_reg, src_reg, sa);
12158 } else {
12159 __ dsll32(dst_reg, src_reg, sa - 32);
12160 }
12161 }
12162 %}
12163 ins_pipe( ialu_regL_regL );
12164 %}
12166 // Shift Right Long
12167 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
12168 match(Set dst (RShiftL src shift));
12169 ins_cost(100);
12170 format %{ "sarL $dst, $src, $shift @ sarL_Reg_imm" %}
12171 ins_encode %{
12172 Register src_reg = as_Register($src$$reg);
12173 Register dst_reg = as_Register($dst$$reg);
12174 int shamt = ($shift$$constant & 0x3f);
12175 if (__ is_simm(shamt, 5))
12176 __ dsra(dst_reg, src_reg, shamt);
12177 else {
12178 int sa = Assembler::low(shamt, 6);
12179 if (sa < 32) {
12180 __ dsra(dst_reg, src_reg, sa);
12181 } else {
12182 __ dsra32(dst_reg, src_reg, sa - 32);
12183 }
12184 }
12185 %}
12186 ins_pipe( ialu_regL_regL );
12187 %}
12189 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
12190 match(Set dst (ConvL2I (RShiftL src shift)));
12191 ins_cost(100);
12192 format %{ "sarL $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
12193 ins_encode %{
12194 Register src_reg = as_Register($src$$reg);
12195 Register dst_reg = as_Register($dst$$reg);
12196 int shamt = $shift$$constant;
12198 __ dsra32(dst_reg, src_reg, shamt - 32);
12199 %}
12200 ins_pipe( ialu_regL_regL );
12201 %}
12203 // Shift Right Long arithmetically
12204 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12205 //predicate(UseNewLongLShift);
12206 match(Set dst (RShiftL src shift));
12207 ins_cost(100);
12208 format %{ "sarL $dst, $src, $shift @ sarL_Reg_Reg" %}
12209 ins_encode %{
12210 Register src_reg = as_Register($src$$reg);
12211 Register dst_reg = as_Register($dst$$reg);
12213 __ dsrav(dst_reg, src_reg, $shift$$Register);
12214 %}
12215 ins_pipe( ialu_regL_regL );
12216 %}
12218 // Shift Right Long logically
12219 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12220 match(Set dst (URShiftL src shift));
12221 ins_cost(100);
12222 format %{ "slrL $dst, $src, $shift @ slrL_Reg_Reg" %}
12223 ins_encode %{
12224 Register src_reg = as_Register($src$$reg);
12225 Register dst_reg = as_Register($dst$$reg);
12227 __ dsrlv(dst_reg, src_reg, $shift$$Register);
12228 %}
12229 ins_pipe( ialu_regL_regL );
12230 %}
12232 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
12233 match(Set dst (URShiftL src shift));
12234 ins_cost(80);
12235 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
12236 ins_encode %{
12237 Register src_reg = as_Register($src$$reg);
12238 Register dst_reg = as_Register($dst$$reg);
12239 int shamt = $shift$$constant;
12241 __ dsrl(dst_reg, src_reg, shamt);
12242 %}
12243 ins_pipe( ialu_regL_regL );
12244 %}
12246 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
12247 match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
12248 ins_cost(80);
12249 format %{ "dext $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
12250 ins_encode %{
12251 Register src_reg = as_Register($src$$reg);
12252 Register dst_reg = as_Register($dst$$reg);
12253 int shamt = $shift$$constant;
12255 __ dext(dst_reg, src_reg, shamt, 31);
12256 %}
12257 ins_pipe( ialu_regL_regL );
12258 %}
12260 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
12261 match(Set dst (URShiftL (CastP2X src) shift));
12262 ins_cost(80);
12263 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
12264 ins_encode %{
12265 Register src_reg = as_Register($src$$reg);
12266 Register dst_reg = as_Register($dst$$reg);
12267 int shamt = $shift$$constant;
12269 __ dsrl(dst_reg, src_reg, shamt);
12270 %}
12271 ins_pipe( ialu_regL_regL );
12272 %}
12274 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
12275 match(Set dst (URShiftL src shift));
12276 ins_cost(80);
12277 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
12278 ins_encode %{
12279 Register src_reg = as_Register($src$$reg);
12280 Register dst_reg = as_Register($dst$$reg);
12281 int shamt = $shift$$constant;
12283 __ dsrl32(dst_reg, src_reg, shamt - 32);
12284 %}
12285 ins_pipe( ialu_regL_regL );
12286 %}
12288 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
12289 match(Set dst (ConvL2I (URShiftL src shift)));
12290 predicate(n->in(1)->in(2)->get_int() > 32);
12291 ins_cost(80);
12292 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
12293 ins_encode %{
12294 Register src_reg = as_Register($src$$reg);
12295 Register dst_reg = as_Register($dst$$reg);
12296 int shamt = $shift$$constant;
12298 __ dsrl32(dst_reg, src_reg, shamt - 32);
12299 %}
12300 ins_pipe( ialu_regL_regL );
12301 %}
12303 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
12304 match(Set dst (URShiftL (CastP2X src) shift));
12305 ins_cost(80);
12306 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
12307 ins_encode %{
12308 Register src_reg = as_Register($src$$reg);
12309 Register dst_reg = as_Register($dst$$reg);
12310 int shamt = $shift$$constant;
12312 __ dsrl32(dst_reg, src_reg, shamt - 32);
12313 %}
12314 ins_pipe( ialu_regL_regL );
12315 %}
12317 // Xor Instructions
12318 // Xor Register with Register
12319 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
12320 match(Set dst (XorI src1 src2));
12322 format %{ "XOR $dst, $src1, $src2 #@xorI_Reg_Reg" %}
12324 ins_encode %{
12325 Register dst = $dst$$Register;
12326 Register src1 = $src1$$Register;
12327 Register src2 = $src2$$Register;
12328 __ xorr(dst, src1, src2);
12329 __ sll(dst, dst, 0); /* long -> int */
12330 %}
12332 ins_pipe( ialu_regI_regI );
12333 %}
12335 // Or Instructions
12336 // Or Register with Register
12337 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
12338 match(Set dst (OrI src1 src2));
12340 format %{ "OR $dst, $src1, $src2 #@orI_Reg_Reg" %}
12341 ins_encode %{
12342 Register dst = $dst$$Register;
12343 Register src1 = $src1$$Register;
12344 Register src2 = $src2$$Register;
12345 __ orr(dst, src1, src2);
12346 %}
12348 ins_pipe( ialu_regI_regI );
12349 %}
12351 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
12352 match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
12353 predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
12355 format %{ "rotr $dst, $src, 1 ...\n\t"
12356 "srl $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
12357 ins_encode %{
12358 Register dst = $dst$$Register;
12359 Register src = $src$$Register;
12360 int rshift = $rshift$$constant;
12362 __ rotr(dst, src, 1);
12363 if (rshift - 1) {
12364 __ srl(dst, dst, rshift - 1);
12365 }
12366 %}
12368 ins_pipe( ialu_regI_regI );
12369 %}
12371 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
12372 match(Set dst (OrI src1 (CastP2X src2)));
12374 format %{ "OR $dst, $src1, $src2 #@orI_Reg_castP2X" %}
12375 ins_encode %{
12376 Register dst = $dst$$Register;
12377 Register src1 = $src1$$Register;
12378 Register src2 = $src2$$Register;
12379 __ orr(dst, src1, src2);
12380 %}
12382 ins_pipe( ialu_regI_regI );
12383 %}
12385 // Logical Shift Right by 8-bit immediate
12386 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
12387 match(Set dst (URShiftI src shift));
12388 //effect(KILL cr);
12390 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_imm" %}
12391 ins_encode %{
12392 Register src = $src$$Register;
12393 Register dst = $dst$$Register;
12394 int shift = $shift$$constant;
12396 __ srl(dst, src, shift);
12397 %}
12398 ins_pipe( ialu_regI_regI );
12399 %}
12401 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
12402 match(Set dst (AndI (URShiftI src shift) mask));
12404 format %{ "ext $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
12405 ins_encode %{
12406 Register src = $src$$Register;
12407 Register dst = $dst$$Register;
12408 int pos = $shift$$constant;
12409 int size = Assembler::is_int_mask($mask$$constant);
12411 __ ext(dst, src, pos, size);
12412 %}
12413 ins_pipe( ialu_regI_regI );
12414 %}
12416 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
12417 %{
12418 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
12419 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
12421 ins_cost(100);
12422 format %{ "rotr $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
12423 ins_encode %{
12424 Register dst = $dst$$Register;
12425 int sa = $rshift$$constant;
12427 __ rotr(dst, dst, sa);
12428 %}
12429 ins_pipe( ialu_regI_regI );
12430 %}
12432 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
12433 %{
12434 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12435 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
12437 ins_cost(100);
12438 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
12439 ins_encode %{
12440 Register dst = $dst$$Register;
12441 int sa = $rshift$$constant;
12443 __ drotr(dst, dst, sa);
12444 %}
12445 ins_pipe( ialu_regI_regI );
12446 %}
12448 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
12449 %{
12450 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12451 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
12453 ins_cost(100);
12454 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
12455 ins_encode %{
12456 Register dst = $dst$$Register;
12457 int sa = $rshift$$constant;
12459 __ drotr32(dst, dst, sa - 32);
12460 %}
12461 ins_pipe( ialu_regI_regI );
12462 %}
12464 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
12465 %{
12466 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
12467 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
12469 ins_cost(100);
12470 format %{ "rotr $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
12471 ins_encode %{
12472 Register dst = $dst$$Register;
12473 int sa = $rshift$$constant;
12475 __ rotr(dst, dst, sa);
12476 %}
12477 ins_pipe( ialu_regI_regI );
12478 %}
12480 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
12481 %{
12482 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12483 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
12485 ins_cost(100);
12486 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
12487 ins_encode %{
12488 Register dst = $dst$$Register;
12489 int sa = $rshift$$constant;
12491 __ drotr(dst, dst, sa);
12492 %}
12493 ins_pipe( ialu_regI_regI );
12494 %}
12496 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
12497 %{
12498 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12499 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
12501 ins_cost(100);
12502 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
12503 ins_encode %{
12504 Register dst = $dst$$Register;
12505 int sa = $rshift$$constant;
12507 __ drotr32(dst, dst, sa - 32);
12508 %}
12509 ins_pipe( ialu_regI_regI );
12510 %}
12512 // Logical Shift Right
12513 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12514 match(Set dst (URShiftI src shift));
12516 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_Reg" %}
12517 ins_encode %{
12518 Register src = $src$$Register;
12519 Register dst = $dst$$Register;
12520 Register shift = $shift$$Register;
12521 __ srlv(dst, src, shift);
12522 %}
12523 ins_pipe( ialu_regI_regI );
12524 %}
12527 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
12528 match(Set dst (RShiftI src shift));
12529 // effect(KILL cr);
12531 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_imm" %}
12532 ins_encode %{
12533 Register src = $src$$Register;
12534 Register dst = $dst$$Register;
12535 int shift = $shift$$constant;
12536 __ sra(dst, src, shift);
12537 %}
12538 ins_pipe( ialu_regI_regI );
12539 %}
12541 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12542 match(Set dst (RShiftI src shift));
12543 // effect(KILL cr);
12545 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_Reg" %}
12546 ins_encode %{
12547 Register src = $src$$Register;
12548 Register dst = $dst$$Register;
12549 Register shift = $shift$$Register;
12550 __ srav(dst, src, shift);
12551 %}
12552 ins_pipe( ialu_regI_regI );
12553 %}
12555 //----------Convert Int to Boolean---------------------------------------------
12557 instruct convI2B(mRegI dst, mRegI src) %{
12558 match(Set dst (Conv2B src));
12560 ins_cost(100);
12561 format %{ "convI2B $dst, $src @ convI2B" %}
12562 ins_encode %{
12563 Register dst = as_Register($dst$$reg);
12564 Register src = as_Register($src$$reg);
12566 if (dst != src) {
12567 __ daddiu(dst, R0, 1);
12568 __ movz(dst, R0, src);
12569 } else {
12570 __ move(AT, src);
12571 __ daddiu(dst, R0, 1);
12572 __ movz(dst, R0, AT);
12573 }
12574 %}
12576 ins_pipe( ialu_regL_regL );
12577 %}
12579 instruct convI2L_reg( mRegL dst, mRegI src) %{
12580 match(Set dst (ConvI2L src));
12582 ins_cost(100);
12583 format %{ "SLL $dst, $src @ convI2L_reg\t" %}
12584 ins_encode %{
12585 Register dst = as_Register($dst$$reg);
12586 Register src = as_Register($src$$reg);
12588 if(dst != src) __ sll(dst, src, 0);
12589 %}
12590 ins_pipe( ialu_regL_regL );
12591 %}
12594 instruct convL2I_reg( mRegI dst, mRegL src ) %{
12595 match(Set dst (ConvL2I src));
12597 format %{ "MOV $dst, $src @ convL2I_reg" %}
12598 ins_encode %{
12599 Register dst = as_Register($dst$$reg);
12600 Register src = as_Register($src$$reg);
12602 __ sll(dst, src, 0);
12603 %}
12605 ins_pipe( ialu_regI_regI );
12606 %}
12608 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
12609 match(Set dst (ConvI2L (ConvL2I src)));
12611 format %{ "sll $dst, $src, 0 @ convL2I2L_reg" %}
12612 ins_encode %{
12613 Register dst = as_Register($dst$$reg);
12614 Register src = as_Register($src$$reg);
12616 __ sll(dst, src, 0);
12617 %}
12619 ins_pipe( ialu_regI_regI );
12620 %}
12622 instruct convL2D_reg( regD dst, mRegL src ) %{
12623 match(Set dst (ConvL2D src));
12624 format %{ "convL2D $dst, $src @ convL2D_reg" %}
12625 ins_encode %{
12626 Register src = as_Register($src$$reg);
12627 FloatRegister dst = as_FloatRegister($dst$$reg);
12629 __ dmtc1(src, dst);
12630 __ cvt_d_l(dst, dst);
12631 %}
12633 ins_pipe( pipe_slow );
12634 %}
12637 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
12638 match(Set dst (ConvD2L src));
12639 ins_cost(150);
12640 format %{ "convD2L $dst, $src @ convD2L_reg_fast" %}
12641 ins_encode %{
12642 Register dst = as_Register($dst$$reg);
12643 FloatRegister src = as_FloatRegister($src$$reg);
12645 Label Done;
12647 __ trunc_l_d(F30, src);
12648 // max_long: 0x7fffffffffffffff
12649 // __ set64(AT, 0x7fffffffffffffff);
12650 __ daddiu(AT, R0, -1);
12651 __ dsrl(AT, AT, 1);
12652 __ dmfc1(dst, F30);
12654 __ bne(dst, AT, Done);
12655 __ delayed()->mtc1(R0, F30);
12657 __ cvt_d_w(F30, F30);
12658 __ c_ult_d(src, F30);
12659 __ bc1f(Done);
12660 __ delayed()->daddiu(T9, R0, -1);
12662 __ c_un_d(src, src); //NaN?
12663 __ subu(dst, T9, AT);
12664 __ movt(dst, R0);
12666 __ bind(Done);
12667 %}
12669 ins_pipe( pipe_slow );
12670 %}
12673 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
12674 match(Set dst (ConvD2L src));
12675 ins_cost(250);
12676 format %{ "convD2L $dst, $src @ convD2L_reg_slow" %}
12677 ins_encode %{
12678 Register dst = as_Register($dst$$reg);
12679 FloatRegister src = as_FloatRegister($src$$reg);
12681 Label L;
12683 __ c_un_d(src, src); //NaN?
12684 __ bc1t(L);
12685 __ delayed();
12686 __ move(dst, R0);
12688 __ trunc_l_d(F30, src);
12689 __ cfc1(AT, 31);
12690 __ li(T9, 0x10000);
12691 __ andr(AT, AT, T9);
12692 __ beq(AT, R0, L);
12693 __ delayed()->dmfc1(dst, F30);
12695 __ mov_d(F12, src);
12696 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
12697 __ move(dst, V0);
12698 __ bind(L);
12699 %}
12701 ins_pipe( pipe_slow );
12702 %}
12705 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
12706 match(Set dst (ConvF2I src));
12707 ins_cost(150);
12708 format %{ "convf2i $dst, $src @ convF2I_reg_fast" %}
12709 ins_encode %{
12710 Register dreg = $dst$$Register;
12711 FloatRegister fval = $src$$FloatRegister;
12712 Label L;
12714 __ trunc_w_s(F30, fval);
12715 __ move(AT, 0x7fffffff);
12716 __ mfc1(dreg, F30);
12717 __ c_un_s(fval, fval); //NaN?
12718 __ movt(dreg, R0);
12720 __ bne(AT, dreg, L);
12721 __ delayed()->lui(T9, 0x8000);
12723 __ mfc1(AT, fval);
12724 __ andr(AT, AT, T9);
12726 __ movn(dreg, T9, AT);
12728 __ bind(L);
12730 %}
12732 ins_pipe( pipe_slow );
12733 %}
12737 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
12738 match(Set dst (ConvF2I src));
12739 ins_cost(250);
12740 format %{ "convf2i $dst, $src @ convF2I_reg_slow" %}
12741 ins_encode %{
12742 Register dreg = $dst$$Register;
12743 FloatRegister fval = $src$$FloatRegister;
12744 Label L;
12746 __ c_un_s(fval, fval); //NaN?
12747 __ bc1t(L);
12748 __ delayed();
12749 __ move(dreg, R0);
12751 __ trunc_w_s(F30, fval);
12753 /* Call SharedRuntime:f2i() to do valid convention */
12754 __ cfc1(AT, 31);
12755 __ li(T9, 0x10000);
12756 __ andr(AT, AT, T9);
12757 __ beq(AT, R0, L);
12758 __ delayed()->mfc1(dreg, F30);
12760 __ mov_s(F12, fval);
12762 //This bug was found when running ezDS's control-panel.
12763 // J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
12764 //
12765 // An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
12766 // V0 is corrupted during call_VM_leaf(), and should be preserved.
12767 //
12768 __ push(fval);
12769 if(dreg != V0) {
12770 __ push(V0);
12771 }
12772 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
12773 if(dreg != V0) {
12774 __ move(dreg, V0);
12775 __ pop(V0);
12776 }
12777 __ pop(fval);
12778 __ bind(L);
12779 %}
12781 ins_pipe( pipe_slow );
12782 %}
12785 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
12786 match(Set dst (ConvF2L src));
12787 ins_cost(150);
12788 format %{ "convf2l $dst, $src @ convF2L_reg_fast" %}
12789 ins_encode %{
12790 Register dreg = $dst$$Register;
12791 FloatRegister fval = $src$$FloatRegister;
12792 Label L;
12794 __ trunc_l_s(F30, fval);
12795 __ daddiu(AT, R0, -1);
12796 __ dsrl(AT, AT, 1);
12797 __ dmfc1(dreg, F30);
12798 __ c_un_s(fval, fval); //NaN?
12799 __ movt(dreg, R0);
12801 __ bne(AT, dreg, L);
12802 __ delayed()->lui(T9, 0x8000);
12804 __ mfc1(AT, fval);
12805 __ andr(AT, AT, T9);
12807 __ dsll32(T9, T9, 0);
12808 __ movn(dreg, T9, AT);
12810 __ bind(L);
12811 %}
12813 ins_pipe( pipe_slow );
12814 %}
12817 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
12818 match(Set dst (ConvF2L src));
12819 ins_cost(250);
12820 format %{ "convf2l $dst, $src @ convF2L_reg_slow" %}
12821 ins_encode %{
12822 Register dst = as_Register($dst$$reg);
12823 FloatRegister fval = $src$$FloatRegister;
12824 Label L;
12826 __ c_un_s(fval, fval); //NaN?
12827 __ bc1t(L);
12828 __ delayed();
12829 __ move(dst, R0);
12831 __ trunc_l_s(F30, fval);
12832 __ cfc1(AT, 31);
12833 __ li(T9, 0x10000);
12834 __ andr(AT, AT, T9);
12835 __ beq(AT, R0, L);
12836 __ delayed()->dmfc1(dst, F30);
12838 __ mov_s(F12, fval);
12839 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
12840 __ move(dst, V0);
12841 __ bind(L);
12842 %}
12844 ins_pipe( pipe_slow );
12845 %}
12847 instruct convL2F_reg( regF dst, mRegL src ) %{
12848 match(Set dst (ConvL2F src));
12849 format %{ "convl2f $dst, $src @ convL2F_reg" %}
12850 ins_encode %{
12851 FloatRegister dst = $dst$$FloatRegister;
12852 Register src = as_Register($src$$reg);
12853 Label L;
12855 __ dmtc1(src, dst);
12856 __ cvt_s_l(dst, dst);
12857 %}
12859 ins_pipe( pipe_slow );
12860 %}
12862 instruct convI2F_reg( regF dst, mRegI src ) %{
12863 match(Set dst (ConvI2F src));
12864 format %{ "convi2f $dst, $src @ convI2F_reg" %}
12865 ins_encode %{
12866 Register src = $src$$Register;
12867 FloatRegister dst = $dst$$FloatRegister;
12869 __ mtc1(src, dst);
12870 __ cvt_s_w(dst, dst);
12871 %}
12873 ins_pipe( fpu_regF_regF );
12874 %}
12876 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
12877 match(Set dst (CmpLTMask p zero));
12878 ins_cost(100);
12880 format %{ "sra $dst, $p, 31 @ cmpLTMask_immI0" %}
12881 ins_encode %{
12882 Register src = $p$$Register;
12883 Register dst = $dst$$Register;
12885 __ sra(dst, src, 31);
12886 %}
12887 ins_pipe( pipe_slow );
12888 %}
12891 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
12892 match(Set dst (CmpLTMask p q));
12893 ins_cost(400);
12895 format %{ "cmpLTMask $dst, $p, $q @ cmpLTMask" %}
12896 ins_encode %{
12897 Register p = $p$$Register;
12898 Register q = $q$$Register;
12899 Register dst = $dst$$Register;
12901 __ slt(dst, p, q);
12902 __ subu(dst, R0, dst);
12903 %}
12904 ins_pipe( pipe_slow );
12905 %}
12907 instruct convP2B(mRegI dst, mRegP src) %{
12908 match(Set dst (Conv2B src));
12910 ins_cost(100);
12911 format %{ "convP2B $dst, $src @ convP2B" %}
12912 ins_encode %{
12913 Register dst = as_Register($dst$$reg);
12914 Register src = as_Register($src$$reg);
12916 if (dst != src) {
12917 __ daddiu(dst, R0, 1);
12918 __ movz(dst, R0, src);
12919 } else {
12920 __ move(AT, src);
12921 __ daddiu(dst, R0, 1);
12922 __ movz(dst, R0, AT);
12923 }
12924 %}
12926 ins_pipe( ialu_regL_regL );
12927 %}
12930 instruct convI2D_reg_reg(regD dst, mRegI src) %{
12931 match(Set dst (ConvI2D src));
12932 format %{ "conI2D $dst, $src @convI2D_reg" %}
12933 ins_encode %{
12934 Register src = $src$$Register;
12935 FloatRegister dst = $dst$$FloatRegister;
12936 __ mtc1(src, dst);
12937 __ cvt_d_w(dst, dst);
12938 %}
12939 ins_pipe( fpu_regF_regF );
12940 %}
12942 instruct convF2D_reg_reg(regD dst, regF src) %{
12943 match(Set dst (ConvF2D src));
12944 format %{ "convF2D $dst, $src\t# @convF2D_reg_reg" %}
12945 ins_encode %{
12946 FloatRegister dst = $dst$$FloatRegister;
12947 FloatRegister src = $src$$FloatRegister;
12949 __ cvt_d_s(dst, src);
12950 %}
12951 ins_pipe( fpu_regF_regF );
12952 %}
12954 instruct convD2F_reg_reg(regF dst, regD src) %{
12955 match(Set dst (ConvD2F src));
12956 format %{ "convD2F $dst, $src\t# @convD2F_reg_reg" %}
12957 ins_encode %{
12958 FloatRegister dst = $dst$$FloatRegister;
12959 FloatRegister src = $src$$FloatRegister;
12961 __ cvt_s_d(dst, src);
12962 %}
12963 ins_pipe( fpu_regF_regF );
12964 %}
12967 // Convert a double to an int. If the double is a NAN, stuff a zero in instead.
12968 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
12969 match(Set dst (ConvD2I src));
12971 ins_cost(150);
12972 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
12974 ins_encode %{
12975 FloatRegister src = $src$$FloatRegister;
12976 Register dst = $dst$$Register;
12978 Label Done;
12980 __ trunc_w_d(F30, src);
12981 // max_int: 2147483647
12982 __ move(AT, 0x7fffffff);
12983 __ mfc1(dst, F30);
12985 __ bne(dst, AT, Done);
12986 __ delayed()->mtc1(R0, F30);
12988 __ cvt_d_w(F30, F30);
12989 __ c_ult_d(src, F30);
12990 __ bc1f(Done);
12991 __ delayed()->addiu(T9, R0, -1);
12993 __ c_un_d(src, src); //NaN?
12994 __ subu32(dst, T9, AT);
12995 __ movt(dst, R0);
12997 __ bind(Done);
12998 %}
12999 ins_pipe( pipe_slow );
13000 %}
13003 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
13004 match(Set dst (ConvD2I src));
13006 ins_cost(250);
13007 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
13009 ins_encode %{
13010 FloatRegister src = $src$$FloatRegister;
13011 Register dst = $dst$$Register;
13012 Label L;
13014 __ trunc_w_d(F30, src);
13015 __ cfc1(AT, 31);
13016 __ li(T9, 0x10000);
13017 __ andr(AT, AT, T9);
13018 __ beq(AT, R0, L);
13019 __ delayed()->mfc1(dst, F30);
13021 __ mov_d(F12, src);
13022 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
13023 __ move(dst, V0);
13024 __ bind(L);
13026 %}
13027 ins_pipe( pipe_slow );
13028 %}
13030 // Convert oop pointer into compressed form
13031 instruct encodeHeapOop(mRegN dst, mRegP src) %{
13032 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
13033 match(Set dst (EncodeP src));
13034 format %{ "encode_heap_oop $dst,$src" %}
13035 ins_encode %{
13036 Register src = $src$$Register;
13037 Register dst = $dst$$Register;
13039 __ encode_heap_oop(dst, src);
13040 %}
13041 ins_pipe( ialu_regL_regL );
13042 %}
13044 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
13045 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
13046 match(Set dst (EncodeP src));
13047 format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
13048 ins_encode %{
13049 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
13050 %}
13051 ins_pipe( ialu_regL_regL );
13052 %}
13054 instruct decodeHeapOop(mRegP dst, mRegN src) %{
13055 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
13056 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
13057 match(Set dst (DecodeN src));
13058 format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
13059 ins_encode %{
13060 Register s = $src$$Register;
13061 Register d = $dst$$Register;
13063 __ decode_heap_oop(d, s);
13064 %}
13065 ins_pipe( ialu_regL_regL );
13066 %}
13068 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
13069 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
13070 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
13071 match(Set dst (DecodeN src));
13072 format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
13073 ins_encode %{
13074 Register s = $src$$Register;
13075 Register d = $dst$$Register;
13076 if (s != d) {
13077 __ decode_heap_oop_not_null(d, s);
13078 } else {
13079 __ decode_heap_oop_not_null(d);
13080 }
13081 %}
13082 ins_pipe( ialu_regL_regL );
13083 %}
13085 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
13086 match(Set dst (EncodePKlass src));
13087 format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
13088 ins_encode %{
13089 __ encode_klass_not_null($dst$$Register, $src$$Register);
13090 %}
13091 ins_pipe( ialu_regL_regL );
13092 %}
13094 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
13095 match(Set dst (DecodeNKlass src));
13096 format %{ "decode_heap_klass_not_null $dst,$src" %}
13097 ins_encode %{
13098 Register s = $src$$Register;
13099 Register d = $dst$$Register;
13100 if (s != d) {
13101 __ decode_klass_not_null(d, s);
13102 } else {
13103 __ decode_klass_not_null(d);
13104 }
13105 %}
13106 ins_pipe( ialu_regL_regL );
13107 %}
13109 //FIXME
13110 instruct tlsLoadP(mRegP dst) %{
13111 match(Set dst (ThreadLocal));
13113 ins_cost(0);
13114 format %{ " get_thread in $dst #@tlsLoadP" %}
13115 ins_encode %{
13116 Register dst = $dst$$Register;
13117 #ifdef OPT_THREAD
13118 __ move(dst, TREG);
13119 #else
13120 __ get_thread(dst);
13121 #endif
13122 %}
13124 ins_pipe( ialu_loadI );
13125 %}
13128 instruct checkCastPP( mRegP dst ) %{
13129 match(Set dst (CheckCastPP dst));
13131 format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
13132 ins_encode( /*empty encoding*/ );
13133 ins_pipe( empty );
13134 %}
13136 instruct castPP(mRegP dst)
13137 %{
13138 match(Set dst (CastPP dst));
13140 size(0);
13141 format %{ "# castPP of $dst" %}
13142 ins_encode(/* empty encoding */);
13143 ins_pipe(empty);
13144 %}
13146 instruct castII( mRegI dst ) %{
13147 match(Set dst (CastII dst));
13148 format %{ "#castII of $dst empty encoding" %}
13149 ins_encode( /*empty encoding*/ );
13150 ins_cost(0);
13151 ins_pipe( empty );
13152 %}
13154 // Return Instruction
13155 // Remove the return address & jump to it.
13156 instruct Ret() %{
13157 match(Return);
13158 format %{ "RET #@Ret" %}
13160 ins_encode %{
13161 __ jr(RA);
13162 __ delayed()->nop();
13163 %}
13165 ins_pipe( pipe_jump );
13166 %}
13168 /*
13169 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
13170 instruct jumpXtnd(mRegL switch_val) %{
13171 match(Jump switch_val);
13173 ins_cost(350);
13175 format %{ "load T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
13176 "jr T9\n\t"
13177 "nop" %}
13178 ins_encode %{
13179 Register table_base = $constanttablebase;
13180 int con_offset = $constantoffset;
13181 Register switch_reg = $switch_val$$Register;
13183 if (UseLoongsonISA) {
13184 if (Assembler::is_simm(con_offset, 8)) {
13185 __ gsldx(T9, table_base, switch_reg, con_offset);
13186 } else if (Assembler::is_simm16(con_offset)) {
13187 __ daddu(T9, table_base, switch_reg);
13188 __ ld(T9, T9, con_offset);
13189 } else {
13190 __ move(T9, con_offset);
13191 __ daddu(AT, table_base, switch_reg);
13192 __ gsldx(T9, AT, T9, 0);
13193 }
13194 } else {
13195 if (Assembler::is_simm16(con_offset)) {
13196 __ daddu(T9, table_base, switch_reg);
13197 __ ld(T9, T9, con_offset);
13198 } else {
13199 __ move(T9, con_offset);
13200 __ daddu(AT, table_base, switch_reg);
13201 __ daddu(AT, T9, AT);
13202 __ ld(T9, AT, 0);
13203 }
13204 }
13206 __ jr(T9);
13207 __ delayed()->nop();
13209 %}
13210 ins_pipe(pipe_jump);
13211 %}
13212 */
13215 // Tail Jump; remove the return address; jump to target.
13216 // TailCall above leaves the return address around.
13217 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13218 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13219 // "restore" before this instruction (in Epilogue), we need to materialize it
13220 // in %i0.
13221 //FIXME
13222 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
13223 match( TailJump jump_target ex_oop );
13224 ins_cost(200);
13225 format %{ "Jmp $jump_target ; ex_oop = $ex_oop #@tailjmpInd" %}
13226 ins_encode %{
13227 Register target = $jump_target$$Register;
13229 // V0, V1 are indicated in:
13230 // [stubGenerator_mips.cpp] generate_forward_exception()
13231 // [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
13232 //
13233 Register oop = $ex_oop$$Register;
13234 Register exception_oop = V0;
13235 Register exception_pc = V1;
13237 __ move(exception_pc, RA);
13238 __ move(exception_oop, oop);
13240 __ jr(target);
13241 __ delayed()->nop();
13242 %}
13243 ins_pipe( pipe_jump );
13244 %}
13246 // ============================================================================
13247 // Procedure Call/Return Instructions
13248 // Call Java Static Instruction
13249 // Note: If this code changes, the corresponding ret_addr_offset() and
13250 // compute_padding() functions will have to be adjusted.
13251 instruct CallStaticJavaDirect(method meth) %{
13252 match(CallStaticJava);
13253 effect(USE meth);
13255 ins_cost(300);
13256 format %{ "CALL,static #@CallStaticJavaDirect " %}
13257 ins_encode( Java_Static_Call( meth ) );
13258 ins_pipe( pipe_slow );
13259 ins_pc_relative(1);
13260 %}
13262 // Call Java Dynamic Instruction
13263 // Note: If this code changes, the corresponding ret_addr_offset() and
13264 // compute_padding() functions will have to be adjusted.
13265 instruct CallDynamicJavaDirect(method meth) %{
13266 match(CallDynamicJava);
13267 effect(USE meth);
13269 ins_cost(300);
13270 format %{"MOV IC_Klass, #Universe::non_oop_word()\n\t"
13271 "CallDynamic @ CallDynamicJavaDirect" %}
13272 ins_encode( Java_Dynamic_Call( meth ) );
13273 ins_pipe( pipe_slow );
13274 ins_pc_relative(1);
13275 %}
13277 instruct CallLeafNoFPDirect(method meth) %{
13278 match(CallLeafNoFP);
13279 effect(USE meth);
13281 ins_cost(300);
13282 format %{ "CALL_LEAF_NOFP,runtime " %}
13283 ins_encode(Java_To_Runtime(meth));
13284 ins_pipe( pipe_slow );
13285 ins_pc_relative(1);
13286 ins_alignment(16);
13287 %}
13289 // Prefetch instructions.
13291 instruct prefetchrNTA( memory mem ) %{
13292 match(PrefetchRead mem);
13293 ins_cost(125);
13295 format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
13296 ins_encode %{
13297 int base = $mem$$base;
13298 int index = $mem$$index;
13299 int scale = $mem$$scale;
13300 int disp = $mem$$disp;
13302 if( index != 0 ) {
13303 if (scale == 0) {
13304 __ daddu(AT, as_Register(base), as_Register(index));
13305 } else {
13306 __ dsll(AT, as_Register(index), scale);
13307 __ daddu(AT, as_Register(base), AT);
13308 }
13309 } else {
13310 __ move(AT, as_Register(base));
13311 }
13312 if( Assembler::is_simm16(disp) ) {
13313 __ daddiu(AT, as_Register(base), disp);
13314 __ daddiu(AT, AT, disp);
13315 } else {
13316 __ move(T9, disp);
13317 __ daddu(AT, as_Register(base), T9);
13318 }
13319 __ pref(0, AT, 0); //hint: 0:load
13320 %}
13321 ins_pipe(pipe_slow);
13322 %}
13324 instruct prefetchwNTA( memory mem ) %{
13325 match(PrefetchWrite mem);
13326 ins_cost(125);
13327 format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
13328 ins_encode %{
13329 int base = $mem$$base;
13330 int index = $mem$$index;
13331 int scale = $mem$$scale;
13332 int disp = $mem$$disp;
13334 if( index != 0 ) {
13335 if (scale == 0) {
13336 __ daddu(AT, as_Register(base), as_Register(index));
13337 } else {
13338 __ dsll(AT, as_Register(index), scale);
13339 __ daddu(AT, as_Register(base), AT);
13340 }
13341 } else {
13342 __ move(AT, as_Register(base));
13343 }
13344 if( Assembler::is_simm16(disp) ) {
13345 __ daddiu(AT, as_Register(base), disp);
13346 __ daddiu(AT, AT, disp);
13347 } else {
13348 __ move(T9, disp);
13349 __ daddu(AT, as_Register(base), T9);
13350 }
13351 __ pref(1, AT, 0); //hint: 1:store
13352 %}
13353 ins_pipe(pipe_slow);
13354 %}
13356 // Prefetch instructions for allocation.
13358 instruct prefetchAllocNTA( memory mem ) %{
13359 match(PrefetchAllocation mem);
13360 ins_cost(125);
13361 format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
13362 ins_encode %{
13363 int base = $mem$$base;
13364 int index = $mem$$index;
13365 int scale = $mem$$scale;
13366 int disp = $mem$$disp;
13368 Register dst = R0;
13370 if( index != 0 ) {
13371 if( Assembler::is_simm16(disp) ) {
13372 if( UseLoongsonISA ) {
13373 if (scale == 0) {
13374 __ gslbx(dst, as_Register(base), as_Register(index), disp);
13375 } else {
13376 __ dsll(AT, as_Register(index), scale);
13377 __ gslbx(dst, as_Register(base), AT, disp);
13378 }
13379 } else {
13380 if (scale == 0) {
13381 __ addu(AT, as_Register(base), as_Register(index));
13382 } else {
13383 __ dsll(AT, as_Register(index), scale);
13384 __ addu(AT, as_Register(base), AT);
13385 }
13386 __ lb(dst, AT, disp);
13387 }
13388 } else {
13389 if (scale == 0) {
13390 __ addu(AT, as_Register(base), as_Register(index));
13391 } else {
13392 __ dsll(AT, as_Register(index), scale);
13393 __ addu(AT, as_Register(base), AT);
13394 }
13395 __ move(T9, disp);
13396 if( UseLoongsonISA ) {
13397 __ gslbx(dst, AT, T9, 0);
13398 } else {
13399 __ addu(AT, AT, T9);
13400 __ lb(dst, AT, 0);
13401 }
13402 }
13403 } else {
13404 if( Assembler::is_simm16(disp) ) {
13405 __ lb(dst, as_Register(base), disp);
13406 } else {
13407 __ move(T9, disp);
13408 if( UseLoongsonISA ) {
13409 __ gslbx(dst, as_Register(base), T9, 0);
13410 } else {
13411 __ addu(AT, as_Register(base), T9);
13412 __ lb(dst, AT, 0);
13413 }
13414 }
13415 }
13416 %}
13417 ins_pipe(pipe_slow);
13418 %}
13421 // Call runtime without safepoint
13422 instruct CallLeafDirect(method meth) %{
13423 match(CallLeaf);
13424 effect(USE meth);
13426 ins_cost(300);
13427 format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
13428 ins_encode(Java_To_Runtime(meth));
13429 ins_pipe( pipe_slow );
13430 ins_pc_relative(1);
13431 ins_alignment(16);
13432 %}
13434 // Load Char (16bit unsigned)
13435 instruct loadUS(mRegI dst, memory mem) %{
13436 match(Set dst (LoadUS mem));
13438 ins_cost(125);
13439 format %{ "loadUS $dst,$mem @ loadC" %}
13440 ins_encode(load_C_enc(dst, mem));
13441 ins_pipe( ialu_loadI );
13442 %}
13444 instruct loadUS_convI2L(mRegL dst, memory mem) %{
13445 match(Set dst (ConvI2L (LoadUS mem)));
13447 ins_cost(125);
13448 format %{ "loadUS $dst,$mem @ loadUS_convI2L" %}
13449 ins_encode(load_C_enc(dst, mem));
13450 ins_pipe( ialu_loadI );
13451 %}
13453 // Store Char (16bit unsigned)
13454 instruct storeC(memory mem, mRegI src) %{
13455 match(Set mem (StoreC mem src));
13457 ins_cost(125);
13458 format %{ "storeC $src, $mem @ storeC" %}
13459 ins_encode(store_C_reg_enc(mem, src));
13460 ins_pipe( ialu_loadI );
13461 %}
13463 instruct storeC0(memory mem, immI0 zero) %{
13464 match(Set mem (StoreC mem zero));
13466 ins_cost(125);
13467 format %{ "storeC $zero, $mem @ storeC0" %}
13468 ins_encode(store_C0_enc(mem));
13469 ins_pipe( ialu_loadI );
13470 %}
13473 instruct loadConF0(regF dst, immF0 zero) %{
13474 match(Set dst zero);
13475 ins_cost(100);
13477 format %{ "mov $dst, zero @ loadConF0\n"%}
13478 ins_encode %{
13479 FloatRegister dst = $dst$$FloatRegister;
13481 __ mtc1(R0, dst);
13482 %}
13483 ins_pipe( fpu_loadF );
13484 %}
13487 instruct loadConF(regF dst, immF src) %{
13488 match(Set dst src);
13489 ins_cost(125);
13491 format %{ "lwc1 $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
13492 ins_encode %{
13493 int con_offset = $constantoffset($src);
13495 if (Assembler::is_simm16(con_offset)) {
13496 __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
13497 } else {
13498 __ set64(AT, con_offset);
13499 if (UseLoongsonISA) {
13500 __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
13501 } else {
13502 __ daddu(AT, $constanttablebase, AT);
13503 __ lwc1($dst$$FloatRegister, AT, 0);
13504 }
13505 }
13506 %}
13507 ins_pipe( fpu_loadF );
13508 %}
13511 instruct loadConD0(regD dst, immD0 zero) %{
13512 match(Set dst zero);
13513 ins_cost(100);
13515 format %{ "mov $dst, zero @ loadConD0"%}
13516 ins_encode %{
13517 FloatRegister dst = as_FloatRegister($dst$$reg);
13519 __ dmtc1(R0, dst);
13520 %}
13521 ins_pipe( fpu_loadF );
13522 %}
13524 instruct loadConD(regD dst, immD src) %{
13525 match(Set dst src);
13526 ins_cost(125);
13528 format %{ "ldc1 $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
13529 ins_encode %{
13530 int con_offset = $constantoffset($src);
13532 if (Assembler::is_simm16(con_offset)) {
13533 __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
13534 } else {
13535 __ set64(AT, con_offset);
13536 if (UseLoongsonISA) {
13537 __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
13538 } else {
13539 __ daddu(AT, $constanttablebase, AT);
13540 __ ldc1($dst$$FloatRegister, AT, 0);
13541 }
13542 }
13543 %}
13544 ins_pipe( fpu_loadF );
13545 %}
13547 // Store register Float value (it is faster than store from FPU register)
13548 instruct storeF_reg( memory mem, regF src) %{
13549 match(Set mem (StoreF mem src));
13551 ins_cost(50);
13552 format %{ "store $mem, $src\t# store float @ storeF_reg" %}
13553 ins_encode(store_F_reg_enc(mem, src));
13554 ins_pipe( fpu_storeF );
13555 %}
13557 instruct storeF_imm0( memory mem, immF0 zero) %{
13558 match(Set mem (StoreF mem zero));
13560 ins_cost(40);
13561 format %{ "store $mem, zero\t# store float @ storeF_imm0" %}
13562 ins_encode %{
13563 int base = $mem$$base;
13564 int index = $mem$$index;
13565 int scale = $mem$$scale;
13566 int disp = $mem$$disp;
13568 if( index != 0 ) {
13569 if ( UseLoongsonISA ) {
13570 if ( Assembler::is_simm(disp, 8) ) {
13571 if ( scale == 0 ) {
13572 __ gsswx(R0, as_Register(base), as_Register(index), disp);
13573 } else {
13574 __ dsll(T9, as_Register(index), scale);
13575 __ gsswx(R0, as_Register(base), T9, disp);
13576 }
13577 } else if ( Assembler::is_simm16(disp) ) {
13578 if ( scale == 0 ) {
13579 __ daddu(AT, as_Register(base), as_Register(index));
13580 } else {
13581 __ dsll(T9, as_Register(index), scale);
13582 __ daddu(AT, as_Register(base), T9);
13583 }
13584 __ sw(R0, AT, disp);
13585 } else {
13586 if ( scale == 0 ) {
13587 __ move(T9, disp);
13588 __ daddu(AT, as_Register(index), T9);
13589 __ gsswx(R0, as_Register(base), AT, 0);
13590 } else {
13591 __ dsll(T9, as_Register(index), scale);
13592 __ move(AT, disp);
13593 __ daddu(AT, AT, T9);
13594 __ gsswx(R0, as_Register(base), AT, 0);
13595 }
13596 }
13597 } else { //not use loongson isa
13598 if(scale != 0) {
13599 __ dsll(T9, as_Register(index), scale);
13600 __ daddu(AT, as_Register(base), T9);
13601 } else {
13602 __ daddu(AT, as_Register(base), as_Register(index));
13603 }
13604 if( Assembler::is_simm16(disp) ) {
13605 __ sw(R0, AT, disp);
13606 } else {
13607 __ move(T9, disp);
13608 __ daddu(AT, AT, T9);
13609 __ sw(R0, AT, 0);
13610 }
13611 }
13612 } else { //index is 0
13613 if ( UseLoongsonISA ) {
13614 if ( Assembler::is_simm16(disp) ) {
13615 __ sw(R0, as_Register(base), disp);
13616 } else {
13617 __ move(T9, disp);
13618 __ gsswx(R0, as_Register(base), T9, 0);
13619 }
13620 } else {
13621 if( Assembler::is_simm16(disp) ) {
13622 __ sw(R0, as_Register(base), disp);
13623 } else {
13624 __ move(T9, disp);
13625 __ daddu(AT, as_Register(base), T9);
13626 __ sw(R0, AT, 0);
13627 }
13628 }
13629 }
13630 %}
13631 ins_pipe( ialu_storeI );
13632 %}
13634 // Load Double
13635 instruct loadD(regD dst, memory mem) %{
13636 match(Set dst (LoadD mem));
13638 ins_cost(150);
13639 format %{ "loadD $dst, $mem #@loadD" %}
13640 ins_encode(load_D_enc(dst, mem));
13641 ins_pipe( ialu_loadI );
13642 %}
13644 // Load Double - UNaligned
13645 instruct loadD_unaligned(regD dst, memory mem ) %{
13646 match(Set dst (LoadD_unaligned mem));
13647 ins_cost(250);
13648 // FIXME: Need more effective ldl/ldr
13649 format %{ "loadD_unaligned $dst, $mem #@loadD_unaligned" %}
13650 ins_encode(load_D_enc(dst, mem));
13651 ins_pipe( ialu_loadI );
13652 %}
13654 instruct storeD_reg( memory mem, regD src) %{
13655 match(Set mem (StoreD mem src));
13657 ins_cost(50);
13658 format %{ "store $mem, $src\t# store float @ storeD_reg" %}
13659 ins_encode(store_D_reg_enc(mem, src));
13660 ins_pipe( fpu_storeF );
13661 %}
13663 instruct storeD_imm0( memory mem, immD0 zero) %{
13664 match(Set mem (StoreD mem zero));
13666 ins_cost(40);
13667 format %{ "store $mem, zero\t# store float @ storeD_imm0" %}
13668 ins_encode %{
13669 int base = $mem$$base;
13670 int index = $mem$$index;
13671 int scale = $mem$$scale;
13672 int disp = $mem$$disp;
13674 __ mtc1(R0, F30);
13675 __ cvt_d_w(F30, F30);
13677 if( index != 0 ) {
13678 if ( UseLoongsonISA ) {
13679 if ( Assembler::is_simm(disp, 8) ) {
13680 if (scale == 0) {
13681 __ gssdxc1(F30, as_Register(base), as_Register(index), disp);
13682 } else {
13683 __ dsll(T9, as_Register(index), scale);
13684 __ gssdxc1(F30, as_Register(base), T9, disp);
13685 }
13686 } else if ( Assembler::is_simm16(disp) ) {
13687 if (scale == 0) {
13688 __ daddu(AT, as_Register(base), as_Register(index));
13689 __ sdc1(F30, AT, disp);
13690 } else {
13691 __ dsll(T9, as_Register(index), scale);
13692 __ daddu(AT, as_Register(base), T9);
13693 __ sdc1(F30, AT, disp);
13694 }
13695 } else {
13696 if (scale == 0) {
13697 __ move(T9, disp);
13698 __ daddu(AT, as_Register(index), T9);
13699 __ gssdxc1(F30, as_Register(base), AT, 0);
13700 } else {
13701 __ move(T9, disp);
13702 __ dsll(AT, as_Register(index), scale);
13703 __ daddu(AT, AT, T9);
13704 __ gssdxc1(F30, as_Register(base), AT, 0);
13705 }
13706 }
13707 } else { // not use loongson isa
13708 if(scale != 0) {
13709 __ dsll(T9, as_Register(index), scale);
13710 __ daddu(AT, as_Register(base), T9);
13711 } else {
13712 __ daddu(AT, as_Register(base), as_Register(index));
13713 }
13714 if( Assembler::is_simm16(disp) ) {
13715 __ sdc1(F30, AT, disp);
13716 } else {
13717 __ move(T9, disp);
13718 __ daddu(AT, AT, T9);
13719 __ sdc1(F30, AT, 0);
13720 }
13721 }
13722 } else {// index is 0
13723 if ( UseLoongsonISA ) {
13724 if ( Assembler::is_simm16(disp) ) {
13725 __ sdc1(F30, as_Register(base), disp);
13726 } else {
13727 __ move(T9, disp);
13728 __ gssdxc1(F30, as_Register(base), T9, 0);
13729 }
13730 } else {
13731 if( Assembler::is_simm16(disp) ) {
13732 __ sdc1(F30, as_Register(base), disp);
13733 } else {
13734 __ move(T9, disp);
13735 __ daddu(AT, as_Register(base), T9);
13736 __ sdc1(F30, AT, 0);
13737 }
13738 }
13739 }
13740 %}
13741 ins_pipe( ialu_storeI );
13742 %}
13744 instruct loadSSI(mRegI dst, stackSlotI src)
13745 %{
13746 match(Set dst src);
13748 ins_cost(125);
13749 format %{ "lw $dst, $src\t# int stk @ loadSSI" %}
13750 ins_encode %{
13751 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
13752 __ lw($dst$$Register, SP, $src$$disp);
13753 %}
13754 ins_pipe(ialu_loadI);
13755 %}
13757 instruct storeSSI(stackSlotI dst, mRegI src)
13758 %{
13759 match(Set dst src);
13761 ins_cost(100);
13762 format %{ "sw $dst, $src\t# int stk @ storeSSI" %}
13763 ins_encode %{
13764 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
13765 __ sw($src$$Register, SP, $dst$$disp);
13766 %}
13767 ins_pipe(ialu_storeI);
13768 %}
13770 instruct loadSSL(mRegL dst, stackSlotL src)
13771 %{
13772 match(Set dst src);
13774 ins_cost(125);
13775 format %{ "ld $dst, $src\t# long stk @ loadSSL" %}
13776 ins_encode %{
13777 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
13778 __ ld($dst$$Register, SP, $src$$disp);
13779 %}
13780 ins_pipe(ialu_loadI);
13781 %}
13783 instruct storeSSL(stackSlotL dst, mRegL src)
13784 %{
13785 match(Set dst src);
13787 ins_cost(100);
13788 format %{ "sd $dst, $src\t# long stk @ storeSSL" %}
13789 ins_encode %{
13790 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
13791 __ sd($src$$Register, SP, $dst$$disp);
13792 %}
13793 ins_pipe(ialu_storeI);
13794 %}
13796 instruct loadSSP(mRegP dst, stackSlotP src)
13797 %{
13798 match(Set dst src);
13800 ins_cost(125);
13801 format %{ "ld $dst, $src\t# ptr stk @ loadSSP" %}
13802 ins_encode %{
13803 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
13804 __ ld($dst$$Register, SP, $src$$disp);
13805 %}
13806 ins_pipe(ialu_loadI);
13807 %}
13809 instruct storeSSP(stackSlotP dst, mRegP src)
13810 %{
13811 match(Set dst src);
13813 ins_cost(100);
13814 format %{ "sd $dst, $src\t# ptr stk @ storeSSP" %}
13815 ins_encode %{
13816 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
13817 __ sd($src$$Register, SP, $dst$$disp);
13818 %}
13819 ins_pipe(ialu_storeI);
13820 %}
13822 instruct loadSSF(regF dst, stackSlotF src)
13823 %{
13824 match(Set dst src);
13826 ins_cost(125);
13827 format %{ "lwc1 $dst, $src\t# float stk @ loadSSF" %}
13828 ins_encode %{
13829 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
13830 __ lwc1($dst$$FloatRegister, SP, $src$$disp);
13831 %}
13832 ins_pipe(ialu_loadI);
13833 %}
13835 instruct storeSSF(stackSlotF dst, regF src)
13836 %{
13837 match(Set dst src);
13839 ins_cost(100);
13840 format %{ "swc1 $dst, $src\t# float stk @ storeSSF" %}
13841 ins_encode %{
13842 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
13843 __ swc1($src$$FloatRegister, SP, $dst$$disp);
13844 %}
13845 ins_pipe(fpu_storeF);
13846 %}
13848 // Use the same format since predicate() can not be used here.
13849 instruct loadSSD(regD dst, stackSlotD src)
13850 %{
13851 match(Set dst src);
13853 ins_cost(125);
13854 format %{ "ldc1 $dst, $src\t# double stk @ loadSSD" %}
13855 ins_encode %{
13856 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
13857 __ ldc1($dst$$FloatRegister, SP, $src$$disp);
13858 %}
13859 ins_pipe(ialu_loadI);
13860 %}
13862 instruct storeSSD(stackSlotD dst, regD src)
13863 %{
13864 match(Set dst src);
13866 ins_cost(100);
13867 format %{ "sdc1 $dst, $src\t# double stk @ storeSSD" %}
13868 ins_encode %{
13869 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
13870 __ sdc1($src$$FloatRegister, SP, $dst$$disp);
13871 %}
13872 ins_pipe(fpu_storeF);
13873 %}
13875 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
13876 match( Set cr (FastLock object box) );
13877 effect( TEMP tmp, TEMP scr, USE_KILL box );
13878 ins_cost(300);
13879 format %{ "FASTLOCK $cr <-- $object, $box, $tmp, $scr #@ cmpFastLock" %}
13880 ins_encode %{
13881 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
13882 %}
13884 ins_pipe( pipe_slow );
13885 ins_pc_relative(1);
13886 %}
13888 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
13889 match( Set cr (FastUnlock object box) );
13890 effect( TEMP tmp, USE_KILL box );
13891 ins_cost(300);
13892 format %{ "FASTUNLOCK $cr <-- $object, $box, $tmp #@cmpFastUnlock" %}
13893 ins_encode %{
13894 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
13895 %}
13897 ins_pipe( pipe_slow );
13898 ins_pc_relative(1);
13899 %}
13901 // Store CMS card-mark Immediate
13902 instruct storeImmCM(memory mem, immI8 src) %{
13903 match(Set mem (StoreCM mem src));
13905 ins_cost(150);
13906 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %}
13907 // opcode(0xC6);
13908 ins_encode(store_B_immI_enc_sync(mem, src));
13909 ins_pipe( ialu_storeI );
13910 %}
13912 // Die now
13913 instruct ShouldNotReachHere( )
13914 %{
13915 match(Halt);
13916 ins_cost(300);
13918 // Use the following format syntax
13919 format %{ "ILLTRAP ;#@ShouldNotReachHere" %}
13920 ins_encode %{
13921 // Here we should emit illtrap !
13923 __ stop("in ShoudNotReachHere");
13925 %}
13926 ins_pipe( pipe_jump );
13927 %}
13929 instruct leaP8Narrow(mRegP dst, indOffset8Narrow mem)
13930 %{
13931 predicate(Universe::narrow_oop_shift() == 0);
13932 match(Set dst mem);
13934 ins_cost(110);
13935 format %{ "leaq $dst, $mem\t# ptr off8narrow @ leaP8Narrow" %}
13936 ins_encode %{
13937 Register dst = $dst$$Register;
13938 Register base = as_Register($mem$$base);
13939 int disp = $mem$$disp;
13941 __ daddiu(dst, base, disp);
13942 %}
13943 ins_pipe( ialu_regI_imm16 );
13944 %}
13946 instruct leaPPosIdxScaleOff8(mRegP dst, basePosIndexScaleOffset8 mem)
13947 %{
13948 match(Set dst mem);
13950 ins_cost(110);
13951 format %{ "leaq $dst, $mem\t# @ PosIdxScaleOff8" %}
13952 ins_encode %{
13953 Register dst = $dst$$Register;
13954 Register base = as_Register($mem$$base);
13955 Register index = as_Register($mem$$index);
13956 int scale = $mem$$scale;
13957 int disp = $mem$$disp;
13959 if (scale == 0) {
13960 __ daddu(AT, base, index);
13961 __ daddiu(dst, AT, disp);
13962 } else {
13963 __ dsll(AT, index, scale);
13964 __ daddu(AT, base, AT);
13965 __ daddiu(dst, AT, disp);
13966 }
13967 %}
13969 ins_pipe( ialu_regI_imm16 );
13970 %}
13972 instruct leaPIdxScale(mRegP dst, indIndexScale mem)
13973 %{
13974 match(Set dst mem);
13976 ins_cost(110);
13977 format %{ "leaq $dst, $mem\t# @ leaPIdxScale" %}
13978 ins_encode %{
13979 Register dst = $dst$$Register;
13980 Register base = as_Register($mem$$base);
13981 Register index = as_Register($mem$$index);
13982 int scale = $mem$$scale;
13984 if (scale == 0) {
13985 __ daddu(dst, base, index);
13986 } else {
13987 __ dsll(AT, index, scale);
13988 __ daddu(dst, base, AT);
13989 }
13990 %}
13992 ins_pipe( ialu_regI_imm16 );
13993 %}
13996 // ============================================================================
13997 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
13998 // array for an instance of the superklass. Set a hidden internal cache on a
13999 // hit (cache is checked with exposed code in gen_subtype_check()). Return
14000 // NZ for a miss or zero for a hit. The encoding ALSO sets flags.
14001 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
14002 match(Set result (PartialSubtypeCheck sub super));
14003 effect(KILL tmp);
14004 ins_cost(1100); // slightly larger than the next version
14005 format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
14007 ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
14008 ins_pipe( pipe_slow );
14009 %}
14012 // Conditional-store of an int value.
14013 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
14014 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
14015 match(Set cr (StoreIConditional mem (Binary oldval newval)));
14016 // effect(KILL oldval);
14017 format %{ "CMPXCHG $newval, $mem, $oldval \t# @storeIConditional" %}
14019 ins_encode %{
14020 Register oldval = $oldval$$Register;
14021 Register newval = $newval$$Register;
14022 Address addr(as_Register($mem$$base), $mem$$disp);
14023 Label again, failure;
14025 int index = $mem$$index;
14026 int scale = $mem$$scale;
14027 int disp = $mem$$disp;
14029 guarantee(Assembler::is_simm16(disp), "");
14031 if( index != 0 ) {
14032 __ stop("in storeIConditional: index != 0");
14033 } else {
14034 __ bind(again);
14035 if(UseSyncLevel >= 3000 || UseSyncLevel < 2000) __ sync();
14036 __ ll(AT, addr);
14037 __ bne(AT, oldval, failure);
14038 __ delayed()->addu(AT, R0, R0);
14040 __ addu(AT, newval, R0);
14041 __ sc(AT, addr);
14042 __ beq(AT, R0, again);
14043 __ delayed()->addiu(AT, R0, 0xFF);
14044 __ bind(failure);
14045 __ sync();
14046 }
14047 %}
14049 ins_pipe( long_memory_op );
14050 %}
14052 // Conditional-store of a long value.
14053 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
14054 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
14055 %{
14056 match(Set cr (StoreLConditional mem (Binary oldval newval)));
14057 effect(KILL oldval);
14059 format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
14060 ins_encode%{
14061 Register oldval = $oldval$$Register;
14062 Register newval = $newval$$Register;
14063 Address addr(as_Register($mem$$base), $mem$$disp);
14065 int index = $mem$$index;
14066 int scale = $mem$$scale;
14067 int disp = $mem$$disp;
14069 guarantee(Assembler::is_simm16(disp), "");
14071 if( index != 0 ) {
14072 __ stop("in storeIConditional: index != 0");
14073 } else {
14074 __ cmpxchg(newval, addr, oldval);
14075 }
14076 %}
14077 ins_pipe( long_memory_op );
14078 %}
14081 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
14082 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
14083 effect(KILL oldval);
14084 // match(CompareAndSwapI mem_ptr (Binary oldval newval));
14085 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapL\n\t"
14086 "MOV $res, 1 @ compareAndSwapI\n\t"
14087 "BNE AT, R0 @ compareAndSwapI\n\t"
14088 "MOV $res, 0 @ compareAndSwapI\n"
14089 "L:" %}
14090 ins_encode %{
14091 Register newval = $newval$$Register;
14092 Register oldval = $oldval$$Register;
14093 Register res = $res$$Register;
14094 Address addr($mem_ptr$$Register, 0);
14095 Label L;
14097 __ cmpxchg32(newval, addr, oldval);
14098 __ move(res, AT);
14099 %}
14100 ins_pipe( long_memory_op );
14101 %}
14103 instruct compareAndSwapL( mRegI res, mRegP mem_ptr, s2RegL oldval, mRegL newval) %{
14104 predicate(VM_Version::supports_cx8());
14105 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
14106 effect(KILL oldval);
14107 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
14108 "MOV $res, 1 @ compareAndSwapI\n\t"
14109 "BNE AT, R0 @ compareAndSwapI\n\t"
14110 "MOV $res, 0 @ compareAndSwapI\n"
14111 "L:" %}
14112 ins_encode %{
14113 Register newval = $newval$$Register;
14114 Register oldval = $oldval$$Register;
14115 Register res = $res$$Register;
14116 Address addr($mem_ptr$$Register, 0);
14117 Label L;
14119 __ cmpxchg(newval, addr, oldval);
14120 __ move(res, AT);
14121 %}
14122 ins_pipe( long_memory_op );
14123 %}
14125 //FIXME:
14126 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
14127 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
14128 effect(KILL oldval);
14129 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
14130 "MOV $res, AT @ compareAndSwapP\n\t"
14131 "L:" %}
14132 ins_encode %{
14133 Register newval = $newval$$Register;
14134 Register oldval = $oldval$$Register;
14135 Register res = $res$$Register;
14136 Address addr($mem_ptr$$Register, 0);
14137 Label L;
14139 __ cmpxchg(newval, addr, oldval);
14140 __ move(res, AT);
14141 %}
14142 ins_pipe( long_memory_op );
14143 %}
14145 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
14146 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
14147 effect(KILL oldval);
14148 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
14149 "MOV $res, AT @ compareAndSwapN\n\t"
14150 "L:" %}
14151 ins_encode %{
14152 Register newval = $newval$$Register;
14153 Register oldval = $oldval$$Register;
14154 Register res = $res$$Register;
14155 Address addr($mem_ptr$$Register, 0);
14156 Label L;
14158 // cmpxchg32 is implemented with ll/sc, which will do sign extension.
14159 // Thus, we should extend oldval's sign for correct comparision.
14160 //
14161 __ sll(oldval, oldval, 0);
14163 __ cmpxchg32(newval, addr, oldval);
14164 __ move(res, AT);
14165 %}
14166 ins_pipe( long_memory_op );
14167 %}
14169 //----------Max and Min--------------------------------------------------------
14170 // Min Instructions
14171 ////
14172 // *** Min and Max using the conditional move are slower than the
14173 // *** branch version on a Pentium III.
14174 // // Conditional move for min
14175 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
14176 // effect( USE_DEF op2, USE op1, USE cr );
14177 // format %{ "CMOVlt $op2,$op1\t! min" %}
14178 // opcode(0x4C,0x0F);
14179 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
14180 // ins_pipe( pipe_cmov_reg );
14181 //%}
14182 //
14183 //// Min Register with Register (P6 version)
14184 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
14185 // predicate(VM_Version::supports_cmov() );
14186 // match(Set op2 (MinI op1 op2));
14187 // ins_cost(200);
14188 // expand %{
14189 // eFlagsReg cr;
14190 // compI_eReg(cr,op1,op2);
14191 // cmovI_reg_lt(op2,op1,cr);
14192 // %}
14193 //%}
14195 // Min Register with Register (generic version)
14196 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
14197 match(Set dst (MinI dst src));
14198 //effect(KILL flags);
14199 ins_cost(80);
14201 format %{ "MIN $dst, $src @minI_Reg_Reg" %}
14202 ins_encode %{
14203 Register dst = $dst$$Register;
14204 Register src = $src$$Register;
14206 __ slt(AT, src, dst);
14207 __ movn(dst, src, AT);
14209 %}
14211 ins_pipe( pipe_slow );
14212 %}
14214 // Max Register with Register
14215 // *** Min and Max using the conditional move are slower than the
14216 // *** branch version on a Pentium III.
14217 // // Conditional move for max
14218 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
14219 // effect( USE_DEF op2, USE op1, USE cr );
14220 // format %{ "CMOVgt $op2,$op1\t! max" %}
14221 // opcode(0x4F,0x0F);
14222 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
14223 // ins_pipe( pipe_cmov_reg );
14224 //%}
14225 //
14226 // // Max Register with Register (P6 version)
14227 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
14228 // predicate(VM_Version::supports_cmov() );
14229 // match(Set op2 (MaxI op1 op2));
14230 // ins_cost(200);
14231 // expand %{
14232 // eFlagsReg cr;
14233 // compI_eReg(cr,op1,op2);
14234 // cmovI_reg_gt(op2,op1,cr);
14235 // %}
14236 //%}
14238 // Max Register with Register (generic version)
14239 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
14240 match(Set dst (MaxI dst src));
14241 ins_cost(80);
14243 format %{ "MAX $dst, $src @maxI_Reg_Reg" %}
14245 ins_encode %{
14246 Register dst = $dst$$Register;
14247 Register src = $src$$Register;
14249 __ slt(AT, dst, src);
14250 __ movn(dst, src, AT);
14252 %}
14254 ins_pipe( pipe_slow );
14255 %}
14257 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
14258 match(Set dst (MaxI dst zero));
14259 ins_cost(50);
14261 format %{ "MAX $dst, 0 @maxI_Reg_zero" %}
14263 ins_encode %{
14264 Register dst = $dst$$Register;
14266 __ slt(AT, dst, R0);
14267 __ movn(dst, R0, AT);
14269 %}
14271 ins_pipe( pipe_slow );
14272 %}
14274 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
14275 %{
14276 match(Set dst (AndL src mask));
14278 format %{ "movl $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
14279 ins_encode %{
14280 Register dst = $dst$$Register;
14281 Register src = $src$$Register;
14283 __ dext(dst, src, 0, 32);
14284 %}
14285 ins_pipe(ialu_regI_regI);
14286 %}
14288 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
14289 %{
14290 match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
14292 format %{ "combine_i2l $dst, $src2(H), $src1(L) @ combine_i2l" %}
14293 ins_encode %{
14294 Register dst = $dst$$Register;
14295 Register src1 = $src1$$Register;
14296 Register src2 = $src2$$Register;
14298 if (src1 == dst) {
14299 __ dinsu(dst, src2, 32, 32);
14300 } else if (src2 == dst) {
14301 __ dsll32(dst, dst, 0);
14302 __ dins(dst, src1, 0, 32);
14303 } else {
14304 __ dext(dst, src1, 0, 32);
14305 __ dinsu(dst, src2, 32, 32);
14306 }
14307 %}
14308 ins_pipe(ialu_regI_regI);
14309 %}
14311 // Zero-extend convert int to long
14312 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
14313 %{
14314 match(Set dst (AndL (ConvI2L src) mask));
14316 format %{ "movl $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
14317 ins_encode %{
14318 Register dst = $dst$$Register;
14319 Register src = $src$$Register;
14321 __ dext(dst, src, 0, 32);
14322 %}
14323 ins_pipe(ialu_regI_regI);
14324 %}
14326 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
14327 %{
14328 match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
14330 format %{ "movl $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
14331 ins_encode %{
14332 Register dst = $dst$$Register;
14333 Register src = $src$$Register;
14335 __ dext(dst, src, 0, 32);
14336 %}
14337 ins_pipe(ialu_regI_regI);
14338 %}
14340 // Match loading integer and casting it to unsigned int in long register.
14341 // LoadI + ConvI2L + AndL 0xffffffff.
14342 instruct loadUI2L_rmask(mRegL dst, memory mem, immL_32bits mask) %{
14343 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
14345 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
14346 ins_encode (load_N_enc(dst, mem));
14347 ins_pipe(ialu_loadI);
14348 %}
14350 instruct loadUI2L_lmask(mRegL dst, memory mem, immL_32bits mask) %{
14351 match(Set dst (AndL mask (ConvI2L (LoadI mem))));
14353 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
14354 ins_encode (load_N_enc(dst, mem));
14355 ins_pipe(ialu_loadI);
14356 %}
14359 // ============================================================================
14360 // Safepoint Instruction
14361 instruct safePoint_poll_reg(mRegP poll) %{
14362 match(SafePoint poll);
14363 predicate(false);
14364 effect(USE poll);
14366 ins_cost(125);
14367 format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
14369 ins_encode %{
14370 Register poll_reg = $poll$$Register;
14372 __ block_comment("Safepoint:");
14373 __ relocate(relocInfo::poll_type);
14374 __ lw(AT, poll_reg, 0);
14375 %}
14377 ins_pipe( ialu_storeI );
14378 %}
14380 instruct safePoint_poll() %{
14381 match(SafePoint);
14383 ins_cost(105);
14384 format %{ "poll for GC @ safePoint_poll" %}
14386 ins_encode %{
14387 __ block_comment("Safepoint:");
14388 __ set64(T9, (long)os::get_polling_page());
14389 __ relocate(relocInfo::poll_type);
14390 __ lw(AT, T9, 0);
14391 %}
14393 ins_pipe( ialu_storeI );
14394 %}
14396 //----------Arithmetic Conversion Instructions---------------------------------
14398 instruct roundFloat_nop(regF dst)
14399 %{
14400 match(Set dst (RoundFloat dst));
14402 ins_cost(0);
14403 ins_encode();
14404 ins_pipe(empty);
14405 %}
14407 instruct roundDouble_nop(regD dst)
14408 %{
14409 match(Set dst (RoundDouble dst));
14411 ins_cost(0);
14412 ins_encode();
14413 ins_pipe(empty);
14414 %}
14416 //---------- Zeros Count Instructions ------------------------------------------
14417 // CountLeadingZerosINode CountTrailingZerosINode
14418 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
14419 predicate(UseCountLeadingZerosInstructionMIPS64);
14420 match(Set dst (CountLeadingZerosI src));
14422 format %{ "clz $dst, $src\t# count leading zeros (int)" %}
14423 ins_encode %{
14424 __ clz($dst$$Register, $src$$Register);
14425 %}
14426 ins_pipe( ialu_regL_regL );
14427 %}
14429 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
14430 predicate(UseCountLeadingZerosInstructionMIPS64);
14431 match(Set dst (CountLeadingZerosL src));
14433 format %{ "dclz $dst, $src\t# count leading zeros (long)" %}
14434 ins_encode %{
14435 __ dclz($dst$$Register, $src$$Register);
14436 %}
14437 ins_pipe( ialu_regL_regL );
14438 %}
14440 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
14441 predicate(UseCountTrailingZerosInstructionMIPS64);
14442 match(Set dst (CountTrailingZerosI src));
14444 format %{ "ctz $dst, $src\t# count trailing zeros (int)" %}
14445 ins_encode %{
14446 // ctz and dctz is gs instructions.
14447 __ ctz($dst$$Register, $src$$Register);
14448 %}
14449 ins_pipe( ialu_regL_regL );
14450 %}
14452 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
14453 predicate(UseCountTrailingZerosInstructionMIPS64);
14454 match(Set dst (CountTrailingZerosL src));
14456 format %{ "dcto $dst, $src\t# count trailing zeros (long)" %}
14457 ins_encode %{
14458 __ dctz($dst$$Register, $src$$Register);
14459 %}
14460 ins_pipe( ialu_regL_regL );
14461 %}
14463 // ====================VECTOR INSTRUCTIONS=====================================
14465 // Load vectors (8 bytes long)
14466 instruct loadV8(vecD dst, memory mem) %{
14467 predicate(n->as_LoadVector()->memory_size() == 8);
14468 match(Set dst (LoadVector mem));
14469 ins_cost(125);
14470 format %{ "load $dst, $mem\t! load vector (8 bytes)" %}
14471 ins_encode(load_D_enc(dst, mem));
14472 ins_pipe( fpu_loadF );
14473 %}
14475 // Store vectors (8 bytes long)
14476 instruct storeV8(memory mem, vecD src) %{
14477 predicate(n->as_StoreVector()->memory_size() == 8);
14478 match(Set mem (StoreVector mem src));
14479 ins_cost(145);
14480 format %{ "store $mem, $src\t! store vector (8 bytes)" %}
14481 ins_encode(store_D_reg_enc(mem, src));
14482 ins_pipe( fpu_storeF );
14483 %}
14485 instruct Repl8B_DSP(vecD dst, mRegI src) %{
14486 predicate(n->as_Vector()->length() == 8 && Use3A2000);
14487 match(Set dst (ReplicateB src));
14488 ins_cost(100);
14489 format %{ "replv_ob AT, $src\n\t"
14490 "dmtc1 AT, $dst\t! replicate8B" %}
14491 ins_encode %{
14492 __ replv_ob(AT, $src$$Register);
14493 __ dmtc1(AT, $dst$$FloatRegister);
14494 %}
14495 ins_pipe( pipe_mtc1 );
14496 %}
14498 instruct Repl8B(vecD dst, mRegI src) %{
14499 predicate(n->as_Vector()->length() == 8);
14500 match(Set dst (ReplicateB src));
14501 ins_cost(140);
14502 format %{ "move AT, $src\n\t"
14503 "dins AT, AT, 8, 8\n\t"
14504 "dins AT, AT, 16, 16\n\t"
14505 "dinsu AT, AT, 32, 32\n\t"
14506 "dmtc1 AT, $dst\t! replicate8B" %}
14507 ins_encode %{
14508 __ move(AT, $src$$Register);
14509 __ dins(AT, AT, 8, 8);
14510 __ dins(AT, AT, 16, 16);
14511 __ dinsu(AT, AT, 32, 32);
14512 __ dmtc1(AT, $dst$$FloatRegister);
14513 %}
14514 ins_pipe( pipe_mtc1 );
14515 %}
14517 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
14518 predicate(n->as_Vector()->length() == 8 && Use3A2000);
14519 match(Set dst (ReplicateB con));
14520 ins_cost(110);
14521 format %{ "repl_ob AT, [$con]\n\t"
14522 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
14523 ins_encode %{
14524 int val = $con$$constant;
14525 __ repl_ob(AT, val);
14526 __ dmtc1(AT, $dst$$FloatRegister);
14527 %}
14528 ins_pipe( pipe_mtc1 );
14529 %}
14531 instruct Repl8B_imm(vecD dst, immI con) %{
14532 predicate(n->as_Vector()->length() == 8);
14533 match(Set dst (ReplicateB con));
14534 ins_cost(150);
14535 format %{ "move AT, [$con]\n\t"
14536 "dins AT, AT, 8, 8\n\t"
14537 "dins AT, AT, 16, 16\n\t"
14538 "dinsu AT, AT, 32, 32\n\t"
14539 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
14540 ins_encode %{
14541 __ move(AT, $con$$constant);
14542 __ dins(AT, AT, 8, 8);
14543 __ dins(AT, AT, 16, 16);
14544 __ dinsu(AT, AT, 32, 32);
14545 __ dmtc1(AT, $dst$$FloatRegister);
14546 %}
14547 ins_pipe( pipe_mtc1 );
14548 %}
14550 instruct Repl8B_zero(vecD dst, immI0 zero) %{
14551 predicate(n->as_Vector()->length() == 8);
14552 match(Set dst (ReplicateB zero));
14553 ins_cost(90);
14554 format %{ "dmtc1 R0, $dst\t! replicate8B zero" %}
14555 ins_encode %{
14556 __ dmtc1(R0, $dst$$FloatRegister);
14557 %}
14558 ins_pipe( pipe_mtc1 );
14559 %}
14561 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
14562 predicate(n->as_Vector()->length() == 8);
14563 match(Set dst (ReplicateB M1));
14564 ins_cost(80);
14565 format %{ "dmtc1 -1, $dst\t! replicate8B -1" %}
14566 ins_encode %{
14567 __ nor(AT, R0, R0);
14568 __ dmtc1(AT, $dst$$FloatRegister);
14569 %}
14570 ins_pipe( pipe_mtc1 );
14571 %}
14573 instruct Repl4S_DSP(vecD dst, mRegI src) %{
14574 predicate(n->as_Vector()->length() == 4 && Use3A2000);
14575 match(Set dst (ReplicateS src));
14576 ins_cost(100);
14577 format %{ "replv_qh AT, $src\n\t"
14578 "dmtc1 AT, $dst\t! replicate4S" %}
14579 ins_encode %{
14580 __ replv_qh(AT, $src$$Register);
14581 __ dmtc1(AT, $dst$$FloatRegister);
14582 %}
14583 ins_pipe( pipe_mtc1 );
14584 %}
14586 instruct Repl4S(vecD dst, mRegI src) %{
14587 predicate(n->as_Vector()->length() == 4);
14588 match(Set dst (ReplicateS src));
14589 ins_cost(120);
14590 format %{ "move AT, $src \n\t"
14591 "dins AT, AT, 16, 16\n\t"
14592 "dinsu AT, AT, 32, 32\n\t"
14593 "dmtc1 AT, $dst\t! replicate4S" %}
14594 ins_encode %{
14595 __ move(AT, $src$$Register);
14596 __ dins(AT, AT, 16, 16);
14597 __ dinsu(AT, AT, 32, 32);
14598 __ dmtc1(AT, $dst$$FloatRegister);
14599 %}
14600 ins_pipe( pipe_mtc1 );
14601 %}
14603 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
14604 predicate(n->as_Vector()->length() == 4 && Use3A2000);
14605 match(Set dst (ReplicateS con));
14606 ins_cost(100);
14607 format %{ "repl_qh AT, [$con]\n\t"
14608 "dmtc1 AT, $dst\t! replicate4S($con)" %}
14609 ins_encode %{
14610 int val = $con$$constant;
14611 if ( Assembler::is_simm(val, 10)) {
14612 //repl_qh supports 10 bits immediate
14613 __ repl_qh(AT, val);
14614 } else {
14615 __ li32(AT, val);
14616 __ replv_qh(AT, AT);
14617 }
14618 __ dmtc1(AT, $dst$$FloatRegister);
14619 %}
14620 ins_pipe( pipe_mtc1 );
14621 %}
14623 instruct Repl4S_imm(vecD dst, immI con) %{
14624 predicate(n->as_Vector()->length() == 4);
14625 match(Set dst (ReplicateS con));
14626 ins_cost(110);
14627 format %{ "move AT, [$con]\n\t"
14628 "dins AT, AT, 16, 16\n\t"
14629 "dinsu AT, AT, 32, 32\n\t"
14630 "dmtc1 AT, $dst\t! replicate4S($con)" %}
14631 ins_encode %{
14632 __ move(AT, $con$$constant);
14633 __ dins(AT, AT, 16, 16);
14634 __ dinsu(AT, AT, 32, 32);
14635 __ dmtc1(AT, $dst$$FloatRegister);
14636 %}
14637 ins_pipe( pipe_mtc1 );
14638 %}
14640 instruct Repl4S_zero(vecD dst, immI0 zero) %{
14641 predicate(n->as_Vector()->length() == 4);
14642 match(Set dst (ReplicateS zero));
14643 format %{ "dmtc1 R0, $dst\t! replicate4S zero" %}
14644 ins_encode %{
14645 __ dmtc1(R0, $dst$$FloatRegister);
14646 %}
14647 ins_pipe( pipe_mtc1 );
14648 %}
14650 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
14651 predicate(n->as_Vector()->length() == 4);
14652 match(Set dst (ReplicateS M1));
14653 format %{ "dmtc1 -1, $dst\t! replicate4S -1" %}
14654 ins_encode %{
14655 __ nor(AT, R0, R0);
14656 __ dmtc1(AT, $dst$$FloatRegister);
14657 %}
14658 ins_pipe( pipe_mtc1 );
14659 %}
14661 // Replicate integer (4 byte) scalar to be vector
14662 instruct Repl2I(vecD dst, mRegI src) %{
14663 predicate(n->as_Vector()->length() == 2);
14664 match(Set dst (ReplicateI src));
14665 format %{ "dins AT, $src, 0, 32\n\t"
14666 "dinsu AT, $src, 32, 32\n\t"
14667 "dmtc1 AT, $dst\t! replicate2I" %}
14668 ins_encode %{
14669 __ dins(AT, $src$$Register, 0, 32);
14670 __ dinsu(AT, $src$$Register, 32, 32);
14671 __ dmtc1(AT, $dst$$FloatRegister);
14672 %}
14673 ins_pipe( pipe_mtc1 );
14674 %}
14676 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
14677 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
14678 predicate(n->as_Vector()->length() == 2);
14679 match(Set dst (ReplicateI con));
14680 effect(KILL tmp);
14681 format %{ "li32 AT, [$con], 32\n\t"
14682 "dinsu AT, AT\n\t"
14683 "dmtc1 AT, $dst\t! replicate2I($con)" %}
14684 ins_encode %{
14685 int val = $con$$constant;
14686 __ li32(AT, val);
14687 __ dinsu(AT, AT, 32, 32);
14688 __ dmtc1(AT, $dst$$FloatRegister);
14689 %}
14690 ins_pipe( pipe_mtc1 );
14691 %}
14693 // Replicate integer (4 byte) scalar zero to be vector
14694 instruct Repl2I_zero(vecD dst, immI0 zero) %{
14695 predicate(n->as_Vector()->length() == 2);
14696 match(Set dst (ReplicateI zero));
14697 format %{ "dmtc1 R0, $dst\t! replicate2I zero" %}
14698 ins_encode %{
14699 __ dmtc1(R0, $dst$$FloatRegister);
14700 %}
14701 ins_pipe( pipe_mtc1 );
14702 %}
14704 // Replicate integer (4 byte) scalar -1 to be vector
14705 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
14706 predicate(n->as_Vector()->length() == 2);
14707 match(Set dst (ReplicateI M1));
14708 format %{ "dmtc1 -1, $dst\t! replicate2I -1, use AT" %}
14709 ins_encode %{
14710 __ nor(AT, R0, R0);
14711 __ dmtc1(AT, $dst$$FloatRegister);
14712 %}
14713 ins_pipe( pipe_mtc1 );
14714 %}
14716 // Replicate float (4 byte) scalar to be vector
14717 instruct Repl2F(vecD dst, regF src) %{
14718 predicate(n->as_Vector()->length() == 2);
14719 match(Set dst (ReplicateF src));
14720 format %{ "cvt.ps $dst, $src, $src\t! replicate2F" %}
14721 ins_encode %{
14722 __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
14723 %}
14724 ins_pipe( pipe_slow );
14725 %}
14727 // Replicate float (4 byte) scalar zero to be vector
14728 instruct Repl2F_zero(vecD dst, immF0 zero) %{
14729 predicate(n->as_Vector()->length() == 2);
14730 match(Set dst (ReplicateF zero));
14731 format %{ "dmtc1 R0, $dst\t! replicate2F zero" %}
14732 ins_encode %{
14733 __ dmtc1(R0, $dst$$FloatRegister);
14734 %}
14735 ins_pipe( pipe_mtc1 );
14736 %}
14739 // ====================VECTOR ARITHMETIC=======================================
14741 // --------------------------------- ADD --------------------------------------
14743 // Floats vector add
14744 // kernel does not have emulation of PS instructions yet, so PS instructions is disabled.
14745 instruct vadd2F(vecD dst, vecD src) %{
14746 predicate(n->as_Vector()->length() == 2);
14747 match(Set dst (AddVF dst src));
14748 format %{ "add.ps $dst,$src\t! add packed2F" %}
14749 ins_encode %{
14750 __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14751 %}
14752 ins_pipe( pipe_slow );
14753 %}
14755 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
14756 predicate(n->as_Vector()->length() == 2);
14757 match(Set dst (AddVF src1 src2));
14758 format %{ "add.ps $dst,$src1,$src2\t! add packed2F" %}
14759 ins_encode %{
14760 __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14761 %}
14762 ins_pipe( fpu_regF_regF );
14763 %}
14765 // --------------------------------- SUB --------------------------------------
14767 // Floats vector sub
14768 instruct vsub2F(vecD dst, vecD src) %{
14769 predicate(n->as_Vector()->length() == 2);
14770 match(Set dst (SubVF dst src));
14771 format %{ "sub.ps $dst,$src\t! sub packed2F" %}
14772 ins_encode %{
14773 __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14774 %}
14775 ins_pipe( fpu_regF_regF );
14776 %}
14778 // --------------------------------- MUL --------------------------------------
14780 // Floats vector mul
14781 instruct vmul2F(vecD dst, vecD src) %{
14782 predicate(n->as_Vector()->length() == 2);
14783 match(Set dst (MulVF dst src));
14784 format %{ "mul.ps $dst, $src\t! mul packed2F" %}
14785 ins_encode %{
14786 __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14787 %}
14788 ins_pipe( fpu_regF_regF );
14789 %}
14791 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
14792 predicate(n->as_Vector()->length() == 2);
14793 match(Set dst (MulVF src1 src2));
14794 format %{ "mul.ps $dst, $src1, $src2\t! mul packed2F" %}
14795 ins_encode %{
14796 __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14797 %}
14798 ins_pipe( fpu_regF_regF );
14799 %}
14801 // --------------------------------- DIV --------------------------------------
14802 // MIPS do not have div.ps
14804 // --------------------------------- MADD --------------------------------------
14805 // Floats vector madd
14806 //instruct vmadd2F(vecD dst, vecD src1, vecD src2, vecD src3) %{
14807 // predicate(n->as_Vector()->length() == 2);
14808 // match(Set dst (AddVF (MulVF src1 src2) src3));
14809 // ins_cost(50);
14810 // format %{ "madd.ps $dst, $src3, $src1, $src2\t! madd packed2F" %}
14811 // ins_encode %{
14812 // __ madd_ps($dst$$FloatRegister, $src3$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14813 // %}
14814 // ins_pipe( fpu_regF_regF );
14815 //%}
14818 //----------PEEPHOLE RULES-----------------------------------------------------
14819 // These must follow all instruction definitions as they use the names
14820 // defined in the instructions definitions.
14821 //
14822 // peepmatch ( root_instr_name [preceeding_instruction]* );
14823 //
14824 // peepconstraint %{
14825 // (instruction_number.operand_name relational_op instruction_number.operand_name
14826 // [, ...] );
14827 // // instruction numbers are zero-based using left to right order in peepmatch
14828 //
14829 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14830 // // provide an instruction_number.operand_name for each operand that appears
14831 // // in the replacement instruction's match rule
14832 //
14833 // ---------VM FLAGS---------------------------------------------------------
14834 //
14835 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14836 //
14837 // Each peephole rule is given an identifying number starting with zero and
14838 // increasing by one in the order seen by the parser. An individual peephole
14839 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14840 // on the command-line.
14841 //
14842 // ---------CURRENT LIMITATIONS----------------------------------------------
14843 //
14844 // Only match adjacent instructions in same basic block
14845 // Only equality constraints
14846 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14847 // Only one replacement instruction
14848 //
14849 // ---------EXAMPLE----------------------------------------------------------
14850 //
14851 // // pertinent parts of existing instructions in architecture description
14852 // instruct movI(eRegI dst, eRegI src) %{
14853 // match(Set dst (CopyI src));
14854 // %}
14855 //
14856 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14857 // match(Set dst (AddI dst src));
14858 // effect(KILL cr);
14859 // %}
14860 //
14861 // // Change (inc mov) to lea
14862 // peephole %{
14863 // // increment preceeded by register-register move
14864 // peepmatch ( incI_eReg movI );
14865 // // require that the destination register of the increment
14866 // // match the destination register of the move
14867 // peepconstraint ( 0.dst == 1.dst );
14868 // // construct a replacement instruction that sets
14869 // // the destination to ( move's source register + one )
14870 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14871 // %}
14872 //
14873 // Implementation no longer uses movX instructions since
14874 // machine-independent system no longer uses CopyX nodes.
14875 //
14876 // peephole %{
14877 // peepmatch ( incI_eReg movI );
14878 // peepconstraint ( 0.dst == 1.dst );
14879 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14880 // %}
14881 //
14882 // peephole %{
14883 // peepmatch ( decI_eReg movI );
14884 // peepconstraint ( 0.dst == 1.dst );
14885 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14886 // %}
14887 //
14888 // peephole %{
14889 // peepmatch ( addI_eReg_imm movI );
14890 // peepconstraint ( 0.dst == 1.dst );
14891 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14892 // %}
14893 //
14894 // peephole %{
14895 // peepmatch ( addP_eReg_imm movP );
14896 // peepconstraint ( 0.dst == 1.dst );
14897 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
14898 // %}
14900 // // Change load of spilled value to only a spill
14901 // instruct storeI(memory mem, eRegI src) %{
14902 // match(Set mem (StoreI mem src));
14903 // %}
14904 //
14905 // instruct loadI(eRegI dst, memory mem) %{
14906 // match(Set dst (LoadI mem));
14907 // %}
14908 //
14909 //peephole %{
14910 // peepmatch ( loadI storeI );
14911 // peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14912 // peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14913 //%}
14915 //----------SMARTSPILL RULES---------------------------------------------------
14916 // These must follow all instruction definitions as they use the names
14917 // defined in the instructions definitions.