Fri, 07 Sep 2018 10:24:01 +0800
fixed a gcc 4.9.3 warning
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 cmovN_cmpL_reg_reg(mRegN dst, mRegN src, mRegL tmp1, mRegL tmp2, cmpOp cop) %{
9798 match(Set dst (CMoveN (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
9799 ins_cost(80);
9800 format %{
9801 "CMP$cop $tmp1, $tmp2\t @cmovN_cmpL_reg_reg\n"
9802 "\tCMOV $dst,$src \t @cmovN_cmpL_reg_reg"
9803 %}
9804 ins_encode %{
9805 Register opr1 = as_Register($tmp1$$reg);
9806 Register opr2 = as_Register($tmp2$$reg);
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, opr1, opr2);
9814 __ movz(dst, src, AT);
9815 break;
9817 case 0x02: //not_equal
9818 __ subu(AT, opr1, opr2);
9819 __ movn(dst, src, AT);
9820 break;
9822 case 0x03: //greater
9823 __ slt(AT, opr2, opr1);
9824 __ movn(dst, src, AT);
9825 break;
9827 case 0x04: //greater_equal
9828 __ slt(AT, opr1, opr2);
9829 __ movz(dst, src, AT);
9830 break;
9832 case 0x05: //less
9833 __ slt(AT, opr1, opr2);
9834 __ movn(dst, src, AT);
9835 break;
9837 case 0x06: //less_equal
9838 __ slt(AT, opr2, opr1);
9839 __ movz(dst, src, AT);
9840 break;
9842 default:
9843 Unimplemented();
9844 }
9845 %}
9847 ins_pipe( pipe_slow );
9848 %}
9850 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9851 match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9852 ins_cost(80);
9853 format %{
9854 "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
9855 "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
9856 %}
9857 ins_encode %{
9858 Register op1 = $tmp1$$Register;
9859 Register op2 = $tmp2$$Register;
9860 Register dst = $dst$$Register;
9861 Register src = $src$$Register;
9862 int flag = $cop$$cmpcode;
9864 switch(flag) {
9865 case 0x01: //equal
9866 __ subu32(AT, op1, op2);
9867 __ movz(dst, src, AT);
9868 break;
9870 case 0x02: //not_equal
9871 __ subu32(AT, op1, op2);
9872 __ movn(dst, src, AT);
9873 break;
9875 case 0x03: //above
9876 __ slt(AT, op2, op1);
9877 __ movn(dst, src, AT);
9878 break;
9880 case 0x04: //above_equal
9881 __ slt(AT, op1, op2);
9882 __ movz(dst, src, AT);
9883 break;
9885 case 0x05: //below
9886 __ slt(AT, op1, op2);
9887 __ movn(dst, src, AT);
9888 break;
9890 case 0x06: //below_equal
9891 __ slt(AT, op2, op1);
9892 __ movz(dst, src, AT);
9893 break;
9895 default:
9896 Unimplemented();
9897 }
9898 %}
9900 ins_pipe( pipe_slow );
9901 %}
9903 instruct cmovL_cmpU_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
9904 match(Set dst (CMoveL (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
9905 ins_cost(80);
9906 format %{
9907 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpU_reg_reg\n\t"
9908 "CMOV $dst,$src\t @cmovL_cmpU_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 __ sltu(AT, op2, op1);
9930 __ movn(dst, src, AT);
9931 break;
9933 case 0x04: //above_equal
9934 __ sltu(AT, op1, op2);
9935 __ movz(dst, src, AT);
9936 break;
9938 case 0x05: //below
9939 __ sltu(AT, op1, op2);
9940 __ movn(dst, src, AT);
9941 break;
9943 case 0x06: //below_equal
9944 __ sltu(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_cmpF_reg_reg(mRegL dst, mRegL src, regF tmp1, regF tmp2, cmpOp cop ) %{
9957 match(Set dst (CMoveL (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
9958 ins_cost(80);
9959 format %{
9960 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpF_reg_reg\n"
9961 "\tCMOV $dst,$src \t @cmovL_cmpF_reg_reg"
9962 %}
9964 ins_encode %{
9965 FloatRegister reg_op1 = $tmp1$$FloatRegister;
9966 FloatRegister reg_op2 = $tmp2$$FloatRegister;
9967 Register dst = $dst$$Register;
9968 Register src = $src$$Register;
9969 int flag = $cop$$cmpcode;
9971 switch(flag) {
9972 case 0x01: //equal
9973 __ c_eq_s(reg_op1, reg_op2);
9974 __ movt(dst, src);
9975 break;
9976 case 0x02: //not_equal
9977 __ c_eq_s(reg_op1, reg_op2);
9978 __ movf(dst, src);
9979 break;
9980 case 0x03: //greater
9981 __ c_ole_s(reg_op1, reg_op2);
9982 __ movf(dst, src);
9983 break;
9984 case 0x04: //greater_equal
9985 __ c_olt_s(reg_op1, reg_op2);
9986 __ movf(dst, src);
9987 break;
9988 case 0x05: //less
9989 __ c_ult_s(reg_op1, reg_op2);
9990 __ movt(dst, src);
9991 break;
9992 case 0x06: //less_equal
9993 __ c_ule_s(reg_op1, reg_op2);
9994 __ movt(dst, src);
9995 break;
9996 default:
9997 Unimplemented();
9998 }
9999 %}
10000 ins_pipe( pipe_slow );
10001 %}
10003 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10004 match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10005 ins_cost(80);
10006 format %{
10007 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpI_reg_reg\n"
10008 "\tCMOV $dst,$src \t @cmovL_cmpI_reg_reg"
10009 %}
10011 ins_encode %{
10012 Register op1 = $tmp1$$Register;
10013 Register op2 = $tmp2$$Register;
10014 Register dst = as_Register($dst$$reg);
10015 Register src = as_Register($src$$reg);
10016 int flag = $cop$$cmpcode;
10018 switch(flag)
10019 {
10020 case 0x01: //equal
10021 __ subu32(AT, op1, op2);
10022 __ movz(dst, src, AT);
10023 break;
10025 case 0x02: //not_equal
10026 __ subu32(AT, op1, op2);
10027 __ movn(dst, src, AT);
10028 break;
10030 case 0x03: //great
10031 __ slt(AT, op2, op1);
10032 __ movn(dst, src, AT);
10033 break;
10035 case 0x04: //great_equal
10036 __ slt(AT, op1, op2);
10037 __ movz(dst, src, AT);
10038 break;
10040 case 0x05: //less
10041 __ slt(AT, op1, op2);
10042 __ movn(dst, src, AT);
10043 break;
10045 case 0x06: //less_equal
10046 __ slt(AT, op2, op1);
10047 __ movz(dst, src, AT);
10048 break;
10050 default:
10051 Unimplemented();
10052 }
10053 %}
10055 ins_pipe( pipe_slow );
10056 %}
10058 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
10059 match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
10060 ins_cost(80);
10061 format %{
10062 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpL_reg_reg\n"
10063 "\tCMOV $dst,$src \t @cmovL_cmpL_reg_reg"
10064 %}
10065 ins_encode %{
10066 Register opr1 = as_Register($tmp1$$reg);
10067 Register opr2 = as_Register($tmp2$$reg);
10068 Register dst = as_Register($dst$$reg);
10069 Register src = as_Register($src$$reg);
10070 int flag = $cop$$cmpcode;
10072 switch(flag) {
10073 case 0x01: //equal
10074 __ subu(AT, opr1, opr2);
10075 __ movz(dst, src, AT);
10076 break;
10078 case 0x02: //not_equal
10079 __ subu(AT, opr1, opr2);
10080 __ movn(dst, src, AT);
10081 break;
10083 case 0x03: //greater
10084 __ slt(AT, opr2, opr1);
10085 __ movn(dst, src, AT);
10086 break;
10088 case 0x04: //greater_equal
10089 __ slt(AT, opr1, opr2);
10090 __ movz(dst, src, AT);
10091 break;
10093 case 0x05: //less
10094 __ slt(AT, opr1, opr2);
10095 __ movn(dst, src, AT);
10096 break;
10098 case 0x06: //less_equal
10099 __ slt(AT, opr2, opr1);
10100 __ movz(dst, src, AT);
10101 break;
10103 default:
10104 Unimplemented();
10105 }
10106 %}
10108 ins_pipe( pipe_slow );
10109 %}
10111 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
10112 match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
10113 ins_cost(80);
10114 format %{
10115 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
10116 "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
10117 %}
10118 ins_encode %{
10119 Register op1 = $tmp1$$Register;
10120 Register op2 = $tmp2$$Register;
10121 Register dst = $dst$$Register;
10122 Register src = $src$$Register;
10123 int flag = $cop$$cmpcode;
10125 switch(flag) {
10126 case 0x01: //equal
10127 __ subu32(AT, op1, op2);
10128 __ movz(dst, src, AT);
10129 break;
10131 case 0x02: //not_equal
10132 __ subu32(AT, op1, op2);
10133 __ movn(dst, src, AT);
10134 break;
10136 case 0x03: //above
10137 __ sltu(AT, op2, op1);
10138 __ movn(dst, src, AT);
10139 break;
10141 case 0x04: //above_equal
10142 __ sltu(AT, op1, op2);
10143 __ movz(dst, src, AT);
10144 break;
10146 case 0x05: //below
10147 __ sltu(AT, op1, op2);
10148 __ movn(dst, src, AT);
10149 break;
10151 case 0x06: //below_equal
10152 __ sltu(AT, op2, op1);
10153 __ movz(dst, src, AT);
10154 break;
10156 default:
10157 Unimplemented();
10158 }
10159 %}
10161 ins_pipe( pipe_slow );
10162 %}
10165 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
10166 match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
10167 ins_cost(80);
10168 format %{
10169 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpD_reg_reg\n"
10170 "\tCMOV $dst,$src \t @cmovL_cmpD_reg_reg"
10171 %}
10172 ins_encode %{
10173 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
10174 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
10175 Register dst = as_Register($dst$$reg);
10176 Register src = as_Register($src$$reg);
10178 int flag = $cop$$cmpcode;
10180 switch(flag) {
10181 case 0x01: //equal
10182 __ c_eq_d(reg_op1, reg_op2);
10183 __ movt(dst, src);
10184 break;
10185 case 0x02: //not_equal
10186 __ c_eq_d(reg_op1, reg_op2);
10187 __ movf(dst, src);
10188 break;
10189 case 0x03: //greater
10190 __ c_ole_d(reg_op1, reg_op2);
10191 __ movf(dst, src);
10192 break;
10193 case 0x04: //greater_equal
10194 __ c_olt_d(reg_op1, reg_op2);
10195 __ movf(dst, src);
10196 break;
10197 case 0x05: //less
10198 __ c_ult_d(reg_op1, reg_op2);
10199 __ movt(dst, src);
10200 break;
10201 case 0x06: //less_equal
10202 __ c_ule_d(reg_op1, reg_op2);
10203 __ movt(dst, src);
10204 break;
10205 default:
10206 Unimplemented();
10207 }
10208 %}
10210 ins_pipe( pipe_slow );
10211 %}
10213 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
10214 match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
10215 ins_cost(200);
10216 format %{
10217 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpD_reg_reg\n"
10218 "\tCMOV $dst,$src \t @cmovD_cmpD_reg_reg"
10219 %}
10220 ins_encode %{
10221 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
10222 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
10223 FloatRegister dst = as_FloatRegister($dst$$reg);
10224 FloatRegister src = as_FloatRegister($src$$reg);
10226 int flag = $cop$$cmpcode;
10228 switch(flag) {
10229 case 0x01: //equal
10230 __ c_eq_d(reg_op1, reg_op2);
10231 __ movt_d(dst, src);
10232 break;
10233 case 0x02: //not_equal
10234 __ c_eq_d(reg_op1, reg_op2);
10235 __ movf_d(dst, src);
10236 break;
10237 case 0x03: //greater
10238 __ c_ole_d(reg_op1, reg_op2);
10239 __ movf_d(dst, src);
10240 break;
10241 case 0x04: //greater_equal
10242 __ c_olt_d(reg_op1, reg_op2);
10243 __ movf_d(dst, src);
10244 break;
10245 case 0x05: //less
10246 __ c_ult_d(reg_op1, reg_op2);
10247 __ movt_d(dst, src);
10248 break;
10249 case 0x06: //less_equal
10250 __ c_ule_d(reg_op1, reg_op2);
10251 __ movt_d(dst, src);
10252 break;
10253 default:
10254 Unimplemented();
10255 }
10256 %}
10258 ins_pipe( pipe_slow );
10259 %}
10261 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10262 match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10263 ins_cost(200);
10264 format %{
10265 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpI_reg_reg\n"
10266 "\tCMOV $dst, $src \t @cmovF_cmpI_reg_reg"
10267 %}
10269 ins_encode %{
10270 Register op1 = $tmp1$$Register;
10271 Register op2 = $tmp2$$Register;
10272 FloatRegister dst = as_FloatRegister($dst$$reg);
10273 FloatRegister src = as_FloatRegister($src$$reg);
10274 int flag = $cop$$cmpcode;
10275 Label L;
10277 switch(flag) {
10278 case 0x01: //equal
10279 __ bne(op1, op2, L);
10280 __ delayed()->nop();
10281 __ mov_s(dst, src);
10282 __ bind(L);
10283 break;
10284 case 0x02: //not_equal
10285 __ beq(op1, op2, L);
10286 __ delayed()->nop();
10287 __ mov_s(dst, src);
10288 __ bind(L);
10289 break;
10290 case 0x03: //great
10291 __ slt(AT, op2, op1);
10292 __ beq(AT, R0, L);
10293 __ delayed()->nop();
10294 __ mov_s(dst, src);
10295 __ bind(L);
10296 break;
10297 case 0x04: //great_equal
10298 __ slt(AT, op1, op2);
10299 __ bne(AT, R0, L);
10300 __ delayed()->nop();
10301 __ mov_s(dst, src);
10302 __ bind(L);
10303 break;
10304 case 0x05: //less
10305 __ slt(AT, op1, op2);
10306 __ beq(AT, R0, L);
10307 __ delayed()->nop();
10308 __ mov_s(dst, src);
10309 __ bind(L);
10310 break;
10311 case 0x06: //less_equal
10312 __ slt(AT, op2, op1);
10313 __ bne(AT, R0, L);
10314 __ delayed()->nop();
10315 __ mov_s(dst, src);
10316 __ bind(L);
10317 break;
10318 default:
10319 Unimplemented();
10320 }
10321 %}
10323 ins_pipe( pipe_slow );
10324 %}
10326 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10327 match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10328 ins_cost(200);
10329 format %{
10330 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpI_reg_reg\n"
10331 "\tCMOV $dst, $src \t @cmovD_cmpI_reg_reg"
10332 %}
10334 ins_encode %{
10335 Register op1 = $tmp1$$Register;
10336 Register op2 = $tmp2$$Register;
10337 FloatRegister dst = as_FloatRegister($dst$$reg);
10338 FloatRegister src = as_FloatRegister($src$$reg);
10339 int flag = $cop$$cmpcode;
10340 Label L;
10342 switch(flag) {
10343 case 0x01: //equal
10344 __ bne(op1, op2, L);
10345 __ delayed()->nop();
10346 __ mov_d(dst, src);
10347 __ bind(L);
10348 break;
10349 case 0x02: //not_equal
10350 __ beq(op1, op2, L);
10351 __ delayed()->nop();
10352 __ mov_d(dst, src);
10353 __ bind(L);
10354 break;
10355 case 0x03: //great
10356 __ slt(AT, op2, op1);
10357 __ beq(AT, R0, L);
10358 __ delayed()->nop();
10359 __ mov_d(dst, src);
10360 __ bind(L);
10361 break;
10362 case 0x04: //great_equal
10363 __ slt(AT, op1, op2);
10364 __ bne(AT, R0, L);
10365 __ delayed()->nop();
10366 __ mov_d(dst, src);
10367 __ bind(L);
10368 break;
10369 case 0x05: //less
10370 __ slt(AT, op1, op2);
10371 __ beq(AT, R0, L);
10372 __ delayed()->nop();
10373 __ mov_d(dst, src);
10374 __ bind(L);
10375 break;
10376 case 0x06: //less_equal
10377 __ slt(AT, op2, op1);
10378 __ bne(AT, R0, L);
10379 __ delayed()->nop();
10380 __ mov_d(dst, src);
10381 __ bind(L);
10382 break;
10383 default:
10384 Unimplemented();
10385 }
10386 %}
10388 ins_pipe( pipe_slow );
10389 %}
10391 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
10392 match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
10393 ins_cost(200);
10394 format %{
10395 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpP_reg_reg\n"
10396 "\tCMOV $dst, $src \t @cmovD_cmpP_reg_reg"
10397 %}
10399 ins_encode %{
10400 Register op1 = $tmp1$$Register;
10401 Register op2 = $tmp2$$Register;
10402 FloatRegister dst = as_FloatRegister($dst$$reg);
10403 FloatRegister src = as_FloatRegister($src$$reg);
10404 int flag = $cop$$cmpcode;
10405 Label L;
10407 switch(flag) {
10408 case 0x01: //equal
10409 __ bne(op1, op2, L);
10410 __ delayed()->nop();
10411 __ mov_d(dst, src);
10412 __ bind(L);
10413 break;
10414 case 0x02: //not_equal
10415 __ beq(op1, op2, L);
10416 __ delayed()->nop();
10417 __ mov_d(dst, src);
10418 __ bind(L);
10419 break;
10420 case 0x03: //great
10421 __ slt(AT, op2, op1);
10422 __ beq(AT, R0, L);
10423 __ delayed()->nop();
10424 __ mov_d(dst, src);
10425 __ bind(L);
10426 break;
10427 case 0x04: //great_equal
10428 __ slt(AT, op1, op2);
10429 __ bne(AT, R0, L);
10430 __ delayed()->nop();
10431 __ mov_d(dst, src);
10432 __ bind(L);
10433 break;
10434 case 0x05: //less
10435 __ slt(AT, op1, op2);
10436 __ beq(AT, R0, L);
10437 __ delayed()->nop();
10438 __ mov_d(dst, src);
10439 __ bind(L);
10440 break;
10441 case 0x06: //less_equal
10442 __ slt(AT, op2, op1);
10443 __ bne(AT, R0, L);
10444 __ delayed()->nop();
10445 __ mov_d(dst, src);
10446 __ bind(L);
10447 break;
10448 default:
10449 Unimplemented();
10450 }
10451 %}
10453 ins_pipe( pipe_slow );
10454 %}
10456 //FIXME
10457 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
10458 match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
10459 ins_cost(80);
10460 format %{
10461 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpF_reg_reg\n"
10462 "\tCMOV $dst,$src \t @cmovI_cmpF_reg_reg"
10463 %}
10465 ins_encode %{
10466 FloatRegister reg_op1 = $tmp1$$FloatRegister;
10467 FloatRegister reg_op2 = $tmp2$$FloatRegister;
10468 Register dst = $dst$$Register;
10469 Register src = $src$$Register;
10470 int flag = $cop$$cmpcode;
10472 switch(flag) {
10473 case 0x01: //equal
10474 __ c_eq_s(reg_op1, reg_op2);
10475 __ movt(dst, src);
10476 break;
10477 case 0x02: //not_equal
10478 __ c_eq_s(reg_op1, reg_op2);
10479 __ movf(dst, src);
10480 break;
10481 case 0x03: //greater
10482 __ c_ole_s(reg_op1, reg_op2);
10483 __ movf(dst, src);
10484 break;
10485 case 0x04: //greater_equal
10486 __ c_olt_s(reg_op1, reg_op2);
10487 __ movf(dst, src);
10488 break;
10489 case 0x05: //less
10490 __ c_ult_s(reg_op1, reg_op2);
10491 __ movt(dst, src);
10492 break;
10493 case 0x06: //less_equal
10494 __ c_ule_s(reg_op1, reg_op2);
10495 __ movt(dst, src);
10496 break;
10497 default:
10498 Unimplemented();
10499 }
10500 %}
10501 ins_pipe( pipe_slow );
10502 %}
10504 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
10505 match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
10506 ins_cost(200);
10507 format %{
10508 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpF_reg_reg\n"
10509 "\tCMOV $dst,$src \t @cmovF_cmpF_reg_reg"
10510 %}
10512 ins_encode %{
10513 FloatRegister reg_op1 = $tmp1$$FloatRegister;
10514 FloatRegister reg_op2 = $tmp2$$FloatRegister;
10515 FloatRegister dst = $dst$$FloatRegister;
10516 FloatRegister src = $src$$FloatRegister;
10517 int flag = $cop$$cmpcode;
10519 switch(flag) {
10520 case 0x01: //equal
10521 __ c_eq_s(reg_op1, reg_op2);
10522 __ movt_s(dst, src);
10523 break;
10524 case 0x02: //not_equal
10525 __ c_eq_s(reg_op1, reg_op2);
10526 __ movf_s(dst, src);
10527 break;
10528 case 0x03: //greater
10529 __ c_ole_s(reg_op1, reg_op2);
10530 __ movf_s(dst, src);
10531 break;
10532 case 0x04: //greater_equal
10533 __ c_olt_s(reg_op1, reg_op2);
10534 __ movf_s(dst, src);
10535 break;
10536 case 0x05: //less
10537 __ c_ult_s(reg_op1, reg_op2);
10538 __ movt_s(dst, src);
10539 break;
10540 case 0x06: //less_equal
10541 __ c_ule_s(reg_op1, reg_op2);
10542 __ movt_s(dst, src);
10543 break;
10544 default:
10545 Unimplemented();
10546 }
10547 %}
10548 ins_pipe( pipe_slow );
10549 %}
10551 // Manifest a CmpL result in an integer register. Very painful.
10552 // This is the test to avoid.
10553 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
10554 match(Set dst (CmpL3 src1 src2));
10555 ins_cost(1000);
10556 format %{ "cmpL3 $dst, $src1, $src2 @ cmpL3_reg_reg" %}
10557 ins_encode %{
10558 Register opr1 = as_Register($src1$$reg);
10559 Register opr2 = as_Register($src2$$reg);
10560 Register dst = as_Register($dst$$reg);
10562 Label Done;
10564 __ subu(AT, opr1, opr2);
10565 __ bltz(AT, Done);
10566 __ delayed()->daddiu(dst, R0, -1);
10568 __ move(dst, 1);
10569 __ movz(dst, R0, AT);
10571 __ bind(Done);
10572 %}
10573 ins_pipe( pipe_slow );
10574 %}
10576 //
10577 // less_rsult = -1
10578 // greater_result = 1
10579 // equal_result = 0
10580 // nan_result = -1
10581 //
10582 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
10583 match(Set dst (CmpF3 src1 src2));
10584 ins_cost(1000);
10585 format %{ "cmpF3 $dst, $src1, $src2 @ cmpF3_reg_reg" %}
10586 ins_encode %{
10587 FloatRegister src1 = as_FloatRegister($src1$$reg);
10588 FloatRegister src2 = as_FloatRegister($src2$$reg);
10589 Register dst = as_Register($dst$$reg);
10591 Label Done;
10593 __ c_ult_s(src1, src2);
10594 __ bc1t(Done);
10595 __ delayed()->daddiu(dst, R0, -1);
10597 __ c_eq_s(src1, src2);
10598 __ move(dst, 1);
10599 __ movt(dst, R0);
10601 __ bind(Done);
10602 %}
10603 ins_pipe( pipe_slow );
10604 %}
10606 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
10607 match(Set dst (CmpD3 src1 src2));
10608 ins_cost(1000);
10609 format %{ "cmpD3 $dst, $src1, $src2 @ cmpD3_reg_reg" %}
10610 ins_encode %{
10611 FloatRegister src1 = as_FloatRegister($src1$$reg);
10612 FloatRegister src2 = as_FloatRegister($src2$$reg);
10613 Register dst = as_Register($dst$$reg);
10615 Label Done;
10617 __ c_ult_d(src1, src2);
10618 __ bc1t(Done);
10619 __ delayed()->daddiu(dst, R0, -1);
10621 __ c_eq_d(src1, src2);
10622 __ move(dst, 1);
10623 __ movt(dst, R0);
10625 __ bind(Done);
10626 %}
10627 ins_pipe( pipe_slow );
10628 %}
10630 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
10631 match(Set dummy (ClearArray cnt base));
10632 format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
10633 ins_encode %{
10634 //Assume cnt is the number of bytes in an array to be cleared,
10635 //and base points to the starting address of the array.
10636 Register base = $base$$Register;
10637 Register num = $cnt$$Register;
10638 Label Loop, done;
10640 __ beq(num, R0, done);
10641 __ delayed()->daddu(AT, base, R0);
10643 __ move(T9, num); /* T9 = words */
10645 __ bind(Loop);
10646 __ sd(R0, AT, 0);
10647 __ daddi(T9, T9, -1);
10648 __ bne(T9, R0, Loop);
10649 __ delayed()->daddi(AT, AT, wordSize);
10651 __ bind(done);
10652 %}
10653 ins_pipe( pipe_slow );
10654 %}
10656 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2, mA7RegI cnt2, no_Ax_mRegI result) %{
10657 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
10658 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
10660 format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
10661 ins_encode %{
10662 // Get the first character position in both strings
10663 // [8] char array, [12] offset, [16] count
10664 Register str1 = $str1$$Register;
10665 Register str2 = $str2$$Register;
10666 Register cnt1 = $cnt1$$Register;
10667 Register cnt2 = $cnt2$$Register;
10668 Register result = $result$$Register;
10670 Label L, Loop, haveResult, done;
10672 // compute the and difference of lengths (in result)
10673 __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
10675 // compute the shorter length (in cnt1)
10676 __ slt(AT, cnt2, cnt1);
10677 __ movn(cnt1, cnt2, AT);
10679 // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
10680 __ bind(Loop); // Loop begin
10681 __ beq(cnt1, R0, done);
10682 __ delayed()->lhu(AT, str1, 0);;
10684 // compare current character
10685 __ lhu(cnt2, str2, 0);
10686 __ bne(AT, cnt2, haveResult);
10687 __ delayed()->addi(str1, str1, 2);
10688 __ addi(str2, str2, 2);
10689 __ b(Loop);
10690 __ delayed()->addi(cnt1, cnt1, -1); // Loop end
10692 __ bind(haveResult);
10693 __ subu(result, AT, cnt2);
10695 __ bind(done);
10696 %}
10698 ins_pipe( pipe_slow );
10699 %}
10701 // intrinsic optimization
10702 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
10703 match(Set result (StrEquals (Binary str1 str2) cnt));
10704 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
10706 format %{ "String Equal $str1, $str2, len:$cnt tmp:$temp -> $result @ string_equals" %}
10707 ins_encode %{
10708 // Get the first character position in both strings
10709 // [8] char array, [12] offset, [16] count
10710 Register str1 = $str1$$Register;
10711 Register str2 = $str2$$Register;
10712 Register cnt = $cnt$$Register;
10713 Register tmp = $temp$$Register;
10714 Register result = $result$$Register;
10716 Label Loop, done;
10719 __ beq(str1, str2, done); // same char[] ?
10720 __ delayed()->daddiu(result, R0, 1);
10722 __ bind(Loop); // Loop begin
10723 __ beq(cnt, R0, done);
10724 __ delayed()->daddiu(result, R0, 1); // count == 0
10726 // compare current character
10727 __ lhu(AT, str1, 0);;
10728 __ lhu(tmp, str2, 0);
10729 __ bne(AT, tmp, done);
10730 __ delayed()->daddi(result, R0, 0);
10731 __ addi(str1, str1, 2);
10732 __ addi(str2, str2, 2);
10733 __ b(Loop);
10734 __ delayed()->addi(cnt, cnt, -1); // Loop end
10736 __ bind(done);
10737 %}
10739 ins_pipe( pipe_slow );
10740 %}
10742 //----------Arithmetic Instructions-------------------------------------------
10743 //----------Addition Instructions---------------------------------------------
10744 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10745 match(Set dst (AddI src1 src2));
10747 format %{ "add $dst, $src1, $src2 #@addI_Reg_Reg" %}
10748 ins_encode %{
10749 Register dst = $dst$$Register;
10750 Register src1 = $src1$$Register;
10751 Register src2 = $src2$$Register;
10752 __ addu32(dst, src1, src2);
10753 %}
10754 ins_pipe( ialu_regI_regI );
10755 %}
10757 instruct addI_Reg_imm(mRegI dst, mRegI src1, immI src2) %{
10758 match(Set dst (AddI src1 src2));
10760 format %{ "add $dst, $src1, $src2 #@addI_Reg_imm" %}
10761 ins_encode %{
10762 Register dst = $dst$$Register;
10763 Register src1 = $src1$$Register;
10764 int imm = $src2$$constant;
10766 if(Assembler::is_simm16(imm)) {
10767 __ addiu32(dst, src1, imm);
10768 } else {
10769 __ move(AT, imm);
10770 __ addu32(dst, src1, AT);
10771 }
10772 %}
10773 ins_pipe( ialu_regI_regI );
10774 %}
10776 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
10777 match(Set dst (AddP src1 src2));
10779 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg" %}
10781 ins_encode %{
10782 Register dst = $dst$$Register;
10783 Register src1 = $src1$$Register;
10784 Register src2 = $src2$$Register;
10785 __ daddu(dst, src1, src2);
10786 %}
10788 ins_pipe( ialu_regI_regI );
10789 %}
10791 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
10792 match(Set dst (AddP src1 (ConvI2L src2)));
10794 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
10796 ins_encode %{
10797 Register dst = $dst$$Register;
10798 Register src1 = $src1$$Register;
10799 Register src2 = $src2$$Register;
10800 __ daddu(dst, src1, src2);
10801 %}
10803 ins_pipe( ialu_regI_regI );
10804 %}
10806 instruct addP_reg_imm(mRegP dst, mRegP src1, immL src2) %{
10807 match(Set dst (AddP src1 src2));
10809 format %{ "daddi $dst, $src1, $src2 #@addP_reg_imm" %}
10810 ins_encode %{
10811 Register src1 = $src1$$Register;
10812 long src2 = $src2$$constant;
10813 Register dst = $dst$$Register;
10815 if(Assembler::is_simm16(src2)) {
10816 __ daddiu(dst, src1, src2);
10817 } else {
10818 __ set64(AT, src2);
10819 __ daddu(dst, src1, AT);
10820 }
10821 %}
10822 ins_pipe( ialu_regI_imm16 );
10823 %}
10825 // Add Long Register with Register
10826 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10827 match(Set dst (AddL src1 src2));
10828 ins_cost(200);
10829 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
10831 ins_encode %{
10832 Register dst_reg = as_Register($dst$$reg);
10833 Register src1_reg = as_Register($src1$$reg);
10834 Register src2_reg = as_Register($src2$$reg);
10836 __ daddu(dst_reg, src1_reg, src2_reg);
10837 %}
10839 ins_pipe( ialu_regL_regL );
10840 %}
10842 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
10843 %{
10844 match(Set dst (AddL src1 src2));
10846 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_imm " %}
10847 ins_encode %{
10848 Register dst_reg = as_Register($dst$$reg);
10849 Register src1_reg = as_Register($src1$$reg);
10850 int src2_imm = $src2$$constant;
10852 __ daddiu(dst_reg, src1_reg, src2_imm);
10853 %}
10855 ins_pipe( ialu_regL_regL );
10856 %}
10858 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
10859 %{
10860 match(Set dst (AddL (ConvI2L src1) src2));
10862 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_imm " %}
10863 ins_encode %{
10864 Register dst_reg = as_Register($dst$$reg);
10865 Register src1_reg = as_Register($src1$$reg);
10866 int src2_imm = $src2$$constant;
10868 __ daddiu(dst_reg, src1_reg, src2_imm);
10869 %}
10871 ins_pipe( ialu_regL_regL );
10872 %}
10874 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
10875 match(Set dst (AddL (ConvI2L src1) src2));
10876 ins_cost(200);
10877 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
10879 ins_encode %{
10880 Register dst_reg = as_Register($dst$$reg);
10881 Register src1_reg = as_Register($src1$$reg);
10882 Register src2_reg = as_Register($src2$$reg);
10884 __ daddu(dst_reg, src1_reg, src2_reg);
10885 %}
10887 ins_pipe( ialu_regL_regL );
10888 %}
10890 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
10891 match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
10892 ins_cost(200);
10893 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
10895 ins_encode %{
10896 Register dst_reg = as_Register($dst$$reg);
10897 Register src1_reg = as_Register($src1$$reg);
10898 Register src2_reg = as_Register($src2$$reg);
10900 __ daddu(dst_reg, src1_reg, src2_reg);
10901 %}
10903 ins_pipe( ialu_regL_regL );
10904 %}
10906 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
10907 match(Set dst (AddL src1 (ConvI2L src2)));
10908 ins_cost(200);
10909 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
10911 ins_encode %{
10912 Register dst_reg = as_Register($dst$$reg);
10913 Register src1_reg = as_Register($src1$$reg);
10914 Register src2_reg = as_Register($src2$$reg);
10916 __ daddu(dst_reg, src1_reg, src2_reg);
10917 %}
10919 ins_pipe( ialu_regL_regL );
10920 %}
10922 //----------Subtraction Instructions-------------------------------------------
10923 // Integer Subtraction Instructions
10924 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10925 match(Set dst (SubI src1 src2));
10926 ins_cost(100);
10928 format %{ "sub $dst, $src1, $src2 #@subI_Reg_Reg" %}
10929 ins_encode %{
10930 Register dst = $dst$$Register;
10931 Register src1 = $src1$$Register;
10932 Register src2 = $src2$$Register;
10933 __ subu32(dst, src1, src2);
10934 %}
10935 ins_pipe( ialu_regI_regI );
10936 %}
10938 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1, immI16_sub src2) %{
10939 match(Set dst (SubI src1 src2));
10940 ins_cost(80);
10942 format %{ "sub $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
10943 ins_encode %{
10944 Register dst = $dst$$Register;
10945 Register src1 = $src1$$Register;
10946 __ addiu32(dst, src1, -1 * $src2$$constant);
10947 %}
10948 ins_pipe( ialu_regI_regI );
10949 %}
10951 instruct negI_Reg(mRegI dst, immI0 zero, mRegI src) %{
10952 match(Set dst (SubI zero src));
10953 ins_cost(80);
10955 format %{ "neg $dst, $src #@negI_Reg" %}
10956 ins_encode %{
10957 Register dst = $dst$$Register;
10958 Register src = $src$$Register;
10959 __ subu32(dst, R0, src);
10960 %}
10961 ins_pipe( ialu_regI_regI );
10962 %}
10964 instruct negL_Reg(mRegL dst, immL0 zero, mRegL src) %{
10965 match(Set dst (SubL zero src));
10966 ins_cost(80);
10968 format %{ "neg $dst, $src #@negL_Reg" %}
10969 ins_encode %{
10970 Register dst = $dst$$Register;
10971 Register src = $src$$Register;
10972 __ subu(dst, R0, src);
10973 %}
10974 ins_pipe( ialu_regI_regI );
10975 %}
10977 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1, immL16_sub src2) %{
10978 match(Set dst (SubL src1 src2));
10979 ins_cost(80);
10981 format %{ "sub $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
10982 ins_encode %{
10983 Register dst = $dst$$Register;
10984 Register src1 = $src1$$Register;
10985 __ daddiu(dst, src1, -1 * $src2$$constant);
10986 %}
10987 ins_pipe( ialu_regI_regI );
10988 %}
10990 // Subtract Long Register with Register.
10991 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10992 match(Set dst (SubL src1 src2));
10993 ins_cost(100);
10994 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_Reg" %}
10995 ins_encode %{
10996 Register dst = as_Register($dst$$reg);
10997 Register src1 = as_Register($src1$$reg);
10998 Register src2 = as_Register($src2$$reg);
11000 __ subu(dst, src1, src2);
11001 %}
11002 ins_pipe( ialu_regL_regL );
11003 %}
11005 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
11006 match(Set dst (SubL src1 (ConvI2L src2)));
11007 ins_cost(100);
11008 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
11009 ins_encode %{
11010 Register dst = as_Register($dst$$reg);
11011 Register src1 = as_Register($src1$$reg);
11012 Register src2 = as_Register($src2$$reg);
11014 __ subu(dst, src1, src2);
11015 %}
11016 ins_pipe( ialu_regL_regL );
11017 %}
11019 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
11020 match(Set dst (SubL (ConvI2L src1) src2));
11021 ins_cost(200);
11022 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
11023 ins_encode %{
11024 Register dst = as_Register($dst$$reg);
11025 Register src1 = as_Register($src1$$reg);
11026 Register src2 = as_Register($src2$$reg);
11028 __ subu(dst, src1, src2);
11029 %}
11030 ins_pipe( ialu_regL_regL );
11031 %}
11033 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
11034 match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
11035 ins_cost(200);
11036 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
11037 ins_encode %{
11038 Register dst = as_Register($dst$$reg);
11039 Register src1 = as_Register($src1$$reg);
11040 Register src2 = as_Register($src2$$reg);
11042 __ subu(dst, src1, src2);
11043 %}
11044 ins_pipe( ialu_regL_regL );
11045 %}
11047 // Integer MOD with Register
11048 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11049 match(Set dst (ModI src1 src2));
11050 ins_cost(300);
11051 format %{ "modi $dst, $src1, $src2 @ modI_Reg_Reg" %}
11052 ins_encode %{
11053 Register dst = $dst$$Register;
11054 Register src1 = $src1$$Register;
11055 Register src2 = $src2$$Register;
11057 //if (UseLoongsonISA) {
11058 if (0) {
11059 // 2016.08.10
11060 // Experiments show that gsmod is slower that div+mfhi.
11061 // So I just disable it here.
11062 __ gsmod(dst, src1, src2);
11063 } else {
11064 __ div(src1, src2);
11065 __ mfhi(dst);
11066 }
11067 %}
11069 //ins_pipe( ialu_mod );
11070 ins_pipe( ialu_regI_regI );
11071 %}
11073 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11074 match(Set dst (ModL src1 src2));
11075 format %{ "modL $dst, $src1, $src2 @modL_reg_reg" %}
11077 ins_encode %{
11078 Register dst = as_Register($dst$$reg);
11079 Register op1 = as_Register($src1$$reg);
11080 Register op2 = as_Register($src2$$reg);
11082 if (UseLoongsonISA) {
11083 __ gsdmod(dst, op1, op2);
11084 } else {
11085 __ ddiv(op1, op2);
11086 __ mfhi(dst);
11087 }
11088 %}
11089 ins_pipe( pipe_slow );
11090 %}
11092 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11093 match(Set dst (MulI src1 src2));
11095 ins_cost(300);
11096 format %{ "mul $dst, $src1, $src2 @ mulI_Reg_Reg" %}
11097 ins_encode %{
11098 Register src1 = $src1$$Register;
11099 Register src2 = $src2$$Register;
11100 Register dst = $dst$$Register;
11102 __ mul(dst, src1, src2);
11103 %}
11104 ins_pipe( ialu_mult );
11105 %}
11107 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
11108 match(Set dst (AddI (MulI src1 src2) src3));
11110 ins_cost(999);
11111 format %{ "madd $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
11112 ins_encode %{
11113 Register src1 = $src1$$Register;
11114 Register src2 = $src2$$Register;
11115 Register src3 = $src3$$Register;
11116 Register dst = $dst$$Register;
11118 __ mtlo(src3);
11119 __ madd(src1, src2);
11120 __ mflo(dst);
11121 %}
11122 ins_pipe( ialu_mult );
11123 %}
11125 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11126 match(Set dst (DivI src1 src2));
11128 ins_cost(300);
11129 format %{ "div $dst, $src1, $src2 @ divI_Reg_Reg" %}
11130 ins_encode %{
11131 Register src1 = $src1$$Register;
11132 Register src2 = $src2$$Register;
11133 Register dst = $dst$$Register;
11135 // In MIPS, div does not cause exception.
11136 // We must trap an exception manually.
11137 __ teq(R0, src2, 0x7);
11139 if (UseLoongsonISA) {
11140 __ gsdiv(dst, src1, src2);
11141 } else {
11142 __ div(src1, src2);
11144 __ nop();
11145 __ nop();
11146 __ mflo(dst);
11147 }
11148 %}
11149 ins_pipe( ialu_mod );
11150 %}
11152 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
11153 match(Set dst (DivF src1 src2));
11155 ins_cost(300);
11156 format %{ "divF $dst, $src1, $src2 @ divF_Reg_Reg" %}
11157 ins_encode %{
11158 FloatRegister src1 = $src1$$FloatRegister;
11159 FloatRegister src2 = $src2$$FloatRegister;
11160 FloatRegister dst = $dst$$FloatRegister;
11162 /* Here do we need to trap an exception manually ? */
11163 __ div_s(dst, src1, src2);
11164 %}
11165 ins_pipe( pipe_slow );
11166 %}
11168 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
11169 match(Set dst (DivD src1 src2));
11171 ins_cost(300);
11172 format %{ "divD $dst, $src1, $src2 @ divD_Reg_Reg" %}
11173 ins_encode %{
11174 FloatRegister src1 = $src1$$FloatRegister;
11175 FloatRegister src2 = $src2$$FloatRegister;
11176 FloatRegister dst = $dst$$FloatRegister;
11178 /* Here do we need to trap an exception manually ? */
11179 __ div_d(dst, src1, src2);
11180 %}
11181 ins_pipe( pipe_slow );
11182 %}
11184 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11185 match(Set dst (MulL src1 src2));
11186 format %{ "mulL $dst, $src1, $src2 @mulL_reg_reg" %}
11187 ins_encode %{
11188 Register dst = as_Register($dst$$reg);
11189 Register op1 = as_Register($src1$$reg);
11190 Register op2 = as_Register($src2$$reg);
11192 if (UseLoongsonISA) {
11193 __ gsdmult(dst, op1, op2);
11194 } else {
11195 __ dmult(op1, op2);
11196 __ mflo(dst);
11197 }
11198 %}
11199 ins_pipe( pipe_slow );
11200 %}
11202 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
11203 match(Set dst (MulL src1 (ConvI2L src2)));
11204 format %{ "mulL $dst, $src1, $src2 @mulL_reg_regI2L" %}
11205 ins_encode %{
11206 Register dst = as_Register($dst$$reg);
11207 Register op1 = as_Register($src1$$reg);
11208 Register op2 = as_Register($src2$$reg);
11210 if (UseLoongsonISA) {
11211 __ gsdmult(dst, op1, op2);
11212 } else {
11213 __ dmult(op1, op2);
11214 __ mflo(dst);
11215 }
11216 %}
11217 ins_pipe( pipe_slow );
11218 %}
11220 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11221 match(Set dst (DivL src1 src2));
11222 format %{ "divL $dst, $src1, $src2 @divL_reg_reg" %}
11224 ins_encode %{
11225 Register dst = as_Register($dst$$reg);
11226 Register op1 = as_Register($src1$$reg);
11227 Register op2 = as_Register($src2$$reg);
11229 if (UseLoongsonISA) {
11230 __ gsddiv(dst, op1, op2);
11231 } else {
11232 __ ddiv(op1, op2);
11233 __ mflo(dst);
11234 }
11235 %}
11236 ins_pipe( pipe_slow );
11237 %}
11239 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
11240 match(Set dst (AddF src1 src2));
11241 format %{ "AddF $dst, $src1, $src2 @addF_reg_reg" %}
11242 ins_encode %{
11243 FloatRegister src1 = as_FloatRegister($src1$$reg);
11244 FloatRegister src2 = as_FloatRegister($src2$$reg);
11245 FloatRegister dst = as_FloatRegister($dst$$reg);
11247 __ add_s(dst, src1, src2);
11248 %}
11249 ins_pipe( fpu_regF_regF );
11250 %}
11252 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
11253 match(Set dst (SubF src1 src2));
11254 format %{ "SubF $dst, $src1, $src2 @subF_reg_reg" %}
11255 ins_encode %{
11256 FloatRegister src1 = as_FloatRegister($src1$$reg);
11257 FloatRegister src2 = as_FloatRegister($src2$$reg);
11258 FloatRegister dst = as_FloatRegister($dst$$reg);
11260 __ sub_s(dst, src1, src2);
11261 %}
11262 ins_pipe( fpu_regF_regF );
11263 %}
11264 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
11265 match(Set dst (AddD src1 src2));
11266 format %{ "AddD $dst, $src1, $src2 @addD_reg_reg" %}
11267 ins_encode %{
11268 FloatRegister src1 = as_FloatRegister($src1$$reg);
11269 FloatRegister src2 = as_FloatRegister($src2$$reg);
11270 FloatRegister dst = as_FloatRegister($dst$$reg);
11272 __ add_d(dst, src1, src2);
11273 %}
11274 ins_pipe( fpu_regF_regF );
11275 %}
11277 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
11278 match(Set dst (SubD src1 src2));
11279 format %{ "SubD $dst, $src1, $src2 @subD_reg_reg" %}
11280 ins_encode %{
11281 FloatRegister src1 = as_FloatRegister($src1$$reg);
11282 FloatRegister src2 = as_FloatRegister($src2$$reg);
11283 FloatRegister dst = as_FloatRegister($dst$$reg);
11285 __ sub_d(dst, src1, src2);
11286 %}
11287 ins_pipe( fpu_regF_regF );
11288 %}
11290 instruct negF_reg(regF dst, regF src) %{
11291 match(Set dst (NegF src));
11292 format %{ "negF $dst, $src @negF_reg" %}
11293 ins_encode %{
11294 FloatRegister src = as_FloatRegister($src$$reg);
11295 FloatRegister dst = as_FloatRegister($dst$$reg);
11297 __ neg_s(dst, src);
11298 %}
11299 ins_pipe( fpu_regF_regF );
11300 %}
11302 instruct negD_reg(regD dst, regD src) %{
11303 match(Set dst (NegD src));
11304 format %{ "negD $dst, $src @negD_reg" %}
11305 ins_encode %{
11306 FloatRegister src = as_FloatRegister($src$$reg);
11307 FloatRegister dst = as_FloatRegister($dst$$reg);
11309 __ neg_d(dst, src);
11310 %}
11311 ins_pipe( fpu_regF_regF );
11312 %}
11315 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
11316 match(Set dst (MulF src1 src2));
11317 format %{ "MULF $dst, $src1, $src2 @mulF_reg_reg" %}
11318 ins_encode %{
11319 FloatRegister src1 = $src1$$FloatRegister;
11320 FloatRegister src2 = $src2$$FloatRegister;
11321 FloatRegister dst = $dst$$FloatRegister;
11323 __ mul_s(dst, src1, src2);
11324 %}
11325 ins_pipe( fpu_regF_regF );
11326 %}
11328 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
11329 match(Set dst (AddF (MulF src1 src2) src3));
11330 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
11331 ins_cost(44444);
11332 format %{ "maddF $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
11333 ins_encode %{
11334 FloatRegister src1 = $src1$$FloatRegister;
11335 FloatRegister src2 = $src2$$FloatRegister;
11336 FloatRegister src3 = $src3$$FloatRegister;
11337 FloatRegister dst = $dst$$FloatRegister;
11339 __ madd_s(dst, src1, src2, src3);
11340 %}
11341 ins_pipe( fpu_regF_regF );
11342 %}
11344 // Mul two double precision floating piont number
11345 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
11346 match(Set dst (MulD src1 src2));
11347 format %{ "MULD $dst, $src1, $src2 @mulD_reg_reg" %}
11348 ins_encode %{
11349 FloatRegister src1 = $src1$$FloatRegister;
11350 FloatRegister src2 = $src2$$FloatRegister;
11351 FloatRegister dst = $dst$$FloatRegister;
11353 __ mul_d(dst, src1, src2);
11354 %}
11355 ins_pipe( fpu_regF_regF );
11356 %}
11358 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
11359 match(Set dst (AddD (MulD src1 src2) src3));
11360 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
11361 ins_cost(44444);
11362 format %{ "maddD $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
11363 ins_encode %{
11364 FloatRegister src1 = $src1$$FloatRegister;
11365 FloatRegister src2 = $src2$$FloatRegister;
11366 FloatRegister src3 = $src3$$FloatRegister;
11367 FloatRegister dst = $dst$$FloatRegister;
11369 __ madd_d(dst, src1, src2, src3);
11370 %}
11371 ins_pipe( fpu_regF_regF );
11372 %}
11374 instruct absF_reg(regF dst, regF src) %{
11375 match(Set dst (AbsF src));
11376 ins_cost(100);
11377 format %{ "absF $dst, $src @absF_reg" %}
11378 ins_encode %{
11379 FloatRegister src = as_FloatRegister($src$$reg);
11380 FloatRegister dst = as_FloatRegister($dst$$reg);
11382 __ abs_s(dst, src);
11383 %}
11384 ins_pipe( fpu_regF_regF );
11385 %}
11388 // intrinsics for math_native.
11389 // AbsD SqrtD CosD SinD TanD LogD Log10D
11391 instruct absD_reg(regD dst, regD src) %{
11392 match(Set dst (AbsD src));
11393 ins_cost(100);
11394 format %{ "absD $dst, $src @absD_reg" %}
11395 ins_encode %{
11396 FloatRegister src = as_FloatRegister($src$$reg);
11397 FloatRegister dst = as_FloatRegister($dst$$reg);
11399 __ abs_d(dst, src);
11400 %}
11401 ins_pipe( fpu_regF_regF );
11402 %}
11404 instruct sqrtD_reg(regD dst, regD src) %{
11405 match(Set dst (SqrtD src));
11406 ins_cost(100);
11407 format %{ "SqrtD $dst, $src @sqrtD_reg" %}
11408 ins_encode %{
11409 FloatRegister src = as_FloatRegister($src$$reg);
11410 FloatRegister dst = as_FloatRegister($dst$$reg);
11412 __ sqrt_d(dst, src);
11413 %}
11414 ins_pipe( fpu_regF_regF );
11415 %}
11417 instruct sqrtF_reg(regF dst, regF src) %{
11418 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
11419 ins_cost(100);
11420 format %{ "SqrtF $dst, $src @sqrtF_reg" %}
11421 ins_encode %{
11422 FloatRegister src = as_FloatRegister($src$$reg);
11423 FloatRegister dst = as_FloatRegister($dst$$reg);
11425 __ sqrt_s(dst, src);
11426 %}
11427 ins_pipe( fpu_regF_regF );
11428 %}
11429 //----------------------------------Logical Instructions----------------------
11430 //__________________________________Integer Logical Instructions-------------
11432 //And Instuctions
11433 // And Register with Immediate
11434 instruct andI_Reg_immI(mRegI dst, mRegI src1, immI src2) %{
11435 match(Set dst (AndI src1 src2));
11437 format %{ "and $dst, $src1, $src2 #@andI_Reg_immI" %}
11438 ins_encode %{
11439 Register dst = $dst$$Register;
11440 Register src = $src1$$Register;
11441 int val = $src2$$constant;
11443 __ move(AT, val);
11444 __ andr(dst, src, AT);
11445 %}
11446 ins_pipe( ialu_regI_regI );
11447 %}
11449 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
11450 match(Set dst (AndI src1 src2));
11451 ins_cost(60);
11453 format %{ "and $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
11454 ins_encode %{
11455 Register dst = $dst$$Register;
11456 Register src = $src1$$Register;
11457 int val = $src2$$constant;
11459 __ andi(dst, src, val);
11460 %}
11461 ins_pipe( ialu_regI_regI );
11462 %}
11464 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1, immI_nonneg_mask mask) %{
11465 match(Set dst (AndI src1 mask));
11466 ins_cost(60);
11468 format %{ "and $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
11469 ins_encode %{
11470 Register dst = $dst$$Register;
11471 Register src = $src1$$Register;
11472 int size = Assembler::is_int_mask($mask$$constant);
11474 __ ext(dst, src, 0, size);
11475 %}
11476 ins_pipe( ialu_regI_regI );
11477 %}
11479 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1, immL_nonneg_mask mask) %{
11480 match(Set dst (AndL src1 mask));
11481 ins_cost(60);
11483 format %{ "and $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
11484 ins_encode %{
11485 Register dst = $dst$$Register;
11486 Register src = $src1$$Register;
11487 int size = Assembler::is_jlong_mask($mask$$constant);
11489 __ dext(dst, src, 0, size);
11490 %}
11491 ins_pipe( ialu_regI_regI );
11492 %}
11494 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
11495 match(Set dst (XorI src1 src2));
11496 ins_cost(60);
11498 format %{ "xori $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
11499 ins_encode %{
11500 Register dst = $dst$$Register;
11501 Register src = $src1$$Register;
11502 int val = $src2$$constant;
11504 __ xori(dst, src, val);
11505 %}
11506 ins_pipe( ialu_regI_regI );
11507 %}
11509 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1, immI_M1 M1) %{
11510 match(Set dst (XorI src1 M1));
11511 predicate(UseLoongsonISA && Use3A2000);
11512 ins_cost(60);
11514 format %{ "xor $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
11515 ins_encode %{
11516 Register dst = $dst$$Register;
11517 Register src = $src1$$Register;
11519 __ gsorn(dst, R0, src);
11520 %}
11521 ins_pipe( ialu_regI_regI );
11522 %}
11524 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1, immI_M1 M1) %{
11525 match(Set dst (XorI (ConvL2I src1) M1));
11526 predicate(UseLoongsonISA && Use3A2000);
11527 ins_cost(60);
11529 format %{ "xor $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
11530 ins_encode %{
11531 Register dst = $dst$$Register;
11532 Register src = $src1$$Register;
11534 __ gsorn(dst, R0, src);
11535 %}
11536 ins_pipe( ialu_regI_regI );
11537 %}
11539 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
11540 match(Set dst (XorL src1 src2));
11541 ins_cost(60);
11543 format %{ "xori $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
11544 ins_encode %{
11545 Register dst = $dst$$Register;
11546 Register src = $src1$$Register;
11547 int val = $src2$$constant;
11549 __ xori(dst, src, val);
11550 %}
11551 ins_pipe( ialu_regI_regI );
11552 %}
11554 /*
11555 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1, immL_M1 M1) %{
11556 match(Set dst (XorL src1 M1));
11557 predicate(UseLoongsonISA);
11558 ins_cost(60);
11560 format %{ "xor $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
11561 ins_encode %{
11562 Register dst = $dst$$Register;
11563 Register src = $src1$$Register;
11565 __ gsorn(dst, R0, src);
11566 %}
11567 ins_pipe( ialu_regI_regI );
11568 %}
11569 */
11571 instruct lbu_and_lmask(mRegI dst, memory mem, immI_255 mask) %{
11572 match(Set dst (AndI mask (LoadB mem)));
11573 ins_cost(60);
11575 format %{ "lhu $dst, $mem #@lbu_and_lmask" %}
11576 ins_encode(load_UB_enc(dst, mem));
11577 ins_pipe( ialu_loadI );
11578 %}
11580 instruct lbu_and_rmask(mRegI dst, memory mem, immI_255 mask) %{
11581 match(Set dst (AndI (LoadB mem) mask));
11582 ins_cost(60);
11584 format %{ "lhu $dst, $mem #@lbu_and_rmask" %}
11585 ins_encode(load_UB_enc(dst, mem));
11586 ins_pipe( ialu_loadI );
11587 %}
11589 instruct andI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11590 match(Set dst (AndI src1 src2));
11592 format %{ "and $dst, $src1, $src2 #@andI_Reg_Reg" %}
11593 ins_encode %{
11594 Register dst = $dst$$Register;
11595 Register src1 = $src1$$Register;
11596 Register src2 = $src2$$Register;
11597 __ andr(dst, src1, src2);
11598 %}
11599 ins_pipe( ialu_regI_regI );
11600 %}
11602 instruct andnI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11603 match(Set dst (AndI src1 (XorI src2 M1)));
11604 predicate(UseLoongsonISA && Use3A2000);
11606 format %{ "andn $dst, $src1, $src2 #@andnI_Reg_nReg" %}
11607 ins_encode %{
11608 Register dst = $dst$$Register;
11609 Register src1 = $src1$$Register;
11610 Register src2 = $src2$$Register;
11612 __ gsandn(dst, src1, src2);
11613 %}
11614 ins_pipe( ialu_regI_regI );
11615 %}
11617 instruct ornI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11618 match(Set dst (OrI src1 (XorI src2 M1)));
11619 predicate(UseLoongsonISA && Use3A2000);
11621 format %{ "orn $dst, $src1, $src2 #@ornI_Reg_nReg" %}
11622 ins_encode %{
11623 Register dst = $dst$$Register;
11624 Register src1 = $src1$$Register;
11625 Register src2 = $src2$$Register;
11627 __ gsorn(dst, src1, src2);
11628 %}
11629 ins_pipe( ialu_regI_regI );
11630 %}
11632 instruct andnI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11633 match(Set dst (AndI (XorI src1 M1) src2));
11634 predicate(UseLoongsonISA && Use3A2000);
11636 format %{ "andn $dst, $src2, $src1 #@andnI_nReg_Reg" %}
11637 ins_encode %{
11638 Register dst = $dst$$Register;
11639 Register src1 = $src1$$Register;
11640 Register src2 = $src2$$Register;
11642 __ gsandn(dst, src2, src1);
11643 %}
11644 ins_pipe( ialu_regI_regI );
11645 %}
11647 instruct ornI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11648 match(Set dst (OrI (XorI src1 M1) src2));
11649 predicate(UseLoongsonISA && Use3A2000);
11651 format %{ "orn $dst, $src2, $src1 #@ornI_nReg_Reg" %}
11652 ins_encode %{
11653 Register dst = $dst$$Register;
11654 Register src1 = $src1$$Register;
11655 Register src2 = $src2$$Register;
11657 __ gsorn(dst, src2, src1);
11658 %}
11659 ins_pipe( ialu_regI_regI );
11660 %}
11662 // And Long Register with Register
11663 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11664 match(Set dst (AndL src1 src2));
11665 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
11666 ins_encode %{
11667 Register dst_reg = as_Register($dst$$reg);
11668 Register src1_reg = as_Register($src1$$reg);
11669 Register src2_reg = as_Register($src2$$reg);
11671 __ andr(dst_reg, src1_reg, src2_reg);
11672 %}
11673 ins_pipe( ialu_regL_regL );
11674 %}
11676 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
11677 match(Set dst (AndL src1 (ConvI2L src2)));
11678 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
11679 ins_encode %{
11680 Register dst_reg = as_Register($dst$$reg);
11681 Register src1_reg = as_Register($src1$$reg);
11682 Register src2_reg = as_Register($src2$$reg);
11684 __ andr(dst_reg, src1_reg, src2_reg);
11685 %}
11686 ins_pipe( ialu_regL_regL );
11687 %}
11689 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
11690 match(Set dst (AndL src1 src2));
11691 ins_cost(60);
11693 format %{ "and $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
11694 ins_encode %{
11695 Register dst = $dst$$Register;
11696 Register src = $src1$$Register;
11697 long val = $src2$$constant;
11699 __ andi(dst, src, val);
11700 %}
11701 ins_pipe( ialu_regI_regI );
11702 %}
11704 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1, immL_0_65535 src2) %{
11705 match(Set dst (ConvL2I (AndL src1 src2)));
11706 ins_cost(60);
11708 format %{ "and $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
11709 ins_encode %{
11710 Register dst = $dst$$Register;
11711 Register src = $src1$$Register;
11712 long val = $src2$$constant;
11714 __ andi(dst, src, val);
11715 %}
11716 ins_pipe( ialu_regI_regI );
11717 %}
11719 /*
11720 instruct andnL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11721 match(Set dst (AndL src1 (XorL src2 M1)));
11722 predicate(UseLoongsonISA);
11724 format %{ "andn $dst, $src1, $src2 #@andnL_Reg_nReg" %}
11725 ins_encode %{
11726 Register dst = $dst$$Register;
11727 Register src1 = $src1$$Register;
11728 Register src2 = $src2$$Register;
11730 __ gsandn(dst, src1, src2);
11731 %}
11732 ins_pipe( ialu_regI_regI );
11733 %}
11734 */
11736 /*
11737 instruct ornL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11738 match(Set dst (OrL src1 (XorL src2 M1)));
11739 predicate(UseLoongsonISA);
11741 format %{ "orn $dst, $src1, $src2 #@ornL_Reg_nReg" %}
11742 ins_encode %{
11743 Register dst = $dst$$Register;
11744 Register src1 = $src1$$Register;
11745 Register src2 = $src2$$Register;
11747 __ gsorn(dst, src1, src2);
11748 %}
11749 ins_pipe( ialu_regI_regI );
11750 %}
11751 */
11753 /*
11754 instruct andnL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11755 match(Set dst (AndL (XorL src1 M1) src2));
11756 predicate(UseLoongsonISA);
11758 format %{ "andn $dst, $src2, $src1 #@andnL_nReg_Reg" %}
11759 ins_encode %{
11760 Register dst = $dst$$Register;
11761 Register src1 = $src1$$Register;
11762 Register src2 = $src2$$Register;
11764 __ gsandn(dst, src2, src1);
11765 %}
11766 ins_pipe( ialu_regI_regI );
11767 %}
11768 */
11770 /*
11771 instruct ornL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11772 match(Set dst (OrL (XorL src1 M1) src2));
11773 predicate(UseLoongsonISA);
11775 format %{ "orn $dst, $src2, $src1 #@ornL_nReg_Reg" %}
11776 ins_encode %{
11777 Register dst = $dst$$Register;
11778 Register src1 = $src1$$Register;
11779 Register src2 = $src2$$Register;
11781 __ gsorn(dst, src2, src1);
11782 %}
11783 ins_pipe( ialu_regI_regI );
11784 %}
11785 */
11787 instruct andL_Reg_immL_M8(mRegL dst, immL_M8 M8) %{
11788 match(Set dst (AndL dst M8));
11789 ins_cost(60);
11791 format %{ "and $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
11792 ins_encode %{
11793 Register dst = $dst$$Register;
11795 __ dins(dst, R0, 0, 3);
11796 %}
11797 ins_pipe( ialu_regI_regI );
11798 %}
11800 instruct andL_Reg_immL_M5(mRegL dst, immL_M5 M5) %{
11801 match(Set dst (AndL dst M5));
11802 ins_cost(60);
11804 format %{ "and $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
11805 ins_encode %{
11806 Register dst = $dst$$Register;
11808 __ dins(dst, R0, 2, 1);
11809 %}
11810 ins_pipe( ialu_regI_regI );
11811 %}
11813 instruct andL_Reg_immL_M7(mRegL dst, immL_M7 M7) %{
11814 match(Set dst (AndL dst M7));
11815 ins_cost(60);
11817 format %{ "and $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
11818 ins_encode %{
11819 Register dst = $dst$$Register;
11821 __ dins(dst, R0, 1, 2);
11822 %}
11823 ins_pipe( ialu_regI_regI );
11824 %}
11826 instruct andL_Reg_immL_M4(mRegL dst, immL_M4 M4) %{
11827 match(Set dst (AndL dst M4));
11828 ins_cost(60);
11830 format %{ "and $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
11831 ins_encode %{
11832 Register dst = $dst$$Register;
11834 __ dins(dst, R0, 0, 2);
11835 %}
11836 ins_pipe( ialu_regI_regI );
11837 %}
11839 instruct andL_Reg_immL_M121(mRegL dst, immL_M121 M121) %{
11840 match(Set dst (AndL dst M121));
11841 ins_cost(60);
11843 format %{ "and $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
11844 ins_encode %{
11845 Register dst = $dst$$Register;
11847 __ dins(dst, R0, 3, 4);
11848 %}
11849 ins_pipe( ialu_regI_regI );
11850 %}
11852 // Or Long Register with Register
11853 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11854 match(Set dst (OrL src1 src2));
11855 format %{ "OR $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
11856 ins_encode %{
11857 Register dst_reg = $dst$$Register;
11858 Register src1_reg = $src1$$Register;
11859 Register src2_reg = $src2$$Register;
11861 __ orr(dst_reg, src1_reg, src2_reg);
11862 %}
11863 ins_pipe( ialu_regL_regL );
11864 %}
11866 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
11867 match(Set dst (OrL (CastP2X src1) src2));
11868 format %{ "OR $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
11869 ins_encode %{
11870 Register dst_reg = $dst$$Register;
11871 Register src1_reg = $src1$$Register;
11872 Register src2_reg = $src2$$Register;
11874 __ orr(dst_reg, src1_reg, src2_reg);
11875 %}
11876 ins_pipe( ialu_regL_regL );
11877 %}
11879 // Xor Long Register with Register
11880 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11881 match(Set dst (XorL src1 src2));
11882 format %{ "XOR $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
11883 ins_encode %{
11884 Register dst_reg = as_Register($dst$$reg);
11885 Register src1_reg = as_Register($src1$$reg);
11886 Register src2_reg = as_Register($src2$$reg);
11888 __ xorr(dst_reg, src1_reg, src2_reg);
11889 %}
11890 ins_pipe( ialu_regL_regL );
11891 %}
11893 // Shift Left by 8-bit immediate
11894 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
11895 match(Set dst (LShiftI src shift));
11897 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm" %}
11898 ins_encode %{
11899 Register src = $src$$Register;
11900 Register dst = $dst$$Register;
11901 int shamt = $shift$$constant;
11903 __ sll(dst, src, shamt);
11904 %}
11905 ins_pipe( ialu_regI_regI );
11906 %}
11908 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
11909 match(Set dst (LShiftI (ConvL2I src) shift));
11911 format %{ "SHL $dst, $src, $shift #@salL2I_Reg_imm" %}
11912 ins_encode %{
11913 Register src = $src$$Register;
11914 Register dst = $dst$$Register;
11915 int shamt = $shift$$constant;
11917 __ sll(dst, src, shamt);
11918 %}
11919 ins_pipe( ialu_regI_regI );
11920 %}
11922 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
11923 match(Set dst (AndI (LShiftI src shift) mask));
11925 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
11926 ins_encode %{
11927 Register src = $src$$Register;
11928 Register dst = $dst$$Register;
11930 __ sll(dst, src, 16);
11931 %}
11932 ins_pipe( ialu_regI_regI );
11933 %}
11935 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
11936 %{
11937 match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
11939 format %{ "andi $dst, $src, 7\t# @land7_2_s" %}
11940 ins_encode %{
11941 Register src = $src$$Register;
11942 Register dst = $dst$$Register;
11944 __ andi(dst, src, 7);
11945 %}
11946 ins_pipe(ialu_regI_regI);
11947 %}
11949 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
11950 %{
11951 match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
11953 format %{ "ori $dst, $src1, $src2\t# @ori2s" %}
11954 ins_encode %{
11955 Register src = $src1$$Register;
11956 int val = $src2$$constant;
11957 Register dst = $dst$$Register;
11959 __ ori(dst, src, val);
11960 %}
11961 ins_pipe(ialu_regI_regI);
11962 %}
11964 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
11965 // This idiom is used by the compiler the i2s bytecode.
11966 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
11967 %{
11968 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
11970 format %{ "i2s $dst, $src\t# @i2s" %}
11971 ins_encode %{
11972 Register src = $src$$Register;
11973 Register dst = $dst$$Register;
11975 __ seh(dst, src);
11976 %}
11977 ins_pipe(ialu_regI_regI);
11978 %}
11980 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
11981 // This idiom is used by the compiler for the i2b bytecode.
11982 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
11983 %{
11984 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
11986 format %{ "i2b $dst, $src\t# @i2b" %}
11987 ins_encode %{
11988 Register src = $src$$Register;
11989 Register dst = $dst$$Register;
11991 __ seb(dst, src);
11992 %}
11993 ins_pipe(ialu_regI_regI);
11994 %}
11997 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
11998 match(Set dst (LShiftI (ConvL2I src) shift));
12000 format %{ "SHL $dst, $src, $shift #@salI_RegL2I_imm" %}
12001 ins_encode %{
12002 Register src = $src$$Register;
12003 Register dst = $dst$$Register;
12004 int shamt = $shift$$constant;
12006 __ sll(dst, src, shamt);
12007 %}
12008 ins_pipe( ialu_regI_regI );
12009 %}
12011 // Shift Left by 8-bit immediate
12012 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12013 match(Set dst (LShiftI src shift));
12015 format %{ "SHL $dst, $src, $shift #@salI_Reg_Reg" %}
12016 ins_encode %{
12017 Register src = $src$$Register;
12018 Register dst = $dst$$Register;
12019 Register shamt = $shift$$Register;
12020 __ sllv(dst, src, shamt);
12021 %}
12022 ins_pipe( ialu_regI_regI );
12023 %}
12026 // Shift Left Long
12027 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
12028 //predicate(UseNewLongLShift);
12029 match(Set dst (LShiftL src shift));
12030 ins_cost(100);
12031 format %{ "salL $dst, $src, $shift @ salL_Reg_imm" %}
12032 ins_encode %{
12033 Register src_reg = as_Register($src$$reg);
12034 Register dst_reg = as_Register($dst$$reg);
12035 int shamt = $shift$$constant;
12037 if (__ is_simm(shamt, 5))
12038 __ dsll(dst_reg, src_reg, shamt);
12039 else {
12040 int sa = Assembler::low(shamt, 6);
12041 if (sa < 32) {
12042 __ dsll(dst_reg, src_reg, sa);
12043 } else {
12044 __ dsll32(dst_reg, src_reg, sa - 32);
12045 }
12046 }
12047 %}
12048 ins_pipe( ialu_regL_regL );
12049 %}
12051 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
12052 //predicate(UseNewLongLShift);
12053 match(Set dst (LShiftL (ConvI2L src) shift));
12054 ins_cost(100);
12055 format %{ "salL $dst, $src, $shift @ salL_RegI2L_imm" %}
12056 ins_encode %{
12057 Register src_reg = as_Register($src$$reg);
12058 Register dst_reg = as_Register($dst$$reg);
12059 int shamt = $shift$$constant;
12061 if (__ is_simm(shamt, 5))
12062 __ dsll(dst_reg, src_reg, shamt);
12063 else {
12064 int sa = Assembler::low(shamt, 6);
12065 if (sa < 32) {
12066 __ dsll(dst_reg, src_reg, sa);
12067 } else {
12068 __ dsll32(dst_reg, src_reg, sa - 32);
12069 }
12070 }
12071 %}
12072 ins_pipe( ialu_regL_regL );
12073 %}
12075 // Shift Left Long
12076 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12077 //predicate(UseNewLongLShift);
12078 match(Set dst (LShiftL src shift));
12079 ins_cost(100);
12080 format %{ "salL $dst, $src, $shift @ salL_Reg_Reg" %}
12081 ins_encode %{
12082 Register src_reg = as_Register($src$$reg);
12083 Register dst_reg = as_Register($dst$$reg);
12085 __ dsllv(dst_reg, src_reg, $shift$$Register);
12086 %}
12087 ins_pipe( ialu_regL_regL );
12088 %}
12090 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
12091 match(Set dst (LShiftL (ConvI2L src) shift));
12092 ins_cost(100);
12093 format %{ "salL $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
12094 ins_encode %{
12095 Register src_reg = as_Register($src$$reg);
12096 Register dst_reg = as_Register($dst$$reg);
12097 int shamt = $shift$$constant;
12099 if (__ is_simm(shamt, 5)) {
12100 __ dsll(dst_reg, src_reg, shamt);
12101 } else {
12102 int sa = Assembler::low(shamt, 6);
12103 if (sa < 32) {
12104 __ dsll(dst_reg, src_reg, sa);
12105 } else {
12106 __ dsll32(dst_reg, src_reg, sa - 32);
12107 }
12108 }
12109 %}
12110 ins_pipe( ialu_regL_regL );
12111 %}
12113 // Shift Right Long
12114 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
12115 match(Set dst (RShiftL src shift));
12116 ins_cost(100);
12117 format %{ "sarL $dst, $src, $shift @ sarL_Reg_imm" %}
12118 ins_encode %{
12119 Register src_reg = as_Register($src$$reg);
12120 Register dst_reg = as_Register($dst$$reg);
12121 int shamt = ($shift$$constant & 0x3f);
12122 if (__ is_simm(shamt, 5))
12123 __ dsra(dst_reg, src_reg, shamt);
12124 else {
12125 int sa = Assembler::low(shamt, 6);
12126 if (sa < 32) {
12127 __ dsra(dst_reg, src_reg, sa);
12128 } else {
12129 __ dsra32(dst_reg, src_reg, sa - 32);
12130 }
12131 }
12132 %}
12133 ins_pipe( ialu_regL_regL );
12134 %}
12136 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
12137 match(Set dst (ConvL2I (RShiftL src shift)));
12138 ins_cost(100);
12139 format %{ "sarL $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
12140 ins_encode %{
12141 Register src_reg = as_Register($src$$reg);
12142 Register dst_reg = as_Register($dst$$reg);
12143 int shamt = $shift$$constant;
12145 __ dsra32(dst_reg, src_reg, shamt - 32);
12146 %}
12147 ins_pipe( ialu_regL_regL );
12148 %}
12150 // Shift Right Long arithmetically
12151 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12152 //predicate(UseNewLongLShift);
12153 match(Set dst (RShiftL src shift));
12154 ins_cost(100);
12155 format %{ "sarL $dst, $src, $shift @ sarL_Reg_Reg" %}
12156 ins_encode %{
12157 Register src_reg = as_Register($src$$reg);
12158 Register dst_reg = as_Register($dst$$reg);
12160 __ dsrav(dst_reg, src_reg, $shift$$Register);
12161 %}
12162 ins_pipe( ialu_regL_regL );
12163 %}
12165 // Shift Right Long logically
12166 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12167 match(Set dst (URShiftL src shift));
12168 ins_cost(100);
12169 format %{ "slrL $dst, $src, $shift @ slrL_Reg_Reg" %}
12170 ins_encode %{
12171 Register src_reg = as_Register($src$$reg);
12172 Register dst_reg = as_Register($dst$$reg);
12174 __ dsrlv(dst_reg, src_reg, $shift$$Register);
12175 %}
12176 ins_pipe( ialu_regL_regL );
12177 %}
12179 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
12180 match(Set dst (URShiftL src shift));
12181 ins_cost(80);
12182 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
12183 ins_encode %{
12184 Register src_reg = as_Register($src$$reg);
12185 Register dst_reg = as_Register($dst$$reg);
12186 int shamt = $shift$$constant;
12188 __ dsrl(dst_reg, src_reg, shamt);
12189 %}
12190 ins_pipe( ialu_regL_regL );
12191 %}
12193 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
12194 match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
12195 ins_cost(80);
12196 format %{ "dext $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
12197 ins_encode %{
12198 Register src_reg = as_Register($src$$reg);
12199 Register dst_reg = as_Register($dst$$reg);
12200 int shamt = $shift$$constant;
12202 __ dext(dst_reg, src_reg, shamt, 31);
12203 %}
12204 ins_pipe( ialu_regL_regL );
12205 %}
12207 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
12208 match(Set dst (URShiftL (CastP2X src) shift));
12209 ins_cost(80);
12210 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
12211 ins_encode %{
12212 Register src_reg = as_Register($src$$reg);
12213 Register dst_reg = as_Register($dst$$reg);
12214 int shamt = $shift$$constant;
12216 __ dsrl(dst_reg, src_reg, shamt);
12217 %}
12218 ins_pipe( ialu_regL_regL );
12219 %}
12221 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
12222 match(Set dst (URShiftL src shift));
12223 ins_cost(80);
12224 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
12225 ins_encode %{
12226 Register src_reg = as_Register($src$$reg);
12227 Register dst_reg = as_Register($dst$$reg);
12228 int shamt = $shift$$constant;
12230 __ dsrl32(dst_reg, src_reg, shamt - 32);
12231 %}
12232 ins_pipe( ialu_regL_regL );
12233 %}
12235 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
12236 match(Set dst (ConvL2I (URShiftL src shift)));
12237 predicate(n->in(1)->in(2)->get_int() > 32);
12238 ins_cost(80);
12239 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
12240 ins_encode %{
12241 Register src_reg = as_Register($src$$reg);
12242 Register dst_reg = as_Register($dst$$reg);
12243 int shamt = $shift$$constant;
12245 __ dsrl32(dst_reg, src_reg, shamt - 32);
12246 %}
12247 ins_pipe( ialu_regL_regL );
12248 %}
12250 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
12251 match(Set dst (URShiftL (CastP2X src) shift));
12252 ins_cost(80);
12253 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
12254 ins_encode %{
12255 Register src_reg = as_Register($src$$reg);
12256 Register dst_reg = as_Register($dst$$reg);
12257 int shamt = $shift$$constant;
12259 __ dsrl32(dst_reg, src_reg, shamt - 32);
12260 %}
12261 ins_pipe( ialu_regL_regL );
12262 %}
12264 // Xor Instructions
12265 // Xor Register with Register
12266 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
12267 match(Set dst (XorI src1 src2));
12269 format %{ "XOR $dst, $src1, $src2 #@xorI_Reg_Reg" %}
12271 ins_encode %{
12272 Register dst = $dst$$Register;
12273 Register src1 = $src1$$Register;
12274 Register src2 = $src2$$Register;
12275 __ xorr(dst, src1, src2);
12276 __ sll(dst, dst, 0); /* long -> int */
12277 %}
12279 ins_pipe( ialu_regI_regI );
12280 %}
12282 // Or Instructions
12283 // Or Register with Register
12284 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
12285 match(Set dst (OrI src1 src2));
12287 format %{ "OR $dst, $src1, $src2 #@orI_Reg_Reg" %}
12288 ins_encode %{
12289 Register dst = $dst$$Register;
12290 Register src1 = $src1$$Register;
12291 Register src2 = $src2$$Register;
12292 __ orr(dst, src1, src2);
12293 %}
12295 ins_pipe( ialu_regI_regI );
12296 %}
12298 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
12299 match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
12300 predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
12302 format %{ "rotr $dst, $src, 1 ...\n\t"
12303 "srl $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
12304 ins_encode %{
12305 Register dst = $dst$$Register;
12306 Register src = $src$$Register;
12307 int rshift = $rshift$$constant;
12309 __ rotr(dst, src, 1);
12310 if (rshift - 1) {
12311 __ srl(dst, dst, rshift - 1);
12312 }
12313 %}
12315 ins_pipe( ialu_regI_regI );
12316 %}
12318 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
12319 match(Set dst (OrI src1 (CastP2X src2)));
12321 format %{ "OR $dst, $src1, $src2 #@orI_Reg_castP2X" %}
12322 ins_encode %{
12323 Register dst = $dst$$Register;
12324 Register src1 = $src1$$Register;
12325 Register src2 = $src2$$Register;
12326 __ orr(dst, src1, src2);
12327 %}
12329 ins_pipe( ialu_regI_regI );
12330 %}
12332 // Logical Shift Right by 8-bit immediate
12333 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
12334 match(Set dst (URShiftI src shift));
12335 //effect(KILL cr);
12337 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_imm" %}
12338 ins_encode %{
12339 Register src = $src$$Register;
12340 Register dst = $dst$$Register;
12341 int shift = $shift$$constant;
12343 __ srl(dst, src, shift);
12344 %}
12345 ins_pipe( ialu_regI_regI );
12346 %}
12348 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
12349 match(Set dst (AndI (URShiftI src shift) mask));
12351 format %{ "ext $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
12352 ins_encode %{
12353 Register src = $src$$Register;
12354 Register dst = $dst$$Register;
12355 int pos = $shift$$constant;
12356 int size = Assembler::is_int_mask($mask$$constant);
12358 __ ext(dst, src, pos, size);
12359 %}
12360 ins_pipe( ialu_regI_regI );
12361 %}
12363 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
12364 %{
12365 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
12366 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
12368 ins_cost(100);
12369 format %{ "rotr $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
12370 ins_encode %{
12371 Register dst = $dst$$Register;
12372 int sa = $rshift$$constant;
12374 __ rotr(dst, dst, sa);
12375 %}
12376 ins_pipe( ialu_regI_regI );
12377 %}
12379 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
12380 %{
12381 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12382 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
12384 ins_cost(100);
12385 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
12386 ins_encode %{
12387 Register dst = $dst$$Register;
12388 int sa = $rshift$$constant;
12390 __ drotr(dst, dst, sa);
12391 %}
12392 ins_pipe( ialu_regI_regI );
12393 %}
12395 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
12396 %{
12397 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12398 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
12400 ins_cost(100);
12401 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
12402 ins_encode %{
12403 Register dst = $dst$$Register;
12404 int sa = $rshift$$constant;
12406 __ drotr32(dst, dst, sa - 32);
12407 %}
12408 ins_pipe( ialu_regI_regI );
12409 %}
12411 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
12412 %{
12413 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
12414 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
12416 ins_cost(100);
12417 format %{ "rotr $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
12418 ins_encode %{
12419 Register dst = $dst$$Register;
12420 int sa = $rshift$$constant;
12422 __ rotr(dst, dst, sa);
12423 %}
12424 ins_pipe( ialu_regI_regI );
12425 %}
12427 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
12428 %{
12429 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12430 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
12432 ins_cost(100);
12433 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
12434 ins_encode %{
12435 Register dst = $dst$$Register;
12436 int sa = $rshift$$constant;
12438 __ drotr(dst, dst, sa);
12439 %}
12440 ins_pipe( ialu_regI_regI );
12441 %}
12443 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
12444 %{
12445 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12446 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
12448 ins_cost(100);
12449 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
12450 ins_encode %{
12451 Register dst = $dst$$Register;
12452 int sa = $rshift$$constant;
12454 __ drotr32(dst, dst, sa - 32);
12455 %}
12456 ins_pipe( ialu_regI_regI );
12457 %}
12459 // Logical Shift Right
12460 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12461 match(Set dst (URShiftI src shift));
12463 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_Reg" %}
12464 ins_encode %{
12465 Register src = $src$$Register;
12466 Register dst = $dst$$Register;
12467 Register shift = $shift$$Register;
12468 __ srlv(dst, src, shift);
12469 %}
12470 ins_pipe( ialu_regI_regI );
12471 %}
12474 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
12475 match(Set dst (RShiftI src shift));
12476 // effect(KILL cr);
12478 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_imm" %}
12479 ins_encode %{
12480 Register src = $src$$Register;
12481 Register dst = $dst$$Register;
12482 int shift = $shift$$constant;
12483 __ sra(dst, src, shift);
12484 %}
12485 ins_pipe( ialu_regI_regI );
12486 %}
12488 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12489 match(Set dst (RShiftI src shift));
12490 // effect(KILL cr);
12492 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_Reg" %}
12493 ins_encode %{
12494 Register src = $src$$Register;
12495 Register dst = $dst$$Register;
12496 Register shift = $shift$$Register;
12497 __ srav(dst, src, shift);
12498 %}
12499 ins_pipe( ialu_regI_regI );
12500 %}
12502 //----------Convert Int to Boolean---------------------------------------------
12504 instruct convI2B(mRegI dst, mRegI src) %{
12505 match(Set dst (Conv2B src));
12507 ins_cost(100);
12508 format %{ "convI2B $dst, $src @ convI2B" %}
12509 ins_encode %{
12510 Register dst = as_Register($dst$$reg);
12511 Register src = as_Register($src$$reg);
12513 if (dst != src) {
12514 __ daddiu(dst, R0, 1);
12515 __ movz(dst, R0, src);
12516 } else {
12517 __ move(AT, src);
12518 __ daddiu(dst, R0, 1);
12519 __ movz(dst, R0, AT);
12520 }
12521 %}
12523 ins_pipe( ialu_regL_regL );
12524 %}
12526 instruct convI2L_reg( mRegL dst, mRegI src) %{
12527 match(Set dst (ConvI2L src));
12529 ins_cost(100);
12530 format %{ "SLL $dst, $src @ convI2L_reg\t" %}
12531 ins_encode %{
12532 Register dst = as_Register($dst$$reg);
12533 Register src = as_Register($src$$reg);
12535 if(dst != src) __ sll(dst, src, 0);
12536 %}
12537 ins_pipe( ialu_regL_regL );
12538 %}
12541 instruct convL2I_reg( mRegI dst, mRegL src ) %{
12542 match(Set dst (ConvL2I src));
12544 format %{ "MOV $dst, $src @ convL2I_reg" %}
12545 ins_encode %{
12546 Register dst = as_Register($dst$$reg);
12547 Register src = as_Register($src$$reg);
12549 __ sll(dst, src, 0);
12550 %}
12552 ins_pipe( ialu_regI_regI );
12553 %}
12555 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
12556 match(Set dst (ConvI2L (ConvL2I src)));
12558 format %{ "sll $dst, $src, 0 @ convL2I2L_reg" %}
12559 ins_encode %{
12560 Register dst = as_Register($dst$$reg);
12561 Register src = as_Register($src$$reg);
12563 __ sll(dst, src, 0);
12564 %}
12566 ins_pipe( ialu_regI_regI );
12567 %}
12569 instruct convL2D_reg( regD dst, mRegL src ) %{
12570 match(Set dst (ConvL2D src));
12571 format %{ "convL2D $dst, $src @ convL2D_reg" %}
12572 ins_encode %{
12573 Register src = as_Register($src$$reg);
12574 FloatRegister dst = as_FloatRegister($dst$$reg);
12576 __ dmtc1(src, dst);
12577 __ cvt_d_l(dst, dst);
12578 %}
12580 ins_pipe( pipe_slow );
12581 %}
12584 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
12585 match(Set dst (ConvD2L src));
12586 ins_cost(150);
12587 format %{ "convD2L $dst, $src @ convD2L_reg_fast" %}
12588 ins_encode %{
12589 Register dst = as_Register($dst$$reg);
12590 FloatRegister src = as_FloatRegister($src$$reg);
12592 Label Done;
12594 __ trunc_l_d(F30, src);
12595 // max_long: 0x7fffffffffffffff
12596 // __ set64(AT, 0x7fffffffffffffff);
12597 __ daddiu(AT, R0, -1);
12598 __ dsrl(AT, AT, 1);
12599 __ dmfc1(dst, F30);
12601 __ bne(dst, AT, Done);
12602 __ delayed()->mtc1(R0, F30);
12604 __ cvt_d_w(F30, F30);
12605 __ c_ult_d(src, F30);
12606 __ bc1f(Done);
12607 __ delayed()->daddiu(T9, R0, -1);
12609 __ c_un_d(src, src); //NaN?
12610 __ subu(dst, T9, AT);
12611 __ movt(dst, R0);
12613 __ bind(Done);
12614 %}
12616 ins_pipe( pipe_slow );
12617 %}
12620 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
12621 match(Set dst (ConvD2L src));
12622 ins_cost(250);
12623 format %{ "convD2L $dst, $src @ convD2L_reg_slow" %}
12624 ins_encode %{
12625 Register dst = as_Register($dst$$reg);
12626 FloatRegister src = as_FloatRegister($src$$reg);
12628 Label L;
12630 __ c_un_d(src, src); //NaN?
12631 __ bc1t(L);
12632 __ delayed();
12633 __ move(dst, R0);
12635 __ trunc_l_d(F30, src);
12636 __ cfc1(AT, 31);
12637 __ li(T9, 0x10000);
12638 __ andr(AT, AT, T9);
12639 __ beq(AT, R0, L);
12640 __ delayed()->dmfc1(dst, F30);
12642 __ mov_d(F12, src);
12643 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
12644 __ move(dst, V0);
12645 __ bind(L);
12646 %}
12648 ins_pipe( pipe_slow );
12649 %}
12652 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
12653 match(Set dst (ConvF2I src));
12654 ins_cost(150);
12655 format %{ "convf2i $dst, $src @ convF2I_reg_fast" %}
12656 ins_encode %{
12657 Register dreg = $dst$$Register;
12658 FloatRegister fval = $src$$FloatRegister;
12659 Label L;
12661 __ trunc_w_s(F30, fval);
12662 __ move(AT, 0x7fffffff);
12663 __ mfc1(dreg, F30);
12664 __ c_un_s(fval, fval); //NaN?
12665 __ movt(dreg, R0);
12667 __ bne(AT, dreg, L);
12668 __ delayed()->lui(T9, 0x8000);
12670 __ mfc1(AT, fval);
12671 __ andr(AT, AT, T9);
12673 __ movn(dreg, T9, AT);
12675 __ bind(L);
12677 %}
12679 ins_pipe( pipe_slow );
12680 %}
12684 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
12685 match(Set dst (ConvF2I src));
12686 ins_cost(250);
12687 format %{ "convf2i $dst, $src @ convF2I_reg_slow" %}
12688 ins_encode %{
12689 Register dreg = $dst$$Register;
12690 FloatRegister fval = $src$$FloatRegister;
12691 Label L;
12693 __ c_un_s(fval, fval); //NaN?
12694 __ bc1t(L);
12695 __ delayed();
12696 __ move(dreg, R0);
12698 __ trunc_w_s(F30, fval);
12700 /* Call SharedRuntime:f2i() to do valid convention */
12701 __ cfc1(AT, 31);
12702 __ li(T9, 0x10000);
12703 __ andr(AT, AT, T9);
12704 __ beq(AT, R0, L);
12705 __ delayed()->mfc1(dreg, F30);
12707 __ mov_s(F12, fval);
12709 //This bug was found when running ezDS's control-panel.
12710 // J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
12711 //
12712 // An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
12713 // V0 is corrupted during call_VM_leaf(), and should be preserved.
12714 //
12715 __ push(fval);
12716 if(dreg != V0) {
12717 __ push(V0);
12718 }
12719 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
12720 if(dreg != V0) {
12721 __ move(dreg, V0);
12722 __ pop(V0);
12723 }
12724 __ pop(fval);
12725 __ bind(L);
12726 %}
12728 ins_pipe( pipe_slow );
12729 %}
12732 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
12733 match(Set dst (ConvF2L src));
12734 ins_cost(150);
12735 format %{ "convf2l $dst, $src @ convF2L_reg_fast" %}
12736 ins_encode %{
12737 Register dreg = $dst$$Register;
12738 FloatRegister fval = $src$$FloatRegister;
12739 Label L;
12741 __ trunc_l_s(F30, fval);
12742 __ daddiu(AT, R0, -1);
12743 __ dsrl(AT, AT, 1);
12744 __ dmfc1(dreg, F30);
12745 __ c_un_s(fval, fval); //NaN?
12746 __ movt(dreg, R0);
12748 __ bne(AT, dreg, L);
12749 __ delayed()->lui(T9, 0x8000);
12751 __ mfc1(AT, fval);
12752 __ andr(AT, AT, T9);
12754 __ dsll32(T9, T9, 0);
12755 __ movn(dreg, T9, AT);
12757 __ bind(L);
12758 %}
12760 ins_pipe( pipe_slow );
12761 %}
12764 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
12765 match(Set dst (ConvF2L src));
12766 ins_cost(250);
12767 format %{ "convf2l $dst, $src @ convF2L_reg_slow" %}
12768 ins_encode %{
12769 Register dst = as_Register($dst$$reg);
12770 FloatRegister fval = $src$$FloatRegister;
12771 Label L;
12773 __ c_un_s(fval, fval); //NaN?
12774 __ bc1t(L);
12775 __ delayed();
12776 __ move(dst, R0);
12778 __ trunc_l_s(F30, fval);
12779 __ cfc1(AT, 31);
12780 __ li(T9, 0x10000);
12781 __ andr(AT, AT, T9);
12782 __ beq(AT, R0, L);
12783 __ delayed()->dmfc1(dst, F30);
12785 __ mov_s(F12, fval);
12786 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
12787 __ move(dst, V0);
12788 __ bind(L);
12789 %}
12791 ins_pipe( pipe_slow );
12792 %}
12794 instruct convL2F_reg( regF dst, mRegL src ) %{
12795 match(Set dst (ConvL2F src));
12796 format %{ "convl2f $dst, $src @ convL2F_reg" %}
12797 ins_encode %{
12798 FloatRegister dst = $dst$$FloatRegister;
12799 Register src = as_Register($src$$reg);
12800 Label L;
12802 __ dmtc1(src, dst);
12803 __ cvt_s_l(dst, dst);
12804 %}
12806 ins_pipe( pipe_slow );
12807 %}
12809 instruct convI2F_reg( regF dst, mRegI src ) %{
12810 match(Set dst (ConvI2F src));
12811 format %{ "convi2f $dst, $src @ convI2F_reg" %}
12812 ins_encode %{
12813 Register src = $src$$Register;
12814 FloatRegister dst = $dst$$FloatRegister;
12816 __ mtc1(src, dst);
12817 __ cvt_s_w(dst, dst);
12818 %}
12820 ins_pipe( fpu_regF_regF );
12821 %}
12823 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
12824 match(Set dst (CmpLTMask p zero));
12825 ins_cost(100);
12827 format %{ "sra $dst, $p, 31 @ cmpLTMask_immI0" %}
12828 ins_encode %{
12829 Register src = $p$$Register;
12830 Register dst = $dst$$Register;
12832 __ sra(dst, src, 31);
12833 %}
12834 ins_pipe( pipe_slow );
12835 %}
12838 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
12839 match(Set dst (CmpLTMask p q));
12840 ins_cost(400);
12842 format %{ "cmpLTMask $dst, $p, $q @ cmpLTMask" %}
12843 ins_encode %{
12844 Register p = $p$$Register;
12845 Register q = $q$$Register;
12846 Register dst = $dst$$Register;
12848 __ slt(dst, p, q);
12849 __ subu(dst, R0, dst);
12850 %}
12851 ins_pipe( pipe_slow );
12852 %}
12854 instruct convP2B(mRegI dst, mRegP src) %{
12855 match(Set dst (Conv2B src));
12857 ins_cost(100);
12858 format %{ "convP2B $dst, $src @ convP2B" %}
12859 ins_encode %{
12860 Register dst = as_Register($dst$$reg);
12861 Register src = as_Register($src$$reg);
12863 if (dst != src) {
12864 __ daddiu(dst, R0, 1);
12865 __ movz(dst, R0, src);
12866 } else {
12867 __ move(AT, src);
12868 __ daddiu(dst, R0, 1);
12869 __ movz(dst, R0, AT);
12870 }
12871 %}
12873 ins_pipe( ialu_regL_regL );
12874 %}
12877 instruct convI2D_reg_reg(regD dst, mRegI src) %{
12878 match(Set dst (ConvI2D src));
12879 format %{ "conI2D $dst, $src @convI2D_reg" %}
12880 ins_encode %{
12881 Register src = $src$$Register;
12882 FloatRegister dst = $dst$$FloatRegister;
12883 __ mtc1(src, dst);
12884 __ cvt_d_w(dst, dst);
12885 %}
12886 ins_pipe( fpu_regF_regF );
12887 %}
12889 instruct convF2D_reg_reg(regD dst, regF src) %{
12890 match(Set dst (ConvF2D src));
12891 format %{ "convF2D $dst, $src\t# @convF2D_reg_reg" %}
12892 ins_encode %{
12893 FloatRegister dst = $dst$$FloatRegister;
12894 FloatRegister src = $src$$FloatRegister;
12896 __ cvt_d_s(dst, src);
12897 %}
12898 ins_pipe( fpu_regF_regF );
12899 %}
12901 instruct convD2F_reg_reg(regF dst, regD src) %{
12902 match(Set dst (ConvD2F src));
12903 format %{ "convD2F $dst, $src\t# @convD2F_reg_reg" %}
12904 ins_encode %{
12905 FloatRegister dst = $dst$$FloatRegister;
12906 FloatRegister src = $src$$FloatRegister;
12908 __ cvt_s_d(dst, src);
12909 %}
12910 ins_pipe( fpu_regF_regF );
12911 %}
12914 // Convert a double to an int. If the double is a NAN, stuff a zero in instead.
12915 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
12916 match(Set dst (ConvD2I src));
12918 ins_cost(150);
12919 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
12921 ins_encode %{
12922 FloatRegister src = $src$$FloatRegister;
12923 Register dst = $dst$$Register;
12925 Label Done;
12927 __ trunc_w_d(F30, src);
12928 // max_int: 2147483647
12929 __ move(AT, 0x7fffffff);
12930 __ mfc1(dst, F30);
12932 __ bne(dst, AT, Done);
12933 __ delayed()->mtc1(R0, F30);
12935 __ cvt_d_w(F30, F30);
12936 __ c_ult_d(src, F30);
12937 __ bc1f(Done);
12938 __ delayed()->addiu(T9, R0, -1);
12940 __ c_un_d(src, src); //NaN?
12941 __ subu32(dst, T9, AT);
12942 __ movt(dst, R0);
12944 __ bind(Done);
12945 %}
12946 ins_pipe( pipe_slow );
12947 %}
12950 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
12951 match(Set dst (ConvD2I src));
12953 ins_cost(250);
12954 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
12956 ins_encode %{
12957 FloatRegister src = $src$$FloatRegister;
12958 Register dst = $dst$$Register;
12959 Label L;
12961 __ trunc_w_d(F30, src);
12962 __ cfc1(AT, 31);
12963 __ li(T9, 0x10000);
12964 __ andr(AT, AT, T9);
12965 __ beq(AT, R0, L);
12966 __ delayed()->mfc1(dst, F30);
12968 __ mov_d(F12, src);
12969 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
12970 __ move(dst, V0);
12971 __ bind(L);
12973 %}
12974 ins_pipe( pipe_slow );
12975 %}
12977 // Convert oop pointer into compressed form
12978 instruct encodeHeapOop(mRegN dst, mRegP src) %{
12979 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
12980 match(Set dst (EncodeP src));
12981 format %{ "encode_heap_oop $dst,$src" %}
12982 ins_encode %{
12983 Register src = $src$$Register;
12984 Register dst = $dst$$Register;
12986 __ encode_heap_oop(dst, src);
12987 %}
12988 ins_pipe( ialu_regL_regL );
12989 %}
12991 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
12992 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
12993 match(Set dst (EncodeP src));
12994 format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
12995 ins_encode %{
12996 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
12997 %}
12998 ins_pipe( ialu_regL_regL );
12999 %}
13001 instruct decodeHeapOop(mRegP dst, mRegN src) %{
13002 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
13003 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
13004 match(Set dst (DecodeN src));
13005 format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
13006 ins_encode %{
13007 Register s = $src$$Register;
13008 Register d = $dst$$Register;
13010 __ decode_heap_oop(d, s);
13011 %}
13012 ins_pipe( ialu_regL_regL );
13013 %}
13015 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
13016 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
13017 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
13018 match(Set dst (DecodeN src));
13019 format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
13020 ins_encode %{
13021 Register s = $src$$Register;
13022 Register d = $dst$$Register;
13023 if (s != d) {
13024 __ decode_heap_oop_not_null(d, s);
13025 } else {
13026 __ decode_heap_oop_not_null(d);
13027 }
13028 %}
13029 ins_pipe( ialu_regL_regL );
13030 %}
13032 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
13033 match(Set dst (EncodePKlass src));
13034 format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
13035 ins_encode %{
13036 __ encode_klass_not_null($dst$$Register, $src$$Register);
13037 %}
13038 ins_pipe( ialu_regL_regL );
13039 %}
13041 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
13042 match(Set dst (DecodeNKlass src));
13043 format %{ "decode_heap_klass_not_null $dst,$src" %}
13044 ins_encode %{
13045 Register s = $src$$Register;
13046 Register d = $dst$$Register;
13047 if (s != d) {
13048 __ decode_klass_not_null(d, s);
13049 } else {
13050 __ decode_klass_not_null(d);
13051 }
13052 %}
13053 ins_pipe( ialu_regL_regL );
13054 %}
13056 //FIXME
13057 instruct tlsLoadP(mRegP dst) %{
13058 match(Set dst (ThreadLocal));
13060 ins_cost(0);
13061 format %{ " get_thread in $dst #@tlsLoadP" %}
13062 ins_encode %{
13063 Register dst = $dst$$Register;
13064 #ifdef OPT_THREAD
13065 __ move(dst, TREG);
13066 #else
13067 __ get_thread(dst);
13068 #endif
13069 %}
13071 ins_pipe( ialu_loadI );
13072 %}
13075 instruct checkCastPP( mRegP dst ) %{
13076 match(Set dst (CheckCastPP dst));
13078 format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
13079 ins_encode( /*empty encoding*/ );
13080 ins_pipe( empty );
13081 %}
13083 instruct castPP(mRegP dst)
13084 %{
13085 match(Set dst (CastPP dst));
13087 size(0);
13088 format %{ "# castPP of $dst" %}
13089 ins_encode(/* empty encoding */);
13090 ins_pipe(empty);
13091 %}
13093 instruct castII( mRegI dst ) %{
13094 match(Set dst (CastII dst));
13095 format %{ "#castII of $dst empty encoding" %}
13096 ins_encode( /*empty encoding*/ );
13097 ins_cost(0);
13098 ins_pipe( empty );
13099 %}
13101 // Return Instruction
13102 // Remove the return address & jump to it.
13103 instruct Ret() %{
13104 match(Return);
13105 format %{ "RET #@Ret" %}
13107 ins_encode %{
13108 __ jr(RA);
13109 __ delayed()->nop();
13110 %}
13112 ins_pipe( pipe_jump );
13113 %}
13115 /*
13116 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
13117 instruct jumpXtnd(mRegL switch_val) %{
13118 match(Jump switch_val);
13120 ins_cost(350);
13122 format %{ "load T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
13123 "jr T9\n\t"
13124 "nop" %}
13125 ins_encode %{
13126 Register table_base = $constanttablebase;
13127 int con_offset = $constantoffset;
13128 Register switch_reg = $switch_val$$Register;
13130 if (UseLoongsonISA) {
13131 if (Assembler::is_simm(con_offset, 8)) {
13132 __ gsldx(T9, table_base, switch_reg, con_offset);
13133 } else if (Assembler::is_simm16(con_offset)) {
13134 __ daddu(T9, table_base, switch_reg);
13135 __ ld(T9, T9, con_offset);
13136 } else {
13137 __ move(T9, con_offset);
13138 __ daddu(AT, table_base, switch_reg);
13139 __ gsldx(T9, AT, T9, 0);
13140 }
13141 } else {
13142 if (Assembler::is_simm16(con_offset)) {
13143 __ daddu(T9, table_base, switch_reg);
13144 __ ld(T9, T9, con_offset);
13145 } else {
13146 __ move(T9, con_offset);
13147 __ daddu(AT, table_base, switch_reg);
13148 __ daddu(AT, T9, AT);
13149 __ ld(T9, AT, 0);
13150 }
13151 }
13153 __ jr(T9);
13154 __ delayed()->nop();
13156 %}
13157 ins_pipe(pipe_jump);
13158 %}
13159 */
13162 // Tail Jump; remove the return address; jump to target.
13163 // TailCall above leaves the return address around.
13164 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13165 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13166 // "restore" before this instruction (in Epilogue), we need to materialize it
13167 // in %i0.
13168 //FIXME
13169 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
13170 match( TailJump jump_target ex_oop );
13171 ins_cost(200);
13172 format %{ "Jmp $jump_target ; ex_oop = $ex_oop #@tailjmpInd" %}
13173 ins_encode %{
13174 Register target = $jump_target$$Register;
13176 // V0, V1 are indicated in:
13177 // [stubGenerator_mips.cpp] generate_forward_exception()
13178 // [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
13179 //
13180 Register oop = $ex_oop$$Register;
13181 Register exception_oop = V0;
13182 Register exception_pc = V1;
13184 __ move(exception_pc, RA);
13185 __ move(exception_oop, oop);
13187 __ jr(target);
13188 __ delayed()->nop();
13189 %}
13190 ins_pipe( pipe_jump );
13191 %}
13193 // ============================================================================
13194 // Procedure Call/Return Instructions
13195 // Call Java Static Instruction
13196 // Note: If this code changes, the corresponding ret_addr_offset() and
13197 // compute_padding() functions will have to be adjusted.
13198 instruct CallStaticJavaDirect(method meth) %{
13199 match(CallStaticJava);
13200 effect(USE meth);
13202 ins_cost(300);
13203 format %{ "CALL,static #@CallStaticJavaDirect " %}
13204 ins_encode( Java_Static_Call( meth ) );
13205 ins_pipe( pipe_slow );
13206 ins_pc_relative(1);
13207 %}
13209 // Call Java Dynamic Instruction
13210 // Note: If this code changes, the corresponding ret_addr_offset() and
13211 // compute_padding() functions will have to be adjusted.
13212 instruct CallDynamicJavaDirect(method meth) %{
13213 match(CallDynamicJava);
13214 effect(USE meth);
13216 ins_cost(300);
13217 format %{"MOV IC_Klass, #Universe::non_oop_word()\n\t"
13218 "CallDynamic @ CallDynamicJavaDirect" %}
13219 ins_encode( Java_Dynamic_Call( meth ) );
13220 ins_pipe( pipe_slow );
13221 ins_pc_relative(1);
13222 %}
13224 instruct CallLeafNoFPDirect(method meth) %{
13225 match(CallLeafNoFP);
13226 effect(USE meth);
13228 ins_cost(300);
13229 format %{ "CALL_LEAF_NOFP,runtime " %}
13230 ins_encode(Java_To_Runtime(meth));
13231 ins_pipe( pipe_slow );
13232 ins_pc_relative(1);
13233 ins_alignment(16);
13234 %}
13236 // Prefetch instructions.
13238 instruct prefetchrNTA( memory mem ) %{
13239 match(PrefetchRead mem);
13240 ins_cost(125);
13242 format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
13243 ins_encode %{
13244 int base = $mem$$base;
13245 int index = $mem$$index;
13246 int scale = $mem$$scale;
13247 int disp = $mem$$disp;
13249 if( index != 0 ) {
13250 if (scale == 0) {
13251 __ daddu(AT, as_Register(base), as_Register(index));
13252 } else {
13253 __ dsll(AT, as_Register(index), scale);
13254 __ daddu(AT, as_Register(base), AT);
13255 }
13256 } else {
13257 __ move(AT, as_Register(base));
13258 }
13259 if( Assembler::is_simm16(disp) ) {
13260 __ daddiu(AT, as_Register(base), disp);
13261 __ daddiu(AT, AT, disp);
13262 } else {
13263 __ move(T9, disp);
13264 __ daddu(AT, as_Register(base), T9);
13265 }
13266 __ pref(0, AT, 0); //hint: 0:load
13267 %}
13268 ins_pipe(pipe_slow);
13269 %}
13271 instruct prefetchwNTA( memory mem ) %{
13272 match(PrefetchWrite mem);
13273 ins_cost(125);
13274 format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
13275 ins_encode %{
13276 int base = $mem$$base;
13277 int index = $mem$$index;
13278 int scale = $mem$$scale;
13279 int disp = $mem$$disp;
13281 if( index != 0 ) {
13282 if (scale == 0) {
13283 __ daddu(AT, as_Register(base), as_Register(index));
13284 } else {
13285 __ dsll(AT, as_Register(index), scale);
13286 __ daddu(AT, as_Register(base), AT);
13287 }
13288 } else {
13289 __ move(AT, as_Register(base));
13290 }
13291 if( Assembler::is_simm16(disp) ) {
13292 __ daddiu(AT, as_Register(base), disp);
13293 __ daddiu(AT, AT, disp);
13294 } else {
13295 __ move(T9, disp);
13296 __ daddu(AT, as_Register(base), T9);
13297 }
13298 __ pref(1, AT, 0); //hint: 1:store
13299 %}
13300 ins_pipe(pipe_slow);
13301 %}
13303 // Prefetch instructions for allocation.
13305 instruct prefetchAllocNTA( memory mem ) %{
13306 match(PrefetchAllocation mem);
13307 ins_cost(125);
13308 format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
13309 ins_encode %{
13310 int base = $mem$$base;
13311 int index = $mem$$index;
13312 int scale = $mem$$scale;
13313 int disp = $mem$$disp;
13315 Register dst = R0;
13317 if( index != 0 ) {
13318 if( Assembler::is_simm16(disp) ) {
13319 if( UseLoongsonISA ) {
13320 if (scale == 0) {
13321 __ gslbx(dst, as_Register(base), as_Register(index), disp);
13322 } else {
13323 __ dsll(AT, as_Register(index), scale);
13324 __ gslbx(dst, as_Register(base), AT, disp);
13325 }
13326 } else {
13327 if (scale == 0) {
13328 __ addu(AT, as_Register(base), as_Register(index));
13329 } else {
13330 __ dsll(AT, as_Register(index), scale);
13331 __ addu(AT, as_Register(base), AT);
13332 }
13333 __ lb(dst, AT, disp);
13334 }
13335 } else {
13336 if (scale == 0) {
13337 __ addu(AT, as_Register(base), as_Register(index));
13338 } else {
13339 __ dsll(AT, as_Register(index), scale);
13340 __ addu(AT, as_Register(base), AT);
13341 }
13342 __ move(T9, disp);
13343 if( UseLoongsonISA ) {
13344 __ gslbx(dst, AT, T9, 0);
13345 } else {
13346 __ addu(AT, AT, T9);
13347 __ lb(dst, AT, 0);
13348 }
13349 }
13350 } else {
13351 if( Assembler::is_simm16(disp) ) {
13352 __ lb(dst, as_Register(base), disp);
13353 } else {
13354 __ move(T9, disp);
13355 if( UseLoongsonISA ) {
13356 __ gslbx(dst, as_Register(base), T9, 0);
13357 } else {
13358 __ addu(AT, as_Register(base), T9);
13359 __ lb(dst, AT, 0);
13360 }
13361 }
13362 }
13363 %}
13364 ins_pipe(pipe_slow);
13365 %}
13368 // Call runtime without safepoint
13369 instruct CallLeafDirect(method meth) %{
13370 match(CallLeaf);
13371 effect(USE meth);
13373 ins_cost(300);
13374 format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
13375 ins_encode(Java_To_Runtime(meth));
13376 ins_pipe( pipe_slow );
13377 ins_pc_relative(1);
13378 ins_alignment(16);
13379 %}
13381 // Load Char (16bit unsigned)
13382 instruct loadUS(mRegI dst, memory mem) %{
13383 match(Set dst (LoadUS mem));
13385 ins_cost(125);
13386 format %{ "loadUS $dst,$mem @ loadC" %}
13387 ins_encode(load_C_enc(dst, mem));
13388 ins_pipe( ialu_loadI );
13389 %}
13391 instruct loadUS_convI2L(mRegL dst, memory mem) %{
13392 match(Set dst (ConvI2L (LoadUS mem)));
13394 ins_cost(125);
13395 format %{ "loadUS $dst,$mem @ loadUS_convI2L" %}
13396 ins_encode(load_C_enc(dst, mem));
13397 ins_pipe( ialu_loadI );
13398 %}
13400 // Store Char (16bit unsigned)
13401 instruct storeC(memory mem, mRegI src) %{
13402 match(Set mem (StoreC mem src));
13404 ins_cost(125);
13405 format %{ "storeC $src, $mem @ storeC" %}
13406 ins_encode(store_C_reg_enc(mem, src));
13407 ins_pipe( ialu_loadI );
13408 %}
13410 instruct storeC0(memory mem, immI0 zero) %{
13411 match(Set mem (StoreC mem zero));
13413 ins_cost(125);
13414 format %{ "storeC $zero, $mem @ storeC0" %}
13415 ins_encode(store_C0_enc(mem));
13416 ins_pipe( ialu_loadI );
13417 %}
13420 instruct loadConF0(regF dst, immF0 zero) %{
13421 match(Set dst zero);
13422 ins_cost(100);
13424 format %{ "mov $dst, zero @ loadConF0\n"%}
13425 ins_encode %{
13426 FloatRegister dst = $dst$$FloatRegister;
13428 __ mtc1(R0, dst);
13429 %}
13430 ins_pipe( fpu_loadF );
13431 %}
13434 instruct loadConF(regF dst, immF src) %{
13435 match(Set dst src);
13436 ins_cost(125);
13438 format %{ "lwc1 $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
13439 ins_encode %{
13440 int con_offset = $constantoffset($src);
13442 if (Assembler::is_simm16(con_offset)) {
13443 __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
13444 } else {
13445 __ set64(AT, con_offset);
13446 if (UseLoongsonISA) {
13447 __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
13448 } else {
13449 __ daddu(AT, $constanttablebase, AT);
13450 __ lwc1($dst$$FloatRegister, AT, 0);
13451 }
13452 }
13453 %}
13454 ins_pipe( fpu_loadF );
13455 %}
13458 instruct loadConD0(regD dst, immD0 zero) %{
13459 match(Set dst zero);
13460 ins_cost(100);
13462 format %{ "mov $dst, zero @ loadConD0"%}
13463 ins_encode %{
13464 FloatRegister dst = as_FloatRegister($dst$$reg);
13466 __ dmtc1(R0, dst);
13467 %}
13468 ins_pipe( fpu_loadF );
13469 %}
13471 instruct loadConD(regD dst, immD src) %{
13472 match(Set dst src);
13473 ins_cost(125);
13475 format %{ "ldc1 $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
13476 ins_encode %{
13477 int con_offset = $constantoffset($src);
13479 if (Assembler::is_simm16(con_offset)) {
13480 __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
13481 } else {
13482 __ set64(AT, con_offset);
13483 if (UseLoongsonISA) {
13484 __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
13485 } else {
13486 __ daddu(AT, $constanttablebase, AT);
13487 __ ldc1($dst$$FloatRegister, AT, 0);
13488 }
13489 }
13490 %}
13491 ins_pipe( fpu_loadF );
13492 %}
13494 // Store register Float value (it is faster than store from FPU register)
13495 instruct storeF_reg( memory mem, regF src) %{
13496 match(Set mem (StoreF mem src));
13498 ins_cost(50);
13499 format %{ "store $mem, $src\t# store float @ storeF_reg" %}
13500 ins_encode(store_F_reg_enc(mem, src));
13501 ins_pipe( fpu_storeF );
13502 %}
13504 instruct storeF_imm0( memory mem, immF0 zero) %{
13505 match(Set mem (StoreF mem zero));
13507 ins_cost(40);
13508 format %{ "store $mem, zero\t# store float @ storeF_imm0" %}
13509 ins_encode %{
13510 int base = $mem$$base;
13511 int index = $mem$$index;
13512 int scale = $mem$$scale;
13513 int disp = $mem$$disp;
13515 if( index != 0 ) {
13516 if ( UseLoongsonISA ) {
13517 if ( Assembler::is_simm(disp, 8) ) {
13518 if ( scale == 0 ) {
13519 __ gsswx(R0, as_Register(base), as_Register(index), disp);
13520 } else {
13521 __ dsll(T9, as_Register(index), scale);
13522 __ gsswx(R0, as_Register(base), T9, disp);
13523 }
13524 } else if ( Assembler::is_simm16(disp) ) {
13525 if ( scale == 0 ) {
13526 __ daddu(AT, as_Register(base), as_Register(index));
13527 } else {
13528 __ dsll(T9, as_Register(index), scale);
13529 __ daddu(AT, as_Register(base), T9);
13530 }
13531 __ sw(R0, AT, disp);
13532 } else {
13533 if ( scale == 0 ) {
13534 __ move(T9, disp);
13535 __ daddu(AT, as_Register(index), T9);
13536 __ gsswx(R0, as_Register(base), AT, 0);
13537 } else {
13538 __ dsll(T9, as_Register(index), scale);
13539 __ move(AT, disp);
13540 __ daddu(AT, AT, T9);
13541 __ gsswx(R0, as_Register(base), AT, 0);
13542 }
13543 }
13544 } else { //not use loongson isa
13545 if(scale != 0) {
13546 __ dsll(T9, as_Register(index), scale);
13547 __ daddu(AT, as_Register(base), T9);
13548 } else {
13549 __ daddu(AT, as_Register(base), as_Register(index));
13550 }
13551 if( Assembler::is_simm16(disp) ) {
13552 __ sw(R0, AT, disp);
13553 } else {
13554 __ move(T9, disp);
13555 __ daddu(AT, AT, T9);
13556 __ sw(R0, AT, 0);
13557 }
13558 }
13559 } else { //index is 0
13560 if ( UseLoongsonISA ) {
13561 if ( Assembler::is_simm16(disp) ) {
13562 __ sw(R0, as_Register(base), disp);
13563 } else {
13564 __ move(T9, disp);
13565 __ gsswx(R0, as_Register(base), T9, 0);
13566 }
13567 } else {
13568 if( Assembler::is_simm16(disp) ) {
13569 __ sw(R0, as_Register(base), disp);
13570 } else {
13571 __ move(T9, disp);
13572 __ daddu(AT, as_Register(base), T9);
13573 __ sw(R0, AT, 0);
13574 }
13575 }
13576 }
13577 %}
13578 ins_pipe( ialu_storeI );
13579 %}
13581 // Load Double
13582 instruct loadD(regD dst, memory mem) %{
13583 match(Set dst (LoadD mem));
13585 ins_cost(150);
13586 format %{ "loadD $dst, $mem #@loadD" %}
13587 ins_encode(load_D_enc(dst, mem));
13588 ins_pipe( ialu_loadI );
13589 %}
13591 // Load Double - UNaligned
13592 instruct loadD_unaligned(regD dst, memory mem ) %{
13593 match(Set dst (LoadD_unaligned mem));
13594 ins_cost(250);
13595 // FIXME: Need more effective ldl/ldr
13596 format %{ "loadD_unaligned $dst, $mem #@loadD_unaligned" %}
13597 ins_encode(load_D_enc(dst, mem));
13598 ins_pipe( ialu_loadI );
13599 %}
13601 instruct storeD_reg( memory mem, regD src) %{
13602 match(Set mem (StoreD mem src));
13604 ins_cost(50);
13605 format %{ "store $mem, $src\t# store float @ storeD_reg" %}
13606 ins_encode(store_D_reg_enc(mem, src));
13607 ins_pipe( fpu_storeF );
13608 %}
13610 instruct storeD_imm0( memory mem, immD0 zero) %{
13611 match(Set mem (StoreD mem zero));
13613 ins_cost(40);
13614 format %{ "store $mem, zero\t# store float @ storeD_imm0" %}
13615 ins_encode %{
13616 int base = $mem$$base;
13617 int index = $mem$$index;
13618 int scale = $mem$$scale;
13619 int disp = $mem$$disp;
13621 __ mtc1(R0, F30);
13622 __ cvt_d_w(F30, F30);
13624 if( index != 0 ) {
13625 if ( UseLoongsonISA ) {
13626 if ( Assembler::is_simm(disp, 8) ) {
13627 if (scale == 0) {
13628 __ gssdxc1(F30, as_Register(base), as_Register(index), disp);
13629 } else {
13630 __ dsll(T9, as_Register(index), scale);
13631 __ gssdxc1(F30, as_Register(base), T9, disp);
13632 }
13633 } else if ( Assembler::is_simm16(disp) ) {
13634 if (scale == 0) {
13635 __ daddu(AT, as_Register(base), as_Register(index));
13636 __ sdc1(F30, AT, disp);
13637 } else {
13638 __ dsll(T9, as_Register(index), scale);
13639 __ daddu(AT, as_Register(base), T9);
13640 __ sdc1(F30, AT, disp);
13641 }
13642 } else {
13643 if (scale == 0) {
13644 __ move(T9, disp);
13645 __ daddu(AT, as_Register(index), T9);
13646 __ gssdxc1(F30, as_Register(base), AT, 0);
13647 } else {
13648 __ move(T9, disp);
13649 __ dsll(AT, as_Register(index), scale);
13650 __ daddu(AT, AT, T9);
13651 __ gssdxc1(F30, as_Register(base), AT, 0);
13652 }
13653 }
13654 } else { // not use loongson isa
13655 if(scale != 0) {
13656 __ dsll(T9, as_Register(index), scale);
13657 __ daddu(AT, as_Register(base), T9);
13658 } else {
13659 __ daddu(AT, as_Register(base), as_Register(index));
13660 }
13661 if( Assembler::is_simm16(disp) ) {
13662 __ sdc1(F30, AT, disp);
13663 } else {
13664 __ move(T9, disp);
13665 __ daddu(AT, AT, T9);
13666 __ sdc1(F30, AT, 0);
13667 }
13668 }
13669 } else {// index is 0
13670 if ( UseLoongsonISA ) {
13671 if ( Assembler::is_simm16(disp) ) {
13672 __ sdc1(F30, as_Register(base), disp);
13673 } else {
13674 __ move(T9, disp);
13675 __ gssdxc1(F30, as_Register(base), T9, 0);
13676 }
13677 } else {
13678 if( Assembler::is_simm16(disp) ) {
13679 __ sdc1(F30, as_Register(base), disp);
13680 } else {
13681 __ move(T9, disp);
13682 __ daddu(AT, as_Register(base), T9);
13683 __ sdc1(F30, AT, 0);
13684 }
13685 }
13686 }
13687 %}
13688 ins_pipe( ialu_storeI );
13689 %}
13691 instruct loadSSI(mRegI dst, stackSlotI src)
13692 %{
13693 match(Set dst src);
13695 ins_cost(125);
13696 format %{ "lw $dst, $src\t# int stk @ loadSSI" %}
13697 ins_encode %{
13698 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
13699 __ lw($dst$$Register, SP, $src$$disp);
13700 %}
13701 ins_pipe(ialu_loadI);
13702 %}
13704 instruct storeSSI(stackSlotI dst, mRegI src)
13705 %{
13706 match(Set dst src);
13708 ins_cost(100);
13709 format %{ "sw $dst, $src\t# int stk @ storeSSI" %}
13710 ins_encode %{
13711 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
13712 __ sw($src$$Register, SP, $dst$$disp);
13713 %}
13714 ins_pipe(ialu_storeI);
13715 %}
13717 instruct loadSSL(mRegL dst, stackSlotL src)
13718 %{
13719 match(Set dst src);
13721 ins_cost(125);
13722 format %{ "ld $dst, $src\t# long stk @ loadSSL" %}
13723 ins_encode %{
13724 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
13725 __ ld($dst$$Register, SP, $src$$disp);
13726 %}
13727 ins_pipe(ialu_loadI);
13728 %}
13730 instruct storeSSL(stackSlotL dst, mRegL src)
13731 %{
13732 match(Set dst src);
13734 ins_cost(100);
13735 format %{ "sd $dst, $src\t# long stk @ storeSSL" %}
13736 ins_encode %{
13737 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
13738 __ sd($src$$Register, SP, $dst$$disp);
13739 %}
13740 ins_pipe(ialu_storeI);
13741 %}
13743 instruct loadSSP(mRegP dst, stackSlotP src)
13744 %{
13745 match(Set dst src);
13747 ins_cost(125);
13748 format %{ "ld $dst, $src\t# ptr stk @ loadSSP" %}
13749 ins_encode %{
13750 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
13751 __ ld($dst$$Register, SP, $src$$disp);
13752 %}
13753 ins_pipe(ialu_loadI);
13754 %}
13756 instruct storeSSP(stackSlotP dst, mRegP src)
13757 %{
13758 match(Set dst src);
13760 ins_cost(100);
13761 format %{ "sd $dst, $src\t# ptr stk @ storeSSP" %}
13762 ins_encode %{
13763 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
13764 __ sd($src$$Register, SP, $dst$$disp);
13765 %}
13766 ins_pipe(ialu_storeI);
13767 %}
13769 instruct loadSSF(regF dst, stackSlotF src)
13770 %{
13771 match(Set dst src);
13773 ins_cost(125);
13774 format %{ "lwc1 $dst, $src\t# float stk @ loadSSF" %}
13775 ins_encode %{
13776 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
13777 __ lwc1($dst$$FloatRegister, SP, $src$$disp);
13778 %}
13779 ins_pipe(ialu_loadI);
13780 %}
13782 instruct storeSSF(stackSlotF dst, regF src)
13783 %{
13784 match(Set dst src);
13786 ins_cost(100);
13787 format %{ "swc1 $dst, $src\t# float stk @ storeSSF" %}
13788 ins_encode %{
13789 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
13790 __ swc1($src$$FloatRegister, SP, $dst$$disp);
13791 %}
13792 ins_pipe(fpu_storeF);
13793 %}
13795 // Use the same format since predicate() can not be used here.
13796 instruct loadSSD(regD dst, stackSlotD src)
13797 %{
13798 match(Set dst src);
13800 ins_cost(125);
13801 format %{ "ldc1 $dst, $src\t# double stk @ loadSSD" %}
13802 ins_encode %{
13803 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
13804 __ ldc1($dst$$FloatRegister, SP, $src$$disp);
13805 %}
13806 ins_pipe(ialu_loadI);
13807 %}
13809 instruct storeSSD(stackSlotD dst, regD src)
13810 %{
13811 match(Set dst src);
13813 ins_cost(100);
13814 format %{ "sdc1 $dst, $src\t# double stk @ storeSSD" %}
13815 ins_encode %{
13816 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
13817 __ sdc1($src$$FloatRegister, SP, $dst$$disp);
13818 %}
13819 ins_pipe(fpu_storeF);
13820 %}
13822 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
13823 match( Set cr (FastLock object box) );
13824 effect( TEMP tmp, TEMP scr, USE_KILL box );
13825 ins_cost(300);
13826 format %{ "FASTLOCK $cr <-- $object, $box, $tmp, $scr #@ cmpFastLock" %}
13827 ins_encode %{
13828 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
13829 %}
13831 ins_pipe( pipe_slow );
13832 ins_pc_relative(1);
13833 %}
13835 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
13836 match( Set cr (FastUnlock object box) );
13837 effect( TEMP tmp, USE_KILL box );
13838 ins_cost(300);
13839 format %{ "FASTUNLOCK $cr <-- $object, $box, $tmp #@cmpFastUnlock" %}
13840 ins_encode %{
13841 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
13842 %}
13844 ins_pipe( pipe_slow );
13845 ins_pc_relative(1);
13846 %}
13848 // Store CMS card-mark Immediate
13849 instruct storeImmCM(memory mem, immI8 src) %{
13850 match(Set mem (StoreCM mem src));
13852 ins_cost(150);
13853 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %}
13854 // opcode(0xC6);
13855 ins_encode(store_B_immI_enc_sync(mem, src));
13856 ins_pipe( ialu_storeI );
13857 %}
13859 // Die now
13860 instruct ShouldNotReachHere( )
13861 %{
13862 match(Halt);
13863 ins_cost(300);
13865 // Use the following format syntax
13866 format %{ "ILLTRAP ;#@ShouldNotReachHere" %}
13867 ins_encode %{
13868 // Here we should emit illtrap !
13870 __ stop("in ShoudNotReachHere");
13872 %}
13873 ins_pipe( pipe_jump );
13874 %}
13876 instruct leaP8Narrow(mRegP dst, indOffset8Narrow mem)
13877 %{
13878 predicate(Universe::narrow_oop_shift() == 0);
13879 match(Set dst mem);
13881 ins_cost(110);
13882 format %{ "leaq $dst, $mem\t# ptr off8narrow @ leaP8Narrow" %}
13883 ins_encode %{
13884 Register dst = $dst$$Register;
13885 Register base = as_Register($mem$$base);
13886 int disp = $mem$$disp;
13888 __ daddiu(dst, base, disp);
13889 %}
13890 ins_pipe( ialu_regI_imm16 );
13891 %}
13893 instruct leaPPosIdxScaleOff8(mRegP dst, basePosIndexScaleOffset8 mem)
13894 %{
13895 match(Set dst mem);
13897 ins_cost(110);
13898 format %{ "leaq $dst, $mem\t# @ PosIdxScaleOff8" %}
13899 ins_encode %{
13900 Register dst = $dst$$Register;
13901 Register base = as_Register($mem$$base);
13902 Register index = as_Register($mem$$index);
13903 int scale = $mem$$scale;
13904 int disp = $mem$$disp;
13906 if (scale == 0) {
13907 __ daddu(AT, base, index);
13908 __ daddiu(dst, AT, disp);
13909 } else {
13910 __ dsll(AT, index, scale);
13911 __ daddu(AT, base, AT);
13912 __ daddiu(dst, AT, disp);
13913 }
13914 %}
13916 ins_pipe( ialu_regI_imm16 );
13917 %}
13919 instruct leaPIdxScale(mRegP dst, indIndexScale mem)
13920 %{
13921 match(Set dst mem);
13923 ins_cost(110);
13924 format %{ "leaq $dst, $mem\t# @ leaPIdxScale" %}
13925 ins_encode %{
13926 Register dst = $dst$$Register;
13927 Register base = as_Register($mem$$base);
13928 Register index = as_Register($mem$$index);
13929 int scale = $mem$$scale;
13931 if (scale == 0) {
13932 __ daddu(dst, base, index);
13933 } else {
13934 __ dsll(AT, index, scale);
13935 __ daddu(dst, base, AT);
13936 }
13937 %}
13939 ins_pipe( ialu_regI_imm16 );
13940 %}
13943 // ============================================================================
13944 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
13945 // array for an instance of the superklass. Set a hidden internal cache on a
13946 // hit (cache is checked with exposed code in gen_subtype_check()). Return
13947 // NZ for a miss or zero for a hit. The encoding ALSO sets flags.
13948 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
13949 match(Set result (PartialSubtypeCheck sub super));
13950 effect(KILL tmp);
13951 ins_cost(1100); // slightly larger than the next version
13952 format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
13954 ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
13955 ins_pipe( pipe_slow );
13956 %}
13959 // Conditional-store of an int value.
13960 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
13961 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
13962 match(Set cr (StoreIConditional mem (Binary oldval newval)));
13963 // effect(KILL oldval);
13964 format %{ "CMPXCHG $newval, $mem, $oldval \t# @storeIConditional" %}
13966 ins_encode %{
13967 Register oldval = $oldval$$Register;
13968 Register newval = $newval$$Register;
13969 Address addr(as_Register($mem$$base), $mem$$disp);
13970 Label again, failure;
13972 int index = $mem$$index;
13973 int scale = $mem$$scale;
13974 int disp = $mem$$disp;
13976 guarantee(Assembler::is_simm16(disp), "");
13978 if( index != 0 ) {
13979 __ stop("in storeIConditional: index != 0");
13980 } else {
13981 __ bind(again);
13982 if(UseSyncLevel >= 3000 || UseSyncLevel < 2000) __ sync();
13983 __ ll(AT, addr);
13984 __ bne(AT, oldval, failure);
13985 __ delayed()->addu(AT, R0, R0);
13987 __ addu(AT, newval, R0);
13988 __ sc(AT, addr);
13989 __ beq(AT, R0, again);
13990 __ delayed()->addiu(AT, R0, 0xFF);
13991 __ bind(failure);
13992 __ sync();
13993 }
13994 %}
13996 ins_pipe( long_memory_op );
13997 %}
13999 // Conditional-store of a long value.
14000 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
14001 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
14002 %{
14003 match(Set cr (StoreLConditional mem (Binary oldval newval)));
14004 effect(KILL oldval);
14006 format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
14007 ins_encode%{
14008 Register oldval = $oldval$$Register;
14009 Register newval = $newval$$Register;
14010 Address addr(as_Register($mem$$base), $mem$$disp);
14012 int index = $mem$$index;
14013 int scale = $mem$$scale;
14014 int disp = $mem$$disp;
14016 guarantee(Assembler::is_simm16(disp), "");
14018 if( index != 0 ) {
14019 __ stop("in storeIConditional: index != 0");
14020 } else {
14021 __ cmpxchg(newval, addr, oldval);
14022 }
14023 %}
14024 ins_pipe( long_memory_op );
14025 %}
14028 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
14029 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
14030 effect(KILL oldval);
14031 // match(CompareAndSwapI mem_ptr (Binary oldval newval));
14032 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapL\n\t"
14033 "MOV $res, 1 @ compareAndSwapI\n\t"
14034 "BNE AT, R0 @ compareAndSwapI\n\t"
14035 "MOV $res, 0 @ compareAndSwapI\n"
14036 "L:" %}
14037 ins_encode %{
14038 Register newval = $newval$$Register;
14039 Register oldval = $oldval$$Register;
14040 Register res = $res$$Register;
14041 Address addr($mem_ptr$$Register, 0);
14042 Label L;
14044 __ cmpxchg32(newval, addr, oldval);
14045 __ move(res, AT);
14046 %}
14047 ins_pipe( long_memory_op );
14048 %}
14050 instruct compareAndSwapL( mRegI res, mRegP mem_ptr, s2RegL oldval, mRegL newval) %{
14051 predicate(VM_Version::supports_cx8());
14052 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
14053 effect(KILL oldval);
14054 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
14055 "MOV $res, 1 @ compareAndSwapI\n\t"
14056 "BNE AT, R0 @ compareAndSwapI\n\t"
14057 "MOV $res, 0 @ compareAndSwapI\n"
14058 "L:" %}
14059 ins_encode %{
14060 Register newval = $newval$$Register;
14061 Register oldval = $oldval$$Register;
14062 Register res = $res$$Register;
14063 Address addr($mem_ptr$$Register, 0);
14064 Label L;
14066 __ cmpxchg(newval, addr, oldval);
14067 __ move(res, AT);
14068 %}
14069 ins_pipe( long_memory_op );
14070 %}
14072 //FIXME:
14073 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
14074 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
14075 effect(KILL oldval);
14076 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
14077 "MOV $res, AT @ compareAndSwapP\n\t"
14078 "L:" %}
14079 ins_encode %{
14080 Register newval = $newval$$Register;
14081 Register oldval = $oldval$$Register;
14082 Register res = $res$$Register;
14083 Address addr($mem_ptr$$Register, 0);
14084 Label L;
14086 __ cmpxchg(newval, addr, oldval);
14087 __ move(res, AT);
14088 %}
14089 ins_pipe( long_memory_op );
14090 %}
14092 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
14093 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
14094 effect(KILL oldval);
14095 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
14096 "MOV $res, AT @ compareAndSwapN\n\t"
14097 "L:" %}
14098 ins_encode %{
14099 Register newval = $newval$$Register;
14100 Register oldval = $oldval$$Register;
14101 Register res = $res$$Register;
14102 Address addr($mem_ptr$$Register, 0);
14103 Label L;
14105 // cmpxchg32 is implemented with ll/sc, which will do sign extension.
14106 // Thus, we should extend oldval's sign for correct comparision.
14107 //
14108 __ sll(oldval, oldval, 0);
14110 __ cmpxchg32(newval, addr, oldval);
14111 __ move(res, AT);
14112 %}
14113 ins_pipe( long_memory_op );
14114 %}
14116 //----------Max and Min--------------------------------------------------------
14117 // Min Instructions
14118 ////
14119 // *** Min and Max using the conditional move are slower than the
14120 // *** branch version on a Pentium III.
14121 // // Conditional move for min
14122 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
14123 // effect( USE_DEF op2, USE op1, USE cr );
14124 // format %{ "CMOVlt $op2,$op1\t! min" %}
14125 // opcode(0x4C,0x0F);
14126 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
14127 // ins_pipe( pipe_cmov_reg );
14128 //%}
14129 //
14130 //// Min Register with Register (P6 version)
14131 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
14132 // predicate(VM_Version::supports_cmov() );
14133 // match(Set op2 (MinI op1 op2));
14134 // ins_cost(200);
14135 // expand %{
14136 // eFlagsReg cr;
14137 // compI_eReg(cr,op1,op2);
14138 // cmovI_reg_lt(op2,op1,cr);
14139 // %}
14140 //%}
14142 // Min Register with Register (generic version)
14143 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
14144 match(Set dst (MinI dst src));
14145 //effect(KILL flags);
14146 ins_cost(80);
14148 format %{ "MIN $dst, $src @minI_Reg_Reg" %}
14149 ins_encode %{
14150 Register dst = $dst$$Register;
14151 Register src = $src$$Register;
14153 __ slt(AT, src, dst);
14154 __ movn(dst, src, AT);
14156 %}
14158 ins_pipe( pipe_slow );
14159 %}
14161 // Max Register with Register
14162 // *** Min and Max using the conditional move are slower than the
14163 // *** branch version on a Pentium III.
14164 // // Conditional move for max
14165 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
14166 // effect( USE_DEF op2, USE op1, USE cr );
14167 // format %{ "CMOVgt $op2,$op1\t! max" %}
14168 // opcode(0x4F,0x0F);
14169 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
14170 // ins_pipe( pipe_cmov_reg );
14171 //%}
14172 //
14173 // // Max Register with Register (P6 version)
14174 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
14175 // predicate(VM_Version::supports_cmov() );
14176 // match(Set op2 (MaxI op1 op2));
14177 // ins_cost(200);
14178 // expand %{
14179 // eFlagsReg cr;
14180 // compI_eReg(cr,op1,op2);
14181 // cmovI_reg_gt(op2,op1,cr);
14182 // %}
14183 //%}
14185 // Max Register with Register (generic version)
14186 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
14187 match(Set dst (MaxI dst src));
14188 ins_cost(80);
14190 format %{ "MAX $dst, $src @maxI_Reg_Reg" %}
14192 ins_encode %{
14193 Register dst = $dst$$Register;
14194 Register src = $src$$Register;
14196 __ slt(AT, dst, src);
14197 __ movn(dst, src, AT);
14199 %}
14201 ins_pipe( pipe_slow );
14202 %}
14204 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
14205 match(Set dst (MaxI dst zero));
14206 ins_cost(50);
14208 format %{ "MAX $dst, 0 @maxI_Reg_zero" %}
14210 ins_encode %{
14211 Register dst = $dst$$Register;
14213 __ slt(AT, dst, R0);
14214 __ movn(dst, R0, AT);
14216 %}
14218 ins_pipe( pipe_slow );
14219 %}
14221 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
14222 %{
14223 match(Set dst (AndL src mask));
14225 format %{ "movl $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
14226 ins_encode %{
14227 Register dst = $dst$$Register;
14228 Register src = $src$$Register;
14230 __ dext(dst, src, 0, 32);
14231 %}
14232 ins_pipe(ialu_regI_regI);
14233 %}
14235 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
14236 %{
14237 match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
14239 format %{ "combine_i2l $dst, $src2(H), $src1(L) @ combine_i2l" %}
14240 ins_encode %{
14241 Register dst = $dst$$Register;
14242 Register src1 = $src1$$Register;
14243 Register src2 = $src2$$Register;
14245 if (src1 == dst) {
14246 __ dinsu(dst, src2, 32, 32);
14247 } else if (src2 == dst) {
14248 __ dsll32(dst, dst, 0);
14249 __ dins(dst, src1, 0, 32);
14250 } else {
14251 __ dext(dst, src1, 0, 32);
14252 __ dinsu(dst, src2, 32, 32);
14253 }
14254 %}
14255 ins_pipe(ialu_regI_regI);
14256 %}
14258 // Zero-extend convert int to long
14259 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
14260 %{
14261 match(Set dst (AndL (ConvI2L src) mask));
14263 format %{ "movl $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
14264 ins_encode %{
14265 Register dst = $dst$$Register;
14266 Register src = $src$$Register;
14268 __ dext(dst, src, 0, 32);
14269 %}
14270 ins_pipe(ialu_regI_regI);
14271 %}
14273 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
14274 %{
14275 match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
14277 format %{ "movl $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
14278 ins_encode %{
14279 Register dst = $dst$$Register;
14280 Register src = $src$$Register;
14282 __ dext(dst, src, 0, 32);
14283 %}
14284 ins_pipe(ialu_regI_regI);
14285 %}
14287 // Match loading integer and casting it to unsigned int in long register.
14288 // LoadI + ConvI2L + AndL 0xffffffff.
14289 instruct loadUI2L_rmask(mRegL dst, memory mem, immL_32bits mask) %{
14290 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
14292 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
14293 ins_encode (load_N_enc(dst, mem));
14294 ins_pipe(ialu_loadI);
14295 %}
14297 instruct loadUI2L_lmask(mRegL dst, memory mem, immL_32bits mask) %{
14298 match(Set dst (AndL mask (ConvI2L (LoadI mem))));
14300 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
14301 ins_encode (load_N_enc(dst, mem));
14302 ins_pipe(ialu_loadI);
14303 %}
14306 // ============================================================================
14307 // Safepoint Instruction
14308 instruct safePoint_poll_reg(mRegP poll) %{
14309 match(SafePoint poll);
14310 predicate(false);
14311 effect(USE poll);
14313 ins_cost(125);
14314 format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
14316 ins_encode %{
14317 Register poll_reg = $poll$$Register;
14319 __ block_comment("Safepoint:");
14320 __ relocate(relocInfo::poll_type);
14321 __ lw(AT, poll_reg, 0);
14322 %}
14324 ins_pipe( ialu_storeI );
14325 %}
14327 instruct safePoint_poll() %{
14328 match(SafePoint);
14330 ins_cost(105);
14331 format %{ "poll for GC @ safePoint_poll" %}
14333 ins_encode %{
14334 __ block_comment("Safepoint:");
14335 __ set64(T9, (long)os::get_polling_page());
14336 __ relocate(relocInfo::poll_type);
14337 __ lw(AT, T9, 0);
14338 %}
14340 ins_pipe( ialu_storeI );
14341 %}
14343 //----------Arithmetic Conversion Instructions---------------------------------
14345 instruct roundFloat_nop(regF dst)
14346 %{
14347 match(Set dst (RoundFloat dst));
14349 ins_cost(0);
14350 ins_encode();
14351 ins_pipe(empty);
14352 %}
14354 instruct roundDouble_nop(regD dst)
14355 %{
14356 match(Set dst (RoundDouble dst));
14358 ins_cost(0);
14359 ins_encode();
14360 ins_pipe(empty);
14361 %}
14363 //---------- Zeros Count Instructions ------------------------------------------
14364 // CountLeadingZerosINode CountTrailingZerosINode
14365 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
14366 predicate(UseCountLeadingZerosInstructionMIPS64);
14367 match(Set dst (CountLeadingZerosI src));
14369 format %{ "clz $dst, $src\t# count leading zeros (int)" %}
14370 ins_encode %{
14371 __ clz($dst$$Register, $src$$Register);
14372 %}
14373 ins_pipe( ialu_regL_regL );
14374 %}
14376 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
14377 predicate(UseCountLeadingZerosInstructionMIPS64);
14378 match(Set dst (CountLeadingZerosL src));
14380 format %{ "dclz $dst, $src\t# count leading zeros (long)" %}
14381 ins_encode %{
14382 __ dclz($dst$$Register, $src$$Register);
14383 %}
14384 ins_pipe( ialu_regL_regL );
14385 %}
14387 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
14388 predicate(UseCountTrailingZerosInstructionMIPS64);
14389 match(Set dst (CountTrailingZerosI src));
14391 format %{ "ctz $dst, $src\t# count trailing zeros (int)" %}
14392 ins_encode %{
14393 // ctz and dctz is gs instructions.
14394 __ ctz($dst$$Register, $src$$Register);
14395 %}
14396 ins_pipe( ialu_regL_regL );
14397 %}
14399 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
14400 predicate(UseCountTrailingZerosInstructionMIPS64);
14401 match(Set dst (CountTrailingZerosL src));
14403 format %{ "dcto $dst, $src\t# count trailing zeros (long)" %}
14404 ins_encode %{
14405 __ dctz($dst$$Register, $src$$Register);
14406 %}
14407 ins_pipe( ialu_regL_regL );
14408 %}
14410 // ====================VECTOR INSTRUCTIONS=====================================
14412 // Load vectors (8 bytes long)
14413 instruct loadV8(vecD dst, memory mem) %{
14414 predicate(n->as_LoadVector()->memory_size() == 8);
14415 match(Set dst (LoadVector mem));
14416 ins_cost(125);
14417 format %{ "load $dst, $mem\t! load vector (8 bytes)" %}
14418 ins_encode(load_D_enc(dst, mem));
14419 ins_pipe( fpu_loadF );
14420 %}
14422 // Store vectors (8 bytes long)
14423 instruct storeV8(memory mem, vecD src) %{
14424 predicate(n->as_StoreVector()->memory_size() == 8);
14425 match(Set mem (StoreVector mem src));
14426 ins_cost(145);
14427 format %{ "store $mem, $src\t! store vector (8 bytes)" %}
14428 ins_encode(store_D_reg_enc(mem, src));
14429 ins_pipe( fpu_storeF );
14430 %}
14432 instruct Repl8B_DSP(vecD dst, mRegI src) %{
14433 predicate(n->as_Vector()->length() == 8 && Use3A2000);
14434 match(Set dst (ReplicateB src));
14435 ins_cost(100);
14436 format %{ "replv_ob AT, $src\n\t"
14437 "dmtc1 AT, $dst\t! replicate8B" %}
14438 ins_encode %{
14439 __ replv_ob(AT, $src$$Register);
14440 __ dmtc1(AT, $dst$$FloatRegister);
14441 %}
14442 ins_pipe( pipe_mtc1 );
14443 %}
14445 instruct Repl8B(vecD dst, mRegI src) %{
14446 predicate(n->as_Vector()->length() == 8);
14447 match(Set dst (ReplicateB src));
14448 ins_cost(140);
14449 format %{ "move AT, $src\n\t"
14450 "dins AT, AT, 8, 8\n\t"
14451 "dins AT, AT, 16, 16\n\t"
14452 "dinsu AT, AT, 32, 32\n\t"
14453 "dmtc1 AT, $dst\t! replicate8B" %}
14454 ins_encode %{
14455 __ move(AT, $src$$Register);
14456 __ dins(AT, AT, 8, 8);
14457 __ dins(AT, AT, 16, 16);
14458 __ dinsu(AT, AT, 32, 32);
14459 __ dmtc1(AT, $dst$$FloatRegister);
14460 %}
14461 ins_pipe( pipe_mtc1 );
14462 %}
14464 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
14465 predicate(n->as_Vector()->length() == 8 && Use3A2000);
14466 match(Set dst (ReplicateB con));
14467 ins_cost(110);
14468 format %{ "repl_ob AT, [$con]\n\t"
14469 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
14470 ins_encode %{
14471 int val = $con$$constant;
14472 __ repl_ob(AT, val);
14473 __ dmtc1(AT, $dst$$FloatRegister);
14474 %}
14475 ins_pipe( pipe_mtc1 );
14476 %}
14478 instruct Repl8B_imm(vecD dst, immI con) %{
14479 predicate(n->as_Vector()->length() == 8);
14480 match(Set dst (ReplicateB con));
14481 ins_cost(150);
14482 format %{ "move AT, [$con]\n\t"
14483 "dins AT, AT, 8, 8\n\t"
14484 "dins AT, AT, 16, 16\n\t"
14485 "dinsu AT, AT, 32, 32\n\t"
14486 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
14487 ins_encode %{
14488 __ move(AT, $con$$constant);
14489 __ dins(AT, AT, 8, 8);
14490 __ dins(AT, AT, 16, 16);
14491 __ dinsu(AT, AT, 32, 32);
14492 __ dmtc1(AT, $dst$$FloatRegister);
14493 %}
14494 ins_pipe( pipe_mtc1 );
14495 %}
14497 instruct Repl8B_zero(vecD dst, immI0 zero) %{
14498 predicate(n->as_Vector()->length() == 8);
14499 match(Set dst (ReplicateB zero));
14500 ins_cost(90);
14501 format %{ "dmtc1 R0, $dst\t! replicate8B zero" %}
14502 ins_encode %{
14503 __ dmtc1(R0, $dst$$FloatRegister);
14504 %}
14505 ins_pipe( pipe_mtc1 );
14506 %}
14508 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
14509 predicate(n->as_Vector()->length() == 8);
14510 match(Set dst (ReplicateB M1));
14511 ins_cost(80);
14512 format %{ "dmtc1 -1, $dst\t! replicate8B -1" %}
14513 ins_encode %{
14514 __ nor(AT, R0, R0);
14515 __ dmtc1(AT, $dst$$FloatRegister);
14516 %}
14517 ins_pipe( pipe_mtc1 );
14518 %}
14520 instruct Repl4S_DSP(vecD dst, mRegI src) %{
14521 predicate(n->as_Vector()->length() == 4 && Use3A2000);
14522 match(Set dst (ReplicateS src));
14523 ins_cost(100);
14524 format %{ "replv_qh AT, $src\n\t"
14525 "dmtc1 AT, $dst\t! replicate4S" %}
14526 ins_encode %{
14527 __ replv_qh(AT, $src$$Register);
14528 __ dmtc1(AT, $dst$$FloatRegister);
14529 %}
14530 ins_pipe( pipe_mtc1 );
14531 %}
14533 instruct Repl4S(vecD dst, mRegI src) %{
14534 predicate(n->as_Vector()->length() == 4);
14535 match(Set dst (ReplicateS src));
14536 ins_cost(120);
14537 format %{ "move AT, $src \n\t"
14538 "dins AT, AT, 16, 16\n\t"
14539 "dinsu AT, AT, 32, 32\n\t"
14540 "dmtc1 AT, $dst\t! replicate4S" %}
14541 ins_encode %{
14542 __ move(AT, $src$$Register);
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 Repl4S_imm_DSP(vecD dst, immI con) %{
14551 predicate(n->as_Vector()->length() == 4 && Use3A2000);
14552 match(Set dst (ReplicateS con));
14553 ins_cost(100);
14554 format %{ "repl_qh AT, [$con]\n\t"
14555 "dmtc1 AT, $dst\t! replicate4S($con)" %}
14556 ins_encode %{
14557 int val = $con$$constant;
14558 if ( Assembler::is_simm(val, 10)) {
14559 //repl_qh supports 10 bits immediate
14560 __ repl_qh(AT, val);
14561 } else {
14562 __ li32(AT, val);
14563 __ replv_qh(AT, AT);
14564 }
14565 __ dmtc1(AT, $dst$$FloatRegister);
14566 %}
14567 ins_pipe( pipe_mtc1 );
14568 %}
14570 instruct Repl4S_imm(vecD dst, immI con) %{
14571 predicate(n->as_Vector()->length() == 4);
14572 match(Set dst (ReplicateS con));
14573 ins_cost(110);
14574 format %{ "move AT, [$con]\n\t"
14575 "dins AT, AT, 16, 16\n\t"
14576 "dinsu AT, AT, 32, 32\n\t"
14577 "dmtc1 AT, $dst\t! replicate4S($con)" %}
14578 ins_encode %{
14579 __ move(AT, $con$$constant);
14580 __ dins(AT, AT, 16, 16);
14581 __ dinsu(AT, AT, 32, 32);
14582 __ dmtc1(AT, $dst$$FloatRegister);
14583 %}
14584 ins_pipe( pipe_mtc1 );
14585 %}
14587 instruct Repl4S_zero(vecD dst, immI0 zero) %{
14588 predicate(n->as_Vector()->length() == 4);
14589 match(Set dst (ReplicateS zero));
14590 format %{ "dmtc1 R0, $dst\t! replicate4S zero" %}
14591 ins_encode %{
14592 __ dmtc1(R0, $dst$$FloatRegister);
14593 %}
14594 ins_pipe( pipe_mtc1 );
14595 %}
14597 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
14598 predicate(n->as_Vector()->length() == 4);
14599 match(Set dst (ReplicateS M1));
14600 format %{ "dmtc1 -1, $dst\t! replicate4S -1" %}
14601 ins_encode %{
14602 __ nor(AT, R0, R0);
14603 __ dmtc1(AT, $dst$$FloatRegister);
14604 %}
14605 ins_pipe( pipe_mtc1 );
14606 %}
14608 // Replicate integer (4 byte) scalar to be vector
14609 instruct Repl2I(vecD dst, mRegI src) %{
14610 predicate(n->as_Vector()->length() == 2);
14611 match(Set dst (ReplicateI src));
14612 format %{ "dins AT, $src, 0, 32\n\t"
14613 "dinsu AT, $src, 32, 32\n\t"
14614 "dmtc1 AT, $dst\t! replicate2I" %}
14615 ins_encode %{
14616 __ dins(AT, $src$$Register, 0, 32);
14617 __ dinsu(AT, $src$$Register, 32, 32);
14618 __ dmtc1(AT, $dst$$FloatRegister);
14619 %}
14620 ins_pipe( pipe_mtc1 );
14621 %}
14623 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
14624 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
14625 predicate(n->as_Vector()->length() == 2);
14626 match(Set dst (ReplicateI con));
14627 effect(KILL tmp);
14628 format %{ "li32 AT, [$con], 32\n\t"
14629 "dinsu AT, AT\n\t"
14630 "dmtc1 AT, $dst\t! replicate2I($con)" %}
14631 ins_encode %{
14632 int val = $con$$constant;
14633 __ li32(AT, val);
14634 __ dinsu(AT, AT, 32, 32);
14635 __ dmtc1(AT, $dst$$FloatRegister);
14636 %}
14637 ins_pipe( pipe_mtc1 );
14638 %}
14640 // Replicate integer (4 byte) scalar zero to be vector
14641 instruct Repl2I_zero(vecD dst, immI0 zero) %{
14642 predicate(n->as_Vector()->length() == 2);
14643 match(Set dst (ReplicateI zero));
14644 format %{ "dmtc1 R0, $dst\t! replicate2I zero" %}
14645 ins_encode %{
14646 __ dmtc1(R0, $dst$$FloatRegister);
14647 %}
14648 ins_pipe( pipe_mtc1 );
14649 %}
14651 // Replicate integer (4 byte) scalar -1 to be vector
14652 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
14653 predicate(n->as_Vector()->length() == 2);
14654 match(Set dst (ReplicateI M1));
14655 format %{ "dmtc1 -1, $dst\t! replicate2I -1, use AT" %}
14656 ins_encode %{
14657 __ nor(AT, R0, R0);
14658 __ dmtc1(AT, $dst$$FloatRegister);
14659 %}
14660 ins_pipe( pipe_mtc1 );
14661 %}
14663 // Replicate float (4 byte) scalar to be vector
14664 instruct Repl2F(vecD dst, regF src) %{
14665 predicate(n->as_Vector()->length() == 2);
14666 match(Set dst (ReplicateF src));
14667 format %{ "cvt.ps $dst, $src, $src\t! replicate2F" %}
14668 ins_encode %{
14669 __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
14670 %}
14671 ins_pipe( pipe_slow );
14672 %}
14674 // Replicate float (4 byte) scalar zero to be vector
14675 instruct Repl2F_zero(vecD dst, immF0 zero) %{
14676 predicate(n->as_Vector()->length() == 2);
14677 match(Set dst (ReplicateF zero));
14678 format %{ "dmtc1 R0, $dst\t! replicate2F zero" %}
14679 ins_encode %{
14680 __ dmtc1(R0, $dst$$FloatRegister);
14681 %}
14682 ins_pipe( pipe_mtc1 );
14683 %}
14686 // ====================VECTOR ARITHMETIC=======================================
14688 // --------------------------------- ADD --------------------------------------
14690 // Floats vector add
14691 // kernel does not have emulation of PS instructions yet, so PS instructions is disabled.
14692 instruct vadd2F(vecD dst, vecD src) %{
14693 predicate(n->as_Vector()->length() == 2);
14694 match(Set dst (AddVF dst src));
14695 format %{ "add.ps $dst,$src\t! add packed2F" %}
14696 ins_encode %{
14697 __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14698 %}
14699 ins_pipe( pipe_slow );
14700 %}
14702 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
14703 predicate(n->as_Vector()->length() == 2);
14704 match(Set dst (AddVF src1 src2));
14705 format %{ "add.ps $dst,$src1,$src2\t! add packed2F" %}
14706 ins_encode %{
14707 __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14708 %}
14709 ins_pipe( fpu_regF_regF );
14710 %}
14712 // --------------------------------- SUB --------------------------------------
14714 // Floats vector sub
14715 instruct vsub2F(vecD dst, vecD src) %{
14716 predicate(n->as_Vector()->length() == 2);
14717 match(Set dst (SubVF dst src));
14718 format %{ "sub.ps $dst,$src\t! sub packed2F" %}
14719 ins_encode %{
14720 __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14721 %}
14722 ins_pipe( fpu_regF_regF );
14723 %}
14725 // --------------------------------- MUL --------------------------------------
14727 // Floats vector mul
14728 instruct vmul2F(vecD dst, vecD src) %{
14729 predicate(n->as_Vector()->length() == 2);
14730 match(Set dst (MulVF dst src));
14731 format %{ "mul.ps $dst, $src\t! mul packed2F" %}
14732 ins_encode %{
14733 __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14734 %}
14735 ins_pipe( fpu_regF_regF );
14736 %}
14738 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
14739 predicate(n->as_Vector()->length() == 2);
14740 match(Set dst (MulVF src1 src2));
14741 format %{ "mul.ps $dst, $src1, $src2\t! mul packed2F" %}
14742 ins_encode %{
14743 __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14744 %}
14745 ins_pipe( fpu_regF_regF );
14746 %}
14748 // --------------------------------- DIV --------------------------------------
14749 // MIPS do not have div.ps
14751 // --------------------------------- MADD --------------------------------------
14752 // Floats vector madd
14753 //instruct vmadd2F(vecD dst, vecD src1, vecD src2, vecD src3) %{
14754 // predicate(n->as_Vector()->length() == 2);
14755 // match(Set dst (AddVF (MulVF src1 src2) src3));
14756 // ins_cost(50);
14757 // format %{ "madd.ps $dst, $src3, $src1, $src2\t! madd packed2F" %}
14758 // ins_encode %{
14759 // __ madd_ps($dst$$FloatRegister, $src3$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14760 // %}
14761 // ins_pipe( fpu_regF_regF );
14762 //%}
14765 //----------PEEPHOLE RULES-----------------------------------------------------
14766 // These must follow all instruction definitions as they use the names
14767 // defined in the instructions definitions.
14768 //
14769 // peepmatch ( root_instr_name [preceeding_instruction]* );
14770 //
14771 // peepconstraint %{
14772 // (instruction_number.operand_name relational_op instruction_number.operand_name
14773 // [, ...] );
14774 // // instruction numbers are zero-based using left to right order in peepmatch
14775 //
14776 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14777 // // provide an instruction_number.operand_name for each operand that appears
14778 // // in the replacement instruction's match rule
14779 //
14780 // ---------VM FLAGS---------------------------------------------------------
14781 //
14782 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14783 //
14784 // Each peephole rule is given an identifying number starting with zero and
14785 // increasing by one in the order seen by the parser. An individual peephole
14786 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14787 // on the command-line.
14788 //
14789 // ---------CURRENT LIMITATIONS----------------------------------------------
14790 //
14791 // Only match adjacent instructions in same basic block
14792 // Only equality constraints
14793 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14794 // Only one replacement instruction
14795 //
14796 // ---------EXAMPLE----------------------------------------------------------
14797 //
14798 // // pertinent parts of existing instructions in architecture description
14799 // instruct movI(eRegI dst, eRegI src) %{
14800 // match(Set dst (CopyI src));
14801 // %}
14802 //
14803 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14804 // match(Set dst (AddI dst src));
14805 // effect(KILL cr);
14806 // %}
14807 //
14808 // // Change (inc mov) to lea
14809 // peephole %{
14810 // // increment preceeded by register-register move
14811 // peepmatch ( incI_eReg movI );
14812 // // require that the destination register of the increment
14813 // // match the destination register of the move
14814 // peepconstraint ( 0.dst == 1.dst );
14815 // // construct a replacement instruction that sets
14816 // // the destination to ( move's source register + one )
14817 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14818 // %}
14819 //
14820 // Implementation no longer uses movX instructions since
14821 // machine-independent system no longer uses CopyX nodes.
14822 //
14823 // peephole %{
14824 // peepmatch ( incI_eReg movI );
14825 // peepconstraint ( 0.dst == 1.dst );
14826 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14827 // %}
14828 //
14829 // peephole %{
14830 // peepmatch ( decI_eReg movI );
14831 // peepconstraint ( 0.dst == 1.dst );
14832 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14833 // %}
14834 //
14835 // peephole %{
14836 // peepmatch ( addI_eReg_imm movI );
14837 // peepconstraint ( 0.dst == 1.dst );
14838 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14839 // %}
14840 //
14841 // peephole %{
14842 // peepmatch ( addP_eReg_imm movP );
14843 // peepconstraint ( 0.dst == 1.dst );
14844 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
14845 // %}
14847 // // Change load of spilled value to only a spill
14848 // instruct storeI(memory mem, eRegI src) %{
14849 // match(Set mem (StoreI mem src));
14850 // %}
14851 //
14852 // instruct loadI(eRegI dst, memory mem) %{
14853 // match(Set dst (LoadI mem));
14854 // %}
14855 //
14856 //peephole %{
14857 // peepmatch ( loadI storeI );
14858 // peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14859 // peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14860 //%}
14862 //----------SMARTSPILL RULES---------------------------------------------------
14863 // These must follow all instruction definitions as they use the names
14864 // defined in the instructions definitions.