Thu, 21 Feb 2019 10:14:02 +0800
#7830 Add cmovN_cmpU_reg_reg in hotspot/src/cpu/mips/vm/mips_64.ad.
Reviewed-by: aoqi
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 uint 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 uint 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 // Load acquire.
2693 // load_P_enc + sync
2694 enc_class load_P_enc_ac (mRegP dst, memory mem) %{
2695 MacroAssembler _masm(&cbuf);
2696 int dst = $dst$$reg;
2697 int base = $mem$$base;
2698 int index = $mem$$index;
2699 int scale = $mem$$scale;
2700 int disp = $mem$$disp;
2701 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2702 assert(disp_reloc == relocInfo::none, "cannot have disp");
2704 if( index != 0 ) {
2705 if ( UseLoongsonISA ) {
2706 if ( Assembler::is_simm(disp, 8) ) {
2707 if ( scale != 0 ) {
2708 __ dsll(AT, as_Register(index), scale);
2709 __ gsldx(as_Register(dst), as_Register(base), AT, disp);
2710 } else {
2711 __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
2712 }
2713 } else if ( Assembler::is_simm16(disp) ){
2714 if ( scale != 0 ) {
2715 __ dsll(AT, as_Register(index), scale);
2716 __ daddu(AT, AT, as_Register(base));
2717 } else {
2718 __ daddu(AT, as_Register(index), as_Register(base));
2719 }
2720 __ ld(as_Register(dst), AT, disp);
2721 } else {
2722 if ( scale != 0 ) {
2723 __ dsll(AT, as_Register(index), scale);
2724 __ move(T9, disp);
2725 __ daddu(AT, AT, T9);
2726 } else {
2727 __ move(T9, disp);
2728 __ daddu(AT, as_Register(index), T9);
2729 }
2730 __ gsldx(as_Register(dst), as_Register(base), AT, 0);
2731 }
2732 } else { //not use loongson isa
2733 if (scale == 0) {
2734 __ daddu(AT, as_Register(base), as_Register(index));
2735 } else {
2736 __ dsll(AT, as_Register(index), scale);
2737 __ daddu(AT, as_Register(base), AT);
2738 }
2739 if( Assembler::is_simm16(disp) ) {
2740 __ ld(as_Register(dst), AT, disp);
2741 } else {
2742 __ set64(T9, disp);
2743 __ daddu(AT, AT, T9);
2744 __ ld(as_Register(dst), AT, 0);
2745 }
2746 }
2747 } else {
2748 if ( UseLoongsonISA ) {
2749 if ( Assembler::is_simm16(disp) ){
2750 __ ld(as_Register(dst), as_Register(base), disp);
2751 } else {
2752 __ set64(T9, disp);
2753 __ gsldx(as_Register(dst), as_Register(base), T9, 0);
2754 }
2755 } else { //not use loongson isa
2756 if( Assembler::is_simm16(disp) ) {
2757 __ ld(as_Register(dst), as_Register(base), disp);
2758 } else {
2759 __ set64(T9, disp);
2760 __ daddu(AT, as_Register(base), T9);
2761 __ ld(as_Register(dst), AT, 0);
2762 }
2763 }
2764 }
2765 __ sync();
2766 %}
2768 enc_class store_P_reg_enc (memory mem, mRegP src) %{
2769 MacroAssembler _masm(&cbuf);
2770 int src = $src$$reg;
2771 int base = $mem$$base;
2772 int index = $mem$$index;
2773 int scale = $mem$$scale;
2774 int disp = $mem$$disp;
2776 if( index != 0 ) {
2777 if ( UseLoongsonISA ){
2778 if ( Assembler::is_simm(disp, 8) ) {
2779 if ( scale == 0 ) {
2780 __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
2781 } else {
2782 __ dsll(AT, as_Register(index), scale);
2783 __ gssdx(as_Register(src), as_Register(base), AT, disp);
2784 }
2785 } else if ( Assembler::is_simm16(disp) ) {
2786 if ( scale == 0 ) {
2787 __ daddu(AT, as_Register(base), as_Register(index));
2788 } else {
2789 __ dsll(AT, as_Register(index), scale);
2790 __ daddu(AT, as_Register(base), AT);
2791 }
2792 __ sd(as_Register(src), AT, disp);
2793 } else {
2794 if ( scale == 0 ) {
2795 __ move(T9, disp);
2796 __ daddu(AT, as_Register(index), T9);
2797 } else {
2798 __ dsll(AT, as_Register(index), scale);
2799 __ move(T9, disp);
2800 __ daddu(AT, AT, T9);
2801 }
2802 __ gssdx(as_Register(src), as_Register(base), AT, 0);
2803 }
2804 } else { //not use loongson isa
2805 if (scale == 0) {
2806 __ daddu(AT, as_Register(base), as_Register(index));
2807 } else {
2808 __ dsll(AT, as_Register(index), scale);
2809 __ daddu(AT, as_Register(base), AT);
2810 }
2811 if( Assembler::is_simm16(disp) ) {
2812 __ sd(as_Register(src), AT, disp);
2813 } else {
2814 __ move(T9, disp);
2815 __ daddu(AT, AT, T9);
2816 __ sd(as_Register(src), AT, 0);
2817 }
2818 }
2819 } else {
2820 if ( UseLoongsonISA ) {
2821 if ( Assembler::is_simm16(disp) ) {
2822 __ sd(as_Register(src), as_Register(base), disp);
2823 } else {
2824 __ move(T9, disp);
2825 __ gssdx(as_Register(src), as_Register(base), T9, 0);
2826 }
2827 } else {
2828 if( Assembler::is_simm16(disp) ) {
2829 __ sd(as_Register(src), as_Register(base), disp);
2830 } else {
2831 __ move(T9, disp);
2832 __ daddu(AT, as_Register(base), T9);
2833 __ sd(as_Register(src), AT, 0);
2834 }
2835 }
2836 }
2837 %}
2839 enc_class store_N_reg_enc (memory mem, mRegN src) %{
2840 MacroAssembler _masm(&cbuf);
2841 int src = $src$$reg;
2842 int base = $mem$$base;
2843 int index = $mem$$index;
2844 int scale = $mem$$scale;
2845 int disp = $mem$$disp;
2847 if( index != 0 ) {
2848 if ( UseLoongsonISA ){
2849 if ( Assembler::is_simm(disp, 8) ) {
2850 if ( scale == 0 ) {
2851 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
2852 } else {
2853 __ dsll(AT, as_Register(index), scale);
2854 __ gsswx(as_Register(src), as_Register(base), AT, disp);
2855 }
2856 } else if ( Assembler::is_simm16(disp) ) {
2857 if ( scale == 0 ) {
2858 __ daddu(AT, as_Register(base), as_Register(index));
2859 } else {
2860 __ dsll(AT, as_Register(index), scale);
2861 __ daddu(AT, as_Register(base), AT);
2862 }
2863 __ sw(as_Register(src), AT, disp);
2864 } else {
2865 if ( scale == 0 ) {
2866 __ move(T9, disp);
2867 __ daddu(AT, as_Register(index), T9);
2868 } else {
2869 __ dsll(AT, as_Register(index), scale);
2870 __ move(T9, disp);
2871 __ daddu(AT, AT, T9);
2872 }
2873 __ gsswx(as_Register(src), as_Register(base), AT, 0);
2874 }
2875 } else { //not use loongson isa
2876 if (scale == 0) {
2877 __ daddu(AT, as_Register(base), as_Register(index));
2878 } else {
2879 __ dsll(AT, as_Register(index), scale);
2880 __ daddu(AT, as_Register(base), AT);
2881 }
2882 if( Assembler::is_simm16(disp) ) {
2883 __ sw(as_Register(src), AT, disp);
2884 } else {
2885 __ move(T9, disp);
2886 __ daddu(AT, AT, T9);
2887 __ sw(as_Register(src), AT, 0);
2888 }
2889 }
2890 } else {
2891 if ( UseLoongsonISA ) {
2892 if ( Assembler::is_simm16(disp) ) {
2893 __ sw(as_Register(src), as_Register(base), disp);
2894 } else {
2895 __ move(T9, disp);
2896 __ gsswx(as_Register(src), as_Register(base), T9, 0);
2897 }
2898 } else {
2899 if( Assembler::is_simm16(disp) ) {
2900 __ sw(as_Register(src), as_Register(base), disp);
2901 } else {
2902 __ move(T9, disp);
2903 __ daddu(AT, as_Register(base), T9);
2904 __ sw(as_Register(src), AT, 0);
2905 }
2906 }
2907 }
2908 %}
2910 enc_class store_P_immP0_enc (memory mem) %{
2911 MacroAssembler _masm(&cbuf);
2912 int base = $mem$$base;
2913 int index = $mem$$index;
2914 int scale = $mem$$scale;
2915 int disp = $mem$$disp;
2917 if( index != 0 ) {
2918 if (scale == 0) {
2919 if( Assembler::is_simm16(disp) ) {
2920 if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
2921 __ gssdx(R0, as_Register(base), as_Register(index), disp);
2922 } else {
2923 __ daddu(AT, as_Register(base), as_Register(index));
2924 __ sd(R0, AT, disp);
2925 }
2926 } else {
2927 __ daddu(AT, as_Register(base), as_Register(index));
2928 __ move(T9, disp);
2929 if(UseLoongsonISA) {
2930 __ gssdx(R0, AT, T9, 0);
2931 } else {
2932 __ daddu(AT, AT, T9);
2933 __ sd(R0, AT, 0);
2934 }
2935 }
2936 } else {
2937 __ dsll(AT, as_Register(index), scale);
2938 if( Assembler::is_simm16(disp) ) {
2939 if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
2940 __ gssdx(R0, as_Register(base), AT, disp);
2941 } else {
2942 __ daddu(AT, as_Register(base), AT);
2943 __ sd(R0, AT, disp);
2944 }
2945 } else {
2946 __ daddu(AT, as_Register(base), AT);
2947 __ move(T9, disp);
2948 if (UseLoongsonISA) {
2949 __ gssdx(R0, AT, T9, 0);
2950 } else {
2951 __ daddu(AT, AT, T9);
2952 __ sd(R0, AT, 0);
2953 }
2954 }
2955 }
2956 } else {
2957 if( Assembler::is_simm16(disp) ) {
2958 __ sd(R0, as_Register(base), disp);
2959 } else {
2960 __ move(T9, disp);
2961 if (UseLoongsonISA) {
2962 __ gssdx(R0, as_Register(base), T9, 0);
2963 } else {
2964 __ daddu(AT, as_Register(base), T9);
2965 __ sd(R0, AT, 0);
2966 }
2967 }
2968 }
2969 %}
2971 enc_class storeImmN0_enc(memory mem, ImmN0 src) %{
2972 MacroAssembler _masm(&cbuf);
2973 int base = $mem$$base;
2974 int index = $mem$$index;
2975 int scale = $mem$$scale;
2976 int disp = $mem$$disp;
2978 if(index!=0){
2979 if (scale == 0) {
2980 __ daddu(AT, as_Register(base), as_Register(index));
2981 } else {
2982 __ dsll(AT, as_Register(index), scale);
2983 __ daddu(AT, as_Register(base), AT);
2984 }
2986 if( Assembler::is_simm16(disp) ) {
2987 __ sw(R0, AT, disp);
2988 } else {
2989 __ move(T9, disp);
2990 __ daddu(AT, AT, T9);
2991 __ sw(R0, AT, 0);
2992 }
2993 } else {
2994 if( Assembler::is_simm16(disp) ) {
2995 __ sw(R0, as_Register(base), disp);
2996 } else {
2997 __ move(T9, disp);
2998 __ daddu(AT, as_Register(base), T9);
2999 __ sw(R0, AT, 0);
3000 }
3001 }
3002 %}
3004 enc_class load_L_enc (mRegL dst, memory mem) %{
3005 MacroAssembler _masm(&cbuf);
3006 int base = $mem$$base;
3007 int index = $mem$$index;
3008 int scale = $mem$$scale;
3009 int disp = $mem$$disp;
3010 Register dst_reg = as_Register($dst$$reg);
3012 if( index != 0 ) {
3013 if (scale == 0) {
3014 __ daddu(AT, as_Register(base), as_Register(index));
3015 } else {
3016 __ dsll(AT, as_Register(index), scale);
3017 __ daddu(AT, as_Register(base), AT);
3018 }
3019 if( Assembler::is_simm16(disp) ) {
3020 __ ld(dst_reg, AT, disp);
3021 } else {
3022 __ move(T9, disp);
3023 __ daddu(AT, AT, T9);
3024 __ ld(dst_reg, AT, 0);
3025 }
3026 } else {
3027 if( Assembler::is_simm16(disp) ) {
3028 __ ld(dst_reg, as_Register(base), disp);
3029 } else {
3030 __ move(T9, disp);
3031 __ daddu(AT, as_Register(base), T9);
3032 __ ld(dst_reg, AT, 0);
3033 }
3034 }
3035 %}
3037 enc_class store_L_reg_enc (memory mem, mRegL src) %{
3038 MacroAssembler _masm(&cbuf);
3039 int base = $mem$$base;
3040 int index = $mem$$index;
3041 int scale = $mem$$scale;
3042 int disp = $mem$$disp;
3043 Register src_reg = as_Register($src$$reg);
3045 if( index != 0 ) {
3046 if (scale == 0) {
3047 __ daddu(AT, as_Register(base), as_Register(index));
3048 } else {
3049 __ dsll(AT, as_Register(index), scale);
3050 __ daddu(AT, as_Register(base), AT);
3051 }
3052 if( Assembler::is_simm16(disp) ) {
3053 __ sd(src_reg, AT, disp);
3054 } else {
3055 __ move(T9, disp);
3056 __ daddu(AT, AT, T9);
3057 __ sd(src_reg, AT, 0);
3058 }
3059 } else {
3060 if( Assembler::is_simm16(disp) ) {
3061 __ sd(src_reg, as_Register(base), disp);
3062 } else {
3063 __ move(T9, disp);
3064 __ daddu(AT, as_Register(base), T9);
3065 __ sd(src_reg, AT, 0);
3066 }
3067 }
3068 %}
3070 enc_class store_L_immL0_enc (memory mem, immL0 src) %{
3071 MacroAssembler _masm(&cbuf);
3072 int base = $mem$$base;
3073 int index = $mem$$index;
3074 int scale = $mem$$scale;
3075 int disp = $mem$$disp;
3077 if( index != 0 ) {
3078 if (scale == 0) {
3079 __ daddu(AT, as_Register(base), as_Register(index));
3080 } else {
3081 __ dsll(AT, as_Register(index), scale);
3082 __ daddu(AT, as_Register(base), AT);
3083 }
3084 if( Assembler::is_simm16(disp) ) {
3085 __ sd(R0, AT, disp);
3086 } else {
3087 __ move(T9, disp);
3088 __ addu(AT, AT, T9);
3089 __ sd(R0, AT, 0);
3090 }
3091 } else {
3092 if( Assembler::is_simm16(disp) ) {
3093 __ sd(R0, as_Register(base), disp);
3094 } else {
3095 __ move(T9, disp);
3096 __ addu(AT, as_Register(base), T9);
3097 __ sd(R0, AT, 0);
3098 }
3099 }
3100 %}
3102 enc_class store_L_immL_enc (memory mem, immL src) %{
3103 MacroAssembler _masm(&cbuf);
3104 int base = $mem$$base;
3105 int index = $mem$$index;
3106 int scale = $mem$$scale;
3107 int disp = $mem$$disp;
3108 long imm = $src$$constant;
3110 if( index != 0 ) {
3111 if (scale == 0) {
3112 __ daddu(AT, as_Register(base), as_Register(index));
3113 } else {
3114 __ dsll(AT, as_Register(index), scale);
3115 __ daddu(AT, as_Register(base), AT);
3116 }
3117 if( Assembler::is_simm16(disp) ) {
3118 __ set64(T9, imm);
3119 __ sd(T9, AT, disp);
3120 } else {
3121 __ move(T9, disp);
3122 __ addu(AT, AT, T9);
3123 __ set64(T9, imm);
3124 __ sd(T9, AT, 0);
3125 }
3126 } else {
3127 if( Assembler::is_simm16(disp) ) {
3128 __ move(AT, as_Register(base));
3129 __ set64(T9, imm);
3130 __ sd(T9, AT, disp);
3131 } else {
3132 __ move(T9, disp);
3133 __ addu(AT, as_Register(base), T9);
3134 __ set64(T9, imm);
3135 __ sd(T9, AT, 0);
3136 }
3137 }
3138 %}
3140 enc_class load_F_enc (regF dst, memory mem) %{
3141 MacroAssembler _masm(&cbuf);
3142 int base = $mem$$base;
3143 int index = $mem$$index;
3144 int scale = $mem$$scale;
3145 int disp = $mem$$disp;
3146 FloatRegister dst = $dst$$FloatRegister;
3148 if( index != 0 ) {
3149 if( Assembler::is_simm16(disp) ) {
3150 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3151 if (scale == 0) {
3152 __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
3153 } else {
3154 __ dsll(AT, as_Register(index), scale);
3155 __ gslwxc1(dst, as_Register(base), AT, disp);
3156 }
3157 } else {
3158 if (scale == 0) {
3159 __ daddu(AT, as_Register(base), as_Register(index));
3160 } else {
3161 __ dsll(AT, as_Register(index), scale);
3162 __ daddu(AT, as_Register(base), AT);
3163 }
3164 __ lwc1(dst, AT, disp);
3165 }
3166 } else {
3167 if (scale == 0) {
3168 __ daddu(AT, as_Register(base), as_Register(index));
3169 } else {
3170 __ dsll(AT, as_Register(index), scale);
3171 __ daddu(AT, as_Register(base), AT);
3172 }
3173 __ move(T9, disp);
3174 if( UseLoongsonISA ) {
3175 __ gslwxc1(dst, AT, T9, 0);
3176 } else {
3177 __ daddu(AT, AT, T9);
3178 __ lwc1(dst, AT, 0);
3179 }
3180 }
3181 } else {
3182 if( Assembler::is_simm16(disp) ) {
3183 __ lwc1(dst, as_Register(base), disp);
3184 } else {
3185 __ move(T9, disp);
3186 if( UseLoongsonISA ) {
3187 __ gslwxc1(dst, as_Register(base), T9, 0);
3188 } else {
3189 __ daddu(AT, as_Register(base), T9);
3190 __ lwc1(dst, AT, 0);
3191 }
3192 }
3193 }
3194 %}
3196 enc_class store_F_reg_enc (memory mem, regF src) %{
3197 MacroAssembler _masm(&cbuf);
3198 int base = $mem$$base;
3199 int index = $mem$$index;
3200 int scale = $mem$$scale;
3201 int disp = $mem$$disp;
3202 FloatRegister src = $src$$FloatRegister;
3204 if( index != 0 ) {
3205 if( Assembler::is_simm16(disp) ) {
3206 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3207 if (scale == 0) {
3208 __ gsswxc1(src, as_Register(base), as_Register(index), disp);
3209 } else {
3210 __ dsll(AT, as_Register(index), scale);
3211 __ gsswxc1(src, as_Register(base), AT, disp);
3212 }
3213 } else {
3214 if (scale == 0) {
3215 __ daddu(AT, as_Register(base), as_Register(index));
3216 } else {
3217 __ dsll(AT, as_Register(index), scale);
3218 __ daddu(AT, as_Register(base), AT);
3219 }
3220 __ swc1(src, AT, disp);
3221 }
3222 } else {
3223 if (scale == 0) {
3224 __ daddu(AT, as_Register(base), as_Register(index));
3225 } else {
3226 __ dsll(AT, as_Register(index), scale);
3227 __ daddu(AT, as_Register(base), AT);
3228 }
3229 __ move(T9, disp);
3230 if( UseLoongsonISA ) {
3231 __ gsswxc1(src, AT, T9, 0);
3232 } else {
3233 __ daddu(AT, AT, T9);
3234 __ swc1(src, AT, 0);
3235 }
3236 }
3237 } else {
3238 if( Assembler::is_simm16(disp) ) {
3239 __ swc1(src, as_Register(base), disp);
3240 } else {
3241 __ move(T9, disp);
3242 if( UseLoongsonISA ) {
3243 __ gsswxc1(src, as_Register(base), T9, 0);
3244 } else {
3245 __ daddu(AT, as_Register(base), T9);
3246 __ swc1(src, AT, 0);
3247 }
3248 }
3249 }
3250 %}
3252 enc_class load_D_enc (regD dst, memory mem) %{
3253 MacroAssembler _masm(&cbuf);
3254 int base = $mem$$base;
3255 int index = $mem$$index;
3256 int scale = $mem$$scale;
3257 int disp = $mem$$disp;
3258 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3260 if( index != 0 ) {
3261 if( Assembler::is_simm16(disp) ) {
3262 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3263 if (scale == 0) {
3264 __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
3265 } else {
3266 __ dsll(AT, as_Register(index), scale);
3267 __ gsldxc1(dst_reg, as_Register(base), AT, disp);
3268 }
3269 } else {
3270 if (scale == 0) {
3271 __ daddu(AT, as_Register(base), as_Register(index));
3272 } else {
3273 __ dsll(AT, as_Register(index), scale);
3274 __ daddu(AT, as_Register(base), AT);
3275 }
3276 __ ldc1(dst_reg, AT, disp);
3277 }
3278 } else {
3279 if (scale == 0) {
3280 __ daddu(AT, as_Register(base), as_Register(index));
3281 } else {
3282 __ dsll(AT, as_Register(index), scale);
3283 __ daddu(AT, as_Register(base), AT);
3284 }
3285 __ move(T9, disp);
3286 if( UseLoongsonISA ) {
3287 __ gsldxc1(dst_reg, AT, T9, 0);
3288 } else {
3289 __ addu(AT, AT, T9);
3290 __ ldc1(dst_reg, AT, 0);
3291 }
3292 }
3293 } else {
3294 if( Assembler::is_simm16(disp) ) {
3295 __ ldc1(dst_reg, as_Register(base), disp);
3296 } else {
3297 __ move(T9, disp);
3298 if( UseLoongsonISA ) {
3299 __ gsldxc1(dst_reg, as_Register(base), T9, 0);
3300 } else {
3301 __ addu(AT, as_Register(base), T9);
3302 __ ldc1(dst_reg, AT, 0);
3303 }
3304 }
3305 }
3306 %}
3308 enc_class store_D_reg_enc (memory mem, regD src) %{
3309 MacroAssembler _masm(&cbuf);
3310 int base = $mem$$base;
3311 int index = $mem$$index;
3312 int scale = $mem$$scale;
3313 int disp = $mem$$disp;
3314 FloatRegister src_reg = as_FloatRegister($src$$reg);
3316 if( index != 0 ) {
3317 if( Assembler::is_simm16(disp) ) {
3318 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3319 if (scale == 0) {
3320 __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
3321 } else {
3322 __ dsll(AT, as_Register(index), scale);
3323 __ gssdxc1(src_reg, as_Register(base), AT, disp);
3324 }
3325 } else {
3326 if (scale == 0) {
3327 __ daddu(AT, as_Register(base), as_Register(index));
3328 } else {
3329 __ dsll(AT, as_Register(index), scale);
3330 __ daddu(AT, as_Register(base), AT);
3331 }
3332 __ sdc1(src_reg, AT, disp);
3333 }
3334 } else {
3335 if (scale == 0) {
3336 __ daddu(AT, as_Register(base), as_Register(index));
3337 } else {
3338 __ dsll(AT, as_Register(index), scale);
3339 __ daddu(AT, as_Register(base), AT);
3340 }
3341 __ move(T9, disp);
3342 if( UseLoongsonISA ) {
3343 __ gssdxc1(src_reg, AT, T9, 0);
3344 } else {
3345 __ addu(AT, AT, T9);
3346 __ sdc1(src_reg, AT, 0);
3347 }
3348 }
3349 } else {
3350 if( Assembler::is_simm16(disp) ) {
3351 __ sdc1(src_reg, as_Register(base), disp);
3352 } else {
3353 __ move(T9, disp);
3354 if( UseLoongsonISA ) {
3355 __ gssdxc1(src_reg, as_Register(base), T9, 0);
3356 } else {
3357 __ addu(AT, as_Register(base), T9);
3358 __ sdc1(src_reg, AT, 0);
3359 }
3360 }
3361 }
3362 %}
3364 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf
3365 MacroAssembler _masm(&cbuf);
3366 // This is the instruction starting address for relocation info.
3367 __ block_comment("Java_To_Runtime");
3368 cbuf.set_insts_mark();
3369 __ relocate(relocInfo::runtime_call_type);
3371 __ patchable_call((address)$meth$$method);
3372 %}
3374 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
3375 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
3376 // who we intended to call.
3377 MacroAssembler _masm(&cbuf);
3378 cbuf.set_insts_mark();
3380 if ( !_method ) {
3381 __ relocate(relocInfo::runtime_call_type);
3382 } else if(_optimized_virtual) {
3383 __ relocate(relocInfo::opt_virtual_call_type);
3384 } else {
3385 __ relocate(relocInfo::static_call_type);
3386 }
3388 __ patchable_call((address)($meth$$method));
3389 if( _method ) { // Emit stub for static call
3390 emit_java_to_interp(cbuf);
3391 }
3392 %}
3395 /*
3396 * [Ref: LIR_Assembler::ic_call() ]
3397 */
3398 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL
3399 MacroAssembler _masm(&cbuf);
3400 __ block_comment("Java_Dynamic_Call");
3401 __ ic_call((address)$meth$$method);
3402 %}
3405 enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
3406 Register flags = $cr$$Register;
3407 Label L;
3409 MacroAssembler _masm(&cbuf);
3411 __ addu(flags, R0, R0);
3412 __ beq(AT, R0, L);
3413 __ delayed()->nop();
3414 __ move(flags, 0xFFFFFFFF);
3415 __ bind(L);
3416 %}
3418 enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
3419 Register result = $result$$Register;
3420 Register sub = $sub$$Register;
3421 Register super = $super$$Register;
3422 Register length = $tmp$$Register;
3423 Register tmp = T9;
3424 Label miss;
3426 // result may be the same as sub
3427 // 47c B40: # B21 B41 <- B20 Freq: 0.155379
3428 // 47c partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
3429 // 4bc mov S2, NULL #@loadConP
3430 // 4c0 beq S1, S2, B21 #@branchConP P=0.999999 C=-1.000000
3431 //
3432 MacroAssembler _masm(&cbuf);
3433 Label done;
3434 __ check_klass_subtype_slow_path(sub, super, length, tmp,
3435 NULL, &miss,
3436 /*set_cond_codes:*/ true);
3437 // Refer to X86_64's RDI
3438 __ move(result, 0);
3439 __ b(done);
3440 __ delayed()->nop();
3442 __ bind(miss);
3443 __ move(result, 1);
3444 __ bind(done);
3445 %}
3447 %}
3450 //---------MIPS FRAME--------------------------------------------------------------
3451 // Definition of frame structure and management information.
3452 //
3453 // S T A C K L A Y O U T Allocators stack-slot number
3454 // | (to get allocators register number
3455 // G Owned by | | v add SharedInfo::stack0)
3456 // r CALLER | |
3457 // o | +--------+ pad to even-align allocators stack-slot
3458 // w V | pad0 | numbers; owned by CALLER
3459 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
3460 // h ^ | in | 5
3461 // | | args | 4 Holes in incoming args owned by SELF
3462 // | | old | | 3
3463 // | | SP-+--------+----> Matcher::_old_SP, even aligned
3464 // v | | ret | 3 return address
3465 // Owned by +--------+
3466 // Self | pad2 | 2 pad to align old SP
3467 // | +--------+ 1
3468 // | | locks | 0
3469 // | +--------+----> SharedInfo::stack0, even aligned
3470 // | | pad1 | 11 pad to align new SP
3471 // | +--------+
3472 // | | | 10
3473 // | | spills | 9 spills
3474 // V | | 8 (pad0 slot for callee)
3475 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
3476 // ^ | out | 7
3477 // | | args | 6 Holes in outgoing args owned by CALLEE
3478 // Owned by new | |
3479 // Callee SP-+--------+----> Matcher::_new_SP, even aligned
3480 // | |
3481 //
3482 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
3483 // known from SELF's arguments and the Java calling convention.
3484 // Region 6-7 is determined per call site.
3485 // Note 2: If the calling convention leaves holes in the incoming argument
3486 // area, those holes are owned by SELF. Holes in the outgoing area
3487 // are owned by the CALLEE. Holes should not be nessecary in the
3488 // incoming area, as the Java calling convention is completely under
3489 // the control of the AD file. Doubles can be sorted and packed to
3490 // avoid holes. Holes in the outgoing arguments may be nessecary for
3491 // varargs C calling conventions.
3492 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
3493 // even aligned with pad0 as needed.
3494 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
3495 // region 6-11 is even aligned; it may be padded out more so that
3496 // the region from SP to FP meets the minimum stack alignment.
3497 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3498 // alignment. Region 11, pad1, may be dynamically extended so that
3499 // SP meets the minimum alignment.
3502 frame %{
3504 stack_direction(TOWARDS_LOW);
3506 // These two registers define part of the calling convention
3507 // between compiled code and the interpreter.
3508 // SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention
3509 // for more information.
3511 inline_cache_reg(T1); // Inline Cache Register
3512 interpreter_method_oop_reg(S3); // Method Oop Register when calling interpreter
3514 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
3515 cisc_spilling_operand_name(indOffset32);
3517 // Number of stack slots consumed by locking an object
3518 // generate Compile::sync_stack_slots
3519 #ifdef _LP64
3520 sync_stack_slots(2);
3521 #else
3522 sync_stack_slots(1);
3523 #endif
3525 frame_pointer(SP);
3527 // Interpreter stores its frame pointer in a register which is
3528 // stored to the stack by I2CAdaptors.
3529 // I2CAdaptors convert from interpreted java to compiled java.
3531 interpreter_frame_pointer(FP);
3533 // generate Matcher::stack_alignment
3534 stack_alignment(StackAlignmentInBytes); //wordSize = sizeof(char*);
3536 // Number of stack slots between incoming argument block and the start of
3537 // a new frame. The PROLOG must add this many slots to the stack. The
3538 // EPILOG must remove this many slots. Intel needs one slot for
3539 // return address.
3540 // generate Matcher::in_preserve_stack_slots
3541 //in_preserve_stack_slots(VerifyStackAtCalls + 2); //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
3542 in_preserve_stack_slots(4); //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
3544 // Number of outgoing stack slots killed above the out_preserve_stack_slots
3545 // for calls to C. Supports the var-args backing area for register parms.
3546 varargs_C_out_slots_killed(0);
3548 // The after-PROLOG location of the return address. Location of
3549 // return address specifies a type (REG or STACK) and a number
3550 // representing the register number (i.e. - use a register name) or
3551 // stack slot.
3552 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3553 // Otherwise, it is above the locks and verification slot and alignment word
3554 //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
3555 return_addr(REG RA);
3557 // Body of function which returns an integer array locating
3558 // arguments either in registers or in stack slots. Passed an array
3559 // of ideal registers called "sig" and a "length" count. Stack-slot
3560 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3561 // arguments for a CALLEE. Incoming stack arguments are
3562 // automatically biased by the preserve_stack_slots field above.
3565 // will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
3566 // StartNode::calling_convention call this.
3567 calling_convention %{
3568 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3569 %}
3574 // Body of function which returns an integer array locating
3575 // arguments either in registers or in stack slots. Passed an array
3576 // of ideal registers called "sig" and a "length" count. Stack-slot
3577 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3578 // arguments for a CALLEE. Incoming stack arguments are
3579 // automatically biased by the preserve_stack_slots field above.
3582 // SEE CallRuntimeNode::calling_convention for more information.
3583 c_calling_convention %{
3584 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
3585 %}
3588 // Location of C & interpreter return values
3589 // register(s) contain(s) return value for Op_StartI2C and Op_StartOSR.
3590 // SEE Matcher::match.
3591 c_return_value %{
3592 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3593 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
3594 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
3595 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num };
3596 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3597 %}
3599 // Location of return values
3600 // register(s) contain(s) return value for Op_StartC2I and Op_Start.
3601 // SEE Matcher::match.
3603 return_value %{
3604 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3605 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
3606 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
3607 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num};
3608 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3609 %}
3611 %}
3613 //----------ATTRIBUTES---------------------------------------------------------
3614 //----------Operand Attributes-------------------------------------------------
3615 op_attrib op_cost(0); // Required cost attribute
3617 //----------Instruction Attributes---------------------------------------------
3618 ins_attrib ins_cost(100); // Required cost attribute
3619 ins_attrib ins_size(32); // Required size attribute (in bits)
3620 ins_attrib ins_pc_relative(0); // Required PC Relative flag
3621 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
3622 // non-matching short branch variant of some
3623 // long branch?
3624 ins_attrib ins_alignment(4); // Required alignment attribute (must be a power of 2)
3625 // specifies the alignment that some part of the instruction (not
3626 // necessarily the start) requires. If > 1, a compute_padding()
3627 // function must be provided for the instruction
3629 //----------OPERANDS-----------------------------------------------------------
3630 // Operand definitions must precede instruction definitions for correct parsing
3631 // in the ADLC because operands constitute user defined types which are used in
3632 // instruction definitions.
3634 // Vectors
3635 operand vecD() %{
3636 constraint(ALLOC_IN_RC(dbl_reg));
3637 match(VecD);
3639 format %{ %}
3640 interface(REG_INTER);
3641 %}
3643 // Flags register, used as output of compare instructions
3644 operand FlagsReg() %{
3645 constraint(ALLOC_IN_RC(mips_flags));
3646 match(RegFlags);
3648 format %{ "AT" %}
3649 interface(REG_INTER);
3650 %}
3652 //----------Simple Operands----------------------------------------------------
3653 //TODO: Should we need to define some more special immediate number ?
3654 // Immediate Operands
3655 // Integer Immediate
3656 operand immI() %{
3657 match(ConI);
3658 //TODO: should not match immI8 here LEE
3659 match(immI8);
3661 op_cost(20);
3662 format %{ %}
3663 interface(CONST_INTER);
3664 %}
3666 // Long Immediate 8-bit
3667 operand immL8()
3668 %{
3669 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3670 match(ConL);
3672 op_cost(5);
3673 format %{ %}
3674 interface(CONST_INTER);
3675 %}
3677 // Constant for test vs zero
3678 operand immI0() %{
3679 predicate(n->get_int() == 0);
3680 match(ConI);
3682 op_cost(0);
3683 format %{ %}
3684 interface(CONST_INTER);
3685 %}
3687 // Constant for increment
3688 operand immI1() %{
3689 predicate(n->get_int() == 1);
3690 match(ConI);
3692 op_cost(0);
3693 format %{ %}
3694 interface(CONST_INTER);
3695 %}
3697 // Constant for decrement
3698 operand immI_M1() %{
3699 predicate(n->get_int() == -1);
3700 match(ConI);
3702 op_cost(0);
3703 format %{ %}
3704 interface(CONST_INTER);
3705 %}
3707 operand immI_MaxI() %{
3708 predicate(n->get_int() == 2147483647);
3709 match(ConI);
3711 op_cost(0);
3712 format %{ %}
3713 interface(CONST_INTER);
3714 %}
3716 // Valid scale values for addressing modes
3717 operand immI2() %{
3718 predicate(0 <= n->get_int() && (n->get_int() <= 3));
3719 match(ConI);
3721 format %{ %}
3722 interface(CONST_INTER);
3723 %}
3725 operand immI8() %{
3726 predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
3727 match(ConI);
3729 op_cost(5);
3730 format %{ %}
3731 interface(CONST_INTER);
3732 %}
3734 operand immI16() %{
3735 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
3736 match(ConI);
3738 op_cost(10);
3739 format %{ %}
3740 interface(CONST_INTER);
3741 %}
3743 // Constant for long shifts
3744 operand immI_32() %{
3745 predicate( n->get_int() == 32 );
3746 match(ConI);
3748 op_cost(0);
3749 format %{ %}
3750 interface(CONST_INTER);
3751 %}
3753 operand immI_63() %{
3754 predicate( n->get_int() == 63 );
3755 match(ConI);
3757 op_cost(0);
3758 format %{ %}
3759 interface(CONST_INTER);
3760 %}
3762 operand immI_0_31() %{
3763 predicate( n->get_int() >= 0 && n->get_int() <= 31 );
3764 match(ConI);
3766 op_cost(0);
3767 format %{ %}
3768 interface(CONST_INTER);
3769 %}
3771 // Operand for non-negtive integer mask
3772 operand immI_nonneg_mask() %{
3773 predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
3774 match(ConI);
3776 op_cost(0);
3777 format %{ %}
3778 interface(CONST_INTER);
3779 %}
3781 operand immI_32_63() %{
3782 predicate( n->get_int() >= 32 && n->get_int() <= 63 );
3783 match(ConI);
3784 op_cost(0);
3786 format %{ %}
3787 interface(CONST_INTER);
3788 %}
3790 operand immI16_sub() %{
3791 predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
3792 match(ConI);
3794 op_cost(10);
3795 format %{ %}
3796 interface(CONST_INTER);
3797 %}
3799 operand immI_0_32767() %{
3800 predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
3801 match(ConI);
3802 op_cost(0);
3804 format %{ %}
3805 interface(CONST_INTER);
3806 %}
3808 operand immI_0_65535() %{
3809 predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
3810 match(ConI);
3811 op_cost(0);
3813 format %{ %}
3814 interface(CONST_INTER);
3815 %}
3817 operand immI_1() %{
3818 predicate( n->get_int() == 1 );
3819 match(ConI);
3821 op_cost(0);
3822 format %{ %}
3823 interface(CONST_INTER);
3824 %}
3826 operand immI_2() %{
3827 predicate( n->get_int() == 2 );
3828 match(ConI);
3830 op_cost(0);
3831 format %{ %}
3832 interface(CONST_INTER);
3833 %}
3835 operand immI_3() %{
3836 predicate( n->get_int() == 3 );
3837 match(ConI);
3839 op_cost(0);
3840 format %{ %}
3841 interface(CONST_INTER);
3842 %}
3844 operand immI_7() %{
3845 predicate( n->get_int() == 7 );
3846 match(ConI);
3848 format %{ %}
3849 interface(CONST_INTER);
3850 %}
3852 // Immediates for special shifts (sign extend)
3854 // Constants for increment
3855 operand immI_16() %{
3856 predicate( n->get_int() == 16 );
3857 match(ConI);
3859 format %{ %}
3860 interface(CONST_INTER);
3861 %}
3863 operand immI_24() %{
3864 predicate( n->get_int() == 24 );
3865 match(ConI);
3867 format %{ %}
3868 interface(CONST_INTER);
3869 %}
3871 // Constant for byte-wide masking
3872 operand immI_255() %{
3873 predicate( n->get_int() == 255 );
3874 match(ConI);
3876 op_cost(0);
3877 format %{ %}
3878 interface(CONST_INTER);
3879 %}
3881 operand immI_65535() %{
3882 predicate( n->get_int() == 65535 );
3883 match(ConI);
3885 op_cost(5);
3886 format %{ %}
3887 interface(CONST_INTER);
3888 %}
3890 operand immI_65536() %{
3891 predicate( n->get_int() == 65536 );
3892 match(ConI);
3894 op_cost(5);
3895 format %{ %}
3896 interface(CONST_INTER);
3897 %}
3899 operand immI_M65536() %{
3900 predicate( n->get_int() == -65536 );
3901 match(ConI);
3903 op_cost(5);
3904 format %{ %}
3905 interface(CONST_INTER);
3906 %}
3908 // Pointer Immediate
3909 operand immP() %{
3910 match(ConP);
3912 op_cost(10);
3913 format %{ %}
3914 interface(CONST_INTER);
3915 %}
3917 // NULL Pointer Immediate
3918 operand immP0() %{
3919 predicate( n->get_ptr() == 0 );
3920 match(ConP);
3921 op_cost(0);
3923 format %{ %}
3924 interface(CONST_INTER);
3925 %}
3927 // Pointer Immediate: 64-bit
3928 operand immP_set() %{
3929 match(ConP);
3931 op_cost(5);
3932 // formats are generated automatically for constants and base registers
3933 format %{ %}
3934 interface(CONST_INTER);
3935 %}
3937 // Pointer Immediate: 64-bit
3938 operand immP_load() %{
3939 predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
3940 match(ConP);
3942 op_cost(5);
3943 // formats are generated automatically for constants and base registers
3944 format %{ %}
3945 interface(CONST_INTER);
3946 %}
3948 // Pointer Immediate: 64-bit
3949 operand immP_no_oop_cheap() %{
3950 predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
3951 match(ConP);
3953 op_cost(5);
3954 // formats are generated automatically for constants and base registers
3955 format %{ %}
3956 interface(CONST_INTER);
3957 %}
3959 // Pointer for polling page
3960 operand immP_poll() %{
3961 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
3962 match(ConP);
3963 op_cost(5);
3965 format %{ %}
3966 interface(CONST_INTER);
3967 %}
3969 // Pointer Immediate
3970 operand immN() %{
3971 match(ConN);
3973 op_cost(10);
3974 format %{ %}
3975 interface(CONST_INTER);
3976 %}
3978 operand immNKlass() %{
3979 match(ConNKlass);
3981 op_cost(10);
3982 format %{ %}
3983 interface(CONST_INTER);
3984 %}
3986 // NULL Pointer Immediate
3987 operand immN0() %{
3988 predicate(n->get_narrowcon() == 0);
3989 match(ConN);
3991 op_cost(5);
3992 format %{ %}
3993 interface(CONST_INTER);
3994 %}
3996 // Long Immediate
3997 operand immL() %{
3998 match(ConL);
4000 op_cost(20);
4001 format %{ %}
4002 interface(CONST_INTER);
4003 %}
4005 // Long Immediate zero
4006 operand immL0() %{
4007 predicate( n->get_long() == 0L );
4008 match(ConL);
4009 op_cost(0);
4011 format %{ %}
4012 interface(CONST_INTER);
4013 %}
4015 operand immL7() %{
4016 predicate( n->get_long() == 7L );
4017 match(ConL);
4018 op_cost(0);
4020 format %{ %}
4021 interface(CONST_INTER);
4022 %}
4024 operand immL_M1() %{
4025 predicate( n->get_long() == -1L );
4026 match(ConL);
4027 op_cost(0);
4029 format %{ %}
4030 interface(CONST_INTER);
4031 %}
4033 // bit 0..2 zero
4034 operand immL_M8() %{
4035 predicate( n->get_long() == -8L );
4036 match(ConL);
4037 op_cost(0);
4039 format %{ %}
4040 interface(CONST_INTER);
4041 %}
4043 // bit 2 zero
4044 operand immL_M5() %{
4045 predicate( n->get_long() == -5L );
4046 match(ConL);
4047 op_cost(0);
4049 format %{ %}
4050 interface(CONST_INTER);
4051 %}
4053 // bit 1..2 zero
4054 operand immL_M7() %{
4055 predicate( n->get_long() == -7L );
4056 match(ConL);
4057 op_cost(0);
4059 format %{ %}
4060 interface(CONST_INTER);
4061 %}
4063 // bit 0..1 zero
4064 operand immL_M4() %{
4065 predicate( n->get_long() == -4L );
4066 match(ConL);
4067 op_cost(0);
4069 format %{ %}
4070 interface(CONST_INTER);
4071 %}
4073 // bit 3..6 zero
4074 operand immL_M121() %{
4075 predicate( n->get_long() == -121L );
4076 match(ConL);
4077 op_cost(0);
4079 format %{ %}
4080 interface(CONST_INTER);
4081 %}
4083 // Long immediate from 0 to 127.
4084 // Used for a shorter form of long mul by 10.
4085 operand immL_127() %{
4086 predicate((0 <= n->get_long()) && (n->get_long() <= 127));
4087 match(ConL);
4088 op_cost(0);
4090 format %{ %}
4091 interface(CONST_INTER);
4092 %}
4094 // Operand for non-negtive long mask
4095 operand immL_nonneg_mask() %{
4096 predicate( (n->get_long() >= 0) && (Assembler::is_jlong_mask(n->get_long()) != -1) );
4097 match(ConL);
4099 op_cost(0);
4100 format %{ %}
4101 interface(CONST_INTER);
4102 %}
4104 operand immL_0_65535() %{
4105 predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
4106 match(ConL);
4107 op_cost(0);
4109 format %{ %}
4110 interface(CONST_INTER);
4111 %}
4113 // Long Immediate: cheap (materialize in <= 3 instructions)
4114 operand immL_cheap() %{
4115 predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
4116 match(ConL);
4117 op_cost(0);
4119 format %{ %}
4120 interface(CONST_INTER);
4121 %}
4123 // Long Immediate: expensive (materialize in > 3 instructions)
4124 operand immL_expensive() %{
4125 predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
4126 match(ConL);
4127 op_cost(0);
4129 format %{ %}
4130 interface(CONST_INTER);
4131 %}
4133 operand immL16() %{
4134 predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
4135 match(ConL);
4137 op_cost(10);
4138 format %{ %}
4139 interface(CONST_INTER);
4140 %}
4142 operand immL16_sub() %{
4143 predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
4144 match(ConL);
4146 op_cost(10);
4147 format %{ %}
4148 interface(CONST_INTER);
4149 %}
4151 // Long Immediate: low 32-bit mask
4152 operand immL_32bits() %{
4153 predicate(n->get_long() == 0xFFFFFFFFL);
4154 match(ConL);
4155 op_cost(20);
4157 format %{ %}
4158 interface(CONST_INTER);
4159 %}
4161 // Long Immediate 32-bit signed
4162 operand immL32()
4163 %{
4164 predicate(n->get_long() == (int) (n->get_long()));
4165 match(ConL);
4167 op_cost(15);
4168 format %{ %}
4169 interface(CONST_INTER);
4170 %}
4173 //single-precision floating-point zero
4174 operand immF0() %{
4175 predicate(jint_cast(n->getf()) == 0);
4176 match(ConF);
4178 op_cost(5);
4179 format %{ %}
4180 interface(CONST_INTER);
4181 %}
4183 //single-precision floating-point immediate
4184 operand immF() %{
4185 match(ConF);
4187 op_cost(20);
4188 format %{ %}
4189 interface(CONST_INTER);
4190 %}
4192 //double-precision floating-point zero
4193 operand immD0() %{
4194 predicate(jlong_cast(n->getd()) == 0);
4195 match(ConD);
4197 op_cost(5);
4198 format %{ %}
4199 interface(CONST_INTER);
4200 %}
4202 //double-precision floating-point immediate
4203 operand immD() %{
4204 match(ConD);
4206 op_cost(20);
4207 format %{ %}
4208 interface(CONST_INTER);
4209 %}
4211 // Register Operands
4212 // Integer Register
4213 operand mRegI() %{
4214 constraint(ALLOC_IN_RC(int_reg));
4215 match(RegI);
4217 format %{ %}
4218 interface(REG_INTER);
4219 %}
4221 operand no_Ax_mRegI() %{
4222 constraint(ALLOC_IN_RC(no_Ax_int_reg));
4223 match(RegI);
4224 match(mRegI);
4226 format %{ %}
4227 interface(REG_INTER);
4228 %}
4230 operand mS0RegI() %{
4231 constraint(ALLOC_IN_RC(s0_reg));
4232 match(RegI);
4233 match(mRegI);
4235 format %{ "S0" %}
4236 interface(REG_INTER);
4237 %}
4239 operand mS1RegI() %{
4240 constraint(ALLOC_IN_RC(s1_reg));
4241 match(RegI);
4242 match(mRegI);
4244 format %{ "S1" %}
4245 interface(REG_INTER);
4246 %}
4248 operand mS2RegI() %{
4249 constraint(ALLOC_IN_RC(s2_reg));
4250 match(RegI);
4251 match(mRegI);
4253 format %{ "S2" %}
4254 interface(REG_INTER);
4255 %}
4257 operand mS3RegI() %{
4258 constraint(ALLOC_IN_RC(s3_reg));
4259 match(RegI);
4260 match(mRegI);
4262 format %{ "S3" %}
4263 interface(REG_INTER);
4264 %}
4266 operand mS4RegI() %{
4267 constraint(ALLOC_IN_RC(s4_reg));
4268 match(RegI);
4269 match(mRegI);
4271 format %{ "S4" %}
4272 interface(REG_INTER);
4273 %}
4275 operand mS5RegI() %{
4276 constraint(ALLOC_IN_RC(s5_reg));
4277 match(RegI);
4278 match(mRegI);
4280 format %{ "S5" %}
4281 interface(REG_INTER);
4282 %}
4284 operand mS6RegI() %{
4285 constraint(ALLOC_IN_RC(s6_reg));
4286 match(RegI);
4287 match(mRegI);
4289 format %{ "S6" %}
4290 interface(REG_INTER);
4291 %}
4293 operand mS7RegI() %{
4294 constraint(ALLOC_IN_RC(s7_reg));
4295 match(RegI);
4296 match(mRegI);
4298 format %{ "S7" %}
4299 interface(REG_INTER);
4300 %}
4303 operand mT0RegI() %{
4304 constraint(ALLOC_IN_RC(t0_reg));
4305 match(RegI);
4306 match(mRegI);
4308 format %{ "T0" %}
4309 interface(REG_INTER);
4310 %}
4312 operand mT1RegI() %{
4313 constraint(ALLOC_IN_RC(t1_reg));
4314 match(RegI);
4315 match(mRegI);
4317 format %{ "T1" %}
4318 interface(REG_INTER);
4319 %}
4321 operand mT2RegI() %{
4322 constraint(ALLOC_IN_RC(t2_reg));
4323 match(RegI);
4324 match(mRegI);
4326 format %{ "T2" %}
4327 interface(REG_INTER);
4328 %}
4330 operand mT3RegI() %{
4331 constraint(ALLOC_IN_RC(t3_reg));
4332 match(RegI);
4333 match(mRegI);
4335 format %{ "T3" %}
4336 interface(REG_INTER);
4337 %}
4339 operand mT8RegI() %{
4340 constraint(ALLOC_IN_RC(t8_reg));
4341 match(RegI);
4342 match(mRegI);
4344 format %{ "T8" %}
4345 interface(REG_INTER);
4346 %}
4348 operand mT9RegI() %{
4349 constraint(ALLOC_IN_RC(t9_reg));
4350 match(RegI);
4351 match(mRegI);
4353 format %{ "T9" %}
4354 interface(REG_INTER);
4355 %}
4357 operand mA0RegI() %{
4358 constraint(ALLOC_IN_RC(a0_reg));
4359 match(RegI);
4360 match(mRegI);
4362 format %{ "A0" %}
4363 interface(REG_INTER);
4364 %}
4366 operand mA1RegI() %{
4367 constraint(ALLOC_IN_RC(a1_reg));
4368 match(RegI);
4369 match(mRegI);
4371 format %{ "A1" %}
4372 interface(REG_INTER);
4373 %}
4375 operand mA2RegI() %{
4376 constraint(ALLOC_IN_RC(a2_reg));
4377 match(RegI);
4378 match(mRegI);
4380 format %{ "A2" %}
4381 interface(REG_INTER);
4382 %}
4384 operand mA3RegI() %{
4385 constraint(ALLOC_IN_RC(a3_reg));
4386 match(RegI);
4387 match(mRegI);
4389 format %{ "A3" %}
4390 interface(REG_INTER);
4391 %}
4393 operand mA4RegI() %{
4394 constraint(ALLOC_IN_RC(a4_reg));
4395 match(RegI);
4396 match(mRegI);
4398 format %{ "A4" %}
4399 interface(REG_INTER);
4400 %}
4402 operand mA5RegI() %{
4403 constraint(ALLOC_IN_RC(a5_reg));
4404 match(RegI);
4405 match(mRegI);
4407 format %{ "A5" %}
4408 interface(REG_INTER);
4409 %}
4411 operand mA6RegI() %{
4412 constraint(ALLOC_IN_RC(a6_reg));
4413 match(RegI);
4414 match(mRegI);
4416 format %{ "A6" %}
4417 interface(REG_INTER);
4418 %}
4420 operand mA7RegI() %{
4421 constraint(ALLOC_IN_RC(a7_reg));
4422 match(RegI);
4423 match(mRegI);
4425 format %{ "A7" %}
4426 interface(REG_INTER);
4427 %}
4429 operand mV0RegI() %{
4430 constraint(ALLOC_IN_RC(v0_reg));
4431 match(RegI);
4432 match(mRegI);
4434 format %{ "V0" %}
4435 interface(REG_INTER);
4436 %}
4438 operand mV1RegI() %{
4439 constraint(ALLOC_IN_RC(v1_reg));
4440 match(RegI);
4441 match(mRegI);
4443 format %{ "V1" %}
4444 interface(REG_INTER);
4445 %}
4447 operand mRegN() %{
4448 constraint(ALLOC_IN_RC(int_reg));
4449 match(RegN);
4451 format %{ %}
4452 interface(REG_INTER);
4453 %}
4455 operand t0_RegN() %{
4456 constraint(ALLOC_IN_RC(t0_reg));
4457 match(RegN);
4458 match(mRegN);
4460 format %{ %}
4461 interface(REG_INTER);
4462 %}
4464 operand t1_RegN() %{
4465 constraint(ALLOC_IN_RC(t1_reg));
4466 match(RegN);
4467 match(mRegN);
4469 format %{ %}
4470 interface(REG_INTER);
4471 %}
4473 operand t2_RegN() %{
4474 constraint(ALLOC_IN_RC(t2_reg));
4475 match(RegN);
4476 match(mRegN);
4478 format %{ %}
4479 interface(REG_INTER);
4480 %}
4482 operand t3_RegN() %{
4483 constraint(ALLOC_IN_RC(t3_reg));
4484 match(RegN);
4485 match(mRegN);
4487 format %{ %}
4488 interface(REG_INTER);
4489 %}
4491 operand t8_RegN() %{
4492 constraint(ALLOC_IN_RC(t8_reg));
4493 match(RegN);
4494 match(mRegN);
4496 format %{ %}
4497 interface(REG_INTER);
4498 %}
4500 operand t9_RegN() %{
4501 constraint(ALLOC_IN_RC(t9_reg));
4502 match(RegN);
4503 match(mRegN);
4505 format %{ %}
4506 interface(REG_INTER);
4507 %}
4509 operand a0_RegN() %{
4510 constraint(ALLOC_IN_RC(a0_reg));
4511 match(RegN);
4512 match(mRegN);
4514 format %{ %}
4515 interface(REG_INTER);
4516 %}
4518 operand a1_RegN() %{
4519 constraint(ALLOC_IN_RC(a1_reg));
4520 match(RegN);
4521 match(mRegN);
4523 format %{ %}
4524 interface(REG_INTER);
4525 %}
4527 operand a2_RegN() %{
4528 constraint(ALLOC_IN_RC(a2_reg));
4529 match(RegN);
4530 match(mRegN);
4532 format %{ %}
4533 interface(REG_INTER);
4534 %}
4536 operand a3_RegN() %{
4537 constraint(ALLOC_IN_RC(a3_reg));
4538 match(RegN);
4539 match(mRegN);
4541 format %{ %}
4542 interface(REG_INTER);
4543 %}
4545 operand a4_RegN() %{
4546 constraint(ALLOC_IN_RC(a4_reg));
4547 match(RegN);
4548 match(mRegN);
4550 format %{ %}
4551 interface(REG_INTER);
4552 %}
4554 operand a5_RegN() %{
4555 constraint(ALLOC_IN_RC(a5_reg));
4556 match(RegN);
4557 match(mRegN);
4559 format %{ %}
4560 interface(REG_INTER);
4561 %}
4563 operand a6_RegN() %{
4564 constraint(ALLOC_IN_RC(a6_reg));
4565 match(RegN);
4566 match(mRegN);
4568 format %{ %}
4569 interface(REG_INTER);
4570 %}
4572 operand a7_RegN() %{
4573 constraint(ALLOC_IN_RC(a7_reg));
4574 match(RegN);
4575 match(mRegN);
4577 format %{ %}
4578 interface(REG_INTER);
4579 %}
4581 operand s0_RegN() %{
4582 constraint(ALLOC_IN_RC(s0_reg));
4583 match(RegN);
4584 match(mRegN);
4586 format %{ %}
4587 interface(REG_INTER);
4588 %}
4590 operand s1_RegN() %{
4591 constraint(ALLOC_IN_RC(s1_reg));
4592 match(RegN);
4593 match(mRegN);
4595 format %{ %}
4596 interface(REG_INTER);
4597 %}
4599 operand s2_RegN() %{
4600 constraint(ALLOC_IN_RC(s2_reg));
4601 match(RegN);
4602 match(mRegN);
4604 format %{ %}
4605 interface(REG_INTER);
4606 %}
4608 operand s3_RegN() %{
4609 constraint(ALLOC_IN_RC(s3_reg));
4610 match(RegN);
4611 match(mRegN);
4613 format %{ %}
4614 interface(REG_INTER);
4615 %}
4617 operand s4_RegN() %{
4618 constraint(ALLOC_IN_RC(s4_reg));
4619 match(RegN);
4620 match(mRegN);
4622 format %{ %}
4623 interface(REG_INTER);
4624 %}
4626 operand s5_RegN() %{
4627 constraint(ALLOC_IN_RC(s5_reg));
4628 match(RegN);
4629 match(mRegN);
4631 format %{ %}
4632 interface(REG_INTER);
4633 %}
4635 operand s6_RegN() %{
4636 constraint(ALLOC_IN_RC(s6_reg));
4637 match(RegN);
4638 match(mRegN);
4640 format %{ %}
4641 interface(REG_INTER);
4642 %}
4644 operand s7_RegN() %{
4645 constraint(ALLOC_IN_RC(s7_reg));
4646 match(RegN);
4647 match(mRegN);
4649 format %{ %}
4650 interface(REG_INTER);
4651 %}
4653 operand v0_RegN() %{
4654 constraint(ALLOC_IN_RC(v0_reg));
4655 match(RegN);
4656 match(mRegN);
4658 format %{ %}
4659 interface(REG_INTER);
4660 %}
4662 operand v1_RegN() %{
4663 constraint(ALLOC_IN_RC(v1_reg));
4664 match(RegN);
4665 match(mRegN);
4667 format %{ %}
4668 interface(REG_INTER);
4669 %}
4671 // Pointer Register
4672 operand mRegP() %{
4673 constraint(ALLOC_IN_RC(p_reg));
4674 match(RegP);
4675 match(a0_RegP);
4677 format %{ %}
4678 interface(REG_INTER);
4679 %}
4681 operand no_T8_mRegP() %{
4682 constraint(ALLOC_IN_RC(no_T8_p_reg));
4683 match(RegP);
4684 match(mRegP);
4686 format %{ %}
4687 interface(REG_INTER);
4688 %}
4690 operand s0_RegP()
4691 %{
4692 constraint(ALLOC_IN_RC(s0_long_reg));
4693 match(RegP);
4694 match(mRegP);
4695 match(no_T8_mRegP);
4697 format %{ %}
4698 interface(REG_INTER);
4699 %}
4701 operand s1_RegP()
4702 %{
4703 constraint(ALLOC_IN_RC(s1_long_reg));
4704 match(RegP);
4705 match(mRegP);
4706 match(no_T8_mRegP);
4708 format %{ %}
4709 interface(REG_INTER);
4710 %}
4712 operand s2_RegP()
4713 %{
4714 constraint(ALLOC_IN_RC(s2_long_reg));
4715 match(RegP);
4716 match(mRegP);
4717 match(no_T8_mRegP);
4719 format %{ %}
4720 interface(REG_INTER);
4721 %}
4723 operand s3_RegP()
4724 %{
4725 constraint(ALLOC_IN_RC(s3_long_reg));
4726 match(RegP);
4727 match(mRegP);
4728 match(no_T8_mRegP);
4730 format %{ %}
4731 interface(REG_INTER);
4732 %}
4734 operand s4_RegP()
4735 %{
4736 constraint(ALLOC_IN_RC(s4_long_reg));
4737 match(RegP);
4738 match(mRegP);
4739 match(no_T8_mRegP);
4741 format %{ %}
4742 interface(REG_INTER);
4743 %}
4745 operand s5_RegP()
4746 %{
4747 constraint(ALLOC_IN_RC(s5_long_reg));
4748 match(RegP);
4749 match(mRegP);
4750 match(no_T8_mRegP);
4752 format %{ %}
4753 interface(REG_INTER);
4754 %}
4756 operand s6_RegP()
4757 %{
4758 constraint(ALLOC_IN_RC(s6_long_reg));
4759 match(RegP);
4760 match(mRegP);
4761 match(no_T8_mRegP);
4763 format %{ %}
4764 interface(REG_INTER);
4765 %}
4767 operand s7_RegP()
4768 %{
4769 constraint(ALLOC_IN_RC(s7_long_reg));
4770 match(RegP);
4771 match(mRegP);
4772 match(no_T8_mRegP);
4774 format %{ %}
4775 interface(REG_INTER);
4776 %}
4778 operand t0_RegP()
4779 %{
4780 constraint(ALLOC_IN_RC(t0_long_reg));
4781 match(RegP);
4782 match(mRegP);
4783 match(no_T8_mRegP);
4785 format %{ %}
4786 interface(REG_INTER);
4787 %}
4789 operand t1_RegP()
4790 %{
4791 constraint(ALLOC_IN_RC(t1_long_reg));
4792 match(RegP);
4793 match(mRegP);
4794 match(no_T8_mRegP);
4796 format %{ %}
4797 interface(REG_INTER);
4798 %}
4800 operand t2_RegP()
4801 %{
4802 constraint(ALLOC_IN_RC(t2_long_reg));
4803 match(RegP);
4804 match(mRegP);
4805 match(no_T8_mRegP);
4807 format %{ %}
4808 interface(REG_INTER);
4809 %}
4811 operand t3_RegP()
4812 %{
4813 constraint(ALLOC_IN_RC(t3_long_reg));
4814 match(RegP);
4815 match(mRegP);
4816 match(no_T8_mRegP);
4818 format %{ %}
4819 interface(REG_INTER);
4820 %}
4822 operand t8_RegP()
4823 %{
4824 constraint(ALLOC_IN_RC(t8_long_reg));
4825 match(RegP);
4826 match(mRegP);
4828 format %{ %}
4829 interface(REG_INTER);
4830 %}
4832 operand t9_RegP()
4833 %{
4834 constraint(ALLOC_IN_RC(t9_long_reg));
4835 match(RegP);
4836 match(mRegP);
4837 match(no_T8_mRegP);
4839 format %{ %}
4840 interface(REG_INTER);
4841 %}
4843 operand a0_RegP()
4844 %{
4845 constraint(ALLOC_IN_RC(a0_long_reg));
4846 match(RegP);
4847 match(mRegP);
4848 match(no_T8_mRegP);
4850 format %{ %}
4851 interface(REG_INTER);
4852 %}
4854 operand a1_RegP()
4855 %{
4856 constraint(ALLOC_IN_RC(a1_long_reg));
4857 match(RegP);
4858 match(mRegP);
4859 match(no_T8_mRegP);
4861 format %{ %}
4862 interface(REG_INTER);
4863 %}
4865 operand a2_RegP()
4866 %{
4867 constraint(ALLOC_IN_RC(a2_long_reg));
4868 match(RegP);
4869 match(mRegP);
4870 match(no_T8_mRegP);
4872 format %{ %}
4873 interface(REG_INTER);
4874 %}
4876 operand a3_RegP()
4877 %{
4878 constraint(ALLOC_IN_RC(a3_long_reg));
4879 match(RegP);
4880 match(mRegP);
4881 match(no_T8_mRegP);
4883 format %{ %}
4884 interface(REG_INTER);
4885 %}
4887 operand a4_RegP()
4888 %{
4889 constraint(ALLOC_IN_RC(a4_long_reg));
4890 match(RegP);
4891 match(mRegP);
4892 match(no_T8_mRegP);
4894 format %{ %}
4895 interface(REG_INTER);
4896 %}
4899 operand a5_RegP()
4900 %{
4901 constraint(ALLOC_IN_RC(a5_long_reg));
4902 match(RegP);
4903 match(mRegP);
4904 match(no_T8_mRegP);
4906 format %{ %}
4907 interface(REG_INTER);
4908 %}
4910 operand a6_RegP()
4911 %{
4912 constraint(ALLOC_IN_RC(a6_long_reg));
4913 match(RegP);
4914 match(mRegP);
4915 match(no_T8_mRegP);
4917 format %{ %}
4918 interface(REG_INTER);
4919 %}
4921 operand a7_RegP()
4922 %{
4923 constraint(ALLOC_IN_RC(a7_long_reg));
4924 match(RegP);
4925 match(mRegP);
4926 match(no_T8_mRegP);
4928 format %{ %}
4929 interface(REG_INTER);
4930 %}
4932 operand v0_RegP()
4933 %{
4934 constraint(ALLOC_IN_RC(v0_long_reg));
4935 match(RegP);
4936 match(mRegP);
4937 match(no_T8_mRegP);
4939 format %{ %}
4940 interface(REG_INTER);
4941 %}
4943 operand v1_RegP()
4944 %{
4945 constraint(ALLOC_IN_RC(v1_long_reg));
4946 match(RegP);
4947 match(mRegP);
4948 match(no_T8_mRegP);
4950 format %{ %}
4951 interface(REG_INTER);
4952 %}
4954 /*
4955 operand mSPRegP(mRegP reg) %{
4956 constraint(ALLOC_IN_RC(sp_reg));
4957 match(reg);
4959 format %{ "SP" %}
4960 interface(REG_INTER);
4961 %}
4963 operand mFPRegP(mRegP reg) %{
4964 constraint(ALLOC_IN_RC(fp_reg));
4965 match(reg);
4967 format %{ "FP" %}
4968 interface(REG_INTER);
4969 %}
4970 */
4972 operand mRegL() %{
4973 constraint(ALLOC_IN_RC(long_reg));
4974 match(RegL);
4976 format %{ %}
4977 interface(REG_INTER);
4978 %}
4980 operand v0RegL() %{
4981 constraint(ALLOC_IN_RC(v0_long_reg));
4982 match(RegL);
4983 match(mRegL);
4985 format %{ %}
4986 interface(REG_INTER);
4987 %}
4989 operand v1RegL() %{
4990 constraint(ALLOC_IN_RC(v1_long_reg));
4991 match(RegL);
4992 match(mRegL);
4994 format %{ %}
4995 interface(REG_INTER);
4996 %}
4998 operand a0RegL() %{
4999 constraint(ALLOC_IN_RC(a0_long_reg));
5000 match(RegL);
5001 match(mRegL);
5003 format %{ "A0" %}
5004 interface(REG_INTER);
5005 %}
5007 operand a1RegL() %{
5008 constraint(ALLOC_IN_RC(a1_long_reg));
5009 match(RegL);
5010 match(mRegL);
5012 format %{ %}
5013 interface(REG_INTER);
5014 %}
5016 operand a2RegL() %{
5017 constraint(ALLOC_IN_RC(a2_long_reg));
5018 match(RegL);
5019 match(mRegL);
5021 format %{ %}
5022 interface(REG_INTER);
5023 %}
5025 operand a3RegL() %{
5026 constraint(ALLOC_IN_RC(a3_long_reg));
5027 match(RegL);
5028 match(mRegL);
5030 format %{ %}
5031 interface(REG_INTER);
5032 %}
5034 operand t0RegL() %{
5035 constraint(ALLOC_IN_RC(t0_long_reg));
5036 match(RegL);
5037 match(mRegL);
5039 format %{ %}
5040 interface(REG_INTER);
5041 %}
5043 operand t1RegL() %{
5044 constraint(ALLOC_IN_RC(t1_long_reg));
5045 match(RegL);
5046 match(mRegL);
5048 format %{ %}
5049 interface(REG_INTER);
5050 %}
5052 operand t2RegL() %{
5053 constraint(ALLOC_IN_RC(t2_long_reg));
5054 match(RegL);
5055 match(mRegL);
5057 format %{ %}
5058 interface(REG_INTER);
5059 %}
5061 operand t3RegL() %{
5062 constraint(ALLOC_IN_RC(t3_long_reg));
5063 match(RegL);
5064 match(mRegL);
5066 format %{ %}
5067 interface(REG_INTER);
5068 %}
5070 operand t8RegL() %{
5071 constraint(ALLOC_IN_RC(t8_long_reg));
5072 match(RegL);
5073 match(mRegL);
5075 format %{ %}
5076 interface(REG_INTER);
5077 %}
5079 operand a4RegL() %{
5080 constraint(ALLOC_IN_RC(a4_long_reg));
5081 match(RegL);
5082 match(mRegL);
5084 format %{ %}
5085 interface(REG_INTER);
5086 %}
5088 operand a5RegL() %{
5089 constraint(ALLOC_IN_RC(a5_long_reg));
5090 match(RegL);
5091 match(mRegL);
5093 format %{ %}
5094 interface(REG_INTER);
5095 %}
5097 operand a6RegL() %{
5098 constraint(ALLOC_IN_RC(a6_long_reg));
5099 match(RegL);
5100 match(mRegL);
5102 format %{ %}
5103 interface(REG_INTER);
5104 %}
5106 operand a7RegL() %{
5107 constraint(ALLOC_IN_RC(a7_long_reg));
5108 match(RegL);
5109 match(mRegL);
5111 format %{ %}
5112 interface(REG_INTER);
5113 %}
5115 operand s0RegL() %{
5116 constraint(ALLOC_IN_RC(s0_long_reg));
5117 match(RegL);
5118 match(mRegL);
5120 format %{ %}
5121 interface(REG_INTER);
5122 %}
5124 operand s1RegL() %{
5125 constraint(ALLOC_IN_RC(s1_long_reg));
5126 match(RegL);
5127 match(mRegL);
5129 format %{ %}
5130 interface(REG_INTER);
5131 %}
5133 operand s2RegL() %{
5134 constraint(ALLOC_IN_RC(s2_long_reg));
5135 match(RegL);
5136 match(mRegL);
5138 format %{ %}
5139 interface(REG_INTER);
5140 %}
5142 operand s3RegL() %{
5143 constraint(ALLOC_IN_RC(s3_long_reg));
5144 match(RegL);
5145 match(mRegL);
5147 format %{ %}
5148 interface(REG_INTER);
5149 %}
5151 operand s4RegL() %{
5152 constraint(ALLOC_IN_RC(s4_long_reg));
5153 match(RegL);
5154 match(mRegL);
5156 format %{ %}
5157 interface(REG_INTER);
5158 %}
5160 operand s7RegL() %{
5161 constraint(ALLOC_IN_RC(s7_long_reg));
5162 match(RegL);
5163 match(mRegL);
5165 format %{ %}
5166 interface(REG_INTER);
5167 %}
5169 // Floating register operands
5170 operand regF() %{
5171 constraint(ALLOC_IN_RC(flt_reg));
5172 match(RegF);
5174 format %{ %}
5175 interface(REG_INTER);
5176 %}
5178 //Double Precision Floating register operands
5179 operand regD() %{
5180 constraint(ALLOC_IN_RC(dbl_reg));
5181 match(RegD);
5183 format %{ %}
5184 interface(REG_INTER);
5185 %}
5187 //----------Memory Operands----------------------------------------------------
5188 // Indirect Memory Operand
5189 operand indirect(mRegP reg) %{
5190 constraint(ALLOC_IN_RC(p_reg));
5191 match(reg);
5193 format %{ "[$reg] @ indirect" %}
5194 interface(MEMORY_INTER) %{
5195 base($reg);
5196 index(0x0); /* NO_INDEX */
5197 scale(0x0);
5198 disp(0x0);
5199 %}
5200 %}
5202 // Indirect Memory Plus Short Offset Operand
5203 operand indOffset8(mRegP reg, immL8 off)
5204 %{
5205 constraint(ALLOC_IN_RC(p_reg));
5206 match(AddP reg off);
5208 op_cost(10);
5209 format %{ "[$reg + $off (8-bit)] @ indOffset8" %}
5210 interface(MEMORY_INTER) %{
5211 base($reg);
5212 index(0x0); /* NO_INDEX */
5213 scale(0x0);
5214 disp($off);
5215 %}
5216 %}
5218 // Indirect Memory Times Scale Plus Index Register
5219 operand indIndexScale(mRegP reg, mRegL lreg, immI2 scale)
5220 %{
5221 constraint(ALLOC_IN_RC(p_reg));
5222 match(AddP reg (LShiftL lreg scale));
5224 op_cost(10);
5225 format %{"[$reg + $lreg << $scale] @ indIndexScale" %}
5226 interface(MEMORY_INTER) %{
5227 base($reg);
5228 index($lreg);
5229 scale($scale);
5230 disp(0x0);
5231 %}
5232 %}
5235 // [base + index + offset]
5236 operand baseIndexOffset8(mRegP base, mRegL index, immL8 off)
5237 %{
5238 constraint(ALLOC_IN_RC(p_reg));
5239 op_cost(5);
5240 match(AddP (AddP base index) off);
5242 format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8" %}
5243 interface(MEMORY_INTER) %{
5244 base($base);
5245 index($index);
5246 scale(0x0);
5247 disp($off);
5248 %}
5249 %}
5251 // [base + index + offset]
5252 operand baseIndexOffset8_convI2L(mRegP base, mRegI index, immL8 off)
5253 %{
5254 constraint(ALLOC_IN_RC(p_reg));
5255 op_cost(5);
5256 match(AddP (AddP base (ConvI2L index)) off);
5258 format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8_convI2L" %}
5259 interface(MEMORY_INTER) %{
5260 base($base);
5261 index($index);
5262 scale(0x0);
5263 disp($off);
5264 %}
5265 %}
5267 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5268 operand indIndexScaleOffset8(mRegP reg, immL8 off, mRegL lreg, immI2 scale)
5269 %{
5270 constraint(ALLOC_IN_RC(p_reg));
5271 match(AddP (AddP reg (LShiftL lreg scale)) off);
5273 op_cost(10);
5274 format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffset8" %}
5275 interface(MEMORY_INTER) %{
5276 base($reg);
5277 index($lreg);
5278 scale($scale);
5279 disp($off);
5280 %}
5281 %}
5283 operand indIndexScaleOffset8_convI2L(mRegP reg, immL8 off, mRegI ireg, immI2 scale)
5284 %{
5285 constraint(ALLOC_IN_RC(p_reg));
5286 match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
5288 op_cost(10);
5289 format %{"[$reg + $off + $ireg << $scale] @ indIndexScaleOffset8_convI2L" %}
5290 interface(MEMORY_INTER) %{
5291 base($reg);
5292 index($ireg);
5293 scale($scale);
5294 disp($off);
5295 %}
5296 %}
5298 // [base + index<<scale + offset]
5299 operand basePosIndexScaleOffset8(mRegP base, mRegI index, immL8 off, immI_0_31 scale)
5300 %{
5301 constraint(ALLOC_IN_RC(p_reg));
5302 //predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5303 op_cost(10);
5304 match(AddP (AddP base (LShiftL (ConvI2L index) scale)) off);
5306 format %{ "[$base + $index << $scale + $off (8-bit)] @ basePosIndexScaleOffset8" %}
5307 interface(MEMORY_INTER) %{
5308 base($base);
5309 index($index);
5310 scale($scale);
5311 disp($off);
5312 %}
5313 %}
5315 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5316 operand indIndexScaleOffsetNarrow(mRegN reg, immL8 off, mRegL lreg, immI2 scale)
5317 %{
5318 predicate(Universe::narrow_oop_shift() == 0);
5319 constraint(ALLOC_IN_RC(p_reg));
5320 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
5322 op_cost(10);
5323 format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffsetNarrow" %}
5324 interface(MEMORY_INTER) %{
5325 base($reg);
5326 index($lreg);
5327 scale($scale);
5328 disp($off);
5329 %}
5330 %}
5332 // [base + index<<scale + offset] for compressd Oops
5333 operand indPosIndexI2LScaleOffset8Narrow(mRegN base, mRegI index, immL8 off, immI_0_31 scale)
5334 %{
5335 constraint(ALLOC_IN_RC(p_reg));
5336 //predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5337 predicate(Universe::narrow_oop_shift() == 0);
5338 op_cost(10);
5339 match(AddP (AddP (DecodeN base) (LShiftL (ConvI2L index) scale)) off);
5341 format %{ "[$base + $index << $scale + $off (8-bit)] @ indPosIndexI2LScaleOffset8Narrow" %}
5342 interface(MEMORY_INTER) %{
5343 base($base);
5344 index($index);
5345 scale($scale);
5346 disp($off);
5347 %}
5348 %}
5350 //FIXME: I think it's better to limit the immI to be 16-bit at most!
5351 // Indirect Memory Plus Long Offset Operand
5352 operand indOffset32(mRegP reg, immL32 off) %{
5353 constraint(ALLOC_IN_RC(p_reg));
5354 op_cost(20);
5355 match(AddP reg off);
5357 format %{ "[$reg + $off (32-bit)] @ indOffset32" %}
5358 interface(MEMORY_INTER) %{
5359 base($reg);
5360 index(0x0); /* NO_INDEX */
5361 scale(0x0);
5362 disp($off);
5363 %}
5364 %}
5366 // Indirect Memory Plus Index Register
5367 operand indIndex(mRegP addr, mRegL index) %{
5368 constraint(ALLOC_IN_RC(p_reg));
5369 match(AddP addr index);
5371 op_cost(20);
5372 format %{"[$addr + $index] @ indIndex" %}
5373 interface(MEMORY_INTER) %{
5374 base($addr);
5375 index($index);
5376 scale(0x0);
5377 disp(0x0);
5378 %}
5379 %}
5381 operand indirectNarrowKlass(mRegN reg)
5382 %{
5383 predicate(Universe::narrow_klass_shift() == 0);
5384 constraint(ALLOC_IN_RC(p_reg));
5385 op_cost(10);
5386 match(DecodeNKlass reg);
5388 format %{ "[$reg] @ indirectNarrowKlass" %}
5389 interface(MEMORY_INTER) %{
5390 base($reg);
5391 index(0x0);
5392 scale(0x0);
5393 disp(0x0);
5394 %}
5395 %}
5397 operand indOffset8NarrowKlass(mRegN reg, immL8 off)
5398 %{
5399 predicate(Universe::narrow_klass_shift() == 0);
5400 constraint(ALLOC_IN_RC(p_reg));
5401 op_cost(10);
5402 match(AddP (DecodeNKlass reg) off);
5404 format %{ "[$reg + $off (8-bit)] @ indOffset8NarrowKlass" %}
5405 interface(MEMORY_INTER) %{
5406 base($reg);
5407 index(0x0);
5408 scale(0x0);
5409 disp($off);
5410 %}
5411 %}
5413 operand indOffset32NarrowKlass(mRegN reg, immL32 off)
5414 %{
5415 predicate(Universe::narrow_klass_shift() == 0);
5416 constraint(ALLOC_IN_RC(p_reg));
5417 op_cost(10);
5418 match(AddP (DecodeNKlass reg) off);
5420 format %{ "[$reg + $off (32-bit)] @ indOffset32NarrowKlass" %}
5421 interface(MEMORY_INTER) %{
5422 base($reg);
5423 index(0x0);
5424 scale(0x0);
5425 disp($off);
5426 %}
5427 %}
5429 operand indIndexOffsetNarrowKlass(mRegN reg, mRegL lreg, immL32 off)
5430 %{
5431 predicate(Universe::narrow_klass_shift() == 0);
5432 constraint(ALLOC_IN_RC(p_reg));
5433 match(AddP (AddP (DecodeNKlass reg) lreg) off);
5435 op_cost(10);
5436 format %{"[$reg + $off + $lreg] @ indIndexOffsetNarrowKlass" %}
5437 interface(MEMORY_INTER) %{
5438 base($reg);
5439 index($lreg);
5440 scale(0x0);
5441 disp($off);
5442 %}
5443 %}
5445 operand indIndexNarrowKlass(mRegN reg, mRegL lreg)
5446 %{
5447 predicate(Universe::narrow_klass_shift() == 0);
5448 constraint(ALLOC_IN_RC(p_reg));
5449 match(AddP (DecodeNKlass reg) lreg);
5451 op_cost(10);
5452 format %{"[$reg + $lreg] @ indIndexNarrowKlass" %}
5453 interface(MEMORY_INTER) %{
5454 base($reg);
5455 index($lreg);
5456 scale(0x0);
5457 disp(0x0);
5458 %}
5459 %}
5461 // Indirect Memory Operand
5462 operand indirectNarrow(mRegN reg)
5463 %{
5464 predicate(Universe::narrow_oop_shift() == 0);
5465 constraint(ALLOC_IN_RC(p_reg));
5466 op_cost(10);
5467 match(DecodeN reg);
5469 format %{ "[$reg] @ indirectNarrow" %}
5470 interface(MEMORY_INTER) %{
5471 base($reg);
5472 index(0x0);
5473 scale(0x0);
5474 disp(0x0);
5475 %}
5476 %}
5478 // Indirect Memory Plus Short Offset Operand
5479 operand indOffset8Narrow(mRegN reg, immL8 off)
5480 %{
5481 predicate(Universe::narrow_oop_shift() == 0);
5482 constraint(ALLOC_IN_RC(p_reg));
5483 op_cost(10);
5484 match(AddP (DecodeN reg) off);
5486 format %{ "[$reg + $off (8-bit)] @ indOffset8Narrow" %}
5487 interface(MEMORY_INTER) %{
5488 base($reg);
5489 index(0x0);
5490 scale(0x0);
5491 disp($off);
5492 %}
5493 %}
5495 // Indirect Memory Plus Index Register Plus Offset Operand
5496 operand indIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
5497 %{
5498 predicate(Universe::narrow_oop_shift() == 0);
5499 constraint(ALLOC_IN_RC(p_reg));
5500 match(AddP (AddP (DecodeN reg) lreg) off);
5502 op_cost(10);
5503 format %{"[$reg + $off + $lreg] @ indIndexOffset8Narrow" %}
5504 interface(MEMORY_INTER) %{
5505 base($reg);
5506 index($lreg);
5507 scale(0x0);
5508 disp($off);
5509 %}
5510 %}
5512 //----------Load Long Memory Operands------------------------------------------
5513 // The load-long idiom will use it's address expression again after loading
5514 // the first word of the long. If the load-long destination overlaps with
5515 // registers used in the addressing expression, the 2nd half will be loaded
5516 // from a clobbered address. Fix this by requiring that load-long use
5517 // address registers that do not overlap with the load-long target.
5519 // load-long support
5520 operand load_long_RegP() %{
5521 constraint(ALLOC_IN_RC(p_reg));
5522 match(RegP);
5523 match(mRegP);
5524 op_cost(100);
5525 format %{ %}
5526 interface(REG_INTER);
5527 %}
5529 // Indirect Memory Operand Long
5530 operand load_long_indirect(load_long_RegP reg) %{
5531 constraint(ALLOC_IN_RC(p_reg));
5532 match(reg);
5534 format %{ "[$reg]" %}
5535 interface(MEMORY_INTER) %{
5536 base($reg);
5537 index(0x0);
5538 scale(0x0);
5539 disp(0x0);
5540 %}
5541 %}
5543 // Indirect Memory Plus Long Offset Operand
5544 operand load_long_indOffset32(load_long_RegP reg, immL32 off) %{
5545 match(AddP reg off);
5547 format %{ "[$reg + $off]" %}
5548 interface(MEMORY_INTER) %{
5549 base($reg);
5550 index(0x0);
5551 scale(0x0);
5552 disp($off);
5553 %}
5554 %}
5556 //----------Conditional Branch Operands----------------------------------------
5557 // Comparison Op - This is the operation of the comparison, and is limited to
5558 // the following set of codes:
5559 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5560 //
5561 // Other attributes of the comparison, such as unsignedness, are specified
5562 // by the comparison instruction that sets a condition code flags register.
5563 // That result is represented by a flags operand whose subtype is appropriate
5564 // to the unsignedness (etc.) of the comparison.
5565 //
5566 // Later, the instruction which matches both the Comparison Op (a Bool) and
5567 // the flags (produced by the Cmp) specifies the coding of the comparison op
5568 // by matching a specific subtype of Bool operand below, such as cmpOpU.
5570 // Comparision Code
5571 operand cmpOp() %{
5572 match(Bool);
5574 format %{ "" %}
5575 interface(COND_INTER) %{
5576 equal(0x01);
5577 not_equal(0x02);
5578 greater(0x03);
5579 greater_equal(0x04);
5580 less(0x05);
5581 less_equal(0x06);
5582 overflow(0x7);
5583 no_overflow(0x8);
5584 %}
5585 %}
5588 // Comparision Code
5589 // Comparison Code, unsigned compare. Used by FP also, with
5590 // C2 (unordered) turned into GT or LT already. The other bits
5591 // C0 and C3 are turned into Carry & Zero flags.
5592 operand cmpOpU() %{
5593 match(Bool);
5595 format %{ "" %}
5596 interface(COND_INTER) %{
5597 equal(0x01);
5598 not_equal(0x02);
5599 greater(0x03);
5600 greater_equal(0x04);
5601 less(0x05);
5602 less_equal(0x06);
5603 overflow(0x7);
5604 no_overflow(0x8);
5605 %}
5606 %}
5609 //----------Special Memory Operands--------------------------------------------
5610 // Stack Slot Operand - This operand is used for loading and storing temporary
5611 // values on the stack where a match requires a value to
5612 // flow through memory.
5613 operand stackSlotP(sRegP reg) %{
5614 constraint(ALLOC_IN_RC(stack_slots));
5615 // No match rule because this operand is only generated in matching
5616 op_cost(50);
5617 format %{ "[$reg]" %}
5618 interface(MEMORY_INTER) %{
5619 base(0x1d); // SP
5620 index(0x0); // No Index
5621 scale(0x0); // No Scale
5622 disp($reg); // Stack Offset
5623 %}
5624 %}
5626 operand stackSlotI(sRegI reg) %{
5627 constraint(ALLOC_IN_RC(stack_slots));
5628 // No match rule because this operand is only generated in matching
5629 op_cost(50);
5630 format %{ "[$reg]" %}
5631 interface(MEMORY_INTER) %{
5632 base(0x1d); // SP
5633 index(0x0); // No Index
5634 scale(0x0); // No Scale
5635 disp($reg); // Stack Offset
5636 %}
5637 %}
5639 operand stackSlotF(sRegF reg) %{
5640 constraint(ALLOC_IN_RC(stack_slots));
5641 // No match rule because this operand is only generated in matching
5642 op_cost(50);
5643 format %{ "[$reg]" %}
5644 interface(MEMORY_INTER) %{
5645 base(0x1d); // SP
5646 index(0x0); // No Index
5647 scale(0x0); // No Scale
5648 disp($reg); // Stack Offset
5649 %}
5650 %}
5652 operand stackSlotD(sRegD reg) %{
5653 constraint(ALLOC_IN_RC(stack_slots));
5654 // No match rule because this operand is only generated in matching
5655 op_cost(50);
5656 format %{ "[$reg]" %}
5657 interface(MEMORY_INTER) %{
5658 base(0x1d); // SP
5659 index(0x0); // No Index
5660 scale(0x0); // No Scale
5661 disp($reg); // Stack Offset
5662 %}
5663 %}
5665 operand stackSlotL(sRegL reg) %{
5666 constraint(ALLOC_IN_RC(stack_slots));
5667 // No match rule because this operand is only generated in matching
5668 op_cost(50);
5669 format %{ "[$reg]" %}
5670 interface(MEMORY_INTER) %{
5671 base(0x1d); // SP
5672 index(0x0); // No Index
5673 scale(0x0); // No Scale
5674 disp($reg); // Stack Offset
5675 %}
5676 %}
5679 //------------------------OPERAND CLASSES--------------------------------------
5680 //opclass memory( direct, indirect, indOffset16, indOffset32, indOffset32X, indIndexOffset );
5681 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);
5684 //----------PIPELINE-----------------------------------------------------------
5685 // Rules which define the behavior of the target architectures pipeline.
5687 pipeline %{
5689 //----------ATTRIBUTES---------------------------------------------------------
5690 attributes %{
5691 fixed_size_instructions; // Fixed size instructions
5692 branch_has_delay_slot; // branch have delay slot in gs2
5693 max_instructions_per_bundle = 1; // 1 instruction per bundle
5694 max_bundles_per_cycle = 4; // Up to 4 bundles per cycle
5695 bundle_unit_size=4;
5696 instruction_unit_size = 4; // An instruction is 4 bytes long
5697 instruction_fetch_unit_size = 16; // The processor fetches one line
5698 instruction_fetch_units = 1; // of 16 bytes
5700 // List of nop instructions
5701 nops( MachNop );
5702 %}
5704 //----------RESOURCES----------------------------------------------------------
5705 // Resources are the functional units available to the machine
5707 resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4, ALU1, ALU2, ALU = ALU1 | ALU2, FPU1, FPU2, FPU = FPU1 | FPU2, MEM, BR);
5709 //----------PIPELINE DESCRIPTION-----------------------------------------------
5710 // Pipeline Description specifies the stages in the machine's pipeline
5712 // IF: fetch
5713 // ID: decode
5714 // RD: read
5715 // CA: caculate
5716 // WB: write back
5717 // CM: commit
5719 pipe_desc(IF, ID, RD, CA, WB, CM);
5722 //----------PIPELINE CLASSES---------------------------------------------------
5723 // Pipeline Classes describe the stages in which input and output are
5724 // referenced by the hardware pipeline.
5726 //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
5727 pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
5728 single_instruction;
5729 src1 : RD(read);
5730 src2 : RD(read);
5731 dst : WB(write)+1;
5732 DECODE : ID;
5733 ALU : CA;
5734 %}
5736 //No.19 Integer mult operation : dst <-- reg1 mult reg2
5737 pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
5738 src1 : RD(read);
5739 src2 : RD(read);
5740 dst : WB(write)+5;
5741 DECODE : ID;
5742 ALU2 : CA;
5743 %}
5745 pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
5746 src1 : RD(read);
5747 src2 : RD(read);
5748 dst : WB(write)+10;
5749 DECODE : ID;
5750 ALU2 : CA;
5751 %}
5753 //No.19 Integer div operation : dst <-- reg1 div reg2
5754 pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
5755 src1 : RD(read);
5756 src2 : RD(read);
5757 dst : WB(write)+10;
5758 DECODE : ID;
5759 ALU2 : CA;
5760 %}
5762 //No.19 Integer mod operation : dst <-- reg1 mod reg2
5763 pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
5764 instruction_count(2);
5765 src1 : RD(read);
5766 src2 : RD(read);
5767 dst : WB(write)+10;
5768 DECODE : ID;
5769 ALU2 : CA;
5770 %}
5772 //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
5773 pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
5774 instruction_count(2);
5775 src1 : RD(read);
5776 src2 : RD(read);
5777 dst : WB(write);
5778 DECODE : ID;
5779 ALU : CA;
5780 %}
5782 //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
5783 pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
5784 instruction_count(2);
5785 src : RD(read);
5786 dst : WB(write);
5787 DECODE : ID;
5788 ALU : CA;
5789 %}
5791 //no.16 load Long from memory :
5792 pipe_class ialu_loadL(mRegL dst, memory mem) %{
5793 instruction_count(2);
5794 mem : RD(read);
5795 dst : WB(write)+5;
5796 DECODE : ID;
5797 MEM : RD;
5798 %}
5800 //No.17 Store Long to Memory :
5801 pipe_class ialu_storeL(mRegL src, memory mem) %{
5802 instruction_count(2);
5803 mem : RD(read);
5804 src : RD(read);
5805 DECODE : ID;
5806 MEM : RD;
5807 %}
5809 //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
5810 pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
5811 single_instruction;
5812 src : RD(read);
5813 dst : WB(write);
5814 DECODE : ID;
5815 ALU : CA;
5816 %}
5818 //No.3 Integer move operation : dst <-- reg
5819 pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
5820 src : RD(read);
5821 dst : WB(write);
5822 DECODE : ID;
5823 ALU : CA;
5824 %}
5826 //No.4 No instructions : do nothing
5827 pipe_class empty( ) %{
5828 instruction_count(0);
5829 %}
5831 //No.5 UnConditional branch :
5832 pipe_class pipe_jump( label labl ) %{
5833 multiple_bundles;
5834 DECODE : ID;
5835 BR : RD;
5836 %}
5838 //No.6 ALU Conditional branch :
5839 pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
5840 multiple_bundles;
5841 src1 : RD(read);
5842 src2 : RD(read);
5843 DECODE : ID;
5844 BR : RD;
5845 %}
5847 //no.7 load integer from memory :
5848 pipe_class ialu_loadI(mRegI dst, memory mem) %{
5849 mem : RD(read);
5850 dst : WB(write)+3;
5851 DECODE : ID;
5852 MEM : RD;
5853 %}
5855 //No.8 Store Integer to Memory :
5856 pipe_class ialu_storeI(mRegI src, memory mem) %{
5857 mem : RD(read);
5858 src : RD(read);
5859 DECODE : ID;
5860 MEM : RD;
5861 %}
5864 //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
5865 pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
5866 src1 : RD(read);
5867 src2 : RD(read);
5868 dst : WB(write);
5869 DECODE : ID;
5870 FPU : CA;
5871 %}
5873 //No.22 Floating div operation : dst <-- reg1 div reg2
5874 pipe_class fpu_div(regF dst, regF src1, regF src2) %{
5875 src1 : RD(read);
5876 src2 : RD(read);
5877 dst : WB(write);
5878 DECODE : ID;
5879 FPU2 : CA;
5880 %}
5882 pipe_class fcvt_I2D(regD dst, mRegI src) %{
5883 src : RD(read);
5884 dst : WB(write);
5885 DECODE : ID;
5886 FPU1 : CA;
5887 %}
5889 pipe_class fcvt_D2I(mRegI dst, regD src) %{
5890 src : RD(read);
5891 dst : WB(write);
5892 DECODE : ID;
5893 FPU1 : CA;
5894 %}
5896 pipe_class pipe_mfc1(mRegI dst, regD src) %{
5897 src : RD(read);
5898 dst : WB(write);
5899 DECODE : ID;
5900 MEM : RD;
5901 %}
5903 pipe_class pipe_mtc1(regD dst, mRegI src) %{
5904 src : RD(read);
5905 dst : WB(write);
5906 DECODE : ID;
5907 MEM : RD(5);
5908 %}
5910 //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
5911 pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
5912 multiple_bundles;
5913 src1 : RD(read);
5914 src2 : RD(read);
5915 dst : WB(write);
5916 DECODE : ID;
5917 FPU2 : CA;
5918 %}
5920 //No.11 Load Floating from Memory :
5921 pipe_class fpu_loadF(regF dst, memory mem) %{
5922 instruction_count(1);
5923 mem : RD(read);
5924 dst : WB(write)+3;
5925 DECODE : ID;
5926 MEM : RD;
5927 %}
5929 //No.12 Store Floating to Memory :
5930 pipe_class fpu_storeF(regF src, memory mem) %{
5931 instruction_count(1);
5932 mem : RD(read);
5933 src : RD(read);
5934 DECODE : ID;
5935 MEM : RD;
5936 %}
5938 //No.13 FPU Conditional branch :
5939 pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
5940 multiple_bundles;
5941 src1 : RD(read);
5942 src2 : RD(read);
5943 DECODE : ID;
5944 BR : RD;
5945 %}
5947 //No.14 Floating FPU reg operation : dst <-- op reg
5948 pipe_class fpu1_regF(regF dst, regF src) %{
5949 src : RD(read);
5950 dst : WB(write);
5951 DECODE : ID;
5952 FPU : CA;
5953 %}
5955 pipe_class long_memory_op() %{
5956 instruction_count(10); multiple_bundles; force_serialization;
5957 fixed_latency(30);
5958 %}
5960 pipe_class simple_call() %{
5961 instruction_count(10); multiple_bundles; force_serialization;
5962 fixed_latency(200);
5963 BR : RD;
5964 %}
5966 pipe_class call() %{
5967 instruction_count(10); multiple_bundles; force_serialization;
5968 fixed_latency(200);
5969 %}
5971 //FIXME:
5972 //No.9 Piple slow : for multi-instructions
5973 pipe_class pipe_slow( ) %{
5974 instruction_count(20);
5975 force_serialization;
5976 multiple_bundles;
5977 fixed_latency(50);
5978 %}
5980 %}
5984 //----------INSTRUCTIONS-------------------------------------------------------
5985 //
5986 // match -- States which machine-independent subtree may be replaced
5987 // by this instruction.
5988 // ins_cost -- The estimated cost of this instruction is used by instruction
5989 // selection to identify a minimum cost tree of machine
5990 // instructions that matches a tree of machine-independent
5991 // instructions.
5992 // format -- A string providing the disassembly for this instruction.
5993 // The value of an instruction's operand may be inserted
5994 // by referring to it with a '$' prefix.
5995 // opcode -- Three instruction opcodes may be provided. These are referred
5996 // to within an encode class as $primary, $secondary, and $tertiary
5997 // respectively. The primary opcode is commonly used to
5998 // indicate the type of machine instruction, while secondary
5999 // and tertiary are often used for prefix options or addressing
6000 // modes.
6001 // ins_encode -- A list of encode classes with parameters. The encode class
6002 // name must have been defined in an 'enc_class' specification
6003 // in the encode section of the architecture description.
6006 // Load Integer
6007 instruct loadI(mRegI dst, memory mem) %{
6008 match(Set dst (LoadI mem));
6010 ins_cost(125);
6011 format %{ "lw $dst, $mem #@loadI" %}
6012 ins_encode (load_I_enc(dst, mem));
6013 ins_pipe( ialu_loadI );
6014 %}
6016 instruct loadI_convI2L(mRegL dst, memory mem) %{
6017 match(Set dst (ConvI2L (LoadI mem)));
6019 ins_cost(125);
6020 format %{ "lw $dst, $mem #@loadI_convI2L" %}
6021 ins_encode (load_I_enc(dst, mem));
6022 ins_pipe( ialu_loadI );
6023 %}
6025 // Load Integer (32 bit signed) to Byte (8 bit signed)
6026 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
6027 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
6029 ins_cost(125);
6030 format %{ "lb $dst, $mem\t# int -> byte #@loadI2B" %}
6031 ins_encode(load_B_enc(dst, mem));
6032 ins_pipe(ialu_loadI);
6033 %}
6035 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
6036 instruct loadI2UB(mRegI dst, memory mem, immI_255 mask) %{
6037 match(Set dst (AndI (LoadI mem) mask));
6039 ins_cost(125);
6040 format %{ "lbu $dst, $mem\t# int -> ubyte #@loadI2UB" %}
6041 ins_encode(load_UB_enc(dst, mem));
6042 ins_pipe(ialu_loadI);
6043 %}
6045 // Load Integer (32 bit signed) to Short (16 bit signed)
6046 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
6047 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
6049 ins_cost(125);
6050 format %{ "lh $dst, $mem\t# int -> short #@loadI2S" %}
6051 ins_encode(load_S_enc(dst, mem));
6052 ins_pipe(ialu_loadI);
6053 %}
6055 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
6056 instruct loadI2US(mRegI dst, memory mem, immI_65535 mask) %{
6057 match(Set dst (AndI (LoadI mem) mask));
6059 ins_cost(125);
6060 format %{ "lhu $dst, $mem\t# int -> ushort/char #@loadI2US" %}
6061 ins_encode(load_C_enc(dst, mem));
6062 ins_pipe(ialu_loadI);
6063 %}
6065 // Load Long.
6066 instruct loadL(mRegL dst, memory mem) %{
6067 // predicate(!((LoadLNode*)n)->require_atomic_access());
6068 match(Set dst (LoadL mem));
6070 ins_cost(250);
6071 format %{ "ld $dst, $mem #@loadL" %}
6072 ins_encode(load_L_enc(dst, mem));
6073 ins_pipe( ialu_loadL );
6074 %}
6076 // Load Long - UNaligned
6077 instruct loadL_unaligned(mRegL dst, memory mem) %{
6078 match(Set dst (LoadL_unaligned mem));
6080 // FIXME: Need more effective ldl/ldr
6081 ins_cost(450);
6082 format %{ "ld $dst, $mem #@loadL_unaligned\n\t" %}
6083 ins_encode(load_L_enc(dst, mem));
6084 ins_pipe( ialu_loadL );
6085 %}
6087 // Store Long
6088 instruct storeL_reg(memory mem, mRegL src) %{
6089 match(Set mem (StoreL mem src));
6091 ins_cost(200);
6092 format %{ "sd $mem, $src #@storeL_reg\n" %}
6093 ins_encode(store_L_reg_enc(mem, src));
6094 ins_pipe( ialu_storeL );
6095 %}
6097 instruct storeL_immL0(memory mem, immL0 zero) %{
6098 match(Set mem (StoreL mem zero));
6100 ins_cost(180);
6101 format %{ "sd zero, $mem #@storeL_immL0" %}
6102 ins_encode(store_L_immL0_enc(mem, zero));
6103 ins_pipe( ialu_storeL );
6104 %}
6106 instruct storeL_imm(memory mem, immL src) %{
6107 match(Set mem (StoreL mem src));
6109 ins_cost(200);
6110 format %{ "sd $src, $mem #@storeL_imm" %}
6111 ins_encode(store_L_immL_enc(mem, src));
6112 ins_pipe( ialu_storeL );
6113 %}
6115 // Load Compressed Pointer
6116 instruct loadN(mRegN dst, memory mem)
6117 %{
6118 match(Set dst (LoadN mem));
6120 ins_cost(125); // XXX
6121 format %{ "lwu $dst, $mem\t# compressed ptr @ loadN" %}
6122 ins_encode (load_N_enc(dst, mem));
6123 ins_pipe( ialu_loadI ); // XXX
6124 %}
6126 instruct loadN2P(mRegP dst, memory mem)
6127 %{
6128 match(Set dst (DecodeN (LoadN mem)));
6129 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6131 ins_cost(125); // XXX
6132 format %{ "lwu $dst, $mem\t# @ loadN2P" %}
6133 ins_encode (load_N_enc(dst, mem));
6134 ins_pipe( ialu_loadI ); // XXX
6135 %}
6137 // Load Pointer
6138 instruct loadP(mRegP dst, memory mem) %{
6139 match(Set dst (LoadP mem));
6141 ins_cost(125);
6142 format %{ "ld $dst, $mem #@loadP" %}
6143 ins_encode (load_P_enc(dst, mem));
6144 ins_pipe( ialu_loadI );
6145 %}
6147 // Load Klass Pointer
6148 instruct loadKlass(mRegP dst, memory mem) %{
6149 match(Set dst (LoadKlass mem));
6151 ins_cost(125);
6152 format %{ "MOV $dst,$mem @ loadKlass" %}
6153 ins_encode (load_P_enc(dst, mem));
6154 ins_pipe( ialu_loadI );
6155 %}
6157 // Load narrow Klass Pointer
6158 instruct loadNKlass(mRegN dst, memory mem)
6159 %{
6160 match(Set dst (LoadNKlass mem));
6162 ins_cost(125); // XXX
6163 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
6164 ins_encode (load_N_enc(dst, mem));
6165 ins_pipe( ialu_loadI ); // XXX
6166 %}
6168 instruct loadN2PKlass(mRegP dst, memory mem)
6169 %{
6170 match(Set dst (DecodeNKlass (LoadNKlass mem)));
6171 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
6173 ins_cost(125); // XXX
6174 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
6175 ins_encode (load_N_enc(dst, mem));
6176 ins_pipe( ialu_loadI ); // XXX
6177 %}
6179 // Load Constant
6180 instruct loadConI(mRegI dst, immI src) %{
6181 match(Set dst src);
6183 ins_cost(150);
6184 format %{ "mov $dst, $src #@loadConI" %}
6185 ins_encode %{
6186 Register dst = $dst$$Register;
6187 int value = $src$$constant;
6188 __ move(dst, value);
6189 %}
6190 ins_pipe( ialu_regI_regI );
6191 %}
6194 instruct loadConL_set64(mRegL dst, immL src) %{
6195 match(Set dst src);
6196 ins_cost(120);
6197 format %{ "li $dst, $src @ loadConL_set64" %}
6198 ins_encode %{
6199 __ set64($dst$$Register, $src$$constant);
6200 %}
6201 ins_pipe(ialu_regL_regL);
6202 %}
6204 /*
6205 // Load long value from constant table (predicated by immL_expensive).
6206 instruct loadConL_load(mRegL dst, immL_expensive src) %{
6207 match(Set dst src);
6208 ins_cost(150);
6209 format %{ "ld $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
6210 ins_encode %{
6211 int con_offset = $constantoffset($src);
6213 if (Assembler::is_simm16(con_offset)) {
6214 __ ld($dst$$Register, $constanttablebase, con_offset);
6215 } else {
6216 __ set64(AT, con_offset);
6217 if (UseLoongsonISA) {
6218 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
6219 } else {
6220 __ daddu(AT, $constanttablebase, AT);
6221 __ ld($dst$$Register, AT, 0);
6222 }
6223 }
6224 %}
6225 ins_pipe(ialu_loadI);
6226 %}
6227 */
6229 instruct loadConL16(mRegL dst, immL16 src) %{
6230 match(Set dst src);
6231 ins_cost(105);
6232 format %{ "mov $dst, $src #@loadConL16" %}
6233 ins_encode %{
6234 Register dst_reg = as_Register($dst$$reg);
6235 int value = $src$$constant;
6236 __ daddiu(dst_reg, R0, value);
6237 %}
6238 ins_pipe( ialu_regL_regL );
6239 %}
6242 instruct loadConL0(mRegL dst, immL0 src) %{
6243 match(Set dst src);
6244 ins_cost(100);
6245 format %{ "mov $dst, zero #@loadConL0" %}
6246 ins_encode %{
6247 Register dst_reg = as_Register($dst$$reg);
6248 __ daddu(dst_reg, R0, R0);
6249 %}
6250 ins_pipe( ialu_regL_regL );
6251 %}
6253 // Load Range
6254 instruct loadRange(mRegI dst, memory mem) %{
6255 match(Set dst (LoadRange mem));
6257 ins_cost(125);
6258 format %{ "MOV $dst,$mem @ loadRange" %}
6259 ins_encode(load_I_enc(dst, mem));
6260 ins_pipe( ialu_loadI );
6261 %}
6264 instruct storeP(memory mem, mRegP src ) %{
6265 match(Set mem (StoreP mem src));
6267 ins_cost(125);
6268 format %{ "sd $src, $mem #@storeP" %}
6269 ins_encode(store_P_reg_enc(mem, src));
6270 ins_pipe( ialu_storeI );
6271 %}
6273 // Store NULL Pointer, mark word, or other simple pointer constant.
6274 instruct storeImmP0(memory mem, immP0 zero) %{
6275 match(Set mem (StoreP mem zero));
6277 ins_cost(125);
6278 format %{ "mov $mem, $zero #@storeImmP0" %}
6279 ins_encode(store_P_immP0_enc(mem));
6280 ins_pipe( ialu_storeI );
6281 %}
6283 // Store Byte Immediate
6284 instruct storeImmB(memory mem, immI8 src) %{
6285 match(Set mem (StoreB mem src));
6287 ins_cost(150);
6288 format %{ "movb $mem, $src #@storeImmB" %}
6289 ins_encode(store_B_immI_enc(mem, src));
6290 ins_pipe( ialu_storeI );
6291 %}
6293 // Store Compressed Pointer
6294 instruct storeN(memory mem, mRegN src)
6295 %{
6296 match(Set mem (StoreN mem src));
6298 ins_cost(125); // XXX
6299 format %{ "sw $mem, $src\t# compressed ptr @ storeN" %}
6300 ins_encode(store_N_reg_enc(mem, src));
6301 ins_pipe( ialu_storeI );
6302 %}
6304 instruct storeP2N(memory mem, mRegP src)
6305 %{
6306 match(Set mem (StoreN mem (EncodeP src)));
6307 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6309 ins_cost(125); // XXX
6310 format %{ "sw $mem, $src\t# @ storeP2N" %}
6311 ins_encode(store_N_reg_enc(mem, src));
6312 ins_pipe( ialu_storeI );
6313 %}
6315 instruct storeNKlass(memory mem, mRegN src)
6316 %{
6317 match(Set mem (StoreNKlass mem src));
6319 ins_cost(125); // XXX
6320 format %{ "sw $mem, $src\t# compressed klass ptr @ storeNKlass" %}
6321 ins_encode(store_N_reg_enc(mem, src));
6322 ins_pipe( ialu_storeI );
6323 %}
6325 instruct storeP2NKlass(memory mem, mRegP src)
6326 %{
6327 match(Set mem (StoreNKlass mem (EncodePKlass src)));
6328 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
6330 ins_cost(125); // XXX
6331 format %{ "sw $mem, $src\t# @ storeP2NKlass" %}
6332 ins_encode(store_N_reg_enc(mem, src));
6333 ins_pipe( ialu_storeI );
6334 %}
6336 instruct storeImmN0(memory mem, immN0 zero)
6337 %{
6338 match(Set mem (StoreN mem zero));
6340 ins_cost(125); // XXX
6341 format %{ "storeN0 zero, $mem\t# compressed ptr" %}
6342 ins_encode(storeImmN0_enc(mem, zero));
6343 ins_pipe( ialu_storeI );
6344 %}
6346 // Store Byte
6347 instruct storeB(memory mem, mRegI src) %{
6348 match(Set mem (StoreB mem src));
6350 ins_cost(125);
6351 format %{ "sb $src, $mem #@storeB" %}
6352 ins_encode(store_B_reg_enc(mem, src));
6353 ins_pipe( ialu_storeI );
6354 %}
6356 instruct storeB_convL2I(memory mem, mRegL src) %{
6357 match(Set mem (StoreB mem (ConvL2I src)));
6359 ins_cost(125);
6360 format %{ "sb $src, $mem #@storeB_convL2I" %}
6361 ins_encode(store_B_reg_enc(mem, src));
6362 ins_pipe( ialu_storeI );
6363 %}
6365 // Load Byte (8bit signed)
6366 instruct loadB(mRegI dst, memory mem) %{
6367 match(Set dst (LoadB mem));
6369 ins_cost(125);
6370 format %{ "lb $dst, $mem #@loadB" %}
6371 ins_encode(load_B_enc(dst, mem));
6372 ins_pipe( ialu_loadI );
6373 %}
6375 instruct loadB_convI2L(mRegL dst, memory mem) %{
6376 match(Set dst (ConvI2L (LoadB mem)));
6378 ins_cost(125);
6379 format %{ "lb $dst, $mem #@loadB_convI2L" %}
6380 ins_encode(load_B_enc(dst, mem));
6381 ins_pipe( ialu_loadI );
6382 %}
6384 // Load Byte (8bit UNsigned)
6385 instruct loadUB(mRegI dst, memory mem) %{
6386 match(Set dst (LoadUB mem));
6388 ins_cost(125);
6389 format %{ "lbu $dst, $mem #@loadUB" %}
6390 ins_encode(load_UB_enc(dst, mem));
6391 ins_pipe( ialu_loadI );
6392 %}
6394 instruct loadUB_convI2L(mRegL dst, memory mem) %{
6395 match(Set dst (ConvI2L (LoadUB mem)));
6397 ins_cost(125);
6398 format %{ "lbu $dst, $mem #@loadUB_convI2L" %}
6399 ins_encode(load_UB_enc(dst, mem));
6400 ins_pipe( ialu_loadI );
6401 %}
6403 // Load Short (16bit signed)
6404 instruct loadS(mRegI dst, memory mem) %{
6405 match(Set dst (LoadS mem));
6407 ins_cost(125);
6408 format %{ "lh $dst, $mem #@loadS" %}
6409 ins_encode(load_S_enc(dst, mem));
6410 ins_pipe( ialu_loadI );
6411 %}
6413 // Load Short (16 bit signed) to Byte (8 bit signed)
6414 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
6415 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
6417 ins_cost(125);
6418 format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
6419 ins_encode(load_B_enc(dst, mem));
6420 ins_pipe(ialu_loadI);
6421 %}
6423 instruct loadS_convI2L(mRegL dst, memory mem) %{
6424 match(Set dst (ConvI2L (LoadS mem)));
6426 ins_cost(125);
6427 format %{ "lh $dst, $mem #@loadS_convI2L" %}
6428 ins_encode(load_S_enc(dst, mem));
6429 ins_pipe( ialu_loadI );
6430 %}
6432 // Store Integer Immediate
6433 instruct storeImmI(memory mem, immI src) %{
6434 match(Set mem (StoreI mem src));
6436 ins_cost(150);
6437 format %{ "mov $mem, $src #@storeImmI" %}
6438 ins_encode(store_I_immI_enc(mem, src));
6439 ins_pipe( ialu_storeI );
6440 %}
6442 // Store Integer
6443 instruct storeI(memory mem, mRegI src) %{
6444 match(Set mem (StoreI mem src));
6446 ins_cost(125);
6447 format %{ "sw $mem, $src #@storeI" %}
6448 ins_encode(store_I_reg_enc(mem, src));
6449 ins_pipe( ialu_storeI );
6450 %}
6452 instruct storeI_convL2I(memory mem, mRegL src) %{
6453 match(Set mem (StoreI mem (ConvL2I src)));
6455 ins_cost(125);
6456 format %{ "sw $mem, $src #@storeI_convL2I" %}
6457 ins_encode(store_I_reg_enc(mem, src));
6458 ins_pipe( ialu_storeI );
6459 %}
6461 // Load Float
6462 instruct loadF(regF dst, memory mem) %{
6463 match(Set dst (LoadF mem));
6465 ins_cost(150);
6466 format %{ "loadF $dst, $mem #@loadF" %}
6467 ins_encode(load_F_enc(dst, mem));
6468 ins_pipe( ialu_loadI );
6469 %}
6471 instruct loadConP_general(mRegP dst, immP src) %{
6472 match(Set dst src);
6474 ins_cost(120);
6475 format %{ "li $dst, $src #@loadConP_general" %}
6477 ins_encode %{
6478 Register dst = $dst$$Register;
6479 long* value = (long*)$src$$constant;
6481 if($src->constant_reloc() == relocInfo::metadata_type){
6482 int klass_index = __ oop_recorder()->find_index((Klass*)value);
6483 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
6485 __ relocate(rspec);
6486 __ patchable_set48(dst, (long)value);
6487 }else if($src->constant_reloc() == relocInfo::oop_type){
6488 int oop_index = __ oop_recorder()->find_index((jobject)value);
6489 RelocationHolder rspec = oop_Relocation::spec(oop_index);
6491 __ relocate(rspec);
6492 __ patchable_set48(dst, (long)value);
6493 } else if ($src->constant_reloc() == relocInfo::none) {
6494 __ set64(dst, (long)value);
6495 }
6496 %}
6498 ins_pipe( ialu_regI_regI );
6499 %}
6501 /*
6502 instruct loadConP_load(mRegP dst, immP_load src) %{
6503 match(Set dst src);
6505 ins_cost(100);
6506 format %{ "ld $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
6508 ins_encode %{
6510 int con_offset = $constantoffset($src);
6512 if (Assembler::is_simm16(con_offset)) {
6513 __ ld($dst$$Register, $constanttablebase, con_offset);
6514 } else {
6515 __ set64(AT, con_offset);
6516 if (UseLoongsonISA) {
6517 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
6518 } else {
6519 __ daddu(AT, $constanttablebase, AT);
6520 __ ld($dst$$Register, AT, 0);
6521 }
6522 }
6523 %}
6525 ins_pipe(ialu_loadI);
6526 %}
6527 */
6529 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
6530 match(Set dst src);
6532 ins_cost(80);
6533 format %{ "li $dst, $src @ loadConP_no_oop_cheap" %}
6535 ins_encode %{
6536 __ set64($dst$$Register, $src$$constant);
6537 %}
6539 ins_pipe(ialu_regI_regI);
6540 %}
6543 instruct loadConP_poll(mRegP dst, immP_poll src) %{
6544 match(Set dst src);
6546 ins_cost(50);
6547 format %{ "li $dst, $src #@loadConP_poll" %}
6549 ins_encode %{
6550 Register dst = $dst$$Register;
6551 intptr_t value = (intptr_t)$src$$constant;
6553 __ set64(dst, (jlong)value);
6554 %}
6556 ins_pipe( ialu_regI_regI );
6557 %}
6559 instruct loadConP0(mRegP dst, immP0 src)
6560 %{
6561 match(Set dst src);
6563 ins_cost(50);
6564 format %{ "mov $dst, R0\t# ptr" %}
6565 ins_encode %{
6566 Register dst_reg = $dst$$Register;
6567 __ daddu(dst_reg, R0, R0);
6568 %}
6569 ins_pipe( ialu_regI_regI );
6570 %}
6572 instruct loadConN0(mRegN dst, immN0 src) %{
6573 match(Set dst src);
6574 format %{ "move $dst, R0\t# compressed NULL ptr" %}
6575 ins_encode %{
6576 __ move($dst$$Register, R0);
6577 %}
6578 ins_pipe( ialu_regI_regI );
6579 %}
6581 instruct loadConN(mRegN dst, immN src) %{
6582 match(Set dst src);
6584 ins_cost(125);
6585 format %{ "li $dst, $src\t# compressed ptr @ loadConN" %}
6586 ins_encode %{
6587 Register dst = $dst$$Register;
6588 __ set_narrow_oop(dst, (jobject)$src$$constant);
6589 %}
6590 ins_pipe( ialu_regI_regI ); // XXX
6591 %}
6593 instruct loadConNKlass(mRegN dst, immNKlass src) %{
6594 match(Set dst src);
6596 ins_cost(125);
6597 format %{ "li $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
6598 ins_encode %{
6599 Register dst = $dst$$Register;
6600 __ set_narrow_klass(dst, (Klass*)$src$$constant);
6601 %}
6602 ins_pipe( ialu_regI_regI ); // XXX
6603 %}
6605 //FIXME
6606 // Tail Call; Jump from runtime stub to Java code.
6607 // Also known as an 'interprocedural jump'.
6608 // Target of jump will eventually return to caller.
6609 // TailJump below removes the return address.
6610 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
6611 match(TailCall jump_target method_oop );
6612 ins_cost(300);
6613 format %{ "JMP $jump_target \t# @TailCalljmpInd" %}
6615 ins_encode %{
6616 Register target = $jump_target$$Register;
6617 Register oop = $method_oop$$Register;
6619 // RA will be used in generate_forward_exception()
6620 __ push(RA);
6622 __ move(S3, oop);
6623 __ jr(target);
6624 __ delayed()->nop();
6625 %}
6627 ins_pipe( pipe_jump );
6628 %}
6630 // Create exception oop: created by stack-crawling runtime code.
6631 // Created exception is now available to this handler, and is setup
6632 // just prior to jumping to this handler. No code emitted.
6633 instruct CreateException( a0_RegP ex_oop )
6634 %{
6635 match(Set ex_oop (CreateEx));
6637 // use the following format syntax
6638 format %{ "# exception oop is in A0; no code emitted @CreateException" %}
6639 ins_encode %{
6640 // X86 leaves this function empty
6641 __ block_comment("CreateException is empty in MIPS");
6642 %}
6643 ins_pipe( empty );
6644 // ins_pipe( pipe_jump );
6645 %}
6648 /* The mechanism of exception handling is clear now.
6650 - Common try/catch:
6651 [stubGenerator_mips.cpp] generate_forward_exception()
6652 |- V0, V1 are created
6653 |- T9 <= SharedRuntime::exception_handler_for_return_address
6654 `- jr T9
6655 `- the caller's exception_handler
6656 `- jr OptoRuntime::exception_blob
6657 `- here
6658 - Rethrow(e.g. 'unwind'):
6659 * The callee:
6660 |- an exception is triggered during execution
6661 `- exits the callee method through RethrowException node
6662 |- The callee pushes exception_oop(T0) and exception_pc(RA)
6663 `- The callee jumps to OptoRuntime::rethrow_stub()
6664 * In OptoRuntime::rethrow_stub:
6665 |- The VM calls _rethrow_Java to determine the return address in the caller method
6666 `- exits the stub with tailjmpInd
6667 |- pops exception_oop(V0) and exception_pc(V1)
6668 `- jumps to the return address(usually an exception_handler)
6669 * The caller:
6670 `- continues processing the exception_blob with V0/V1
6671 */
6673 /*
6674 Disassembling OptoRuntime::rethrow_stub()
6676 ; locals
6677 0x2d3bf320: addiu sp, sp, 0xfffffff8
6678 0x2d3bf324: sw ra, 0x4(sp)
6679 0x2d3bf328: sw fp, 0x0(sp)
6680 0x2d3bf32c: addu fp, sp, zero
6681 0x2d3bf330: addiu sp, sp, 0xfffffff0
6682 0x2d3bf334: sw ra, 0x8(sp)
6683 0x2d3bf338: sw t0, 0x4(sp)
6684 0x2d3bf33c: sw sp, 0x0(sp)
6686 ; get_thread(S2)
6687 0x2d3bf340: addu s2, sp, zero
6688 0x2d3bf344: srl s2, s2, 12
6689 0x2d3bf348: sll s2, s2, 2
6690 0x2d3bf34c: lui at, 0x2c85
6691 0x2d3bf350: addu at, at, s2
6692 0x2d3bf354: lw s2, 0xffffcc80(at)
6694 0x2d3bf358: lw s0, 0x0(sp)
6695 0x2d3bf35c: sw s0, 0x118(s2) // last_sp -> threa
6696 0x2d3bf360: sw s2, 0xc(sp)
6698 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
6699 0x2d3bf364: lw a0, 0x4(sp)
6700 0x2d3bf368: lw a1, 0xc(sp)
6701 0x2d3bf36c: lw a2, 0x8(sp)
6702 ;; Java_To_Runtime
6703 0x2d3bf370: lui t9, 0x2c34
6704 0x2d3bf374: addiu t9, t9, 0xffff8a48
6705 0x2d3bf378: jalr t9
6706 0x2d3bf37c: nop
6708 0x2d3bf380: addu s3, v0, zero ; S3: SharedRuntime::raw_exception_handler_for_return_address()
6710 0x2d3bf384: lw s0, 0xc(sp)
6711 0x2d3bf388: sw zero, 0x118(s0)
6712 0x2d3bf38c: sw zero, 0x11c(s0)
6713 0x2d3bf390: lw s1, 0x144(s0) ; ex_oop: S1
6714 0x2d3bf394: addu s2, s0, zero
6715 0x2d3bf398: sw zero, 0x144(s2)
6716 0x2d3bf39c: lw s0, 0x4(s2)
6717 0x2d3bf3a0: addiu s4, zero, 0x0
6718 0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
6719 0x2d3bf3a8: nop
6720 0x2d3bf3ac: addiu sp, sp, 0x10
6721 0x2d3bf3b0: addiu sp, sp, 0x8
6722 0x2d3bf3b4: lw ra, 0xfffffffc(sp)
6723 0x2d3bf3b8: lw fp, 0xfffffff8(sp)
6724 0x2d3bf3bc: lui at, 0x2b48
6725 0x2d3bf3c0: lw at, 0x100(at)
6727 ; tailjmpInd: Restores exception_oop & exception_pc
6728 0x2d3bf3c4: addu v1, ra, zero
6729 0x2d3bf3c8: addu v0, s1, zero
6730 0x2d3bf3cc: jr s3
6731 0x2d3bf3d0: nop
6732 ; Exception:
6733 0x2d3bf3d4: lui s1, 0x2cc8 ; generate_forward_exception()
6734 0x2d3bf3d8: addiu s1, s1, 0x40
6735 0x2d3bf3dc: addiu s2, zero, 0x0
6736 0x2d3bf3e0: addiu sp, sp, 0x10
6737 0x2d3bf3e4: addiu sp, sp, 0x8
6738 0x2d3bf3e8: lw ra, 0xfffffffc(sp)
6739 0x2d3bf3ec: lw fp, 0xfffffff8(sp)
6740 0x2d3bf3f0: lui at, 0x2b48
6741 0x2d3bf3f4: lw at, 0x100(at)
6742 ; TailCalljmpInd
6743 __ push(RA); ; to be used in generate_forward_exception()
6744 0x2d3bf3f8: addu t7, s2, zero
6745 0x2d3bf3fc: jr s1
6746 0x2d3bf400: nop
6747 */
6748 // Rethrow exception:
6749 // The exception oop will come in the first argument position.
6750 // Then JUMP (not call) to the rethrow stub code.
6751 instruct RethrowException()
6752 %{
6753 match(Rethrow);
6755 // use the following format syntax
6756 format %{ "JMP rethrow_stub #@RethrowException" %}
6757 ins_encode %{
6758 __ block_comment("@ RethrowException");
6760 cbuf.set_insts_mark();
6761 cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
6763 // call OptoRuntime::rethrow_stub to get the exception handler in parent method
6764 __ patchable_jump((address)OptoRuntime::rethrow_stub());
6765 %}
6766 ins_pipe( pipe_jump );
6767 %}
6769 // ============================================================================
6770 // Branch Instructions --- long offset versions
6772 // Jump Direct
6773 instruct jmpDir_long(label labl) %{
6774 match(Goto);
6775 effect(USE labl);
6777 ins_cost(300);
6778 format %{ "JMP $labl #@jmpDir_long" %}
6780 ins_encode %{
6781 Label* L = $labl$$label;
6782 __ jmp_far(*L);
6783 %}
6785 ins_pipe( pipe_jump );
6786 //ins_pc_relative(1);
6787 %}
6789 // Jump Direct Conditional - Label defines a relative address from Jcc+1
6790 instruct jmpLoopEnd_long(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
6791 match(CountedLoopEnd cop (CmpI src1 src2));
6792 effect(USE labl);
6794 ins_cost(300);
6795 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_long" %}
6796 ins_encode %{
6797 Register op1 = $src1$$Register;
6798 Register op2 = $src2$$Register;
6799 Label* L = $labl$$label;
6800 int flag = $cop$$cmpcode;
6802 switch(flag) {
6803 case 0x01: //equal
6804 __ beq_long(op1, op2, *L);
6805 break;
6806 case 0x02: //not_equal
6807 __ bne_long(op1, op2, *L);
6808 break;
6809 case 0x03: //above
6810 __ slt(AT, op2, op1);
6811 __ bne_long(AT, R0, *L);
6812 break;
6813 case 0x04: //above_equal
6814 __ slt(AT, op1, op2);
6815 __ beq_long(AT, R0, *L);
6816 break;
6817 case 0x05: //below
6818 __ slt(AT, op1, op2);
6819 __ bne_long(AT, R0, *L);
6820 break;
6821 case 0x06: //below_equal
6822 __ slt(AT, op2, op1);
6823 __ beq_long(AT, R0, *L);
6824 break;
6825 default:
6826 Unimplemented();
6827 }
6828 %}
6829 ins_pipe( pipe_jump );
6830 ins_pc_relative(1);
6831 %}
6833 instruct jmpLoopEnd_reg_immI_long(cmpOp cop, mRegI src1, immI src2, label labl) %{
6834 match(CountedLoopEnd cop (CmpI src1 src2));
6835 effect(USE labl);
6837 ins_cost(300);
6838 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_immI_long" %}
6839 ins_encode %{
6840 Register op1 = $src1$$Register;
6841 Register op2 = AT;
6842 Label* L = $labl$$label;
6843 int flag = $cop$$cmpcode;
6845 __ move(op2, $src2$$constant);
6847 switch(flag) {
6848 case 0x01: //equal
6849 __ beq_long(op1, op2, *L);
6850 break;
6851 case 0x02: //not_equal
6852 __ bne_long(op1, op2, *L);
6853 break;
6854 case 0x03: //above
6855 __ slt(AT, op2, op1);
6856 __ bne_long(AT, R0, *L);
6857 break;
6858 case 0x04: //above_equal
6859 __ slt(AT, op1, op2);
6860 __ beq_long(AT, R0, *L);
6861 break;
6862 case 0x05: //below
6863 __ slt(AT, op1, op2);
6864 __ bne_long(AT, R0, *L);
6865 break;
6866 case 0x06: //below_equal
6867 __ slt(AT, op2, op1);
6868 __ beq_long(AT, R0, *L);
6869 break;
6870 default:
6871 Unimplemented();
6872 }
6873 %}
6874 ins_pipe( pipe_jump );
6875 ins_pc_relative(1);
6876 %}
6879 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
6880 instruct jmpCon_flags_long(cmpOp cop, FlagsReg cr, label labl) %{
6881 match(If cop cr);
6882 effect(USE labl);
6884 ins_cost(300);
6885 format %{ "J$cop $labl #mips uses AT as eflag @jmpCon_flags_long" %}
6887 ins_encode %{
6888 Label* L = $labl$$label;
6889 switch($cop$$cmpcode) {
6890 case 0x01: //equal
6891 __ bne_long(AT, R0, *L);
6892 break;
6893 case 0x02: //not equal
6894 __ beq_long(AT, R0, *L);
6895 break;
6896 default:
6897 Unimplemented();
6898 }
6899 %}
6901 ins_pipe( pipe_jump );
6902 ins_pc_relative(1);
6903 %}
6905 // Conditional jumps
6906 instruct branchConP_zero_long(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
6907 match(If cmp (CmpP op1 zero));
6908 effect(USE labl);
6910 ins_cost(180);
6911 format %{ "b$cmp $op1, R0, $labl #@branchConP_zero_long" %}
6913 ins_encode %{
6914 Register op1 = $op1$$Register;
6915 Register op2 = R0;
6916 Label* L = $labl$$label;
6917 int flag = $cmp$$cmpcode;
6919 switch(flag) {
6920 case 0x01: //equal
6921 __ beq_long(op1, op2, *L);
6922 break;
6923 case 0x02: //not_equal
6924 __ bne_long(op1, op2, *L);
6925 break;
6926 default:
6927 Unimplemented();
6928 }
6929 %}
6931 ins_pc_relative(1);
6932 ins_pipe( pipe_alu_branch );
6933 %}
6935 instruct branchConN2P_zero_long(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
6936 match(If cmp (CmpP (DecodeN op1) zero));
6937 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6938 effect(USE labl);
6940 ins_cost(180);
6941 format %{ "b$cmp $op1, R0, $labl #@branchConN2P_zero_long" %}
6943 ins_encode %{
6944 Register op1 = $op1$$Register;
6945 Register op2 = R0;
6946 Label* L = $labl$$label;
6947 int flag = $cmp$$cmpcode;
6949 switch(flag)
6950 {
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 %}
6962 ins_pc_relative(1);
6963 ins_pipe( pipe_alu_branch );
6964 %}
6967 instruct branchConP_long(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
6968 match(If cmp (CmpP op1 op2));
6969 // predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
6970 effect(USE labl);
6972 ins_cost(200);
6973 format %{ "b$cmp $op1, $op2, $labl #@branchConP_long" %}
6975 ins_encode %{
6976 Register op1 = $op1$$Register;
6977 Register op2 = $op2$$Register;
6978 Label* L = $labl$$label;
6979 int flag = $cmp$$cmpcode;
6981 switch(flag) {
6982 case 0x01: //equal
6983 __ beq_long(op1, op2, *L);
6984 break;
6985 case 0x02: //not_equal
6986 __ bne_long(op1, op2, *L);
6987 break;
6988 case 0x03: //above
6989 __ sltu(AT, op2, op1);
6990 __ bne_long(R0, AT, *L);
6991 break;
6992 case 0x04: //above_equal
6993 __ sltu(AT, op1, op2);
6994 __ beq_long(AT, R0, *L);
6995 break;
6996 case 0x05: //below
6997 __ sltu(AT, op1, op2);
6998 __ bne_long(R0, AT, *L);
6999 break;
7000 case 0x06: //below_equal
7001 __ sltu(AT, op2, op1);
7002 __ beq_long(AT, R0, *L);
7003 break;
7004 default:
7005 Unimplemented();
7006 }
7007 %}
7009 ins_pc_relative(1);
7010 ins_pipe( pipe_alu_branch );
7011 %}
7013 instruct cmpN_null_branch_long(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
7014 match(If cmp (CmpN op1 null));
7015 effect(USE labl);
7017 ins_cost(180);
7018 format %{ "CMP $op1,0\t! compressed ptr\n\t"
7019 "BP$cmp $labl @ cmpN_null_branch_long" %}
7020 ins_encode %{
7021 Register op1 = $op1$$Register;
7022 Register op2 = R0;
7023 Label* L = $labl$$label;
7024 int flag = $cmp$$cmpcode;
7026 switch(flag) {
7027 case 0x01: //equal
7028 __ beq_long(op1, op2, *L);
7029 break;
7030 case 0x02: //not_equal
7031 __ bne_long(op1, op2, *L);
7032 break;
7033 default:
7034 Unimplemented();
7035 }
7036 %}
7037 //TODO: pipe_branchP or create pipe_branchN LEE
7038 ins_pc_relative(1);
7039 ins_pipe( pipe_alu_branch );
7040 %}
7042 instruct cmpN_reg_branch_long(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
7043 match(If cmp (CmpN op1 op2));
7044 effect(USE labl);
7046 ins_cost(180);
7047 format %{ "CMP $op1,$op2\t! compressed ptr\n\t"
7048 "BP$cmp $labl @ cmpN_reg_branch_long" %}
7049 ins_encode %{
7050 Register op1_reg = $op1$$Register;
7051 Register op2_reg = $op2$$Register;
7052 Label* L = $labl$$label;
7053 int flag = $cmp$$cmpcode;
7055 switch(flag) {
7056 case 0x01: //equal
7057 __ beq_long(op1_reg, op2_reg, *L);
7058 break;
7059 case 0x02: //not_equal
7060 __ bne_long(op1_reg, op2_reg, *L);
7061 break;
7062 case 0x03: //above
7063 __ sltu(AT, op2_reg, op1_reg);
7064 __ bne_long(R0, AT, *L);
7065 break;
7066 case 0x04: //above_equal
7067 __ sltu(AT, op1_reg, op2_reg);
7068 __ beq_long(AT, R0, *L);
7069 break;
7070 case 0x05: //below
7071 __ sltu(AT, op1_reg, op2_reg);
7072 __ bne_long(R0, AT, *L);
7073 break;
7074 case 0x06: //below_equal
7075 __ sltu(AT, op2_reg, op1_reg);
7076 __ beq_long(AT, R0, *L);
7077 break;
7078 default:
7079 Unimplemented();
7080 }
7081 %}
7082 ins_pc_relative(1);
7083 ins_pipe( pipe_alu_branch );
7084 %}
7086 instruct branchConIU_reg_reg_long(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
7087 match( If cmp (CmpU src1 src2) );
7088 effect(USE labl);
7089 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_reg_long" %}
7091 ins_encode %{
7092 Register op1 = $src1$$Register;
7093 Register op2 = $src2$$Register;
7094 Label* L = $labl$$label;
7095 int flag = $cmp$$cmpcode;
7097 switch(flag) {
7098 case 0x01: //equal
7099 __ beq_long(op1, op2, *L);
7100 break;
7101 case 0x02: //not_equal
7102 __ bne_long(op1, op2, *L);
7103 break;
7104 case 0x03: //above
7105 __ sltu(AT, op2, op1);
7106 __ bne_long(AT, R0, *L);
7107 break;
7108 case 0x04: //above_equal
7109 __ sltu(AT, op1, op2);
7110 __ beq_long(AT, R0, *L);
7111 break;
7112 case 0x05: //below
7113 __ sltu(AT, op1, op2);
7114 __ bne_long(AT, R0, *L);
7115 break;
7116 case 0x06: //below_equal
7117 __ sltu(AT, op2, op1);
7118 __ beq_long(AT, R0, *L);
7119 break;
7120 default:
7121 Unimplemented();
7122 }
7123 %}
7125 ins_pc_relative(1);
7126 ins_pipe( pipe_alu_branch );
7127 %}
7130 instruct branchConIU_reg_imm_long(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
7131 match( If cmp (CmpU src1 src2) );
7132 effect(USE labl);
7133 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_imm_long" %}
7135 ins_encode %{
7136 Register op1 = $src1$$Register;
7137 int val = $src2$$constant;
7138 Label* L = $labl$$label;
7139 int flag = $cmp$$cmpcode;
7141 __ move(AT, val);
7142 switch(flag) {
7143 case 0x01: //equal
7144 __ beq_long(op1, AT, *L);
7145 break;
7146 case 0x02: //not_equal
7147 __ bne_long(op1, AT, *L);
7148 break;
7149 case 0x03: //above
7150 __ sltu(AT, AT, op1);
7151 __ bne_long(R0, AT, *L);
7152 break;
7153 case 0x04: //above_equal
7154 __ sltu(AT, op1, AT);
7155 __ beq_long(AT, R0, *L);
7156 break;
7157 case 0x05: //below
7158 __ sltu(AT, op1, AT);
7159 __ bne_long(R0, AT, *L);
7160 break;
7161 case 0x06: //below_equal
7162 __ sltu(AT, AT, op1);
7163 __ beq_long(AT, R0, *L);
7164 break;
7165 default:
7166 Unimplemented();
7167 }
7168 %}
7170 ins_pc_relative(1);
7171 ins_pipe( pipe_alu_branch );
7172 %}
7174 instruct branchConI_reg_reg_long(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
7175 match( If cmp (CmpI src1 src2) );
7176 effect(USE labl);
7177 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_reg_long" %}
7179 ins_encode %{
7180 Register op1 = $src1$$Register;
7181 Register op2 = $src2$$Register;
7182 Label* L = $labl$$label;
7183 int flag = $cmp$$cmpcode;
7185 switch(flag) {
7186 case 0x01: //equal
7187 __ beq_long(op1, op2, *L);
7188 break;
7189 case 0x02: //not_equal
7190 __ bne_long(op1, op2, *L);
7191 break;
7192 case 0x03: //above
7193 __ slt(AT, op2, op1);
7194 __ bne_long(R0, AT, *L);
7195 break;
7196 case 0x04: //above_equal
7197 __ slt(AT, op1, op2);
7198 __ beq_long(AT, R0, *L);
7199 break;
7200 case 0x05: //below
7201 __ slt(AT, op1, op2);
7202 __ bne_long(R0, AT, *L);
7203 break;
7204 case 0x06: //below_equal
7205 __ slt(AT, op2, op1);
7206 __ beq_long(AT, R0, *L);
7207 break;
7208 default:
7209 Unimplemented();
7210 }
7211 %}
7213 ins_pc_relative(1);
7214 ins_pipe( pipe_alu_branch );
7215 %}
7217 instruct branchConI_reg_imm0_long(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
7218 match( If cmp (CmpI src1 src2) );
7219 effect(USE labl);
7220 ins_cost(170);
7221 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm0_long" %}
7223 ins_encode %{
7224 Register op1 = $src1$$Register;
7225 Label* L = $labl$$label;
7226 int flag = $cmp$$cmpcode;
7228 switch(flag) {
7229 case 0x01: //equal
7230 __ beq_long(op1, R0, *L);
7231 break;
7232 case 0x02: //not_equal
7233 __ bne_long(op1, R0, *L);
7234 break;
7235 case 0x03: //greater
7236 __ slt(AT, R0, op1);
7237 __ bne_long(R0, AT, *L);
7238 break;
7239 case 0x04: //greater_equal
7240 __ slt(AT, op1, R0);
7241 __ beq_long(AT, R0, *L);
7242 break;
7243 case 0x05: //less
7244 __ slt(AT, op1, R0);
7245 __ bne_long(R0, AT, *L);
7246 break;
7247 case 0x06: //less_equal
7248 __ slt(AT, R0, op1);
7249 __ beq_long(AT, R0, *L);
7250 break;
7251 default:
7252 Unimplemented();
7253 }
7254 %}
7256 ins_pc_relative(1);
7257 ins_pipe( pipe_alu_branch );
7258 %}
7260 instruct branchConI_reg_imm_long(cmpOp cmp, mRegI src1, immI src2, label labl) %{
7261 match( If cmp (CmpI src1 src2) );
7262 effect(USE labl);
7263 ins_cost(200);
7264 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm_long" %}
7266 ins_encode %{
7267 Register op1 = $src1$$Register;
7268 int val = $src2$$constant;
7269 Label* L = $labl$$label;
7270 int flag = $cmp$$cmpcode;
7272 __ move(AT, val);
7273 switch(flag) {
7274 case 0x01: //equal
7275 __ beq_long(op1, AT, *L);
7276 break;
7277 case 0x02: //not_equal
7278 __ bne_long(op1, AT, *L);
7279 break;
7280 case 0x03: //greater
7281 __ slt(AT, AT, op1);
7282 __ bne_long(R0, AT, *L);
7283 break;
7284 case 0x04: //greater_equal
7285 __ slt(AT, op1, AT);
7286 __ beq_long(AT, R0, *L);
7287 break;
7288 case 0x05: //less
7289 __ slt(AT, op1, AT);
7290 __ bne_long(R0, AT, *L);
7291 break;
7292 case 0x06: //less_equal
7293 __ slt(AT, AT, op1);
7294 __ beq_long(AT, R0, *L);
7295 break;
7296 default:
7297 Unimplemented();
7298 }
7299 %}
7301 ins_pc_relative(1);
7302 ins_pipe( pipe_alu_branch );
7303 %}
7305 instruct branchConIU_reg_imm0_long(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
7306 match( If cmp (CmpU src1 zero) );
7307 effect(USE labl);
7308 format %{ "BR$cmp $src1, zero, $labl #@branchConIU_reg_imm0_long" %}
7310 ins_encode %{
7311 Register op1 = $src1$$Register;
7312 Label* L = $labl$$label;
7313 int flag = $cmp$$cmpcode;
7315 switch(flag) {
7316 case 0x01: //equal
7317 __ beq_long(op1, R0, *L);
7318 break;
7319 case 0x02: //not_equal
7320 __ bne_long(op1, R0, *L);
7321 break;
7322 case 0x03: //above
7323 __ bne_long(R0, op1, *L);
7324 break;
7325 case 0x04: //above_equal
7326 __ beq_long(R0, R0, *L);
7327 break;
7328 case 0x05: //below
7329 return;
7330 break;
7331 case 0x06: //below_equal
7332 __ beq_long(op1, R0, *L);
7333 break;
7334 default:
7335 Unimplemented();
7336 }
7337 %}
7339 ins_pc_relative(1);
7340 ins_pipe( pipe_alu_branch );
7341 %}
7344 instruct branchConIU_reg_immI16_long(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
7345 match( If cmp (CmpU src1 src2) );
7346 effect(USE labl);
7347 ins_cost(180);
7348 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_immI16_long" %}
7350 ins_encode %{
7351 Register op1 = $src1$$Register;
7352 int val = $src2$$constant;
7353 Label* L = $labl$$label;
7354 int flag = $cmp$$cmpcode;
7356 switch(flag) {
7357 case 0x01: //equal
7358 __ move(AT, val);
7359 __ beq_long(op1, AT, *L);
7360 break;
7361 case 0x02: //not_equal
7362 __ move(AT, val);
7363 __ bne_long(op1, AT, *L);
7364 break;
7365 case 0x03: //above
7366 __ move(AT, val);
7367 __ sltu(AT, AT, op1);
7368 __ bne_long(R0, AT, *L);
7369 break;
7370 case 0x04: //above_equal
7371 __ sltiu(AT, op1, val);
7372 __ beq_long(AT, R0, *L);
7373 break;
7374 case 0x05: //below
7375 __ sltiu(AT, op1, val);
7376 __ bne_long(R0, AT, *L);
7377 break;
7378 case 0x06: //below_equal
7379 __ move(AT, val);
7380 __ sltu(AT, AT, op1);
7381 __ beq_long(AT, R0, *L);
7382 break;
7383 default:
7384 Unimplemented();
7385 }
7386 %}
7388 ins_pc_relative(1);
7389 ins_pipe( pipe_alu_branch );
7390 %}
7393 instruct branchConL_regL_regL_long(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
7394 match( If cmp (CmpL src1 src2) );
7395 effect(USE labl);
7396 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_regL_long" %}
7397 ins_cost(250);
7399 ins_encode %{
7400 Register opr1_reg = as_Register($src1$$reg);
7401 Register opr2_reg = as_Register($src2$$reg);
7403 Label* target = $labl$$label;
7404 int flag = $cmp$$cmpcode;
7406 switch(flag) {
7407 case 0x01: //equal
7408 __ beq_long(opr1_reg, opr2_reg, *target);
7409 break;
7411 case 0x02: //not_equal
7412 __ bne_long(opr1_reg, opr2_reg, *target);
7413 break;
7415 case 0x03: //greater
7416 __ slt(AT, opr2_reg, opr1_reg);
7417 __ bne_long(AT, R0, *target);
7418 break;
7420 case 0x04: //greater_equal
7421 __ slt(AT, opr1_reg, opr2_reg);
7422 __ beq_long(AT, R0, *target);
7423 break;
7425 case 0x05: //less
7426 __ slt(AT, opr1_reg, opr2_reg);
7427 __ bne_long(AT, R0, *target);
7428 break;
7430 case 0x06: //less_equal
7431 __ slt(AT, opr2_reg, opr1_reg);
7432 __ beq_long(AT, R0, *target);
7433 break;
7435 default:
7436 Unimplemented();
7437 }
7438 %}
7441 ins_pc_relative(1);
7442 ins_pipe( pipe_alu_branch );
7443 %}
7445 instruct branchConL_regL_immL0_long(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
7446 match( If cmp (CmpL src1 zero) );
7447 effect(USE labl);
7448 format %{ "BR$cmp $src1, zero, $labl #@branchConL_regL_immL0_long" %}
7449 ins_cost(150);
7451 ins_encode %{
7452 Register opr1_reg = as_Register($src1$$reg);
7453 Register opr2_reg = R0;
7455 Label* target = $labl$$label;
7456 int flag = $cmp$$cmpcode;
7458 switch(flag) {
7459 case 0x01: //equal
7460 __ beq_long(opr1_reg, opr2_reg, *target);
7461 break;
7463 case 0x02: //not_equal
7464 __ bne_long(opr1_reg, opr2_reg, *target);
7465 break;
7467 case 0x03: //greater
7468 __ slt(AT, opr2_reg, opr1_reg);
7469 __ bne_long(AT, R0, *target);
7470 break;
7472 case 0x04: //greater_equal
7473 __ slt(AT, opr1_reg, opr2_reg);
7474 __ beq_long(AT, R0, *target);
7475 break;
7477 case 0x05: //less
7478 __ slt(AT, opr1_reg, opr2_reg);
7479 __ bne_long(AT, R0, *target);
7480 break;
7482 case 0x06: //less_equal
7483 __ slt(AT, opr2_reg, opr1_reg);
7484 __ beq_long(AT, R0, *target);
7485 break;
7487 default:
7488 Unimplemented();
7489 }
7490 %}
7493 ins_pc_relative(1);
7494 ins_pipe( pipe_alu_branch );
7495 %}
7497 instruct branchConL_regL_immL_long(cmpOp cmp, mRegL src1, immL src2, label labl) %{
7498 match( If cmp (CmpL src1 src2) );
7499 effect(USE labl);
7500 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_immL_long" %}
7501 ins_cost(180);
7503 ins_encode %{
7504 Register opr1_reg = as_Register($src1$$reg);
7505 Register opr2_reg = AT;
7507 Label* target = $labl$$label;
7508 int flag = $cmp$$cmpcode;
7510 __ set64(opr2_reg, $src2$$constant);
7512 switch(flag) {
7513 case 0x01: //equal
7514 __ beq_long(opr1_reg, opr2_reg, *target);
7515 break;
7517 case 0x02: //not_equal
7518 __ bne_long(opr1_reg, opr2_reg, *target);
7519 break;
7521 case 0x03: //greater
7522 __ slt(AT, opr2_reg, opr1_reg);
7523 __ bne_long(AT, R0, *target);
7524 break;
7526 case 0x04: //greater_equal
7527 __ slt(AT, opr1_reg, opr2_reg);
7528 __ beq_long(AT, R0, *target);
7529 break;
7531 case 0x05: //less
7532 __ slt(AT, opr1_reg, opr2_reg);
7533 __ bne_long(AT, R0, *target);
7534 break;
7536 case 0x06: //less_equal
7537 __ slt(AT, opr2_reg, opr1_reg);
7538 __ beq_long(AT, R0, *target);
7539 break;
7541 default:
7542 Unimplemented();
7543 }
7544 %}
7547 ins_pc_relative(1);
7548 ins_pipe( pipe_alu_branch );
7549 %}
7552 //FIXME
7553 instruct branchConF_reg_reg_long(cmpOp cmp, regF src1, regF src2, label labl) %{
7554 match( If cmp (CmpF src1 src2) );
7555 effect(USE labl);
7556 format %{ "BR$cmp $src1, $src2, $labl #@branchConF_reg_reg_long" %}
7558 ins_encode %{
7559 FloatRegister reg_op1 = $src1$$FloatRegister;
7560 FloatRegister reg_op2 = $src2$$FloatRegister;
7561 Label* L = $labl$$label;
7562 int flag = $cmp$$cmpcode;
7564 switch(flag) {
7565 case 0x01: //equal
7566 __ c_eq_s(reg_op1, reg_op2);
7567 __ bc1t_long(*L);
7568 break;
7569 case 0x02: //not_equal
7570 __ c_eq_s(reg_op1, reg_op2);
7571 __ bc1f_long(*L);
7572 break;
7573 case 0x03: //greater
7574 __ c_ule_s(reg_op1, reg_op2);
7575 __ bc1f_long(*L);
7576 break;
7577 case 0x04: //greater_equal
7578 __ c_ult_s(reg_op1, reg_op2);
7579 __ bc1f_long(*L);
7580 break;
7581 case 0x05: //less
7582 __ c_ult_s(reg_op1, reg_op2);
7583 __ bc1t_long(*L);
7584 break;
7585 case 0x06: //less_equal
7586 __ c_ule_s(reg_op1, reg_op2);
7587 __ bc1t_long(*L);
7588 break;
7589 default:
7590 Unimplemented();
7591 }
7592 %}
7594 ins_pc_relative(1);
7595 ins_pipe(pipe_slow);
7596 %}
7598 instruct branchConD_reg_reg_long(cmpOp cmp, regD src1, regD src2, label labl) %{
7599 match( If cmp (CmpD src1 src2) );
7600 effect(USE labl);
7601 format %{ "BR$cmp $src1, $src2, $labl #@branchConD_reg_reg_long" %}
7603 ins_encode %{
7604 FloatRegister reg_op1 = $src1$$FloatRegister;
7605 FloatRegister reg_op2 = $src2$$FloatRegister;
7606 Label* L = $labl$$label;
7607 int flag = $cmp$$cmpcode;
7609 switch(flag) {
7610 case 0x01: //equal
7611 __ c_eq_d(reg_op1, reg_op2);
7612 __ bc1t_long(*L);
7613 break;
7614 case 0x02: //not_equal
7615 // 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.
7616 __ c_eq_d(reg_op1, reg_op2);
7617 __ bc1f_long(*L);
7618 break;
7619 case 0x03: //greater
7620 __ c_ule_d(reg_op1, reg_op2);
7621 __ bc1f_long(*L);
7622 break;
7623 case 0x04: //greater_equal
7624 __ c_ult_d(reg_op1, reg_op2);
7625 __ bc1f_long(*L);
7626 break;
7627 case 0x05: //less
7628 __ c_ult_d(reg_op1, reg_op2);
7629 __ bc1t_long(*L);
7630 break;
7631 case 0x06: //less_equal
7632 __ c_ule_d(reg_op1, reg_op2);
7633 __ bc1t_long(*L);
7634 break;
7635 default:
7636 Unimplemented();
7637 }
7638 %}
7640 ins_pc_relative(1);
7641 ins_pipe(pipe_slow);
7642 %}
7645 // ============================================================================
7646 // Branch Instructions -- short offset versions
7648 // Jump Direct
7649 instruct jmpDir_short(label labl) %{
7650 match(Goto);
7651 effect(USE labl);
7653 ins_cost(300);
7654 format %{ "JMP $labl #@jmpDir_short" %}
7656 ins_encode %{
7657 Label &L = *($labl$$label);
7658 if(&L)
7659 __ b(L);
7660 else
7661 __ b(int(0));
7662 __ delayed()->nop();
7663 %}
7665 ins_pipe( pipe_jump );
7666 ins_pc_relative(1);
7667 ins_short_branch(1);
7668 %}
7670 // Jump Direct Conditional - Label defines a relative address from Jcc+1
7671 instruct jmpLoopEnd_short(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
7672 match(CountedLoopEnd cop (CmpI src1 src2));
7673 effect(USE labl);
7675 ins_cost(300);
7676 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_short" %}
7677 ins_encode %{
7678 Register op1 = $src1$$Register;
7679 Register op2 = $src2$$Register;
7680 Label &L = *($labl$$label);
7681 int flag = $cop$$cmpcode;
7683 switch(flag) {
7684 case 0x01: //equal
7685 if (&L)
7686 __ beq(op1, op2, L);
7687 else
7688 __ beq(op1, op2, (int)0);
7689 break;
7690 case 0x02: //not_equal
7691 if (&L)
7692 __ bne(op1, op2, L);
7693 else
7694 __ bne(op1, op2, (int)0);
7695 break;
7696 case 0x03: //above
7697 __ slt(AT, op2, op1);
7698 if(&L)
7699 __ bne(AT, R0, L);
7700 else
7701 __ bne(AT, R0, (int)0);
7702 break;
7703 case 0x04: //above_equal
7704 __ slt(AT, op1, op2);
7705 if(&L)
7706 __ beq(AT, R0, L);
7707 else
7708 __ beq(AT, R0, (int)0);
7709 break;
7710 case 0x05: //below
7711 __ slt(AT, op1, op2);
7712 if(&L)
7713 __ bne(AT, R0, L);
7714 else
7715 __ bne(AT, R0, (int)0);
7716 break;
7717 case 0x06: //below_equal
7718 __ slt(AT, op2, op1);
7719 if(&L)
7720 __ beq(AT, R0, L);
7721 else
7722 __ beq(AT, R0, (int)0);
7723 break;
7724 default:
7725 Unimplemented();
7726 }
7727 __ delayed()->nop();
7728 %}
7729 ins_pipe( pipe_jump );
7730 ins_pc_relative(1);
7731 ins_short_branch(1);
7732 %}
7734 instruct jmpLoopEnd_reg_immI_short(cmpOp cop, mRegI src1, immI src2, label labl) %{
7735 match(CountedLoopEnd cop (CmpI src1 src2));
7736 effect(USE labl);
7738 ins_cost(300);
7739 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_immI_short" %}
7740 ins_encode %{
7741 Register op1 = $src1$$Register;
7742 Register op2 = AT;
7743 Label &L = *($labl$$label);
7744 int flag = $cop$$cmpcode;
7746 __ move(op2, $src2$$constant);
7748 switch(flag) {
7749 case 0x01: //equal
7750 if (&L)
7751 __ beq(op1, op2, L);
7752 else
7753 __ beq(op1, op2, (int)0);
7754 break;
7755 case 0x02: //not_equal
7756 if (&L)
7757 __ bne(op1, op2, L);
7758 else
7759 __ bne(op1, op2, (int)0);
7760 break;
7761 case 0x03: //above
7762 __ slt(AT, op2, op1);
7763 if(&L)
7764 __ bne(AT, R0, L);
7765 else
7766 __ bne(AT, R0, (int)0);
7767 break;
7768 case 0x04: //above_equal
7769 __ slt(AT, op1, op2);
7770 if(&L)
7771 __ beq(AT, R0, L);
7772 else
7773 __ beq(AT, R0, (int)0);
7774 break;
7775 case 0x05: //below
7776 __ slt(AT, op1, op2);
7777 if(&L)
7778 __ bne(AT, R0, L);
7779 else
7780 __ bne(AT, R0, (int)0);
7781 break;
7782 case 0x06: //below_equal
7783 __ slt(AT, op2, op1);
7784 if(&L)
7785 __ beq(AT, R0, L);
7786 else
7787 __ beq(AT, R0, (int)0);
7788 break;
7789 default:
7790 Unimplemented();
7791 }
7792 __ delayed()->nop();
7793 %}
7794 ins_pipe( pipe_jump );
7795 ins_pc_relative(1);
7796 ins_short_branch(1);
7797 %}
7800 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
7801 instruct jmpCon_flags_short(cmpOp cop, FlagsReg cr, label labl) %{
7802 match(If cop cr);
7803 effect(USE labl);
7805 ins_cost(300);
7806 format %{ "J$cop $labl #mips uses AT as eflag @jmpCon_flags_short" %}
7808 ins_encode %{
7809 Label &L = *($labl$$label);
7810 switch($cop$$cmpcode) {
7811 case 0x01: //equal
7812 if (&L)
7813 __ bne(AT, R0, L);
7814 else
7815 __ bne(AT, R0, (int)0);
7816 break;
7817 case 0x02: //not equal
7818 if (&L)
7819 __ beq(AT, R0, L);
7820 else
7821 __ beq(AT, R0, (int)0);
7822 break;
7823 default:
7824 Unimplemented();
7825 }
7826 __ delayed()->nop();
7827 %}
7829 ins_pipe( pipe_jump );
7830 ins_pc_relative(1);
7831 ins_short_branch(1);
7832 %}
7834 // Conditional jumps
7835 instruct branchConP_zero_short(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
7836 match(If cmp (CmpP op1 zero));
7837 effect(USE labl);
7839 ins_cost(180);
7840 format %{ "b$cmp $op1, R0, $labl #@branchConP_zero_short" %}
7842 ins_encode %{
7843 Register op1 = $op1$$Register;
7844 Register op2 = R0;
7845 Label &L = *($labl$$label);
7846 int flag = $cmp$$cmpcode;
7848 switch(flag) {
7849 case 0x01: //equal
7850 if (&L)
7851 __ beq(op1, op2, L);
7852 else
7853 __ beq(op1, op2, (int)0);
7854 break;
7855 case 0x02: //not_equal
7856 if (&L)
7857 __ bne(op1, op2, L);
7858 else
7859 __ bne(op1, op2, (int)0);
7860 break;
7861 default:
7862 Unimplemented();
7863 }
7864 __ delayed()->nop();
7865 %}
7867 ins_pc_relative(1);
7868 ins_pipe( pipe_alu_branch );
7869 ins_short_branch(1);
7870 %}
7872 instruct branchConN2P_zero_short(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
7873 match(If cmp (CmpP (DecodeN op1) zero));
7874 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
7875 effect(USE labl);
7877 ins_cost(180);
7878 format %{ "b$cmp $op1, R0, $labl #@branchConN2P_zero_short" %}
7880 ins_encode %{
7881 Register op1 = $op1$$Register;
7882 Register op2 = R0;
7883 Label &L = *($labl$$label);
7884 int flag = $cmp$$cmpcode;
7886 switch(flag)
7887 {
7888 case 0x01: //equal
7889 if (&L)
7890 __ beq(op1, op2, L);
7891 else
7892 __ beq(op1, op2, (int)0);
7893 break;
7894 case 0x02: //not_equal
7895 if (&L)
7896 __ bne(op1, op2, L);
7897 else
7898 __ bne(op1, op2, (int)0);
7899 break;
7900 default:
7901 Unimplemented();
7902 }
7903 __ delayed()->nop();
7904 %}
7906 ins_pc_relative(1);
7907 ins_pipe( pipe_alu_branch );
7908 ins_short_branch(1);
7909 %}
7912 instruct branchConP_short(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
7913 match(If cmp (CmpP op1 op2));
7914 // predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
7915 effect(USE labl);
7917 ins_cost(200);
7918 format %{ "b$cmp $op1, $op2, $labl #@branchConP_short" %}
7920 ins_encode %{
7921 Register op1 = $op1$$Register;
7922 Register op2 = $op2$$Register;
7923 Label &L = *($labl$$label);
7924 int flag = $cmp$$cmpcode;
7926 switch(flag) {
7927 case 0x01: //equal
7928 if (&L)
7929 __ beq(op1, op2, L);
7930 else
7931 __ beq(op1, op2, (int)0);
7932 break;
7933 case 0x02: //not_equal
7934 if (&L)
7935 __ bne(op1, op2, L);
7936 else
7937 __ bne(op1, op2, (int)0);
7938 break;
7939 case 0x03: //above
7940 __ sltu(AT, op2, op1);
7941 if(&L)
7942 __ bne(R0, AT, L);
7943 else
7944 __ bne(R0, AT, (int)0);
7945 break;
7946 case 0x04: //above_equal
7947 __ sltu(AT, op1, op2);
7948 if(&L)
7949 __ beq(AT, R0, L);
7950 else
7951 __ beq(AT, R0, (int)0);
7952 break;
7953 case 0x05: //below
7954 __ sltu(AT, op1, op2);
7955 if(&L)
7956 __ bne(R0, AT, L);
7957 else
7958 __ bne(R0, AT, (int)0);
7959 break;
7960 case 0x06: //below_equal
7961 __ sltu(AT, op2, op1);
7962 if(&L)
7963 __ beq(AT, R0, L);
7964 else
7965 __ beq(AT, R0, (int)0);
7966 break;
7967 default:
7968 Unimplemented();
7969 }
7970 __ delayed()->nop();
7971 %}
7973 ins_pc_relative(1);
7974 ins_pipe( pipe_alu_branch );
7975 ins_short_branch(1);
7976 %}
7978 instruct cmpN_null_branch_short(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
7979 match(If cmp (CmpN op1 null));
7980 effect(USE labl);
7982 ins_cost(180);
7983 format %{ "CMP $op1,0\t! compressed ptr\n\t"
7984 "BP$cmp $labl @ cmpN_null_branch_short" %}
7985 ins_encode %{
7986 Register op1 = $op1$$Register;
7987 Register op2 = R0;
7988 Label &L = *($labl$$label);
7989 int flag = $cmp$$cmpcode;
7991 switch(flag) {
7992 case 0x01: //equal
7993 if (&L)
7994 __ beq(op1, op2, L);
7995 else
7996 __ beq(op1, op2, (int)0);
7997 break;
7998 case 0x02: //not_equal
7999 if (&L)
8000 __ bne(op1, op2, L);
8001 else
8002 __ bne(op1, op2, (int)0);
8003 break;
8004 default:
8005 Unimplemented();
8006 }
8007 __ delayed()->nop();
8008 %}
8009 //TODO: pipe_branchP or create pipe_branchN LEE
8010 ins_pc_relative(1);
8011 ins_pipe( pipe_alu_branch );
8012 ins_short_branch(1);
8013 %}
8015 instruct cmpN_reg_branch_short(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
8016 match(If cmp (CmpN op1 op2));
8017 effect(USE labl);
8019 ins_cost(180);
8020 format %{ "CMP $op1,$op2\t! compressed ptr\n\t"
8021 "BP$cmp $labl @ cmpN_reg_branch_short" %}
8022 ins_encode %{
8023 Register op1_reg = $op1$$Register;
8024 Register op2_reg = $op2$$Register;
8025 Label &L = *($labl$$label);
8026 int flag = $cmp$$cmpcode;
8028 switch(flag) {
8029 case 0x01: //equal
8030 if (&L)
8031 __ beq(op1_reg, op2_reg, L);
8032 else
8033 __ beq(op1_reg, op2_reg, (int)0);
8034 break;
8035 case 0x02: //not_equal
8036 if (&L)
8037 __ bne(op1_reg, op2_reg, L);
8038 else
8039 __ bne(op1_reg, op2_reg, (int)0);
8040 break;
8041 case 0x03: //above
8042 __ sltu(AT, op2_reg, op1_reg);
8043 if(&L)
8044 __ bne(R0, AT, L);
8045 else
8046 __ bne(R0, AT, (int)0);
8047 break;
8048 case 0x04: //above_equal
8049 __ sltu(AT, op1_reg, op2_reg);
8050 if(&L)
8051 __ beq(AT, R0, L);
8052 else
8053 __ beq(AT, R0, (int)0);
8054 break;
8055 case 0x05: //below
8056 __ sltu(AT, op1_reg, op2_reg);
8057 if(&L)
8058 __ bne(R0, AT, L);
8059 else
8060 __ bne(R0, AT, (int)0);
8061 break;
8062 case 0x06: //below_equal
8063 __ sltu(AT, op2_reg, op1_reg);
8064 if(&L)
8065 __ beq(AT, R0, L);
8066 else
8067 __ beq(AT, R0, (int)0);
8068 break;
8069 default:
8070 Unimplemented();
8071 }
8072 __ delayed()->nop();
8073 %}
8074 ins_pc_relative(1);
8075 ins_pipe( pipe_alu_branch );
8076 ins_short_branch(1);
8077 %}
8079 instruct branchConIU_reg_reg_short(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
8080 match( If cmp (CmpU src1 src2) );
8081 effect(USE labl);
8082 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_reg_short" %}
8084 ins_encode %{
8085 Register op1 = $src1$$Register;
8086 Register op2 = $src2$$Register;
8087 Label &L = *($labl$$label);
8088 int flag = $cmp$$cmpcode;
8090 switch(flag) {
8091 case 0x01: //equal
8092 if (&L)
8093 __ beq(op1, op2, L);
8094 else
8095 __ beq(op1, op2, (int)0);
8096 break;
8097 case 0x02: //not_equal
8098 if (&L)
8099 __ bne(op1, op2, L);
8100 else
8101 __ bne(op1, op2, (int)0);
8102 break;
8103 case 0x03: //above
8104 __ sltu(AT, op2, op1);
8105 if(&L)
8106 __ bne(AT, R0, L);
8107 else
8108 __ bne(AT, R0, (int)0);
8109 break;
8110 case 0x04: //above_equal
8111 __ sltu(AT, op1, op2);
8112 if(&L)
8113 __ beq(AT, R0, L);
8114 else
8115 __ beq(AT, R0, (int)0);
8116 break;
8117 case 0x05: //below
8118 __ sltu(AT, op1, op2);
8119 if(&L)
8120 __ bne(AT, R0, L);
8121 else
8122 __ bne(AT, R0, (int)0);
8123 break;
8124 case 0x06: //below_equal
8125 __ sltu(AT, op2, op1);
8126 if(&L)
8127 __ beq(AT, R0, L);
8128 else
8129 __ beq(AT, R0, (int)0);
8130 break;
8131 default:
8132 Unimplemented();
8133 }
8134 __ delayed()->nop();
8135 %}
8137 ins_pc_relative(1);
8138 ins_pipe( pipe_alu_branch );
8139 ins_short_branch(1);
8140 %}
8143 instruct branchConIU_reg_imm_short(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
8144 match( If cmp (CmpU src1 src2) );
8145 effect(USE labl);
8146 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_imm_short" %}
8148 ins_encode %{
8149 Register op1 = $src1$$Register;
8150 int val = $src2$$constant;
8151 Label &L = *($labl$$label);
8152 int flag = $cmp$$cmpcode;
8154 __ move(AT, val);
8155 switch(flag) {
8156 case 0x01: //equal
8157 if (&L)
8158 __ beq(op1, AT, L);
8159 else
8160 __ beq(op1, AT, (int)0);
8161 break;
8162 case 0x02: //not_equal
8163 if (&L)
8164 __ bne(op1, AT, L);
8165 else
8166 __ bne(op1, AT, (int)0);
8167 break;
8168 case 0x03: //above
8169 __ sltu(AT, AT, op1);
8170 if(&L)
8171 __ bne(R0, AT, L);
8172 else
8173 __ bne(R0, AT, (int)0);
8174 break;
8175 case 0x04: //above_equal
8176 __ sltu(AT, op1, AT);
8177 if(&L)
8178 __ beq(AT, R0, L);
8179 else
8180 __ beq(AT, R0, (int)0);
8181 break;
8182 case 0x05: //below
8183 __ sltu(AT, op1, AT);
8184 if(&L)
8185 __ bne(R0, AT, L);
8186 else
8187 __ bne(R0, AT, (int)0);
8188 break;
8189 case 0x06: //below_equal
8190 __ sltu(AT, AT, op1);
8191 if(&L)
8192 __ beq(AT, R0, L);
8193 else
8194 __ beq(AT, R0, (int)0);
8195 break;
8196 default:
8197 Unimplemented();
8198 }
8199 __ delayed()->nop();
8200 %}
8202 ins_pc_relative(1);
8203 ins_pipe( pipe_alu_branch );
8204 ins_short_branch(1);
8205 %}
8207 instruct branchConI_reg_reg_short(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
8208 match( If cmp (CmpI src1 src2) );
8209 effect(USE labl);
8210 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_reg_short" %}
8212 ins_encode %{
8213 Register op1 = $src1$$Register;
8214 Register op2 = $src2$$Register;
8215 Label &L = *($labl$$label);
8216 int flag = $cmp$$cmpcode;
8218 switch(flag) {
8219 case 0x01: //equal
8220 if (&L)
8221 __ beq(op1, op2, L);
8222 else
8223 __ beq(op1, op2, (int)0);
8224 break;
8225 case 0x02: //not_equal
8226 if (&L)
8227 __ bne(op1, op2, L);
8228 else
8229 __ bne(op1, op2, (int)0);
8230 break;
8231 case 0x03: //above
8232 __ slt(AT, op2, op1);
8233 if(&L)
8234 __ bne(R0, AT, L);
8235 else
8236 __ bne(R0, AT, (int)0);
8237 break;
8238 case 0x04: //above_equal
8239 __ slt(AT, op1, op2);
8240 if(&L)
8241 __ beq(AT, R0, L);
8242 else
8243 __ beq(AT, R0, (int)0);
8244 break;
8245 case 0x05: //below
8246 __ slt(AT, op1, op2);
8247 if(&L)
8248 __ bne(R0, AT, L);
8249 else
8250 __ bne(R0, AT, (int)0);
8251 break;
8252 case 0x06: //below_equal
8253 __ slt(AT, op2, op1);
8254 if(&L)
8255 __ beq(AT, R0, L);
8256 else
8257 __ beq(AT, R0, (int)0);
8258 break;
8259 default:
8260 Unimplemented();
8261 }
8262 __ delayed()->nop();
8263 %}
8265 ins_pc_relative(1);
8266 ins_pipe( pipe_alu_branch );
8267 ins_short_branch(1);
8268 %}
8270 instruct branchConI_reg_imm0_short(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
8271 match( If cmp (CmpI src1 src2) );
8272 effect(USE labl);
8273 ins_cost(170);
8274 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm0_short" %}
8276 ins_encode %{
8277 Register op1 = $src1$$Register;
8278 Label &L = *($labl$$label);
8279 int flag = $cmp$$cmpcode;
8281 switch(flag) {
8282 case 0x01: //equal
8283 if (&L)
8284 __ beq(op1, R0, L);
8285 else
8286 __ beq(op1, R0, (int)0);
8287 break;
8288 case 0x02: //not_equal
8289 if (&L)
8290 __ bne(op1, R0, L);
8291 else
8292 __ bne(op1, R0, (int)0);
8293 break;
8294 case 0x03: //greater
8295 if(&L)
8296 __ bgtz(op1, L);
8297 else
8298 __ bgtz(op1, (int)0);
8299 break;
8300 case 0x04: //greater_equal
8301 if(&L)
8302 __ bgez(op1, L);
8303 else
8304 __ bgez(op1, (int)0);
8305 break;
8306 case 0x05: //less
8307 if(&L)
8308 __ bltz(op1, L);
8309 else
8310 __ bltz(op1, (int)0);
8311 break;
8312 case 0x06: //less_equal
8313 if(&L)
8314 __ blez(op1, L);
8315 else
8316 __ blez(op1, (int)0);
8317 break;
8318 default:
8319 Unimplemented();
8320 }
8321 __ delayed()->nop();
8322 %}
8324 ins_pc_relative(1);
8325 ins_pipe( pipe_alu_branch );
8326 ins_short_branch(1);
8327 %}
8330 instruct branchConI_reg_imm_short(cmpOp cmp, mRegI src1, immI src2, label labl) %{
8331 match( If cmp (CmpI src1 src2) );
8332 effect(USE labl);
8333 ins_cost(200);
8334 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm_short" %}
8336 ins_encode %{
8337 Register op1 = $src1$$Register;
8338 int val = $src2$$constant;
8339 Label &L = *($labl$$label);
8340 int flag = $cmp$$cmpcode;
8342 __ move(AT, val);
8343 switch(flag) {
8344 case 0x01: //equal
8345 if (&L)
8346 __ beq(op1, AT, L);
8347 else
8348 __ beq(op1, AT, (int)0);
8349 break;
8350 case 0x02: //not_equal
8351 if (&L)
8352 __ bne(op1, AT, L);
8353 else
8354 __ bne(op1, AT, (int)0);
8355 break;
8356 case 0x03: //greater
8357 __ slt(AT, AT, op1);
8358 if(&L)
8359 __ bne(R0, AT, L);
8360 else
8361 __ bne(R0, AT, (int)0);
8362 break;
8363 case 0x04: //greater_equal
8364 __ slt(AT, op1, AT);
8365 if(&L)
8366 __ beq(AT, R0, L);
8367 else
8368 __ beq(AT, R0, (int)0);
8369 break;
8370 case 0x05: //less
8371 __ slt(AT, op1, AT);
8372 if(&L)
8373 __ bne(R0, AT, L);
8374 else
8375 __ bne(R0, AT, (int)0);
8376 break;
8377 case 0x06: //less_equal
8378 __ slt(AT, AT, op1);
8379 if(&L)
8380 __ beq(AT, R0, L);
8381 else
8382 __ beq(AT, R0, (int)0);
8383 break;
8384 default:
8385 Unimplemented();
8386 }
8387 __ delayed()->nop();
8388 %}
8390 ins_pc_relative(1);
8391 ins_pipe( pipe_alu_branch );
8392 ins_short_branch(1);
8393 %}
8395 instruct branchConIU_reg_imm0_short(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
8396 match( If cmp (CmpU src1 zero) );
8397 effect(USE labl);
8398 format %{ "BR$cmp $src1, zero, $labl #@branchConIU_reg_imm0_short" %}
8400 ins_encode %{
8401 Register op1 = $src1$$Register;
8402 Label &L = *($labl$$label);
8403 int flag = $cmp$$cmpcode;
8405 switch(flag) {
8406 case 0x01: //equal
8407 if (&L)
8408 __ beq(op1, R0, L);
8409 else
8410 __ beq(op1, R0, (int)0);
8411 break;
8412 case 0x02: //not_equal
8413 if (&L)
8414 __ bne(op1, R0, L);
8415 else
8416 __ bne(op1, R0, (int)0);
8417 break;
8418 case 0x03: //above
8419 if(&L)
8420 __ bne(R0, op1, L);
8421 else
8422 __ bne(R0, op1, (int)0);
8423 break;
8424 case 0x04: //above_equal
8425 if(&L)
8426 __ beq(R0, R0, L);
8427 else
8428 __ beq(R0, R0, (int)0);
8429 break;
8430 case 0x05: //below
8431 return;
8432 break;
8433 case 0x06: //below_equal
8434 if(&L)
8435 __ beq(op1, R0, L);
8436 else
8437 __ beq(op1, R0, (int)0);
8438 break;
8439 default:
8440 Unimplemented();
8441 }
8442 __ delayed()->nop();
8443 %}
8445 ins_pc_relative(1);
8446 ins_pipe( pipe_alu_branch );
8447 ins_short_branch(1);
8448 %}
8451 instruct branchConIU_reg_immI16_short(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
8452 match( If cmp (CmpU src1 src2) );
8453 effect(USE labl);
8454 ins_cost(180);
8455 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_immI16_short" %}
8457 ins_encode %{
8458 Register op1 = $src1$$Register;
8459 int val = $src2$$constant;
8460 Label &L = *($labl$$label);
8461 int flag = $cmp$$cmpcode;
8463 switch(flag) {
8464 case 0x01: //equal
8465 __ move(AT, val);
8466 if (&L)
8467 __ beq(op1, AT, L);
8468 else
8469 __ beq(op1, AT, (int)0);
8470 break;
8471 case 0x02: //not_equal
8472 __ move(AT, val);
8473 if (&L)
8474 __ bne(op1, AT, L);
8475 else
8476 __ bne(op1, AT, (int)0);
8477 break;
8478 case 0x03: //above
8479 __ move(AT, val);
8480 __ sltu(AT, AT, op1);
8481 if(&L)
8482 __ bne(R0, AT, L);
8483 else
8484 __ bne(R0, AT, (int)0);
8485 break;
8486 case 0x04: //above_equal
8487 __ sltiu(AT, op1, val);
8488 if(&L)
8489 __ beq(AT, R0, L);
8490 else
8491 __ beq(AT, R0, (int)0);
8492 break;
8493 case 0x05: //below
8494 __ sltiu(AT, op1, val);
8495 if(&L)
8496 __ bne(R0, AT, L);
8497 else
8498 __ bne(R0, AT, (int)0);
8499 break;
8500 case 0x06: //below_equal
8501 __ move(AT, val);
8502 __ sltu(AT, AT, op1);
8503 if(&L)
8504 __ beq(AT, R0, L);
8505 else
8506 __ beq(AT, R0, (int)0);
8507 break;
8508 default:
8509 Unimplemented();
8510 }
8511 __ delayed()->nop();
8512 %}
8514 ins_pc_relative(1);
8515 ins_pipe( pipe_alu_branch );
8516 ins_short_branch(1);
8517 %}
8520 instruct branchConL_regL_regL_short(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
8521 match( If cmp (CmpL src1 src2) );
8522 effect(USE labl);
8523 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_regL_short" %}
8524 ins_cost(250);
8526 ins_encode %{
8527 Register opr1_reg = as_Register($src1$$reg);
8528 Register opr2_reg = as_Register($src2$$reg);
8530 Label &target = *($labl$$label);
8531 int flag = $cmp$$cmpcode;
8533 switch(flag) {
8534 case 0x01: //equal
8535 if (&target)
8536 __ beq(opr1_reg, opr2_reg, target);
8537 else
8538 __ beq(opr1_reg, opr2_reg, (int)0);
8539 __ delayed()->nop();
8540 break;
8542 case 0x02: //not_equal
8543 if(&target)
8544 __ bne(opr1_reg, opr2_reg, target);
8545 else
8546 __ bne(opr1_reg, opr2_reg, (int)0);
8547 __ delayed()->nop();
8548 break;
8550 case 0x03: //greater
8551 __ slt(AT, opr2_reg, opr1_reg);
8552 if(&target)
8553 __ bne(AT, R0, target);
8554 else
8555 __ bne(AT, R0, (int)0);
8556 __ delayed()->nop();
8557 break;
8559 case 0x04: //greater_equal
8560 __ slt(AT, opr1_reg, opr2_reg);
8561 if(&target)
8562 __ beq(AT, R0, target);
8563 else
8564 __ beq(AT, R0, (int)0);
8565 __ delayed()->nop();
8567 break;
8569 case 0x05: //less
8570 __ slt(AT, opr1_reg, opr2_reg);
8571 if(&target)
8572 __ bne(AT, R0, target);
8573 else
8574 __ bne(AT, R0, (int)0);
8575 __ delayed()->nop();
8577 break;
8579 case 0x06: //less_equal
8580 __ slt(AT, opr2_reg, opr1_reg);
8582 if(&target)
8583 __ beq(AT, R0, target);
8584 else
8585 __ beq(AT, R0, (int)0);
8586 __ delayed()->nop();
8588 break;
8590 default:
8591 Unimplemented();
8592 }
8593 %}
8596 ins_pc_relative(1);
8597 ins_pipe( pipe_alu_branch );
8598 ins_short_branch(1);
8599 %}
8602 instruct branchConL_regL_immL0_short(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
8603 match( If cmp (CmpL src1 zero) );
8604 effect(USE labl);
8605 format %{ "BR$cmp $src1, zero, $labl #@branchConL_regL_immL0_short" %}
8606 ins_cost(150);
8608 ins_encode %{
8609 Register opr1_reg = as_Register($src1$$reg);
8610 Label &target = *($labl$$label);
8611 int flag = $cmp$$cmpcode;
8613 switch(flag) {
8614 case 0x01: //equal
8615 if (&target)
8616 __ beq(opr1_reg, R0, target);
8617 else
8618 __ beq(opr1_reg, R0, int(0));
8619 break;
8621 case 0x02: //not_equal
8622 if(&target)
8623 __ bne(opr1_reg, R0, target);
8624 else
8625 __ bne(opr1_reg, R0, (int)0);
8626 break;
8628 case 0x03: //greater
8629 if(&target)
8630 __ bgtz(opr1_reg, target);
8631 else
8632 __ bgtz(opr1_reg, (int)0);
8633 break;
8635 case 0x04: //greater_equal
8636 if(&target)
8637 __ bgez(opr1_reg, target);
8638 else
8639 __ bgez(opr1_reg, (int)0);
8640 break;
8642 case 0x05: //less
8643 __ slt(AT, opr1_reg, R0);
8644 if(&target)
8645 __ bne(AT, R0, target);
8646 else
8647 __ bne(AT, R0, (int)0);
8648 break;
8650 case 0x06: //less_equal
8651 if (&target)
8652 __ blez(opr1_reg, target);
8653 else
8654 __ blez(opr1_reg, int(0));
8655 break;
8657 default:
8658 Unimplemented();
8659 }
8660 __ delayed()->nop();
8661 %}
8664 ins_pc_relative(1);
8665 ins_pipe( pipe_alu_branch );
8666 ins_short_branch(1);
8667 %}
8669 instruct branchConL_regL_immL_short(cmpOp cmp, mRegL src1, immL src2, label labl) %{
8670 match( If cmp (CmpL src1 src2) );
8671 effect(USE labl);
8672 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_immL_short" %}
8673 ins_cost(180);
8675 ins_encode %{
8676 Register opr1_reg = as_Register($src1$$reg);
8677 Register opr2_reg = AT;
8679 Label &target = *($labl$$label);
8680 int flag = $cmp$$cmpcode;
8682 __ set64(opr2_reg, $src2$$constant);
8684 switch(flag) {
8685 case 0x01: //equal
8686 if (&target)
8687 __ beq(opr1_reg, opr2_reg, target);
8688 else
8689 __ beq(opr1_reg, opr2_reg, (int)0);
8690 break;
8692 case 0x02: //not_equal
8693 if(&target)
8694 __ bne(opr1_reg, opr2_reg, target);
8695 else
8696 __ bne(opr1_reg, opr2_reg, (int)0);
8697 break;
8699 case 0x03: //greater
8700 __ slt(AT, opr2_reg, opr1_reg);
8701 if(&target)
8702 __ bne(AT, R0, target);
8703 else
8704 __ bne(AT, R0, (int)0);
8705 break;
8707 case 0x04: //greater_equal
8708 __ slt(AT, opr1_reg, opr2_reg);
8709 if(&target)
8710 __ beq(AT, R0, target);
8711 else
8712 __ beq(AT, R0, (int)0);
8713 break;
8715 case 0x05: //less
8716 __ slt(AT, opr1_reg, opr2_reg);
8717 if(&target)
8718 __ bne(AT, R0, target);
8719 else
8720 __ bne(AT, R0, (int)0);
8721 break;
8723 case 0x06: //less_equal
8724 __ slt(AT, opr2_reg, opr1_reg);
8725 if(&target)
8726 __ beq(AT, R0, target);
8727 else
8728 __ beq(AT, R0, (int)0);
8729 break;
8731 default:
8732 Unimplemented();
8733 }
8734 __ delayed()->nop();
8735 %}
8738 ins_pc_relative(1);
8739 ins_pipe( pipe_alu_branch );
8740 ins_short_branch(1);
8741 %}
8744 //FIXME
8745 instruct branchConF_reg_reg_short(cmpOp cmp, regF src1, regF src2, label labl) %{
8746 match( If cmp (CmpF src1 src2) );
8747 effect(USE labl);
8748 format %{ "BR$cmp $src1, $src2, $labl #@branchConF_reg_reg_short" %}
8750 ins_encode %{
8751 FloatRegister reg_op1 = $src1$$FloatRegister;
8752 FloatRegister reg_op2 = $src2$$FloatRegister;
8753 Label &L = *($labl$$label);
8754 int flag = $cmp$$cmpcode;
8756 switch(flag) {
8757 case 0x01: //equal
8758 __ c_eq_s(reg_op1, reg_op2);
8759 if (&L)
8760 __ bc1t(L);
8761 else
8762 __ bc1t((int)0);
8763 break;
8764 case 0x02: //not_equal
8765 __ c_eq_s(reg_op1, reg_op2);
8766 if (&L)
8767 __ bc1f(L);
8768 else
8769 __ bc1f((int)0);
8770 break;
8771 case 0x03: //greater
8772 __ c_ule_s(reg_op1, reg_op2);
8773 if(&L)
8774 __ bc1f(L);
8775 else
8776 __ bc1f((int)0);
8777 break;
8778 case 0x04: //greater_equal
8779 __ c_ult_s(reg_op1, reg_op2);
8780 if(&L)
8781 __ bc1f(L);
8782 else
8783 __ bc1f((int)0);
8784 break;
8785 case 0x05: //less
8786 __ c_ult_s(reg_op1, reg_op2);
8787 if(&L)
8788 __ bc1t(L);
8789 else
8790 __ bc1t((int)0);
8791 break;
8792 case 0x06: //less_equal
8793 __ c_ule_s(reg_op1, reg_op2);
8794 if(&L)
8795 __ bc1t(L);
8796 else
8797 __ bc1t((int)0);
8798 break;
8799 default:
8800 Unimplemented();
8801 }
8802 __ delayed()->nop();
8803 %}
8805 ins_pc_relative(1);
8806 ins_pipe(pipe_slow);
8807 ins_short_branch(1);
8808 %}
8810 instruct branchConD_reg_reg_short(cmpOp cmp, regD src1, regD src2, label labl) %{
8811 match( If cmp (CmpD src1 src2) );
8812 effect(USE labl);
8813 format %{ "BR$cmp $src1, $src2, $labl #@branchConD_reg_reg_short" %}
8815 ins_encode %{
8816 FloatRegister reg_op1 = $src1$$FloatRegister;
8817 FloatRegister reg_op2 = $src2$$FloatRegister;
8818 Label &L = *($labl$$label);
8819 int flag = $cmp$$cmpcode;
8821 switch(flag) {
8822 case 0x01: //equal
8823 __ c_eq_d(reg_op1, reg_op2);
8824 if (&L)
8825 __ bc1t(L);
8826 else
8827 __ bc1t((int)0);
8828 break;
8829 case 0x02: //not_equal
8830 // 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.
8831 __ c_eq_d(reg_op1, reg_op2);
8832 if (&L)
8833 __ bc1f(L);
8834 else
8835 __ bc1f((int)0);
8836 break;
8837 case 0x03: //greater
8838 __ c_ule_d(reg_op1, reg_op2);
8839 if(&L)
8840 __ bc1f(L);
8841 else
8842 __ bc1f((int)0);
8843 break;
8844 case 0x04: //greater_equal
8845 __ c_ult_d(reg_op1, reg_op2);
8846 if(&L)
8847 __ bc1f(L);
8848 else
8849 __ bc1f((int)0);
8850 break;
8851 case 0x05: //less
8852 __ c_ult_d(reg_op1, reg_op2);
8853 if(&L)
8854 __ bc1t(L);
8855 else
8856 __ bc1t((int)0);
8857 break;
8858 case 0x06: //less_equal
8859 __ c_ule_d(reg_op1, reg_op2);
8860 if(&L)
8861 __ bc1t(L);
8862 else
8863 __ bc1t((int)0);
8864 break;
8865 default:
8866 Unimplemented();
8867 }
8868 __ delayed()->nop();
8869 %}
8871 ins_pc_relative(1);
8872 ins_pipe(pipe_slow);
8873 ins_short_branch(1);
8874 %}
8876 // =================== End of branch instructions ==========================
8878 // Call Runtime Instruction
8879 instruct CallRuntimeDirect(method meth) %{
8880 match(CallRuntime );
8881 effect(USE meth);
8883 ins_cost(300);
8884 format %{ "CALL,runtime #@CallRuntimeDirect" %}
8885 ins_encode( Java_To_Runtime( meth ) );
8886 ins_pipe( pipe_slow );
8887 ins_alignment(16);
8888 %}
8892 //------------------------MemBar Instructions-------------------------------
8893 //Memory barrier flavors
8895 instruct membar_acquire() %{
8896 match(MemBarAcquire);
8897 ins_cost(400);
8899 format %{ "MEMBAR-acquire @ membar_acquire" %}
8900 ins_encode %{
8901 __ sync();
8902 %}
8903 ins_pipe(empty);
8904 %}
8906 instruct load_fence() %{
8907 match(LoadFence);
8908 ins_cost(400);
8910 format %{ "MEMBAR @ load_fence" %}
8911 ins_encode %{
8912 __ sync();
8913 %}
8914 ins_pipe(pipe_slow);
8915 %}
8917 instruct membar_acquire_lock()
8918 %{
8919 match(MemBarAcquireLock);
8920 ins_cost(0);
8922 size(0);
8923 format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
8924 ins_encode();
8925 ins_pipe(empty);
8926 %}
8928 instruct membar_release() %{
8929 match(MemBarRelease);
8930 ins_cost(400);
8932 format %{ "MEMBAR-release @ membar_release" %}
8934 ins_encode %{
8935 // Attention: DO NOT DELETE THIS GUY!
8936 __ sync();
8937 %}
8939 ins_pipe(pipe_slow);
8940 %}
8942 instruct store_fence() %{
8943 match(StoreFence);
8944 ins_cost(400);
8946 format %{ "MEMBAR @ store_fence" %}
8948 ins_encode %{
8949 __ sync();
8950 %}
8952 ins_pipe(pipe_slow);
8953 %}
8955 instruct membar_release_lock()
8956 %{
8957 match(MemBarReleaseLock);
8958 ins_cost(0);
8960 size(0);
8961 format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
8962 ins_encode();
8963 ins_pipe(empty);
8964 %}
8967 instruct membar_volatile() %{
8968 match(MemBarVolatile);
8969 ins_cost(400);
8971 format %{ "MEMBAR-volatile" %}
8972 ins_encode %{
8973 if( !os::is_MP() ) return; // Not needed on single CPU
8974 __ sync();
8976 %}
8977 ins_pipe(pipe_slow);
8978 %}
8980 instruct unnecessary_membar_volatile() %{
8981 match(MemBarVolatile);
8982 predicate(Matcher::post_store_load_barrier(n));
8983 ins_cost(0);
8985 size(0);
8986 format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
8987 ins_encode( );
8988 ins_pipe(empty);
8989 %}
8991 instruct membar_storestore() %{
8992 match(MemBarStoreStore);
8994 ins_cost(400);
8995 format %{ "MEMBAR-storestore @ membar_storestore" %}
8996 ins_encode %{
8997 __ sync();
8998 %}
8999 ins_pipe(empty);
9000 %}
9002 //----------Move Instructions--------------------------------------------------
9003 instruct castX2P(mRegP dst, mRegL src) %{
9004 match(Set dst (CastX2P src));
9005 format %{ "castX2P $dst, $src @ castX2P" %}
9006 ins_encode %{
9007 Register src = $src$$Register;
9008 Register dst = $dst$$Register;
9010 if(src != dst)
9011 __ move(dst, src);
9012 %}
9013 ins_cost(10);
9014 ins_pipe( ialu_regI_mov );
9015 %}
9017 instruct castP2X(mRegL dst, mRegP src ) %{
9018 match(Set dst (CastP2X src));
9020 format %{ "mov $dst, $src\t #@castP2X" %}
9021 ins_encode %{
9022 Register src = $src$$Register;
9023 Register dst = $dst$$Register;
9025 if(src != dst)
9026 __ move(dst, src);
9027 %}
9028 ins_pipe( ialu_regI_mov );
9029 %}
9031 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
9032 match(Set dst (MoveF2I src));
9033 effect(DEF dst, USE src);
9034 ins_cost(85);
9035 format %{ "MoveF2I $dst, $src @ MoveF2I_reg_reg" %}
9036 ins_encode %{
9037 Register dst = as_Register($dst$$reg);
9038 FloatRegister src = as_FloatRegister($src$$reg);
9040 __ mfc1(dst, src);
9041 %}
9042 ins_pipe( pipe_slow );
9043 %}
9045 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
9046 match(Set dst (MoveI2F src));
9047 effect(DEF dst, USE src);
9048 ins_cost(85);
9049 format %{ "MoveI2F $dst, $src @ MoveI2F_reg_reg" %}
9050 ins_encode %{
9051 Register src = as_Register($src$$reg);
9052 FloatRegister dst = as_FloatRegister($dst$$reg);
9054 __ mtc1(src, dst);
9055 %}
9056 ins_pipe( pipe_slow );
9057 %}
9059 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
9060 match(Set dst (MoveD2L src));
9061 effect(DEF dst, USE src);
9062 ins_cost(85);
9063 format %{ "MoveD2L $dst, $src @ MoveD2L_reg_reg" %}
9064 ins_encode %{
9065 Register dst = as_Register($dst$$reg);
9066 FloatRegister src = as_FloatRegister($src$$reg);
9068 __ dmfc1(dst, src);
9069 %}
9070 ins_pipe( pipe_slow );
9071 %}
9073 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
9074 match(Set dst (MoveL2D src));
9075 effect(DEF dst, USE src);
9076 ins_cost(85);
9077 format %{ "MoveL2D $dst, $src @ MoveL2D_reg_reg" %}
9078 ins_encode %{
9079 FloatRegister dst = as_FloatRegister($dst$$reg);
9080 Register src = as_Register($src$$reg);
9082 __ dmtc1(src, dst);
9083 %}
9084 ins_pipe( pipe_slow );
9085 %}
9087 //----------Conditional Move---------------------------------------------------
9088 // Conditional move
9089 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9090 match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9091 ins_cost(80);
9092 format %{
9093 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpI_reg_reg\n"
9094 "\tCMOV $dst,$src \t @cmovI_cmpI_reg_reg"
9095 %}
9097 ins_encode %{
9098 Register op1 = $tmp1$$Register;
9099 Register op2 = $tmp2$$Register;
9100 Register dst = $dst$$Register;
9101 Register src = $src$$Register;
9102 int flag = $cop$$cmpcode;
9104 switch(flag) {
9105 case 0x01: //equal
9106 __ subu32(AT, op1, op2);
9107 __ movz(dst, src, AT);
9108 break;
9110 case 0x02: //not_equal
9111 __ subu32(AT, op1, op2);
9112 __ movn(dst, src, AT);
9113 break;
9115 case 0x03: //great
9116 __ slt(AT, op2, op1);
9117 __ movn(dst, src, AT);
9118 break;
9120 case 0x04: //great_equal
9121 __ slt(AT, op1, op2);
9122 __ movz(dst, src, AT);
9123 break;
9125 case 0x05: //less
9126 __ slt(AT, op1, op2);
9127 __ movn(dst, src, AT);
9128 break;
9130 case 0x06: //less_equal
9131 __ slt(AT, op2, op1);
9132 __ movz(dst, src, AT);
9133 break;
9135 default:
9136 Unimplemented();
9137 }
9138 %}
9140 ins_pipe( pipe_slow );
9141 %}
9143 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9144 match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9145 ins_cost(80);
9146 format %{
9147 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
9148 "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
9149 %}
9150 ins_encode %{
9151 Register op1 = $tmp1$$Register;
9152 Register op2 = $tmp2$$Register;
9153 Register dst = $dst$$Register;
9154 Register src = $src$$Register;
9155 int flag = $cop$$cmpcode;
9157 switch(flag) {
9158 case 0x01: //equal
9159 __ subu(AT, op1, op2);
9160 __ movz(dst, src, AT);
9161 break;
9163 case 0x02: //not_equal
9164 __ subu(AT, op1, op2);
9165 __ movn(dst, src, AT);
9166 break;
9168 case 0x03: //above
9169 __ sltu(AT, op2, op1);
9170 __ movn(dst, src, AT);
9171 break;
9173 case 0x04: //above_equal
9174 __ sltu(AT, op1, op2);
9175 __ movz(dst, src, AT);
9176 break;
9178 case 0x05: //below
9179 __ sltu(AT, op1, op2);
9180 __ movn(dst, src, AT);
9181 break;
9183 case 0x06: //below_equal
9184 __ sltu(AT, op2, op1);
9185 __ movz(dst, src, AT);
9186 break;
9188 default:
9189 Unimplemented();
9190 }
9191 %}
9193 ins_pipe( pipe_slow );
9194 %}
9196 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
9197 match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
9198 ins_cost(80);
9199 format %{
9200 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
9201 "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
9202 %}
9203 ins_encode %{
9204 Register op1 = $tmp1$$Register;
9205 Register op2 = $tmp2$$Register;
9206 Register dst = $dst$$Register;
9207 Register src = $src$$Register;
9208 int flag = $cop$$cmpcode;
9210 switch(flag) {
9211 case 0x01: //equal
9212 __ subu32(AT, op1, op2);
9213 __ movz(dst, src, AT);
9214 break;
9216 case 0x02: //not_equal
9217 __ subu32(AT, op1, op2);
9218 __ movn(dst, src, AT);
9219 break;
9221 case 0x03: //above
9222 __ sltu(AT, op2, op1);
9223 __ movn(dst, src, AT);
9224 break;
9226 case 0x04: //above_equal
9227 __ sltu(AT, op1, op2);
9228 __ movz(dst, src, AT);
9229 break;
9231 case 0x05: //below
9232 __ sltu(AT, op1, op2);
9233 __ movn(dst, src, AT);
9234 break;
9236 case 0x06: //below_equal
9237 __ sltu(AT, op2, op1);
9238 __ movz(dst, src, AT);
9239 break;
9241 default:
9242 Unimplemented();
9243 }
9244 %}
9246 ins_pipe( pipe_slow );
9247 %}
9249 instruct cmovP_cmpU_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
9250 match(Set dst (CMoveP (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
9251 ins_cost(80);
9252 format %{
9253 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpU_reg_reg\n\t"
9254 "CMOV $dst,$src\t @cmovP_cmpU_reg_reg"
9255 %}
9256 ins_encode %{
9257 Register op1 = $tmp1$$Register;
9258 Register op2 = $tmp2$$Register;
9259 Register dst = $dst$$Register;
9260 Register src = $src$$Register;
9261 int flag = $cop$$cmpcode;
9263 switch(flag) {
9264 case 0x01: //equal
9265 __ subu32(AT, op1, op2);
9266 __ movz(dst, src, AT);
9267 break;
9269 case 0x02: //not_equal
9270 __ subu32(AT, op1, op2);
9271 __ movn(dst, src, AT);
9272 break;
9274 case 0x03: //above
9275 __ sltu(AT, op2, op1);
9276 __ movn(dst, src, AT);
9277 break;
9279 case 0x04: //above_equal
9280 __ sltu(AT, op1, op2);
9281 __ movz(dst, src, AT);
9282 break;
9284 case 0x05: //below
9285 __ sltu(AT, op1, op2);
9286 __ movn(dst, src, AT);
9287 break;
9289 case 0x06: //below_equal
9290 __ sltu(AT, op2, op1);
9291 __ movz(dst, src, AT);
9292 break;
9294 default:
9295 Unimplemented();
9296 }
9297 %}
9299 ins_pipe( pipe_slow );
9300 %}
9302 instruct cmovP_cmpF_reg_reg(mRegP dst, mRegP src, regF tmp1, regF tmp2, cmpOp cop ) %{
9303 match(Set dst (CMoveP (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
9304 ins_cost(80);
9305 format %{
9306 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpF_reg_reg\n"
9307 "\tCMOV $dst,$src \t @cmovP_cmpF_reg_reg"
9308 %}
9310 ins_encode %{
9311 FloatRegister reg_op1 = $tmp1$$FloatRegister;
9312 FloatRegister reg_op2 = $tmp2$$FloatRegister;
9313 Register dst = $dst$$Register;
9314 Register src = $src$$Register;
9315 int flag = $cop$$cmpcode;
9317 switch(flag) {
9318 case 0x01: //equal
9319 __ c_eq_s(reg_op1, reg_op2);
9320 __ movt(dst, src);
9321 break;
9322 case 0x02: //not_equal
9323 __ c_eq_s(reg_op1, reg_op2);
9324 __ movf(dst, src);
9325 break;
9326 case 0x03: //greater
9327 __ c_ole_s(reg_op1, reg_op2);
9328 __ movf(dst, src);
9329 break;
9330 case 0x04: //greater_equal
9331 __ c_olt_s(reg_op1, reg_op2);
9332 __ movf(dst, src);
9333 break;
9334 case 0x05: //less
9335 __ c_ult_s(reg_op1, reg_op2);
9336 __ movt(dst, src);
9337 break;
9338 case 0x06: //less_equal
9339 __ c_ule_s(reg_op1, reg_op2);
9340 __ movt(dst, src);
9341 break;
9342 default:
9343 Unimplemented();
9344 }
9345 %}
9346 ins_pipe( pipe_slow );
9347 %}
9349 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
9350 match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
9351 ins_cost(80);
9352 format %{
9353 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
9354 "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
9355 %}
9356 ins_encode %{
9357 Register op1 = $tmp1$$Register;
9358 Register op2 = $tmp2$$Register;
9359 Register dst = $dst$$Register;
9360 Register src = $src$$Register;
9361 int flag = $cop$$cmpcode;
9363 switch(flag) {
9364 case 0x01: //equal
9365 __ subu32(AT, op1, op2);
9366 __ movz(dst, src, AT);
9367 break;
9369 case 0x02: //not_equal
9370 __ subu32(AT, op1, op2);
9371 __ movn(dst, src, AT);
9372 break;
9374 case 0x03: //above
9375 __ sltu(AT, op2, op1);
9376 __ movn(dst, src, AT);
9377 break;
9379 case 0x04: //above_equal
9380 __ sltu(AT, op1, op2);
9381 __ movz(dst, src, AT);
9382 break;
9384 case 0x05: //below
9385 __ sltu(AT, op1, op2);
9386 __ movn(dst, src, AT);
9387 break;
9389 case 0x06: //below_equal
9390 __ sltu(AT, op2, op1);
9391 __ movz(dst, src, AT);
9392 break;
9394 default:
9395 Unimplemented();
9396 }
9397 %}
9399 ins_pipe( pipe_slow );
9400 %}
9402 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9403 match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9404 ins_cost(80);
9405 format %{
9406 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
9407 "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
9408 %}
9409 ins_encode %{
9410 Register op1 = $tmp1$$Register;
9411 Register op2 = $tmp2$$Register;
9412 Register dst = $dst$$Register;
9413 Register src = $src$$Register;
9414 int flag = $cop$$cmpcode;
9416 switch(flag) {
9417 case 0x01: //equal
9418 __ subu(AT, op1, op2);
9419 __ movz(dst, src, AT);
9420 break;
9422 case 0x02: //not_equal
9423 __ subu(AT, op1, op2);
9424 __ movn(dst, src, AT);
9425 break;
9427 case 0x03: //above
9428 __ sltu(AT, op2, op1);
9429 __ movn(dst, src, AT);
9430 break;
9432 case 0x04: //above_equal
9433 __ sltu(AT, op1, op2);
9434 __ movz(dst, src, AT);
9435 break;
9437 case 0x05: //below
9438 __ sltu(AT, op1, op2);
9439 __ movn(dst, src, AT);
9440 break;
9442 case 0x06: //below_equal
9443 __ sltu(AT, op2, op1);
9444 __ movz(dst, src, AT);
9445 break;
9447 default:
9448 Unimplemented();
9449 }
9450 %}
9452 ins_pipe( pipe_slow );
9453 %}
9455 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
9456 match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
9457 ins_cost(80);
9458 format %{
9459 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpD_reg_reg\n"
9460 "\tCMOV $dst,$src \t @cmovP_cmpD_reg_reg"
9461 %}
9462 ins_encode %{
9463 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
9464 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
9465 Register dst = as_Register($dst$$reg);
9466 Register src = as_Register($src$$reg);
9468 int flag = $cop$$cmpcode;
9470 switch(flag) {
9471 case 0x01: //equal
9472 __ c_eq_d(reg_op1, reg_op2);
9473 __ movt(dst, src);
9474 break;
9475 case 0x02: //not_equal
9476 __ c_eq_d(reg_op1, reg_op2);
9477 __ movf(dst, src);
9478 break;
9479 case 0x03: //greater
9480 __ c_ole_d(reg_op1, reg_op2);
9481 __ movf(dst, src);
9482 break;
9483 case 0x04: //greater_equal
9484 __ c_olt_d(reg_op1, reg_op2);
9485 __ movf(dst, src);
9486 break;
9487 case 0x05: //less
9488 __ c_ult_d(reg_op1, reg_op2);
9489 __ movt(dst, src);
9490 break;
9491 case 0x06: //less_equal
9492 __ c_ule_d(reg_op1, reg_op2);
9493 __ movt(dst, src);
9494 break;
9495 default:
9496 Unimplemented();
9497 }
9498 %}
9500 ins_pipe( pipe_slow );
9501 %}
9504 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
9505 match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
9506 ins_cost(80);
9507 format %{
9508 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
9509 "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
9510 %}
9511 ins_encode %{
9512 Register op1 = $tmp1$$Register;
9513 Register op2 = $tmp2$$Register;
9514 Register dst = $dst$$Register;
9515 Register src = $src$$Register;
9516 int flag = $cop$$cmpcode;
9518 switch(flag) {
9519 case 0x01: //equal
9520 __ subu32(AT, op1, op2);
9521 __ movz(dst, src, AT);
9522 break;
9524 case 0x02: //not_equal
9525 __ subu32(AT, op1, op2);
9526 __ movn(dst, src, AT);
9527 break;
9529 case 0x03: //above
9530 __ sltu(AT, op2, op1);
9531 __ movn(dst, src, AT);
9532 break;
9534 case 0x04: //above_equal
9535 __ sltu(AT, op1, op2);
9536 __ movz(dst, src, AT);
9537 break;
9539 case 0x05: //below
9540 __ sltu(AT, op1, op2);
9541 __ movn(dst, src, AT);
9542 break;
9544 case 0x06: //below_equal
9545 __ sltu(AT, op2, op1);
9546 __ movz(dst, src, AT);
9547 break;
9549 default:
9550 Unimplemented();
9551 }
9552 %}
9554 ins_pipe( pipe_slow );
9555 %}
9558 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
9559 match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
9560 ins_cost(80);
9561 format %{
9562 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
9563 "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
9564 %}
9565 ins_encode %{
9566 Register op1 = $tmp1$$Register;
9567 Register op2 = $tmp2$$Register;
9568 Register dst = $dst$$Register;
9569 Register src = $src$$Register;
9570 int flag = $cop$$cmpcode;
9572 switch(flag) {
9573 case 0x01: //equal
9574 __ subu(AT, op1, op2);
9575 __ movz(dst, src, AT);
9576 break;
9578 case 0x02: //not_equal
9579 __ subu(AT, op1, op2);
9580 __ movn(dst, src, AT);
9581 break;
9583 case 0x03: //above
9584 __ sltu(AT, op2, op1);
9585 __ movn(dst, src, AT);
9586 break;
9588 case 0x04: //above_equal
9589 __ sltu(AT, op1, op2);
9590 __ movz(dst, src, AT);
9591 break;
9593 case 0x05: //below
9594 __ sltu(AT, op1, op2);
9595 __ movn(dst, src, AT);
9596 break;
9598 case 0x06: //below_equal
9599 __ sltu(AT, op2, op1);
9600 __ movz(dst, src, AT);
9601 break;
9603 default:
9604 Unimplemented();
9605 }
9606 %}
9608 ins_pipe( pipe_slow );
9609 %}
9611 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
9612 match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
9613 ins_cost(80);
9614 format %{
9615 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpL_reg_reg\n"
9616 "\tCMOV $dst,$src \t @cmovI_cmpL_reg_reg"
9617 %}
9618 ins_encode %{
9619 Register opr1 = as_Register($tmp1$$reg);
9620 Register opr2 = as_Register($tmp2$$reg);
9621 Register dst = $dst$$Register;
9622 Register src = $src$$Register;
9623 int flag = $cop$$cmpcode;
9625 switch(flag) {
9626 case 0x01: //equal
9627 __ subu(AT, opr1, opr2);
9628 __ movz(dst, src, AT);
9629 break;
9631 case 0x02: //not_equal
9632 __ subu(AT, opr1, opr2);
9633 __ movn(dst, src, AT);
9634 break;
9636 case 0x03: //greater
9637 __ slt(AT, opr2, opr1);
9638 __ movn(dst, src, AT);
9639 break;
9641 case 0x04: //greater_equal
9642 __ slt(AT, opr1, opr2);
9643 __ movz(dst, src, AT);
9644 break;
9646 case 0x05: //less
9647 __ slt(AT, opr1, opr2);
9648 __ movn(dst, src, AT);
9649 break;
9651 case 0x06: //less_equal
9652 __ slt(AT, opr2, opr1);
9653 __ movz(dst, src, AT);
9654 break;
9656 default:
9657 Unimplemented();
9658 }
9659 %}
9661 ins_pipe( pipe_slow );
9662 %}
9664 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
9665 match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
9666 ins_cost(80);
9667 format %{
9668 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpL_reg_reg\n"
9669 "\tCMOV $dst,$src \t @cmovP_cmpL_reg_reg"
9670 %}
9671 ins_encode %{
9672 Register opr1 = as_Register($tmp1$$reg);
9673 Register opr2 = as_Register($tmp2$$reg);
9674 Register dst = $dst$$Register;
9675 Register src = $src$$Register;
9676 int flag = $cop$$cmpcode;
9678 switch(flag) {
9679 case 0x01: //equal
9680 __ subu(AT, opr1, opr2);
9681 __ movz(dst, src, AT);
9682 break;
9684 case 0x02: //not_equal
9685 __ subu(AT, opr1, opr2);
9686 __ movn(dst, src, AT);
9687 break;
9689 case 0x03: //greater
9690 __ slt(AT, opr2, opr1);
9691 __ movn(dst, src, AT);
9692 break;
9694 case 0x04: //greater_equal
9695 __ slt(AT, opr1, opr2);
9696 __ movz(dst, src, AT);
9697 break;
9699 case 0x05: //less
9700 __ slt(AT, opr1, opr2);
9701 __ movn(dst, src, AT);
9702 break;
9704 case 0x06: //less_equal
9705 __ slt(AT, opr2, opr1);
9706 __ movz(dst, src, AT);
9707 break;
9709 default:
9710 Unimplemented();
9711 }
9712 %}
9714 ins_pipe( pipe_slow );
9715 %}
9717 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
9718 match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
9719 ins_cost(80);
9720 format %{
9721 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpD_reg_reg\n"
9722 "\tCMOV $dst,$src \t @cmovI_cmpD_reg_reg"
9723 %}
9724 ins_encode %{
9725 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
9726 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
9727 Register dst = as_Register($dst$$reg);
9728 Register src = as_Register($src$$reg);
9730 int flag = $cop$$cmpcode;
9732 switch(flag) {
9733 case 0x01: //equal
9734 __ c_eq_d(reg_op1, reg_op2);
9735 __ movt(dst, src);
9736 break;
9737 case 0x02: //not_equal
9738 // See instruct branchConD_reg_reg. The change in branchConD_reg_reg fixed a bug. It seems similar here, so I made thesame change.
9739 __ c_eq_d(reg_op1, reg_op2);
9740 __ movf(dst, src);
9741 break;
9742 case 0x03: //greater
9743 __ c_ole_d(reg_op1, reg_op2);
9744 __ movf(dst, src);
9745 break;
9746 case 0x04: //greater_equal
9747 __ c_olt_d(reg_op1, reg_op2);
9748 __ movf(dst, src);
9749 break;
9750 case 0x05: //less
9751 __ c_ult_d(reg_op1, reg_op2);
9752 __ movt(dst, src);
9753 break;
9754 case 0x06: //less_equal
9755 __ c_ule_d(reg_op1, reg_op2);
9756 __ movt(dst, src);
9757 break;
9758 default:
9759 Unimplemented();
9760 }
9761 %}
9763 ins_pipe( pipe_slow );
9764 %}
9767 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9768 match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9769 ins_cost(80);
9770 format %{
9771 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
9772 "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
9773 %}
9774 ins_encode %{
9775 Register op1 = $tmp1$$Register;
9776 Register op2 = $tmp2$$Register;
9777 Register dst = $dst$$Register;
9778 Register src = $src$$Register;
9779 int flag = $cop$$cmpcode;
9781 switch(flag) {
9782 case 0x01: //equal
9783 __ subu(AT, op1, op2);
9784 __ movz(dst, src, AT);
9785 break;
9787 case 0x02: //not_equal
9788 __ subu(AT, op1, op2);
9789 __ movn(dst, src, AT);
9790 break;
9792 case 0x03: //above
9793 __ sltu(AT, op2, op1);
9794 __ movn(dst, src, AT);
9795 break;
9797 case 0x04: //above_equal
9798 __ sltu(AT, op1, op2);
9799 __ movz(dst, src, AT);
9800 break;
9802 case 0x05: //below
9803 __ sltu(AT, op1, op2);
9804 __ movn(dst, src, AT);
9805 break;
9807 case 0x06: //below_equal
9808 __ sltu(AT, op2, op1);
9809 __ movz(dst, src, AT);
9810 break;
9812 default:
9813 Unimplemented();
9814 }
9815 %}
9817 ins_pipe( pipe_slow );
9818 %}
9820 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9821 match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9822 ins_cost(80);
9823 format %{
9824 "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
9825 "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
9826 %}
9827 ins_encode %{
9828 Register op1 = $tmp1$$Register;
9829 Register op2 = $tmp2$$Register;
9830 Register dst = $dst$$Register;
9831 Register src = $src$$Register;
9832 int flag = $cop$$cmpcode;
9834 switch(flag) {
9835 case 0x01: //equal
9836 __ subu32(AT, op1, op2);
9837 __ movz(dst, src, AT);
9838 break;
9840 case 0x02: //not_equal
9841 __ subu32(AT, op1, op2);
9842 __ movn(dst, src, AT);
9843 break;
9845 case 0x03: //above
9846 __ slt(AT, op2, op1);
9847 __ movn(dst, src, AT);
9848 break;
9850 case 0x04: //above_equal
9851 __ slt(AT, op1, op2);
9852 __ movz(dst, src, AT);
9853 break;
9855 case 0x05: //below
9856 __ slt(AT, op1, op2);
9857 __ movn(dst, src, AT);
9858 break;
9860 case 0x06: //below_equal
9861 __ slt(AT, op2, op1);
9862 __ movz(dst, src, AT);
9863 break;
9865 default:
9866 Unimplemented();
9867 }
9868 %}
9870 ins_pipe( pipe_slow );
9871 %}
9873 instruct cmovL_cmpP_reg_reg(mRegL dst, mRegL src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9874 match(Set dst (CMoveL (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9875 ins_cost(80);
9876 format %{
9877 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpP_reg_reg\n\t"
9878 "CMOV $dst,$src\t @cmovL_cmpP_reg_reg"
9879 %}
9880 ins_encode %{
9881 Register op1 = $tmp1$$Register;
9882 Register op2 = $tmp2$$Register;
9883 Register dst = $dst$$Register;
9884 Register src = $src$$Register;
9885 int flag = $cop$$cmpcode;
9887 switch(flag) {
9888 case 0x01: //equal
9889 __ subu(AT, op1, op2);
9890 __ movz(dst, src, AT);
9891 break;
9893 case 0x02: //not_equal
9894 __ subu(AT, op1, op2);
9895 __ movn(dst, src, AT);
9896 break;
9898 case 0x03: //above
9899 __ sltu(AT, op2, op1);
9900 __ movn(dst, src, AT);
9901 break;
9903 case 0x04: //above_equal
9904 __ sltu(AT, op1, op2);
9905 __ movz(dst, src, AT);
9906 break;
9908 case 0x05: //below
9909 __ sltu(AT, op1, op2);
9910 __ movn(dst, src, AT);
9911 break;
9913 case 0x06: //below_equal
9914 __ sltu(AT, op2, op1);
9915 __ movz(dst, src, AT);
9916 break;
9918 default:
9919 Unimplemented();
9920 }
9921 %}
9923 ins_pipe( pipe_slow );
9924 %}
9926 instruct cmovN_cmpU_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
9927 match(Set dst (CMoveN (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
9928 ins_cost(80);
9929 format %{
9930 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpU_reg_reg\n\t"
9931 "CMOV $dst,$src\t @cmovN_cmpU_reg_reg"
9932 %}
9933 ins_encode %{
9934 Register op1 = $tmp1$$Register;
9935 Register op2 = $tmp2$$Register;
9936 Register dst = $dst$$Register;
9937 Register src = $src$$Register;
9938 int flag = $cop$$cmpcode;
9940 switch(flag) {
9941 case 0x01: //equal
9942 __ subu32(AT, op1, op2);
9943 __ movz(dst, src, AT);
9944 break;
9946 case 0x02: //not_equal
9947 __ subu32(AT, op1, op2);
9948 __ movn(dst, src, AT);
9949 break;
9951 case 0x03: //above
9952 __ sltu(AT, op2, op1);
9953 __ movn(dst, src, AT);
9954 break;
9956 case 0x04: //above_equal
9957 __ sltu(AT, op1, op2);
9958 __ movz(dst, src, AT);
9959 break;
9961 case 0x05: //below
9962 __ sltu(AT, op1, op2);
9963 __ movn(dst, src, AT);
9964 break;
9966 case 0x06: //below_equal
9967 __ sltu(AT, op2, op1);
9968 __ movz(dst, src, AT);
9969 break;
9971 default:
9972 Unimplemented();
9973 }
9974 %}
9976 ins_pipe( pipe_slow );
9977 %}
9979 instruct cmovN_cmpL_reg_reg(mRegN dst, mRegN src, mRegL tmp1, mRegL tmp2, cmpOp cop) %{
9980 match(Set dst (CMoveN (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
9981 ins_cost(80);
9982 format %{
9983 "CMP$cop $tmp1, $tmp2\t @cmovN_cmpL_reg_reg\n"
9984 "\tCMOV $dst,$src \t @cmovN_cmpL_reg_reg"
9985 %}
9986 ins_encode %{
9987 Register opr1 = as_Register($tmp1$$reg);
9988 Register opr2 = as_Register($tmp2$$reg);
9989 Register dst = $dst$$Register;
9990 Register src = $src$$Register;
9991 int flag = $cop$$cmpcode;
9993 switch(flag) {
9994 case 0x01: //equal
9995 __ subu(AT, opr1, opr2);
9996 __ movz(dst, src, AT);
9997 break;
9999 case 0x02: //not_equal
10000 __ subu(AT, opr1, opr2);
10001 __ movn(dst, src, AT);
10002 break;
10004 case 0x03: //greater
10005 __ slt(AT, opr2, opr1);
10006 __ movn(dst, src, AT);
10007 break;
10009 case 0x04: //greater_equal
10010 __ slt(AT, opr1, opr2);
10011 __ movz(dst, src, AT);
10012 break;
10014 case 0x05: //less
10015 __ slt(AT, opr1, opr2);
10016 __ movn(dst, src, AT);
10017 break;
10019 case 0x06: //less_equal
10020 __ slt(AT, opr2, opr1);
10021 __ movz(dst, src, AT);
10022 break;
10024 default:
10025 Unimplemented();
10026 }
10027 %}
10029 ins_pipe( pipe_slow );
10030 %}
10032 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10033 match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10034 ins_cost(80);
10035 format %{
10036 "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
10037 "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
10038 %}
10039 ins_encode %{
10040 Register op1 = $tmp1$$Register;
10041 Register op2 = $tmp2$$Register;
10042 Register dst = $dst$$Register;
10043 Register src = $src$$Register;
10044 int flag = $cop$$cmpcode;
10046 switch(flag) {
10047 case 0x01: //equal
10048 __ subu32(AT, op1, op2);
10049 __ movz(dst, src, AT);
10050 break;
10052 case 0x02: //not_equal
10053 __ subu32(AT, op1, op2);
10054 __ movn(dst, src, AT);
10055 break;
10057 case 0x03: //above
10058 __ slt(AT, op2, op1);
10059 __ movn(dst, src, AT);
10060 break;
10062 case 0x04: //above_equal
10063 __ slt(AT, op1, op2);
10064 __ movz(dst, src, AT);
10065 break;
10067 case 0x05: //below
10068 __ slt(AT, op1, op2);
10069 __ movn(dst, src, AT);
10070 break;
10072 case 0x06: //below_equal
10073 __ slt(AT, op2, op1);
10074 __ movz(dst, src, AT);
10075 break;
10077 default:
10078 Unimplemented();
10079 }
10080 %}
10082 ins_pipe( pipe_slow );
10083 %}
10085 instruct cmovL_cmpU_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
10086 match(Set dst (CMoveL (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
10087 ins_cost(80);
10088 format %{
10089 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpU_reg_reg\n\t"
10090 "CMOV $dst,$src\t @cmovL_cmpU_reg_reg"
10091 %}
10092 ins_encode %{
10093 Register op1 = $tmp1$$Register;
10094 Register op2 = $tmp2$$Register;
10095 Register dst = $dst$$Register;
10096 Register src = $src$$Register;
10097 int flag = $cop$$cmpcode;
10099 switch(flag) {
10100 case 0x01: //equal
10101 __ subu32(AT, op1, op2);
10102 __ movz(dst, src, AT);
10103 break;
10105 case 0x02: //not_equal
10106 __ subu32(AT, op1, op2);
10107 __ movn(dst, src, AT);
10108 break;
10110 case 0x03: //above
10111 __ sltu(AT, op2, op1);
10112 __ movn(dst, src, AT);
10113 break;
10115 case 0x04: //above_equal
10116 __ sltu(AT, op1, op2);
10117 __ movz(dst, src, AT);
10118 break;
10120 case 0x05: //below
10121 __ sltu(AT, op1, op2);
10122 __ movn(dst, src, AT);
10123 break;
10125 case 0x06: //below_equal
10126 __ sltu(AT, op2, op1);
10127 __ movz(dst, src, AT);
10128 break;
10130 default:
10131 Unimplemented();
10132 }
10133 %}
10135 ins_pipe( pipe_slow );
10136 %}
10138 instruct cmovL_cmpF_reg_reg(mRegL dst, mRegL src, regF tmp1, regF tmp2, cmpOp cop ) %{
10139 match(Set dst (CMoveL (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
10140 ins_cost(80);
10141 format %{
10142 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpF_reg_reg\n"
10143 "\tCMOV $dst,$src \t @cmovL_cmpF_reg_reg"
10144 %}
10146 ins_encode %{
10147 FloatRegister reg_op1 = $tmp1$$FloatRegister;
10148 FloatRegister reg_op2 = $tmp2$$FloatRegister;
10149 Register dst = $dst$$Register;
10150 Register src = $src$$Register;
10151 int flag = $cop$$cmpcode;
10153 switch(flag) {
10154 case 0x01: //equal
10155 __ c_eq_s(reg_op1, reg_op2);
10156 __ movt(dst, src);
10157 break;
10158 case 0x02: //not_equal
10159 __ c_eq_s(reg_op1, reg_op2);
10160 __ movf(dst, src);
10161 break;
10162 case 0x03: //greater
10163 __ c_ole_s(reg_op1, reg_op2);
10164 __ movf(dst, src);
10165 break;
10166 case 0x04: //greater_equal
10167 __ c_olt_s(reg_op1, reg_op2);
10168 __ movf(dst, src);
10169 break;
10170 case 0x05: //less
10171 __ c_ult_s(reg_op1, reg_op2);
10172 __ movt(dst, src);
10173 break;
10174 case 0x06: //less_equal
10175 __ c_ule_s(reg_op1, reg_op2);
10176 __ movt(dst, src);
10177 break;
10178 default:
10179 Unimplemented();
10180 }
10181 %}
10182 ins_pipe( pipe_slow );
10183 %}
10185 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10186 match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10187 ins_cost(80);
10188 format %{
10189 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpI_reg_reg\n"
10190 "\tCMOV $dst,$src \t @cmovL_cmpI_reg_reg"
10191 %}
10193 ins_encode %{
10194 Register op1 = $tmp1$$Register;
10195 Register op2 = $tmp2$$Register;
10196 Register dst = as_Register($dst$$reg);
10197 Register src = as_Register($src$$reg);
10198 int flag = $cop$$cmpcode;
10200 switch(flag)
10201 {
10202 case 0x01: //equal
10203 __ subu32(AT, op1, op2);
10204 __ movz(dst, src, AT);
10205 break;
10207 case 0x02: //not_equal
10208 __ subu32(AT, op1, op2);
10209 __ movn(dst, src, AT);
10210 break;
10212 case 0x03: //great
10213 __ slt(AT, op2, op1);
10214 __ movn(dst, src, AT);
10215 break;
10217 case 0x04: //great_equal
10218 __ slt(AT, op1, op2);
10219 __ movz(dst, src, AT);
10220 break;
10222 case 0x05: //less
10223 __ slt(AT, op1, op2);
10224 __ movn(dst, src, AT);
10225 break;
10227 case 0x06: //less_equal
10228 __ slt(AT, op2, op1);
10229 __ movz(dst, src, AT);
10230 break;
10232 default:
10233 Unimplemented();
10234 }
10235 %}
10237 ins_pipe( pipe_slow );
10238 %}
10240 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
10241 match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
10242 ins_cost(80);
10243 format %{
10244 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpL_reg_reg\n"
10245 "\tCMOV $dst,$src \t @cmovL_cmpL_reg_reg"
10246 %}
10247 ins_encode %{
10248 Register opr1 = as_Register($tmp1$$reg);
10249 Register opr2 = as_Register($tmp2$$reg);
10250 Register dst = as_Register($dst$$reg);
10251 Register src = as_Register($src$$reg);
10252 int flag = $cop$$cmpcode;
10254 switch(flag) {
10255 case 0x01: //equal
10256 __ subu(AT, opr1, opr2);
10257 __ movz(dst, src, AT);
10258 break;
10260 case 0x02: //not_equal
10261 __ subu(AT, opr1, opr2);
10262 __ movn(dst, src, AT);
10263 break;
10265 case 0x03: //greater
10266 __ slt(AT, opr2, opr1);
10267 __ movn(dst, src, AT);
10268 break;
10270 case 0x04: //greater_equal
10271 __ slt(AT, opr1, opr2);
10272 __ movz(dst, src, AT);
10273 break;
10275 case 0x05: //less
10276 __ slt(AT, opr1, opr2);
10277 __ movn(dst, src, AT);
10278 break;
10280 case 0x06: //less_equal
10281 __ slt(AT, opr2, opr1);
10282 __ movz(dst, src, AT);
10283 break;
10285 default:
10286 Unimplemented();
10287 }
10288 %}
10290 ins_pipe( pipe_slow );
10291 %}
10293 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
10294 match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
10295 ins_cost(80);
10296 format %{
10297 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
10298 "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
10299 %}
10300 ins_encode %{
10301 Register op1 = $tmp1$$Register;
10302 Register op2 = $tmp2$$Register;
10303 Register dst = $dst$$Register;
10304 Register src = $src$$Register;
10305 int flag = $cop$$cmpcode;
10307 switch(flag) {
10308 case 0x01: //equal
10309 __ subu32(AT, op1, op2);
10310 __ movz(dst, src, AT);
10311 break;
10313 case 0x02: //not_equal
10314 __ subu32(AT, op1, op2);
10315 __ movn(dst, src, AT);
10316 break;
10318 case 0x03: //above
10319 __ sltu(AT, op2, op1);
10320 __ movn(dst, src, AT);
10321 break;
10323 case 0x04: //above_equal
10324 __ sltu(AT, op1, op2);
10325 __ movz(dst, src, AT);
10326 break;
10328 case 0x05: //below
10329 __ sltu(AT, op1, op2);
10330 __ movn(dst, src, AT);
10331 break;
10333 case 0x06: //below_equal
10334 __ sltu(AT, op2, op1);
10335 __ movz(dst, src, AT);
10336 break;
10338 default:
10339 Unimplemented();
10340 }
10341 %}
10343 ins_pipe( pipe_slow );
10344 %}
10347 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
10348 match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
10349 ins_cost(80);
10350 format %{
10351 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpD_reg_reg\n"
10352 "\tCMOV $dst,$src \t @cmovL_cmpD_reg_reg"
10353 %}
10354 ins_encode %{
10355 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
10356 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
10357 Register dst = as_Register($dst$$reg);
10358 Register src = as_Register($src$$reg);
10360 int flag = $cop$$cmpcode;
10362 switch(flag) {
10363 case 0x01: //equal
10364 __ c_eq_d(reg_op1, reg_op2);
10365 __ movt(dst, src);
10366 break;
10367 case 0x02: //not_equal
10368 __ c_eq_d(reg_op1, reg_op2);
10369 __ movf(dst, src);
10370 break;
10371 case 0x03: //greater
10372 __ c_ole_d(reg_op1, reg_op2);
10373 __ movf(dst, src);
10374 break;
10375 case 0x04: //greater_equal
10376 __ c_olt_d(reg_op1, reg_op2);
10377 __ movf(dst, src);
10378 break;
10379 case 0x05: //less
10380 __ c_ult_d(reg_op1, reg_op2);
10381 __ movt(dst, src);
10382 break;
10383 case 0x06: //less_equal
10384 __ c_ule_d(reg_op1, reg_op2);
10385 __ movt(dst, src);
10386 break;
10387 default:
10388 Unimplemented();
10389 }
10390 %}
10392 ins_pipe( pipe_slow );
10393 %}
10395 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
10396 match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
10397 ins_cost(200);
10398 format %{
10399 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpD_reg_reg\n"
10400 "\tCMOV $dst,$src \t @cmovD_cmpD_reg_reg"
10401 %}
10402 ins_encode %{
10403 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
10404 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
10405 FloatRegister dst = as_FloatRegister($dst$$reg);
10406 FloatRegister src = as_FloatRegister($src$$reg);
10408 int flag = $cop$$cmpcode;
10410 switch(flag) {
10411 case 0x01: //equal
10412 __ c_eq_d(reg_op1, reg_op2);
10413 __ movt_d(dst, src);
10414 break;
10415 case 0x02: //not_equal
10416 __ c_eq_d(reg_op1, reg_op2);
10417 __ movf_d(dst, src);
10418 break;
10419 case 0x03: //greater
10420 __ c_ole_d(reg_op1, reg_op2);
10421 __ movf_d(dst, src);
10422 break;
10423 case 0x04: //greater_equal
10424 __ c_olt_d(reg_op1, reg_op2);
10425 __ movf_d(dst, src);
10426 break;
10427 case 0x05: //less
10428 __ c_ult_d(reg_op1, reg_op2);
10429 __ movt_d(dst, src);
10430 break;
10431 case 0x06: //less_equal
10432 __ c_ule_d(reg_op1, reg_op2);
10433 __ movt_d(dst, src);
10434 break;
10435 default:
10436 Unimplemented();
10437 }
10438 %}
10440 ins_pipe( pipe_slow );
10441 %}
10443 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10444 match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10445 ins_cost(200);
10446 format %{
10447 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpI_reg_reg\n"
10448 "\tCMOV $dst, $src \t @cmovF_cmpI_reg_reg"
10449 %}
10451 ins_encode %{
10452 Register op1 = $tmp1$$Register;
10453 Register op2 = $tmp2$$Register;
10454 FloatRegister dst = as_FloatRegister($dst$$reg);
10455 FloatRegister src = as_FloatRegister($src$$reg);
10456 int flag = $cop$$cmpcode;
10457 Label L;
10459 switch(flag) {
10460 case 0x01: //equal
10461 __ bne(op1, op2, L);
10462 __ delayed()->nop();
10463 __ mov_s(dst, src);
10464 __ bind(L);
10465 break;
10466 case 0x02: //not_equal
10467 __ beq(op1, op2, L);
10468 __ delayed()->nop();
10469 __ mov_s(dst, src);
10470 __ bind(L);
10471 break;
10472 case 0x03: //great
10473 __ slt(AT, op2, op1);
10474 __ beq(AT, R0, L);
10475 __ delayed()->nop();
10476 __ mov_s(dst, src);
10477 __ bind(L);
10478 break;
10479 case 0x04: //great_equal
10480 __ slt(AT, op1, op2);
10481 __ bne(AT, R0, L);
10482 __ delayed()->nop();
10483 __ mov_s(dst, src);
10484 __ bind(L);
10485 break;
10486 case 0x05: //less
10487 __ slt(AT, op1, op2);
10488 __ beq(AT, R0, L);
10489 __ delayed()->nop();
10490 __ mov_s(dst, src);
10491 __ bind(L);
10492 break;
10493 case 0x06: //less_equal
10494 __ slt(AT, op2, op1);
10495 __ bne(AT, R0, L);
10496 __ delayed()->nop();
10497 __ mov_s(dst, src);
10498 __ bind(L);
10499 break;
10500 default:
10501 Unimplemented();
10502 }
10503 %}
10505 ins_pipe( pipe_slow );
10506 %}
10508 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10509 match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10510 ins_cost(200);
10511 format %{
10512 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpI_reg_reg\n"
10513 "\tCMOV $dst, $src \t @cmovD_cmpI_reg_reg"
10514 %}
10516 ins_encode %{
10517 Register op1 = $tmp1$$Register;
10518 Register op2 = $tmp2$$Register;
10519 FloatRegister dst = as_FloatRegister($dst$$reg);
10520 FloatRegister src = as_FloatRegister($src$$reg);
10521 int flag = $cop$$cmpcode;
10522 Label L;
10524 switch(flag) {
10525 case 0x01: //equal
10526 __ bne(op1, op2, L);
10527 __ delayed()->nop();
10528 __ mov_d(dst, src);
10529 __ bind(L);
10530 break;
10531 case 0x02: //not_equal
10532 __ beq(op1, op2, L);
10533 __ delayed()->nop();
10534 __ mov_d(dst, src);
10535 __ bind(L);
10536 break;
10537 case 0x03: //great
10538 __ slt(AT, op2, op1);
10539 __ beq(AT, R0, L);
10540 __ delayed()->nop();
10541 __ mov_d(dst, src);
10542 __ bind(L);
10543 break;
10544 case 0x04: //great_equal
10545 __ slt(AT, op1, op2);
10546 __ bne(AT, R0, L);
10547 __ delayed()->nop();
10548 __ mov_d(dst, src);
10549 __ bind(L);
10550 break;
10551 case 0x05: //less
10552 __ slt(AT, op1, op2);
10553 __ beq(AT, R0, L);
10554 __ delayed()->nop();
10555 __ mov_d(dst, src);
10556 __ bind(L);
10557 break;
10558 case 0x06: //less_equal
10559 __ slt(AT, op2, op1);
10560 __ bne(AT, R0, L);
10561 __ delayed()->nop();
10562 __ mov_d(dst, src);
10563 __ bind(L);
10564 break;
10565 default:
10566 Unimplemented();
10567 }
10568 %}
10570 ins_pipe( pipe_slow );
10571 %}
10573 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
10574 match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
10575 ins_cost(200);
10576 format %{
10577 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpP_reg_reg\n"
10578 "\tCMOV $dst, $src \t @cmovD_cmpP_reg_reg"
10579 %}
10581 ins_encode %{
10582 Register op1 = $tmp1$$Register;
10583 Register op2 = $tmp2$$Register;
10584 FloatRegister dst = as_FloatRegister($dst$$reg);
10585 FloatRegister src = as_FloatRegister($src$$reg);
10586 int flag = $cop$$cmpcode;
10587 Label L;
10589 switch(flag) {
10590 case 0x01: //equal
10591 __ bne(op1, op2, L);
10592 __ delayed()->nop();
10593 __ mov_d(dst, src);
10594 __ bind(L);
10595 break;
10596 case 0x02: //not_equal
10597 __ beq(op1, op2, L);
10598 __ delayed()->nop();
10599 __ mov_d(dst, src);
10600 __ bind(L);
10601 break;
10602 case 0x03: //great
10603 __ slt(AT, op2, op1);
10604 __ beq(AT, R0, L);
10605 __ delayed()->nop();
10606 __ mov_d(dst, src);
10607 __ bind(L);
10608 break;
10609 case 0x04: //great_equal
10610 __ slt(AT, op1, op2);
10611 __ bne(AT, R0, L);
10612 __ delayed()->nop();
10613 __ mov_d(dst, src);
10614 __ bind(L);
10615 break;
10616 case 0x05: //less
10617 __ slt(AT, op1, op2);
10618 __ beq(AT, R0, L);
10619 __ delayed()->nop();
10620 __ mov_d(dst, src);
10621 __ bind(L);
10622 break;
10623 case 0x06: //less_equal
10624 __ slt(AT, op2, op1);
10625 __ bne(AT, R0, L);
10626 __ delayed()->nop();
10627 __ mov_d(dst, src);
10628 __ bind(L);
10629 break;
10630 default:
10631 Unimplemented();
10632 }
10633 %}
10635 ins_pipe( pipe_slow );
10636 %}
10638 //FIXME
10639 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
10640 match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
10641 ins_cost(80);
10642 format %{
10643 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpF_reg_reg\n"
10644 "\tCMOV $dst,$src \t @cmovI_cmpF_reg_reg"
10645 %}
10647 ins_encode %{
10648 FloatRegister reg_op1 = $tmp1$$FloatRegister;
10649 FloatRegister reg_op2 = $tmp2$$FloatRegister;
10650 Register dst = $dst$$Register;
10651 Register src = $src$$Register;
10652 int flag = $cop$$cmpcode;
10654 switch(flag) {
10655 case 0x01: //equal
10656 __ c_eq_s(reg_op1, reg_op2);
10657 __ movt(dst, src);
10658 break;
10659 case 0x02: //not_equal
10660 __ c_eq_s(reg_op1, reg_op2);
10661 __ movf(dst, src);
10662 break;
10663 case 0x03: //greater
10664 __ c_ole_s(reg_op1, reg_op2);
10665 __ movf(dst, src);
10666 break;
10667 case 0x04: //greater_equal
10668 __ c_olt_s(reg_op1, reg_op2);
10669 __ movf(dst, src);
10670 break;
10671 case 0x05: //less
10672 __ c_ult_s(reg_op1, reg_op2);
10673 __ movt(dst, src);
10674 break;
10675 case 0x06: //less_equal
10676 __ c_ule_s(reg_op1, reg_op2);
10677 __ movt(dst, src);
10678 break;
10679 default:
10680 Unimplemented();
10681 }
10682 %}
10683 ins_pipe( pipe_slow );
10684 %}
10686 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
10687 match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
10688 ins_cost(200);
10689 format %{
10690 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpF_reg_reg\n"
10691 "\tCMOV $dst,$src \t @cmovF_cmpF_reg_reg"
10692 %}
10694 ins_encode %{
10695 FloatRegister reg_op1 = $tmp1$$FloatRegister;
10696 FloatRegister reg_op2 = $tmp2$$FloatRegister;
10697 FloatRegister dst = $dst$$FloatRegister;
10698 FloatRegister src = $src$$FloatRegister;
10699 int flag = $cop$$cmpcode;
10701 switch(flag) {
10702 case 0x01: //equal
10703 __ c_eq_s(reg_op1, reg_op2);
10704 __ movt_s(dst, src);
10705 break;
10706 case 0x02: //not_equal
10707 __ c_eq_s(reg_op1, reg_op2);
10708 __ movf_s(dst, src);
10709 break;
10710 case 0x03: //greater
10711 __ c_ole_s(reg_op1, reg_op2);
10712 __ movf_s(dst, src);
10713 break;
10714 case 0x04: //greater_equal
10715 __ c_olt_s(reg_op1, reg_op2);
10716 __ movf_s(dst, src);
10717 break;
10718 case 0x05: //less
10719 __ c_ult_s(reg_op1, reg_op2);
10720 __ movt_s(dst, src);
10721 break;
10722 case 0x06: //less_equal
10723 __ c_ule_s(reg_op1, reg_op2);
10724 __ movt_s(dst, src);
10725 break;
10726 default:
10727 Unimplemented();
10728 }
10729 %}
10730 ins_pipe( pipe_slow );
10731 %}
10733 // Manifest a CmpL result in an integer register. Very painful.
10734 // This is the test to avoid.
10735 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
10736 match(Set dst (CmpL3 src1 src2));
10737 ins_cost(1000);
10738 format %{ "cmpL3 $dst, $src1, $src2 @ cmpL3_reg_reg" %}
10739 ins_encode %{
10740 Register opr1 = as_Register($src1$$reg);
10741 Register opr2 = as_Register($src2$$reg);
10742 Register dst = as_Register($dst$$reg);
10744 Label Done;
10746 __ subu(AT, opr1, opr2);
10747 __ bltz(AT, Done);
10748 __ delayed()->daddiu(dst, R0, -1);
10750 __ move(dst, 1);
10751 __ movz(dst, R0, AT);
10753 __ bind(Done);
10754 %}
10755 ins_pipe( pipe_slow );
10756 %}
10758 //
10759 // less_rsult = -1
10760 // greater_result = 1
10761 // equal_result = 0
10762 // nan_result = -1
10763 //
10764 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
10765 match(Set dst (CmpF3 src1 src2));
10766 ins_cost(1000);
10767 format %{ "cmpF3 $dst, $src1, $src2 @ cmpF3_reg_reg" %}
10768 ins_encode %{
10769 FloatRegister src1 = as_FloatRegister($src1$$reg);
10770 FloatRegister src2 = as_FloatRegister($src2$$reg);
10771 Register dst = as_Register($dst$$reg);
10773 Label Done;
10775 __ c_ult_s(src1, src2);
10776 __ bc1t(Done);
10777 __ delayed()->daddiu(dst, R0, -1);
10779 __ c_eq_s(src1, src2);
10780 __ move(dst, 1);
10781 __ movt(dst, R0);
10783 __ bind(Done);
10784 %}
10785 ins_pipe( pipe_slow );
10786 %}
10788 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
10789 match(Set dst (CmpD3 src1 src2));
10790 ins_cost(1000);
10791 format %{ "cmpD3 $dst, $src1, $src2 @ cmpD3_reg_reg" %}
10792 ins_encode %{
10793 FloatRegister src1 = as_FloatRegister($src1$$reg);
10794 FloatRegister src2 = as_FloatRegister($src2$$reg);
10795 Register dst = as_Register($dst$$reg);
10797 Label Done;
10799 __ c_ult_d(src1, src2);
10800 __ bc1t(Done);
10801 __ delayed()->daddiu(dst, R0, -1);
10803 __ c_eq_d(src1, src2);
10804 __ move(dst, 1);
10805 __ movt(dst, R0);
10807 __ bind(Done);
10808 %}
10809 ins_pipe( pipe_slow );
10810 %}
10812 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
10813 match(Set dummy (ClearArray cnt base));
10814 format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
10815 ins_encode %{
10816 //Assume cnt is the number of bytes in an array to be cleared,
10817 //and base points to the starting address of the array.
10818 Register base = $base$$Register;
10819 Register num = $cnt$$Register;
10820 Label Loop, done;
10822 __ beq(num, R0, done);
10823 __ delayed()->daddu(AT, base, R0);
10825 __ move(T9, num); /* T9 = words */
10827 __ bind(Loop);
10828 __ sd(R0, AT, 0);
10829 __ daddi(T9, T9, -1);
10830 __ bne(T9, R0, Loop);
10831 __ delayed()->daddi(AT, AT, wordSize);
10833 __ bind(done);
10834 %}
10835 ins_pipe( pipe_slow );
10836 %}
10838 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2, mA7RegI cnt2, no_Ax_mRegI result) %{
10839 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
10840 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
10842 format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
10843 ins_encode %{
10844 // Get the first character position in both strings
10845 // [8] char array, [12] offset, [16] count
10846 Register str1 = $str1$$Register;
10847 Register str2 = $str2$$Register;
10848 Register cnt1 = $cnt1$$Register;
10849 Register cnt2 = $cnt2$$Register;
10850 Register result = $result$$Register;
10852 Label L, Loop, haveResult, done;
10854 // compute the and difference of lengths (in result)
10855 __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
10857 // compute the shorter length (in cnt1)
10858 __ slt(AT, cnt2, cnt1);
10859 __ movn(cnt1, cnt2, AT);
10861 // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
10862 __ bind(Loop); // Loop begin
10863 __ beq(cnt1, R0, done);
10864 __ delayed()->lhu(AT, str1, 0);;
10866 // compare current character
10867 __ lhu(cnt2, str2, 0);
10868 __ bne(AT, cnt2, haveResult);
10869 __ delayed()->addi(str1, str1, 2);
10870 __ addi(str2, str2, 2);
10871 __ b(Loop);
10872 __ delayed()->addi(cnt1, cnt1, -1); // Loop end
10874 __ bind(haveResult);
10875 __ subu(result, AT, cnt2);
10877 __ bind(done);
10878 %}
10880 ins_pipe( pipe_slow );
10881 %}
10883 // intrinsic optimization
10884 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
10885 match(Set result (StrEquals (Binary str1 str2) cnt));
10886 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
10888 format %{ "String Equal $str1, $str2, len:$cnt tmp:$temp -> $result @ string_equals" %}
10889 ins_encode %{
10890 // Get the first character position in both strings
10891 // [8] char array, [12] offset, [16] count
10892 Register str1 = $str1$$Register;
10893 Register str2 = $str2$$Register;
10894 Register cnt = $cnt$$Register;
10895 Register tmp = $temp$$Register;
10896 Register result = $result$$Register;
10898 Label Loop, done;
10901 __ beq(str1, str2, done); // same char[] ?
10902 __ delayed()->daddiu(result, R0, 1);
10904 __ bind(Loop); // Loop begin
10905 __ beq(cnt, R0, done);
10906 __ delayed()->daddiu(result, R0, 1); // count == 0
10908 // compare current character
10909 __ lhu(AT, str1, 0);;
10910 __ lhu(tmp, str2, 0);
10911 __ bne(AT, tmp, done);
10912 __ delayed()->daddi(result, R0, 0);
10913 __ addi(str1, str1, 2);
10914 __ addi(str2, str2, 2);
10915 __ b(Loop);
10916 __ delayed()->addi(cnt, cnt, -1); // Loop end
10918 __ bind(done);
10919 %}
10921 ins_pipe( pipe_slow );
10922 %}
10924 //----------Arithmetic Instructions-------------------------------------------
10925 //----------Addition Instructions---------------------------------------------
10926 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10927 match(Set dst (AddI src1 src2));
10929 format %{ "add $dst, $src1, $src2 #@addI_Reg_Reg" %}
10930 ins_encode %{
10931 Register dst = $dst$$Register;
10932 Register src1 = $src1$$Register;
10933 Register src2 = $src2$$Register;
10934 __ addu32(dst, src1, src2);
10935 %}
10936 ins_pipe( ialu_regI_regI );
10937 %}
10939 instruct addI_Reg_imm(mRegI dst, mRegI src1, immI src2) %{
10940 match(Set dst (AddI src1 src2));
10942 format %{ "add $dst, $src1, $src2 #@addI_Reg_imm" %}
10943 ins_encode %{
10944 Register dst = $dst$$Register;
10945 Register src1 = $src1$$Register;
10946 int imm = $src2$$constant;
10948 if(Assembler::is_simm16(imm)) {
10949 __ addiu32(dst, src1, imm);
10950 } else {
10951 __ move(AT, imm);
10952 __ addu32(dst, src1, AT);
10953 }
10954 %}
10955 ins_pipe( ialu_regI_regI );
10956 %}
10958 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
10959 match(Set dst (AddP src1 src2));
10961 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg" %}
10963 ins_encode %{
10964 Register dst = $dst$$Register;
10965 Register src1 = $src1$$Register;
10966 Register src2 = $src2$$Register;
10967 __ daddu(dst, src1, src2);
10968 %}
10970 ins_pipe( ialu_regI_regI );
10971 %}
10973 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
10974 match(Set dst (AddP src1 (ConvI2L src2)));
10976 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
10978 ins_encode %{
10979 Register dst = $dst$$Register;
10980 Register src1 = $src1$$Register;
10981 Register src2 = $src2$$Register;
10982 __ daddu(dst, src1, src2);
10983 %}
10985 ins_pipe( ialu_regI_regI );
10986 %}
10988 instruct addP_reg_imm(mRegP dst, mRegP src1, immL src2) %{
10989 match(Set dst (AddP src1 src2));
10991 format %{ "daddi $dst, $src1, $src2 #@addP_reg_imm" %}
10992 ins_encode %{
10993 Register src1 = $src1$$Register;
10994 long src2 = $src2$$constant;
10995 Register dst = $dst$$Register;
10997 if(Assembler::is_simm16(src2)) {
10998 __ daddiu(dst, src1, src2);
10999 } else {
11000 __ set64(AT, src2);
11001 __ daddu(dst, src1, AT);
11002 }
11003 %}
11004 ins_pipe( ialu_regI_imm16 );
11005 %}
11007 // Add Long Register with Register
11008 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11009 match(Set dst (AddL src1 src2));
11010 ins_cost(200);
11011 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
11013 ins_encode %{
11014 Register dst_reg = as_Register($dst$$reg);
11015 Register src1_reg = as_Register($src1$$reg);
11016 Register src2_reg = as_Register($src2$$reg);
11018 __ daddu(dst_reg, src1_reg, src2_reg);
11019 %}
11021 ins_pipe( ialu_regL_regL );
11022 %}
11024 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
11025 %{
11026 match(Set dst (AddL src1 src2));
11028 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_imm " %}
11029 ins_encode %{
11030 Register dst_reg = as_Register($dst$$reg);
11031 Register src1_reg = as_Register($src1$$reg);
11032 int src2_imm = $src2$$constant;
11034 __ daddiu(dst_reg, src1_reg, src2_imm);
11035 %}
11037 ins_pipe( ialu_regL_regL );
11038 %}
11040 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
11041 %{
11042 match(Set dst (AddL (ConvI2L src1) src2));
11044 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_imm " %}
11045 ins_encode %{
11046 Register dst_reg = as_Register($dst$$reg);
11047 Register src1_reg = as_Register($src1$$reg);
11048 int src2_imm = $src2$$constant;
11050 __ daddiu(dst_reg, src1_reg, src2_imm);
11051 %}
11053 ins_pipe( ialu_regL_regL );
11054 %}
11056 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
11057 match(Set dst (AddL (ConvI2L src1) src2));
11058 ins_cost(200);
11059 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
11061 ins_encode %{
11062 Register dst_reg = as_Register($dst$$reg);
11063 Register src1_reg = as_Register($src1$$reg);
11064 Register src2_reg = as_Register($src2$$reg);
11066 __ daddu(dst_reg, src1_reg, src2_reg);
11067 %}
11069 ins_pipe( ialu_regL_regL );
11070 %}
11072 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
11073 match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
11074 ins_cost(200);
11075 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
11077 ins_encode %{
11078 Register dst_reg = as_Register($dst$$reg);
11079 Register src1_reg = as_Register($src1$$reg);
11080 Register src2_reg = as_Register($src2$$reg);
11082 __ daddu(dst_reg, src1_reg, src2_reg);
11083 %}
11085 ins_pipe( ialu_regL_regL );
11086 %}
11088 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
11089 match(Set dst (AddL src1 (ConvI2L src2)));
11090 ins_cost(200);
11091 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
11093 ins_encode %{
11094 Register dst_reg = as_Register($dst$$reg);
11095 Register src1_reg = as_Register($src1$$reg);
11096 Register src2_reg = as_Register($src2$$reg);
11098 __ daddu(dst_reg, src1_reg, src2_reg);
11099 %}
11101 ins_pipe( ialu_regL_regL );
11102 %}
11104 //----------Subtraction Instructions-------------------------------------------
11105 // Integer Subtraction Instructions
11106 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11107 match(Set dst (SubI src1 src2));
11108 ins_cost(100);
11110 format %{ "sub $dst, $src1, $src2 #@subI_Reg_Reg" %}
11111 ins_encode %{
11112 Register dst = $dst$$Register;
11113 Register src1 = $src1$$Register;
11114 Register src2 = $src2$$Register;
11115 __ subu32(dst, src1, src2);
11116 %}
11117 ins_pipe( ialu_regI_regI );
11118 %}
11120 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1, immI16_sub src2) %{
11121 match(Set dst (SubI src1 src2));
11122 ins_cost(80);
11124 format %{ "sub $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
11125 ins_encode %{
11126 Register dst = $dst$$Register;
11127 Register src1 = $src1$$Register;
11128 __ addiu32(dst, src1, -1 * $src2$$constant);
11129 %}
11130 ins_pipe( ialu_regI_regI );
11131 %}
11133 instruct negI_Reg(mRegI dst, immI0 zero, mRegI src) %{
11134 match(Set dst (SubI zero src));
11135 ins_cost(80);
11137 format %{ "neg $dst, $src #@negI_Reg" %}
11138 ins_encode %{
11139 Register dst = $dst$$Register;
11140 Register src = $src$$Register;
11141 __ subu32(dst, R0, src);
11142 %}
11143 ins_pipe( ialu_regI_regI );
11144 %}
11146 instruct negL_Reg(mRegL dst, immL0 zero, mRegL src) %{
11147 match(Set dst (SubL zero src));
11148 ins_cost(80);
11150 format %{ "neg $dst, $src #@negL_Reg" %}
11151 ins_encode %{
11152 Register dst = $dst$$Register;
11153 Register src = $src$$Register;
11154 __ subu(dst, R0, src);
11155 %}
11156 ins_pipe( ialu_regI_regI );
11157 %}
11159 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1, immL16_sub src2) %{
11160 match(Set dst (SubL src1 src2));
11161 ins_cost(80);
11163 format %{ "sub $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
11164 ins_encode %{
11165 Register dst = $dst$$Register;
11166 Register src1 = $src1$$Register;
11167 __ daddiu(dst, src1, -1 * $src2$$constant);
11168 %}
11169 ins_pipe( ialu_regI_regI );
11170 %}
11172 // Subtract Long Register with Register.
11173 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11174 match(Set dst (SubL src1 src2));
11175 ins_cost(100);
11176 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_Reg" %}
11177 ins_encode %{
11178 Register dst = as_Register($dst$$reg);
11179 Register src1 = as_Register($src1$$reg);
11180 Register src2 = as_Register($src2$$reg);
11182 __ subu(dst, src1, src2);
11183 %}
11184 ins_pipe( ialu_regL_regL );
11185 %}
11187 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
11188 match(Set dst (SubL src1 (ConvI2L src2)));
11189 ins_cost(100);
11190 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
11191 ins_encode %{
11192 Register dst = as_Register($dst$$reg);
11193 Register src1 = as_Register($src1$$reg);
11194 Register src2 = as_Register($src2$$reg);
11196 __ subu(dst, src1, src2);
11197 %}
11198 ins_pipe( ialu_regL_regL );
11199 %}
11201 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
11202 match(Set dst (SubL (ConvI2L src1) src2));
11203 ins_cost(200);
11204 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
11205 ins_encode %{
11206 Register dst = as_Register($dst$$reg);
11207 Register src1 = as_Register($src1$$reg);
11208 Register src2 = as_Register($src2$$reg);
11210 __ subu(dst, src1, src2);
11211 %}
11212 ins_pipe( ialu_regL_regL );
11213 %}
11215 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
11216 match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
11217 ins_cost(200);
11218 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
11219 ins_encode %{
11220 Register dst = as_Register($dst$$reg);
11221 Register src1 = as_Register($src1$$reg);
11222 Register src2 = as_Register($src2$$reg);
11224 __ subu(dst, src1, src2);
11225 %}
11226 ins_pipe( ialu_regL_regL );
11227 %}
11229 // Integer MOD with Register
11230 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11231 match(Set dst (ModI src1 src2));
11232 ins_cost(300);
11233 format %{ "modi $dst, $src1, $src2 @ modI_Reg_Reg" %}
11234 ins_encode %{
11235 Register dst = $dst$$Register;
11236 Register src1 = $src1$$Register;
11237 Register src2 = $src2$$Register;
11239 //if (UseLoongsonISA) {
11240 if (0) {
11241 // 2016.08.10
11242 // Experiments show that gsmod is slower that div+mfhi.
11243 // So I just disable it here.
11244 __ gsmod(dst, src1, src2);
11245 } else {
11246 __ div(src1, src2);
11247 __ mfhi(dst);
11248 }
11249 %}
11251 //ins_pipe( ialu_mod );
11252 ins_pipe( ialu_regI_regI );
11253 %}
11255 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11256 match(Set dst (ModL src1 src2));
11257 format %{ "modL $dst, $src1, $src2 @modL_reg_reg" %}
11259 ins_encode %{
11260 Register dst = as_Register($dst$$reg);
11261 Register op1 = as_Register($src1$$reg);
11262 Register op2 = as_Register($src2$$reg);
11264 if (UseLoongsonISA) {
11265 __ gsdmod(dst, op1, op2);
11266 } else {
11267 __ ddiv(op1, op2);
11268 __ mfhi(dst);
11269 }
11270 %}
11271 ins_pipe( pipe_slow );
11272 %}
11274 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11275 match(Set dst (MulI src1 src2));
11277 ins_cost(300);
11278 format %{ "mul $dst, $src1, $src2 @ mulI_Reg_Reg" %}
11279 ins_encode %{
11280 Register src1 = $src1$$Register;
11281 Register src2 = $src2$$Register;
11282 Register dst = $dst$$Register;
11284 __ mul(dst, src1, src2);
11285 %}
11286 ins_pipe( ialu_mult );
11287 %}
11289 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
11290 match(Set dst (AddI (MulI src1 src2) src3));
11292 ins_cost(999);
11293 format %{ "madd $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
11294 ins_encode %{
11295 Register src1 = $src1$$Register;
11296 Register src2 = $src2$$Register;
11297 Register src3 = $src3$$Register;
11298 Register dst = $dst$$Register;
11300 __ mtlo(src3);
11301 __ madd(src1, src2);
11302 __ mflo(dst);
11303 %}
11304 ins_pipe( ialu_mult );
11305 %}
11307 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11308 match(Set dst (DivI src1 src2));
11310 ins_cost(300);
11311 format %{ "div $dst, $src1, $src2 @ divI_Reg_Reg" %}
11312 ins_encode %{
11313 Register src1 = $src1$$Register;
11314 Register src2 = $src2$$Register;
11315 Register dst = $dst$$Register;
11317 // In MIPS, div does not cause exception.
11318 // We must trap an exception manually.
11319 __ teq(R0, src2, 0x7);
11321 if (UseLoongsonISA) {
11322 __ gsdiv(dst, src1, src2);
11323 } else {
11324 __ div(src1, src2);
11326 __ nop();
11327 __ nop();
11328 __ mflo(dst);
11329 }
11330 %}
11331 ins_pipe( ialu_mod );
11332 %}
11334 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
11335 match(Set dst (DivF src1 src2));
11337 ins_cost(300);
11338 format %{ "divF $dst, $src1, $src2 @ divF_Reg_Reg" %}
11339 ins_encode %{
11340 FloatRegister src1 = $src1$$FloatRegister;
11341 FloatRegister src2 = $src2$$FloatRegister;
11342 FloatRegister dst = $dst$$FloatRegister;
11344 /* Here do we need to trap an exception manually ? */
11345 __ div_s(dst, src1, src2);
11346 %}
11347 ins_pipe( pipe_slow );
11348 %}
11350 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
11351 match(Set dst (DivD src1 src2));
11353 ins_cost(300);
11354 format %{ "divD $dst, $src1, $src2 @ divD_Reg_Reg" %}
11355 ins_encode %{
11356 FloatRegister src1 = $src1$$FloatRegister;
11357 FloatRegister src2 = $src2$$FloatRegister;
11358 FloatRegister dst = $dst$$FloatRegister;
11360 /* Here do we need to trap an exception manually ? */
11361 __ div_d(dst, src1, src2);
11362 %}
11363 ins_pipe( pipe_slow );
11364 %}
11366 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11367 match(Set dst (MulL src1 src2));
11368 format %{ "mulL $dst, $src1, $src2 @mulL_reg_reg" %}
11369 ins_encode %{
11370 Register dst = as_Register($dst$$reg);
11371 Register op1 = as_Register($src1$$reg);
11372 Register op2 = as_Register($src2$$reg);
11374 if (UseLoongsonISA) {
11375 __ gsdmult(dst, op1, op2);
11376 } else {
11377 __ dmult(op1, op2);
11378 __ mflo(dst);
11379 }
11380 %}
11381 ins_pipe( pipe_slow );
11382 %}
11384 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
11385 match(Set dst (MulL src1 (ConvI2L src2)));
11386 format %{ "mulL $dst, $src1, $src2 @mulL_reg_regI2L" %}
11387 ins_encode %{
11388 Register dst = as_Register($dst$$reg);
11389 Register op1 = as_Register($src1$$reg);
11390 Register op2 = as_Register($src2$$reg);
11392 if (UseLoongsonISA) {
11393 __ gsdmult(dst, op1, op2);
11394 } else {
11395 __ dmult(op1, op2);
11396 __ mflo(dst);
11397 }
11398 %}
11399 ins_pipe( pipe_slow );
11400 %}
11402 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11403 match(Set dst (DivL src1 src2));
11404 format %{ "divL $dst, $src1, $src2 @divL_reg_reg" %}
11406 ins_encode %{
11407 Register dst = as_Register($dst$$reg);
11408 Register op1 = as_Register($src1$$reg);
11409 Register op2 = as_Register($src2$$reg);
11411 if (UseLoongsonISA) {
11412 __ gsddiv(dst, op1, op2);
11413 } else {
11414 __ ddiv(op1, op2);
11415 __ mflo(dst);
11416 }
11417 %}
11418 ins_pipe( pipe_slow );
11419 %}
11421 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
11422 match(Set dst (AddF src1 src2));
11423 format %{ "AddF $dst, $src1, $src2 @addF_reg_reg" %}
11424 ins_encode %{
11425 FloatRegister src1 = as_FloatRegister($src1$$reg);
11426 FloatRegister src2 = as_FloatRegister($src2$$reg);
11427 FloatRegister dst = as_FloatRegister($dst$$reg);
11429 __ add_s(dst, src1, src2);
11430 %}
11431 ins_pipe( fpu_regF_regF );
11432 %}
11434 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
11435 match(Set dst (SubF src1 src2));
11436 format %{ "SubF $dst, $src1, $src2 @subF_reg_reg" %}
11437 ins_encode %{
11438 FloatRegister src1 = as_FloatRegister($src1$$reg);
11439 FloatRegister src2 = as_FloatRegister($src2$$reg);
11440 FloatRegister dst = as_FloatRegister($dst$$reg);
11442 __ sub_s(dst, src1, src2);
11443 %}
11444 ins_pipe( fpu_regF_regF );
11445 %}
11446 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
11447 match(Set dst (AddD src1 src2));
11448 format %{ "AddD $dst, $src1, $src2 @addD_reg_reg" %}
11449 ins_encode %{
11450 FloatRegister src1 = as_FloatRegister($src1$$reg);
11451 FloatRegister src2 = as_FloatRegister($src2$$reg);
11452 FloatRegister dst = as_FloatRegister($dst$$reg);
11454 __ add_d(dst, src1, src2);
11455 %}
11456 ins_pipe( fpu_regF_regF );
11457 %}
11459 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
11460 match(Set dst (SubD src1 src2));
11461 format %{ "SubD $dst, $src1, $src2 @subD_reg_reg" %}
11462 ins_encode %{
11463 FloatRegister src1 = as_FloatRegister($src1$$reg);
11464 FloatRegister src2 = as_FloatRegister($src2$$reg);
11465 FloatRegister dst = as_FloatRegister($dst$$reg);
11467 __ sub_d(dst, src1, src2);
11468 %}
11469 ins_pipe( fpu_regF_regF );
11470 %}
11472 instruct negF_reg(regF dst, regF src) %{
11473 match(Set dst (NegF src));
11474 format %{ "negF $dst, $src @negF_reg" %}
11475 ins_encode %{
11476 FloatRegister src = as_FloatRegister($src$$reg);
11477 FloatRegister dst = as_FloatRegister($dst$$reg);
11479 __ neg_s(dst, src);
11480 %}
11481 ins_pipe( fpu_regF_regF );
11482 %}
11484 instruct negD_reg(regD dst, regD src) %{
11485 match(Set dst (NegD src));
11486 format %{ "negD $dst, $src @negD_reg" %}
11487 ins_encode %{
11488 FloatRegister src = as_FloatRegister($src$$reg);
11489 FloatRegister dst = as_FloatRegister($dst$$reg);
11491 __ neg_d(dst, src);
11492 %}
11493 ins_pipe( fpu_regF_regF );
11494 %}
11497 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
11498 match(Set dst (MulF src1 src2));
11499 format %{ "MULF $dst, $src1, $src2 @mulF_reg_reg" %}
11500 ins_encode %{
11501 FloatRegister src1 = $src1$$FloatRegister;
11502 FloatRegister src2 = $src2$$FloatRegister;
11503 FloatRegister dst = $dst$$FloatRegister;
11505 __ mul_s(dst, src1, src2);
11506 %}
11507 ins_pipe( fpu_regF_regF );
11508 %}
11510 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
11511 match(Set dst (AddF (MulF src1 src2) src3));
11512 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
11513 ins_cost(44444);
11514 format %{ "maddF $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
11515 ins_encode %{
11516 FloatRegister src1 = $src1$$FloatRegister;
11517 FloatRegister src2 = $src2$$FloatRegister;
11518 FloatRegister src3 = $src3$$FloatRegister;
11519 FloatRegister dst = $dst$$FloatRegister;
11521 __ madd_s(dst, src1, src2, src3);
11522 %}
11523 ins_pipe( fpu_regF_regF );
11524 %}
11526 // Mul two double precision floating piont number
11527 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
11528 match(Set dst (MulD src1 src2));
11529 format %{ "MULD $dst, $src1, $src2 @mulD_reg_reg" %}
11530 ins_encode %{
11531 FloatRegister src1 = $src1$$FloatRegister;
11532 FloatRegister src2 = $src2$$FloatRegister;
11533 FloatRegister dst = $dst$$FloatRegister;
11535 __ mul_d(dst, src1, src2);
11536 %}
11537 ins_pipe( fpu_regF_regF );
11538 %}
11540 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
11541 match(Set dst (AddD (MulD src1 src2) src3));
11542 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
11543 ins_cost(44444);
11544 format %{ "maddD $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
11545 ins_encode %{
11546 FloatRegister src1 = $src1$$FloatRegister;
11547 FloatRegister src2 = $src2$$FloatRegister;
11548 FloatRegister src3 = $src3$$FloatRegister;
11549 FloatRegister dst = $dst$$FloatRegister;
11551 __ madd_d(dst, src1, src2, src3);
11552 %}
11553 ins_pipe( fpu_regF_regF );
11554 %}
11556 instruct absF_reg(regF dst, regF src) %{
11557 match(Set dst (AbsF src));
11558 ins_cost(100);
11559 format %{ "absF $dst, $src @absF_reg" %}
11560 ins_encode %{
11561 FloatRegister src = as_FloatRegister($src$$reg);
11562 FloatRegister dst = as_FloatRegister($dst$$reg);
11564 __ abs_s(dst, src);
11565 %}
11566 ins_pipe( fpu_regF_regF );
11567 %}
11570 // intrinsics for math_native.
11571 // AbsD SqrtD CosD SinD TanD LogD Log10D
11573 instruct absD_reg(regD dst, regD src) %{
11574 match(Set dst (AbsD src));
11575 ins_cost(100);
11576 format %{ "absD $dst, $src @absD_reg" %}
11577 ins_encode %{
11578 FloatRegister src = as_FloatRegister($src$$reg);
11579 FloatRegister dst = as_FloatRegister($dst$$reg);
11581 __ abs_d(dst, src);
11582 %}
11583 ins_pipe( fpu_regF_regF );
11584 %}
11586 instruct sqrtD_reg(regD dst, regD src) %{
11587 match(Set dst (SqrtD src));
11588 ins_cost(100);
11589 format %{ "SqrtD $dst, $src @sqrtD_reg" %}
11590 ins_encode %{
11591 FloatRegister src = as_FloatRegister($src$$reg);
11592 FloatRegister dst = as_FloatRegister($dst$$reg);
11594 __ sqrt_d(dst, src);
11595 %}
11596 ins_pipe( fpu_regF_regF );
11597 %}
11599 instruct sqrtF_reg(regF dst, regF src) %{
11600 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
11601 ins_cost(100);
11602 format %{ "SqrtF $dst, $src @sqrtF_reg" %}
11603 ins_encode %{
11604 FloatRegister src = as_FloatRegister($src$$reg);
11605 FloatRegister dst = as_FloatRegister($dst$$reg);
11607 __ sqrt_s(dst, src);
11608 %}
11609 ins_pipe( fpu_regF_regF );
11610 %}
11611 //----------------------------------Logical Instructions----------------------
11612 //__________________________________Integer Logical Instructions-------------
11614 //And Instuctions
11615 // And Register with Immediate
11616 instruct andI_Reg_immI(mRegI dst, mRegI src1, immI src2) %{
11617 match(Set dst (AndI src1 src2));
11619 format %{ "and $dst, $src1, $src2 #@andI_Reg_immI" %}
11620 ins_encode %{
11621 Register dst = $dst$$Register;
11622 Register src = $src1$$Register;
11623 int val = $src2$$constant;
11625 __ move(AT, val);
11626 __ andr(dst, src, AT);
11627 %}
11628 ins_pipe( ialu_regI_regI );
11629 %}
11631 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
11632 match(Set dst (AndI src1 src2));
11633 ins_cost(60);
11635 format %{ "and $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
11636 ins_encode %{
11637 Register dst = $dst$$Register;
11638 Register src = $src1$$Register;
11639 int val = $src2$$constant;
11641 __ andi(dst, src, val);
11642 %}
11643 ins_pipe( ialu_regI_regI );
11644 %}
11646 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1, immI_nonneg_mask mask) %{
11647 match(Set dst (AndI src1 mask));
11648 ins_cost(60);
11650 format %{ "and $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
11651 ins_encode %{
11652 Register dst = $dst$$Register;
11653 Register src = $src1$$Register;
11654 int size = Assembler::is_int_mask($mask$$constant);
11656 __ ext(dst, src, 0, size);
11657 %}
11658 ins_pipe( ialu_regI_regI );
11659 %}
11661 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1, immL_nonneg_mask mask) %{
11662 match(Set dst (AndL src1 mask));
11663 ins_cost(60);
11665 format %{ "and $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
11666 ins_encode %{
11667 Register dst = $dst$$Register;
11668 Register src = $src1$$Register;
11669 int size = Assembler::is_jlong_mask($mask$$constant);
11671 __ dext(dst, src, 0, size);
11672 %}
11673 ins_pipe( ialu_regI_regI );
11674 %}
11676 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
11677 match(Set dst (XorI src1 src2));
11678 ins_cost(60);
11680 format %{ "xori $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
11681 ins_encode %{
11682 Register dst = $dst$$Register;
11683 Register src = $src1$$Register;
11684 int val = $src2$$constant;
11686 __ xori(dst, src, val);
11687 %}
11688 ins_pipe( ialu_regI_regI );
11689 %}
11691 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1, immI_M1 M1) %{
11692 match(Set dst (XorI src1 M1));
11693 predicate(UseLoongsonISA && Use3A2000);
11694 ins_cost(60);
11696 format %{ "xor $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
11697 ins_encode %{
11698 Register dst = $dst$$Register;
11699 Register src = $src1$$Register;
11701 __ gsorn(dst, R0, src);
11702 %}
11703 ins_pipe( ialu_regI_regI );
11704 %}
11706 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1, immI_M1 M1) %{
11707 match(Set dst (XorI (ConvL2I src1) M1));
11708 predicate(UseLoongsonISA && Use3A2000);
11709 ins_cost(60);
11711 format %{ "xor $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
11712 ins_encode %{
11713 Register dst = $dst$$Register;
11714 Register src = $src1$$Register;
11716 __ gsorn(dst, R0, src);
11717 %}
11718 ins_pipe( ialu_regI_regI );
11719 %}
11721 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
11722 match(Set dst (XorL src1 src2));
11723 ins_cost(60);
11725 format %{ "xori $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
11726 ins_encode %{
11727 Register dst = $dst$$Register;
11728 Register src = $src1$$Register;
11729 int val = $src2$$constant;
11731 __ xori(dst, src, val);
11732 %}
11733 ins_pipe( ialu_regI_regI );
11734 %}
11736 /*
11737 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1, immL_M1 M1) %{
11738 match(Set dst (XorL src1 M1));
11739 predicate(UseLoongsonISA);
11740 ins_cost(60);
11742 format %{ "xor $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
11743 ins_encode %{
11744 Register dst = $dst$$Register;
11745 Register src = $src1$$Register;
11747 __ gsorn(dst, R0, src);
11748 %}
11749 ins_pipe( ialu_regI_regI );
11750 %}
11751 */
11753 instruct lbu_and_lmask(mRegI dst, memory mem, immI_255 mask) %{
11754 match(Set dst (AndI mask (LoadB mem)));
11755 ins_cost(60);
11757 format %{ "lhu $dst, $mem #@lbu_and_lmask" %}
11758 ins_encode(load_UB_enc(dst, mem));
11759 ins_pipe( ialu_loadI );
11760 %}
11762 instruct lbu_and_rmask(mRegI dst, memory mem, immI_255 mask) %{
11763 match(Set dst (AndI (LoadB mem) mask));
11764 ins_cost(60);
11766 format %{ "lhu $dst, $mem #@lbu_and_rmask" %}
11767 ins_encode(load_UB_enc(dst, mem));
11768 ins_pipe( ialu_loadI );
11769 %}
11771 instruct andI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11772 match(Set dst (AndI src1 src2));
11774 format %{ "and $dst, $src1, $src2 #@andI_Reg_Reg" %}
11775 ins_encode %{
11776 Register dst = $dst$$Register;
11777 Register src1 = $src1$$Register;
11778 Register src2 = $src2$$Register;
11779 __ andr(dst, src1, src2);
11780 %}
11781 ins_pipe( ialu_regI_regI );
11782 %}
11784 instruct andnI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11785 match(Set dst (AndI src1 (XorI src2 M1)));
11786 predicate(UseLoongsonISA && Use3A2000);
11788 format %{ "andn $dst, $src1, $src2 #@andnI_Reg_nReg" %}
11789 ins_encode %{
11790 Register dst = $dst$$Register;
11791 Register src1 = $src1$$Register;
11792 Register src2 = $src2$$Register;
11794 __ gsandn(dst, src1, src2);
11795 %}
11796 ins_pipe( ialu_regI_regI );
11797 %}
11799 instruct ornI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11800 match(Set dst (OrI src1 (XorI src2 M1)));
11801 predicate(UseLoongsonISA && Use3A2000);
11803 format %{ "orn $dst, $src1, $src2 #@ornI_Reg_nReg" %}
11804 ins_encode %{
11805 Register dst = $dst$$Register;
11806 Register src1 = $src1$$Register;
11807 Register src2 = $src2$$Register;
11809 __ gsorn(dst, src1, src2);
11810 %}
11811 ins_pipe( ialu_regI_regI );
11812 %}
11814 instruct andnI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11815 match(Set dst (AndI (XorI src1 M1) src2));
11816 predicate(UseLoongsonISA && Use3A2000);
11818 format %{ "andn $dst, $src2, $src1 #@andnI_nReg_Reg" %}
11819 ins_encode %{
11820 Register dst = $dst$$Register;
11821 Register src1 = $src1$$Register;
11822 Register src2 = $src2$$Register;
11824 __ gsandn(dst, src2, src1);
11825 %}
11826 ins_pipe( ialu_regI_regI );
11827 %}
11829 instruct ornI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11830 match(Set dst (OrI (XorI src1 M1) src2));
11831 predicate(UseLoongsonISA && Use3A2000);
11833 format %{ "orn $dst, $src2, $src1 #@ornI_nReg_Reg" %}
11834 ins_encode %{
11835 Register dst = $dst$$Register;
11836 Register src1 = $src1$$Register;
11837 Register src2 = $src2$$Register;
11839 __ gsorn(dst, src2, src1);
11840 %}
11841 ins_pipe( ialu_regI_regI );
11842 %}
11844 // And Long Register with Register
11845 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11846 match(Set dst (AndL src1 src2));
11847 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
11848 ins_encode %{
11849 Register dst_reg = as_Register($dst$$reg);
11850 Register src1_reg = as_Register($src1$$reg);
11851 Register src2_reg = as_Register($src2$$reg);
11853 __ andr(dst_reg, src1_reg, src2_reg);
11854 %}
11855 ins_pipe( ialu_regL_regL );
11856 %}
11858 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
11859 match(Set dst (AndL src1 (ConvI2L src2)));
11860 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
11861 ins_encode %{
11862 Register dst_reg = as_Register($dst$$reg);
11863 Register src1_reg = as_Register($src1$$reg);
11864 Register src2_reg = as_Register($src2$$reg);
11866 __ andr(dst_reg, src1_reg, src2_reg);
11867 %}
11868 ins_pipe( ialu_regL_regL );
11869 %}
11871 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
11872 match(Set dst (AndL src1 src2));
11873 ins_cost(60);
11875 format %{ "and $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
11876 ins_encode %{
11877 Register dst = $dst$$Register;
11878 Register src = $src1$$Register;
11879 long val = $src2$$constant;
11881 __ andi(dst, src, val);
11882 %}
11883 ins_pipe( ialu_regI_regI );
11884 %}
11886 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1, immL_0_65535 src2) %{
11887 match(Set dst (ConvL2I (AndL src1 src2)));
11888 ins_cost(60);
11890 format %{ "and $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
11891 ins_encode %{
11892 Register dst = $dst$$Register;
11893 Register src = $src1$$Register;
11894 long val = $src2$$constant;
11896 __ andi(dst, src, val);
11897 %}
11898 ins_pipe( ialu_regI_regI );
11899 %}
11901 /*
11902 instruct andnL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11903 match(Set dst (AndL src1 (XorL src2 M1)));
11904 predicate(UseLoongsonISA);
11906 format %{ "andn $dst, $src1, $src2 #@andnL_Reg_nReg" %}
11907 ins_encode %{
11908 Register dst = $dst$$Register;
11909 Register src1 = $src1$$Register;
11910 Register src2 = $src2$$Register;
11912 __ gsandn(dst, src1, src2);
11913 %}
11914 ins_pipe( ialu_regI_regI );
11915 %}
11916 */
11918 /*
11919 instruct ornL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11920 match(Set dst (OrL src1 (XorL src2 M1)));
11921 predicate(UseLoongsonISA);
11923 format %{ "orn $dst, $src1, $src2 #@ornL_Reg_nReg" %}
11924 ins_encode %{
11925 Register dst = $dst$$Register;
11926 Register src1 = $src1$$Register;
11927 Register src2 = $src2$$Register;
11929 __ gsorn(dst, src1, src2);
11930 %}
11931 ins_pipe( ialu_regI_regI );
11932 %}
11933 */
11935 /*
11936 instruct andnL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11937 match(Set dst (AndL (XorL src1 M1) src2));
11938 predicate(UseLoongsonISA);
11940 format %{ "andn $dst, $src2, $src1 #@andnL_nReg_Reg" %}
11941 ins_encode %{
11942 Register dst = $dst$$Register;
11943 Register src1 = $src1$$Register;
11944 Register src2 = $src2$$Register;
11946 __ gsandn(dst, src2, src1);
11947 %}
11948 ins_pipe( ialu_regI_regI );
11949 %}
11950 */
11952 /*
11953 instruct ornL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11954 match(Set dst (OrL (XorL src1 M1) src2));
11955 predicate(UseLoongsonISA);
11957 format %{ "orn $dst, $src2, $src1 #@ornL_nReg_Reg" %}
11958 ins_encode %{
11959 Register dst = $dst$$Register;
11960 Register src1 = $src1$$Register;
11961 Register src2 = $src2$$Register;
11963 __ gsorn(dst, src2, src1);
11964 %}
11965 ins_pipe( ialu_regI_regI );
11966 %}
11967 */
11969 instruct andL_Reg_immL_M8(mRegL dst, immL_M8 M8) %{
11970 match(Set dst (AndL dst M8));
11971 ins_cost(60);
11973 format %{ "and $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
11974 ins_encode %{
11975 Register dst = $dst$$Register;
11977 __ dins(dst, R0, 0, 3);
11978 %}
11979 ins_pipe( ialu_regI_regI );
11980 %}
11982 instruct andL_Reg_immL_M5(mRegL dst, immL_M5 M5) %{
11983 match(Set dst (AndL dst M5));
11984 ins_cost(60);
11986 format %{ "and $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
11987 ins_encode %{
11988 Register dst = $dst$$Register;
11990 __ dins(dst, R0, 2, 1);
11991 %}
11992 ins_pipe( ialu_regI_regI );
11993 %}
11995 instruct andL_Reg_immL_M7(mRegL dst, immL_M7 M7) %{
11996 match(Set dst (AndL dst M7));
11997 ins_cost(60);
11999 format %{ "and $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
12000 ins_encode %{
12001 Register dst = $dst$$Register;
12003 __ dins(dst, R0, 1, 2);
12004 %}
12005 ins_pipe( ialu_regI_regI );
12006 %}
12008 instruct andL_Reg_immL_M4(mRegL dst, immL_M4 M4) %{
12009 match(Set dst (AndL dst M4));
12010 ins_cost(60);
12012 format %{ "and $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
12013 ins_encode %{
12014 Register dst = $dst$$Register;
12016 __ dins(dst, R0, 0, 2);
12017 %}
12018 ins_pipe( ialu_regI_regI );
12019 %}
12021 instruct andL_Reg_immL_M121(mRegL dst, immL_M121 M121) %{
12022 match(Set dst (AndL dst M121));
12023 ins_cost(60);
12025 format %{ "and $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
12026 ins_encode %{
12027 Register dst = $dst$$Register;
12029 __ dins(dst, R0, 3, 4);
12030 %}
12031 ins_pipe( ialu_regI_regI );
12032 %}
12034 // Or Long Register with Register
12035 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
12036 match(Set dst (OrL src1 src2));
12037 format %{ "OR $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
12038 ins_encode %{
12039 Register dst_reg = $dst$$Register;
12040 Register src1_reg = $src1$$Register;
12041 Register src2_reg = $src2$$Register;
12043 __ orr(dst_reg, src1_reg, src2_reg);
12044 %}
12045 ins_pipe( ialu_regL_regL );
12046 %}
12048 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
12049 match(Set dst (OrL (CastP2X src1) src2));
12050 format %{ "OR $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
12051 ins_encode %{
12052 Register dst_reg = $dst$$Register;
12053 Register src1_reg = $src1$$Register;
12054 Register src2_reg = $src2$$Register;
12056 __ orr(dst_reg, src1_reg, src2_reg);
12057 %}
12058 ins_pipe( ialu_regL_regL );
12059 %}
12061 // Xor Long Register with Register
12062 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
12063 match(Set dst (XorL src1 src2));
12064 format %{ "XOR $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
12065 ins_encode %{
12066 Register dst_reg = as_Register($dst$$reg);
12067 Register src1_reg = as_Register($src1$$reg);
12068 Register src2_reg = as_Register($src2$$reg);
12070 __ xorr(dst_reg, src1_reg, src2_reg);
12071 %}
12072 ins_pipe( ialu_regL_regL );
12073 %}
12075 // Shift Left by 8-bit immediate
12076 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
12077 match(Set dst (LShiftI src shift));
12079 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm" %}
12080 ins_encode %{
12081 Register src = $src$$Register;
12082 Register dst = $dst$$Register;
12083 int shamt = $shift$$constant;
12085 __ sll(dst, src, shamt);
12086 %}
12087 ins_pipe( ialu_regI_regI );
12088 %}
12090 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
12091 match(Set dst (LShiftI (ConvL2I src) shift));
12093 format %{ "SHL $dst, $src, $shift #@salL2I_Reg_imm" %}
12094 ins_encode %{
12095 Register src = $src$$Register;
12096 Register dst = $dst$$Register;
12097 int shamt = $shift$$constant;
12099 __ sll(dst, src, shamt);
12100 %}
12101 ins_pipe( ialu_regI_regI );
12102 %}
12104 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
12105 match(Set dst (AndI (LShiftI src shift) mask));
12107 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
12108 ins_encode %{
12109 Register src = $src$$Register;
12110 Register dst = $dst$$Register;
12112 __ sll(dst, src, 16);
12113 %}
12114 ins_pipe( ialu_regI_regI );
12115 %}
12117 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
12118 %{
12119 match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
12121 format %{ "andi $dst, $src, 7\t# @land7_2_s" %}
12122 ins_encode %{
12123 Register src = $src$$Register;
12124 Register dst = $dst$$Register;
12126 __ andi(dst, src, 7);
12127 %}
12128 ins_pipe(ialu_regI_regI);
12129 %}
12131 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
12132 %{
12133 match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
12135 format %{ "ori $dst, $src1, $src2\t# @ori2s" %}
12136 ins_encode %{
12137 Register src = $src1$$Register;
12138 int val = $src2$$constant;
12139 Register dst = $dst$$Register;
12141 __ ori(dst, src, val);
12142 %}
12143 ins_pipe(ialu_regI_regI);
12144 %}
12146 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
12147 // This idiom is used by the compiler the i2s bytecode.
12148 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
12149 %{
12150 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
12152 format %{ "i2s $dst, $src\t# @i2s" %}
12153 ins_encode %{
12154 Register src = $src$$Register;
12155 Register dst = $dst$$Register;
12157 __ seh(dst, src);
12158 %}
12159 ins_pipe(ialu_regI_regI);
12160 %}
12162 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
12163 // This idiom is used by the compiler for the i2b bytecode.
12164 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
12165 %{
12166 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
12168 format %{ "i2b $dst, $src\t# @i2b" %}
12169 ins_encode %{
12170 Register src = $src$$Register;
12171 Register dst = $dst$$Register;
12173 __ seb(dst, src);
12174 %}
12175 ins_pipe(ialu_regI_regI);
12176 %}
12179 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
12180 match(Set dst (LShiftI (ConvL2I src) shift));
12182 format %{ "SHL $dst, $src, $shift #@salI_RegL2I_imm" %}
12183 ins_encode %{
12184 Register src = $src$$Register;
12185 Register dst = $dst$$Register;
12186 int shamt = $shift$$constant;
12188 __ sll(dst, src, shamt);
12189 %}
12190 ins_pipe( ialu_regI_regI );
12191 %}
12193 // Shift Left by 8-bit immediate
12194 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12195 match(Set dst (LShiftI src shift));
12197 format %{ "SHL $dst, $src, $shift #@salI_Reg_Reg" %}
12198 ins_encode %{
12199 Register src = $src$$Register;
12200 Register dst = $dst$$Register;
12201 Register shamt = $shift$$Register;
12202 __ sllv(dst, src, shamt);
12203 %}
12204 ins_pipe( ialu_regI_regI );
12205 %}
12208 // Shift Left Long
12209 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
12210 //predicate(UseNewLongLShift);
12211 match(Set dst (LShiftL src shift));
12212 ins_cost(100);
12213 format %{ "salL $dst, $src, $shift @ salL_Reg_imm" %}
12214 ins_encode %{
12215 Register src_reg = as_Register($src$$reg);
12216 Register dst_reg = as_Register($dst$$reg);
12217 int shamt = $shift$$constant;
12219 if (__ is_simm(shamt, 5))
12220 __ dsll(dst_reg, src_reg, shamt);
12221 else {
12222 int sa = Assembler::low(shamt, 6);
12223 if (sa < 32) {
12224 __ dsll(dst_reg, src_reg, sa);
12225 } else {
12226 __ dsll32(dst_reg, src_reg, sa - 32);
12227 }
12228 }
12229 %}
12230 ins_pipe( ialu_regL_regL );
12231 %}
12233 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
12234 //predicate(UseNewLongLShift);
12235 match(Set dst (LShiftL (ConvI2L src) shift));
12236 ins_cost(100);
12237 format %{ "salL $dst, $src, $shift @ salL_RegI2L_imm" %}
12238 ins_encode %{
12239 Register src_reg = as_Register($src$$reg);
12240 Register dst_reg = as_Register($dst$$reg);
12241 int shamt = $shift$$constant;
12243 if (__ is_simm(shamt, 5))
12244 __ dsll(dst_reg, src_reg, shamt);
12245 else {
12246 int sa = Assembler::low(shamt, 6);
12247 if (sa < 32) {
12248 __ dsll(dst_reg, src_reg, sa);
12249 } else {
12250 __ dsll32(dst_reg, src_reg, sa - 32);
12251 }
12252 }
12253 %}
12254 ins_pipe( ialu_regL_regL );
12255 %}
12257 // Shift Left Long
12258 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12259 //predicate(UseNewLongLShift);
12260 match(Set dst (LShiftL src shift));
12261 ins_cost(100);
12262 format %{ "salL $dst, $src, $shift @ salL_Reg_Reg" %}
12263 ins_encode %{
12264 Register src_reg = as_Register($src$$reg);
12265 Register dst_reg = as_Register($dst$$reg);
12267 __ dsllv(dst_reg, src_reg, $shift$$Register);
12268 %}
12269 ins_pipe( ialu_regL_regL );
12270 %}
12272 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
12273 match(Set dst (LShiftL (ConvI2L src) shift));
12274 ins_cost(100);
12275 format %{ "salL $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
12276 ins_encode %{
12277 Register src_reg = as_Register($src$$reg);
12278 Register dst_reg = as_Register($dst$$reg);
12279 int shamt = $shift$$constant;
12281 if (__ is_simm(shamt, 5)) {
12282 __ dsll(dst_reg, src_reg, shamt);
12283 } else {
12284 int sa = Assembler::low(shamt, 6);
12285 if (sa < 32) {
12286 __ dsll(dst_reg, src_reg, sa);
12287 } else {
12288 __ dsll32(dst_reg, src_reg, sa - 32);
12289 }
12290 }
12291 %}
12292 ins_pipe( ialu_regL_regL );
12293 %}
12295 // Shift Right Long
12296 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
12297 match(Set dst (RShiftL src shift));
12298 ins_cost(100);
12299 format %{ "sarL $dst, $src, $shift @ sarL_Reg_imm" %}
12300 ins_encode %{
12301 Register src_reg = as_Register($src$$reg);
12302 Register dst_reg = as_Register($dst$$reg);
12303 int shamt = ($shift$$constant & 0x3f);
12304 if (__ is_simm(shamt, 5))
12305 __ dsra(dst_reg, src_reg, shamt);
12306 else {
12307 int sa = Assembler::low(shamt, 6);
12308 if (sa < 32) {
12309 __ dsra(dst_reg, src_reg, sa);
12310 } else {
12311 __ dsra32(dst_reg, src_reg, sa - 32);
12312 }
12313 }
12314 %}
12315 ins_pipe( ialu_regL_regL );
12316 %}
12318 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
12319 match(Set dst (ConvL2I (RShiftL src shift)));
12320 ins_cost(100);
12321 format %{ "sarL $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
12322 ins_encode %{
12323 Register src_reg = as_Register($src$$reg);
12324 Register dst_reg = as_Register($dst$$reg);
12325 int shamt = $shift$$constant;
12327 __ dsra32(dst_reg, src_reg, shamt - 32);
12328 %}
12329 ins_pipe( ialu_regL_regL );
12330 %}
12332 // Shift Right Long arithmetically
12333 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12334 //predicate(UseNewLongLShift);
12335 match(Set dst (RShiftL src shift));
12336 ins_cost(100);
12337 format %{ "sarL $dst, $src, $shift @ sarL_Reg_Reg" %}
12338 ins_encode %{
12339 Register src_reg = as_Register($src$$reg);
12340 Register dst_reg = as_Register($dst$$reg);
12342 __ dsrav(dst_reg, src_reg, $shift$$Register);
12343 %}
12344 ins_pipe( ialu_regL_regL );
12345 %}
12347 // Shift Right Long logically
12348 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12349 match(Set dst (URShiftL src shift));
12350 ins_cost(100);
12351 format %{ "slrL $dst, $src, $shift @ slrL_Reg_Reg" %}
12352 ins_encode %{
12353 Register src_reg = as_Register($src$$reg);
12354 Register dst_reg = as_Register($dst$$reg);
12356 __ dsrlv(dst_reg, src_reg, $shift$$Register);
12357 %}
12358 ins_pipe( ialu_regL_regL );
12359 %}
12361 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
12362 match(Set dst (URShiftL src shift));
12363 ins_cost(80);
12364 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
12365 ins_encode %{
12366 Register src_reg = as_Register($src$$reg);
12367 Register dst_reg = as_Register($dst$$reg);
12368 int shamt = $shift$$constant;
12370 __ dsrl(dst_reg, src_reg, shamt);
12371 %}
12372 ins_pipe( ialu_regL_regL );
12373 %}
12375 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
12376 match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
12377 ins_cost(80);
12378 format %{ "dext $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
12379 ins_encode %{
12380 Register src_reg = as_Register($src$$reg);
12381 Register dst_reg = as_Register($dst$$reg);
12382 int shamt = $shift$$constant;
12384 __ dext(dst_reg, src_reg, shamt, 31);
12385 %}
12386 ins_pipe( ialu_regL_regL );
12387 %}
12389 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
12390 match(Set dst (URShiftL (CastP2X src) shift));
12391 ins_cost(80);
12392 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
12393 ins_encode %{
12394 Register src_reg = as_Register($src$$reg);
12395 Register dst_reg = as_Register($dst$$reg);
12396 int shamt = $shift$$constant;
12398 __ dsrl(dst_reg, src_reg, shamt);
12399 %}
12400 ins_pipe( ialu_regL_regL );
12401 %}
12403 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
12404 match(Set dst (URShiftL src shift));
12405 ins_cost(80);
12406 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
12407 ins_encode %{
12408 Register src_reg = as_Register($src$$reg);
12409 Register dst_reg = as_Register($dst$$reg);
12410 int shamt = $shift$$constant;
12412 __ dsrl32(dst_reg, src_reg, shamt - 32);
12413 %}
12414 ins_pipe( ialu_regL_regL );
12415 %}
12417 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
12418 match(Set dst (ConvL2I (URShiftL src shift)));
12419 predicate(n->in(1)->in(2)->get_int() > 32);
12420 ins_cost(80);
12421 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
12422 ins_encode %{
12423 Register src_reg = as_Register($src$$reg);
12424 Register dst_reg = as_Register($dst$$reg);
12425 int shamt = $shift$$constant;
12427 __ dsrl32(dst_reg, src_reg, shamt - 32);
12428 %}
12429 ins_pipe( ialu_regL_regL );
12430 %}
12432 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
12433 match(Set dst (URShiftL (CastP2X src) shift));
12434 ins_cost(80);
12435 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
12436 ins_encode %{
12437 Register src_reg = as_Register($src$$reg);
12438 Register dst_reg = as_Register($dst$$reg);
12439 int shamt = $shift$$constant;
12441 __ dsrl32(dst_reg, src_reg, shamt - 32);
12442 %}
12443 ins_pipe( ialu_regL_regL );
12444 %}
12446 // Xor Instructions
12447 // Xor Register with Register
12448 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
12449 match(Set dst (XorI src1 src2));
12451 format %{ "XOR $dst, $src1, $src2 #@xorI_Reg_Reg" %}
12453 ins_encode %{
12454 Register dst = $dst$$Register;
12455 Register src1 = $src1$$Register;
12456 Register src2 = $src2$$Register;
12457 __ xorr(dst, src1, src2);
12458 __ sll(dst, dst, 0); /* long -> int */
12459 %}
12461 ins_pipe( ialu_regI_regI );
12462 %}
12464 // Or Instructions
12465 // Or Register with Register
12466 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
12467 match(Set dst (OrI src1 src2));
12469 format %{ "OR $dst, $src1, $src2 #@orI_Reg_Reg" %}
12470 ins_encode %{
12471 Register dst = $dst$$Register;
12472 Register src1 = $src1$$Register;
12473 Register src2 = $src2$$Register;
12474 __ orr(dst, src1, src2);
12475 %}
12477 ins_pipe( ialu_regI_regI );
12478 %}
12480 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
12481 match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
12482 predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
12484 format %{ "rotr $dst, $src, 1 ...\n\t"
12485 "srl $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
12486 ins_encode %{
12487 Register dst = $dst$$Register;
12488 Register src = $src$$Register;
12489 int rshift = $rshift$$constant;
12491 __ rotr(dst, src, 1);
12492 if (rshift - 1) {
12493 __ srl(dst, dst, rshift - 1);
12494 }
12495 %}
12497 ins_pipe( ialu_regI_regI );
12498 %}
12500 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
12501 match(Set dst (OrI src1 (CastP2X src2)));
12503 format %{ "OR $dst, $src1, $src2 #@orI_Reg_castP2X" %}
12504 ins_encode %{
12505 Register dst = $dst$$Register;
12506 Register src1 = $src1$$Register;
12507 Register src2 = $src2$$Register;
12508 __ orr(dst, src1, src2);
12509 %}
12511 ins_pipe( ialu_regI_regI );
12512 %}
12514 // Logical Shift Right by 8-bit immediate
12515 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
12516 match(Set dst (URShiftI src shift));
12517 //effect(KILL cr);
12519 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_imm" %}
12520 ins_encode %{
12521 Register src = $src$$Register;
12522 Register dst = $dst$$Register;
12523 int shift = $shift$$constant;
12525 __ srl(dst, src, shift);
12526 %}
12527 ins_pipe( ialu_regI_regI );
12528 %}
12530 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
12531 match(Set dst (AndI (URShiftI src shift) mask));
12533 format %{ "ext $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
12534 ins_encode %{
12535 Register src = $src$$Register;
12536 Register dst = $dst$$Register;
12537 int pos = $shift$$constant;
12538 int size = Assembler::is_int_mask($mask$$constant);
12540 __ ext(dst, src, pos, size);
12541 %}
12542 ins_pipe( ialu_regI_regI );
12543 %}
12545 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
12546 %{
12547 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
12548 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
12550 ins_cost(100);
12551 format %{ "rotr $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
12552 ins_encode %{
12553 Register dst = $dst$$Register;
12554 int sa = $rshift$$constant;
12556 __ rotr(dst, dst, sa);
12557 %}
12558 ins_pipe( ialu_regI_regI );
12559 %}
12561 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
12562 %{
12563 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12564 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
12566 ins_cost(100);
12567 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
12568 ins_encode %{
12569 Register dst = $dst$$Register;
12570 int sa = $rshift$$constant;
12572 __ drotr(dst, dst, sa);
12573 %}
12574 ins_pipe( ialu_regI_regI );
12575 %}
12577 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
12578 %{
12579 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12580 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
12582 ins_cost(100);
12583 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
12584 ins_encode %{
12585 Register dst = $dst$$Register;
12586 int sa = $rshift$$constant;
12588 __ drotr32(dst, dst, sa - 32);
12589 %}
12590 ins_pipe( ialu_regI_regI );
12591 %}
12593 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
12594 %{
12595 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
12596 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
12598 ins_cost(100);
12599 format %{ "rotr $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
12600 ins_encode %{
12601 Register dst = $dst$$Register;
12602 int sa = $rshift$$constant;
12604 __ rotr(dst, dst, sa);
12605 %}
12606 ins_pipe( ialu_regI_regI );
12607 %}
12609 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
12610 %{
12611 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12612 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
12614 ins_cost(100);
12615 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
12616 ins_encode %{
12617 Register dst = $dst$$Register;
12618 int sa = $rshift$$constant;
12620 __ drotr(dst, dst, sa);
12621 %}
12622 ins_pipe( ialu_regI_regI );
12623 %}
12625 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
12626 %{
12627 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12628 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
12630 ins_cost(100);
12631 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
12632 ins_encode %{
12633 Register dst = $dst$$Register;
12634 int sa = $rshift$$constant;
12636 __ drotr32(dst, dst, sa - 32);
12637 %}
12638 ins_pipe( ialu_regI_regI );
12639 %}
12641 // Logical Shift Right
12642 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12643 match(Set dst (URShiftI src shift));
12645 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_Reg" %}
12646 ins_encode %{
12647 Register src = $src$$Register;
12648 Register dst = $dst$$Register;
12649 Register shift = $shift$$Register;
12650 __ srlv(dst, src, shift);
12651 %}
12652 ins_pipe( ialu_regI_regI );
12653 %}
12656 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
12657 match(Set dst (RShiftI src shift));
12658 // effect(KILL cr);
12660 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_imm" %}
12661 ins_encode %{
12662 Register src = $src$$Register;
12663 Register dst = $dst$$Register;
12664 int shift = $shift$$constant;
12665 __ sra(dst, src, shift);
12666 %}
12667 ins_pipe( ialu_regI_regI );
12668 %}
12670 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12671 match(Set dst (RShiftI src shift));
12672 // effect(KILL cr);
12674 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_Reg" %}
12675 ins_encode %{
12676 Register src = $src$$Register;
12677 Register dst = $dst$$Register;
12678 Register shift = $shift$$Register;
12679 __ srav(dst, src, shift);
12680 %}
12681 ins_pipe( ialu_regI_regI );
12682 %}
12684 //----------Convert Int to Boolean---------------------------------------------
12686 instruct convI2B(mRegI dst, mRegI src) %{
12687 match(Set dst (Conv2B src));
12689 ins_cost(100);
12690 format %{ "convI2B $dst, $src @ convI2B" %}
12691 ins_encode %{
12692 Register dst = as_Register($dst$$reg);
12693 Register src = as_Register($src$$reg);
12695 if (dst != src) {
12696 __ daddiu(dst, R0, 1);
12697 __ movz(dst, R0, src);
12698 } else {
12699 __ move(AT, src);
12700 __ daddiu(dst, R0, 1);
12701 __ movz(dst, R0, AT);
12702 }
12703 %}
12705 ins_pipe( ialu_regL_regL );
12706 %}
12708 instruct convI2L_reg( mRegL dst, mRegI src) %{
12709 match(Set dst (ConvI2L src));
12711 ins_cost(100);
12712 format %{ "SLL $dst, $src @ convI2L_reg\t" %}
12713 ins_encode %{
12714 Register dst = as_Register($dst$$reg);
12715 Register src = as_Register($src$$reg);
12717 if(dst != src) __ sll(dst, src, 0);
12718 %}
12719 ins_pipe( ialu_regL_regL );
12720 %}
12723 instruct convL2I_reg( mRegI dst, mRegL src ) %{
12724 match(Set dst (ConvL2I src));
12726 format %{ "MOV $dst, $src @ convL2I_reg" %}
12727 ins_encode %{
12728 Register dst = as_Register($dst$$reg);
12729 Register src = as_Register($src$$reg);
12731 __ sll(dst, src, 0);
12732 %}
12734 ins_pipe( ialu_regI_regI );
12735 %}
12737 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
12738 match(Set dst (ConvI2L (ConvL2I src)));
12740 format %{ "sll $dst, $src, 0 @ convL2I2L_reg" %}
12741 ins_encode %{
12742 Register dst = as_Register($dst$$reg);
12743 Register src = as_Register($src$$reg);
12745 __ sll(dst, src, 0);
12746 %}
12748 ins_pipe( ialu_regI_regI );
12749 %}
12751 instruct convL2D_reg( regD dst, mRegL src ) %{
12752 match(Set dst (ConvL2D src));
12753 format %{ "convL2D $dst, $src @ convL2D_reg" %}
12754 ins_encode %{
12755 Register src = as_Register($src$$reg);
12756 FloatRegister dst = as_FloatRegister($dst$$reg);
12758 __ dmtc1(src, dst);
12759 __ cvt_d_l(dst, dst);
12760 %}
12762 ins_pipe( pipe_slow );
12763 %}
12766 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
12767 match(Set dst (ConvD2L src));
12768 ins_cost(150);
12769 format %{ "convD2L $dst, $src @ convD2L_reg_fast" %}
12770 ins_encode %{
12771 Register dst = as_Register($dst$$reg);
12772 FloatRegister src = as_FloatRegister($src$$reg);
12774 Label Done;
12776 __ trunc_l_d(F30, src);
12777 // max_long: 0x7fffffffffffffff
12778 // __ set64(AT, 0x7fffffffffffffff);
12779 __ daddiu(AT, R0, -1);
12780 __ dsrl(AT, AT, 1);
12781 __ dmfc1(dst, F30);
12783 __ bne(dst, AT, Done);
12784 __ delayed()->mtc1(R0, F30);
12786 __ cvt_d_w(F30, F30);
12787 __ c_ult_d(src, F30);
12788 __ bc1f(Done);
12789 __ delayed()->daddiu(T9, R0, -1);
12791 __ c_un_d(src, src); //NaN?
12792 __ subu(dst, T9, AT);
12793 __ movt(dst, R0);
12795 __ bind(Done);
12796 %}
12798 ins_pipe( pipe_slow );
12799 %}
12802 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
12803 match(Set dst (ConvD2L src));
12804 ins_cost(250);
12805 format %{ "convD2L $dst, $src @ convD2L_reg_slow" %}
12806 ins_encode %{
12807 Register dst = as_Register($dst$$reg);
12808 FloatRegister src = as_FloatRegister($src$$reg);
12810 Label L;
12812 __ c_un_d(src, src); //NaN?
12813 __ bc1t(L);
12814 __ delayed();
12815 __ move(dst, R0);
12817 __ trunc_l_d(F30, src);
12818 __ cfc1(AT, 31);
12819 __ li(T9, 0x10000);
12820 __ andr(AT, AT, T9);
12821 __ beq(AT, R0, L);
12822 __ delayed()->dmfc1(dst, F30);
12824 __ mov_d(F12, src);
12825 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
12826 __ move(dst, V0);
12827 __ bind(L);
12828 %}
12830 ins_pipe( pipe_slow );
12831 %}
12834 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
12835 match(Set dst (ConvF2I src));
12836 ins_cost(150);
12837 format %{ "convf2i $dst, $src @ convF2I_reg_fast" %}
12838 ins_encode %{
12839 Register dreg = $dst$$Register;
12840 FloatRegister fval = $src$$FloatRegister;
12841 Label L;
12843 __ trunc_w_s(F30, fval);
12844 __ move(AT, 0x7fffffff);
12845 __ mfc1(dreg, F30);
12846 __ c_un_s(fval, fval); //NaN?
12847 __ movt(dreg, R0);
12849 __ bne(AT, dreg, L);
12850 __ delayed()->lui(T9, 0x8000);
12852 __ mfc1(AT, fval);
12853 __ andr(AT, AT, T9);
12855 __ movn(dreg, T9, AT);
12857 __ bind(L);
12859 %}
12861 ins_pipe( pipe_slow );
12862 %}
12866 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
12867 match(Set dst (ConvF2I src));
12868 ins_cost(250);
12869 format %{ "convf2i $dst, $src @ convF2I_reg_slow" %}
12870 ins_encode %{
12871 Register dreg = $dst$$Register;
12872 FloatRegister fval = $src$$FloatRegister;
12873 Label L;
12875 __ c_un_s(fval, fval); //NaN?
12876 __ bc1t(L);
12877 __ delayed();
12878 __ move(dreg, R0);
12880 __ trunc_w_s(F30, fval);
12882 /* Call SharedRuntime:f2i() to do valid convention */
12883 __ cfc1(AT, 31);
12884 __ li(T9, 0x10000);
12885 __ andr(AT, AT, T9);
12886 __ beq(AT, R0, L);
12887 __ delayed()->mfc1(dreg, F30);
12889 __ mov_s(F12, fval);
12891 //This bug was found when running ezDS's control-panel.
12892 // J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
12893 //
12894 // An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
12895 // V0 is corrupted during call_VM_leaf(), and should be preserved.
12896 //
12897 __ push(fval);
12898 if(dreg != V0) {
12899 __ push(V0);
12900 }
12901 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
12902 if(dreg != V0) {
12903 __ move(dreg, V0);
12904 __ pop(V0);
12905 }
12906 __ pop(fval);
12907 __ bind(L);
12908 %}
12910 ins_pipe( pipe_slow );
12911 %}
12914 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
12915 match(Set dst (ConvF2L src));
12916 ins_cost(150);
12917 format %{ "convf2l $dst, $src @ convF2L_reg_fast" %}
12918 ins_encode %{
12919 Register dreg = $dst$$Register;
12920 FloatRegister fval = $src$$FloatRegister;
12921 Label L;
12923 __ trunc_l_s(F30, fval);
12924 __ daddiu(AT, R0, -1);
12925 __ dsrl(AT, AT, 1);
12926 __ dmfc1(dreg, F30);
12927 __ c_un_s(fval, fval); //NaN?
12928 __ movt(dreg, R0);
12930 __ bne(AT, dreg, L);
12931 __ delayed()->lui(T9, 0x8000);
12933 __ mfc1(AT, fval);
12934 __ andr(AT, AT, T9);
12936 __ dsll32(T9, T9, 0);
12937 __ movn(dreg, T9, AT);
12939 __ bind(L);
12940 %}
12942 ins_pipe( pipe_slow );
12943 %}
12946 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
12947 match(Set dst (ConvF2L src));
12948 ins_cost(250);
12949 format %{ "convf2l $dst, $src @ convF2L_reg_slow" %}
12950 ins_encode %{
12951 Register dst = as_Register($dst$$reg);
12952 FloatRegister fval = $src$$FloatRegister;
12953 Label L;
12955 __ c_un_s(fval, fval); //NaN?
12956 __ bc1t(L);
12957 __ delayed();
12958 __ move(dst, R0);
12960 __ trunc_l_s(F30, fval);
12961 __ cfc1(AT, 31);
12962 __ li(T9, 0x10000);
12963 __ andr(AT, AT, T9);
12964 __ beq(AT, R0, L);
12965 __ delayed()->dmfc1(dst, F30);
12967 __ mov_s(F12, fval);
12968 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
12969 __ move(dst, V0);
12970 __ bind(L);
12971 %}
12973 ins_pipe( pipe_slow );
12974 %}
12976 instruct convL2F_reg( regF dst, mRegL src ) %{
12977 match(Set dst (ConvL2F src));
12978 format %{ "convl2f $dst, $src @ convL2F_reg" %}
12979 ins_encode %{
12980 FloatRegister dst = $dst$$FloatRegister;
12981 Register src = as_Register($src$$reg);
12982 Label L;
12984 __ dmtc1(src, dst);
12985 __ cvt_s_l(dst, dst);
12986 %}
12988 ins_pipe( pipe_slow );
12989 %}
12991 instruct convI2F_reg( regF dst, mRegI src ) %{
12992 match(Set dst (ConvI2F src));
12993 format %{ "convi2f $dst, $src @ convI2F_reg" %}
12994 ins_encode %{
12995 Register src = $src$$Register;
12996 FloatRegister dst = $dst$$FloatRegister;
12998 __ mtc1(src, dst);
12999 __ cvt_s_w(dst, dst);
13000 %}
13002 ins_pipe( fpu_regF_regF );
13003 %}
13005 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
13006 match(Set dst (CmpLTMask p zero));
13007 ins_cost(100);
13009 format %{ "sra $dst, $p, 31 @ cmpLTMask_immI0" %}
13010 ins_encode %{
13011 Register src = $p$$Register;
13012 Register dst = $dst$$Register;
13014 __ sra(dst, src, 31);
13015 %}
13016 ins_pipe( pipe_slow );
13017 %}
13020 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
13021 match(Set dst (CmpLTMask p q));
13022 ins_cost(400);
13024 format %{ "cmpLTMask $dst, $p, $q @ cmpLTMask" %}
13025 ins_encode %{
13026 Register p = $p$$Register;
13027 Register q = $q$$Register;
13028 Register dst = $dst$$Register;
13030 __ slt(dst, p, q);
13031 __ subu(dst, R0, dst);
13032 %}
13033 ins_pipe( pipe_slow );
13034 %}
13036 instruct convP2B(mRegI dst, mRegP src) %{
13037 match(Set dst (Conv2B src));
13039 ins_cost(100);
13040 format %{ "convP2B $dst, $src @ convP2B" %}
13041 ins_encode %{
13042 Register dst = as_Register($dst$$reg);
13043 Register src = as_Register($src$$reg);
13045 if (dst != src) {
13046 __ daddiu(dst, R0, 1);
13047 __ movz(dst, R0, src);
13048 } else {
13049 __ move(AT, src);
13050 __ daddiu(dst, R0, 1);
13051 __ movz(dst, R0, AT);
13052 }
13053 %}
13055 ins_pipe( ialu_regL_regL );
13056 %}
13059 instruct convI2D_reg_reg(regD dst, mRegI src) %{
13060 match(Set dst (ConvI2D src));
13061 format %{ "conI2D $dst, $src @convI2D_reg" %}
13062 ins_encode %{
13063 Register src = $src$$Register;
13064 FloatRegister dst = $dst$$FloatRegister;
13065 __ mtc1(src, dst);
13066 __ cvt_d_w(dst, dst);
13067 %}
13068 ins_pipe( fpu_regF_regF );
13069 %}
13071 instruct convF2D_reg_reg(regD dst, regF src) %{
13072 match(Set dst (ConvF2D src));
13073 format %{ "convF2D $dst, $src\t# @convF2D_reg_reg" %}
13074 ins_encode %{
13075 FloatRegister dst = $dst$$FloatRegister;
13076 FloatRegister src = $src$$FloatRegister;
13078 __ cvt_d_s(dst, src);
13079 %}
13080 ins_pipe( fpu_regF_regF );
13081 %}
13083 instruct convD2F_reg_reg(regF dst, regD src) %{
13084 match(Set dst (ConvD2F src));
13085 format %{ "convD2F $dst, $src\t# @convD2F_reg_reg" %}
13086 ins_encode %{
13087 FloatRegister dst = $dst$$FloatRegister;
13088 FloatRegister src = $src$$FloatRegister;
13090 __ cvt_s_d(dst, src);
13091 %}
13092 ins_pipe( fpu_regF_regF );
13093 %}
13096 // Convert a double to an int. If the double is a NAN, stuff a zero in instead.
13097 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
13098 match(Set dst (ConvD2I src));
13100 ins_cost(150);
13101 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
13103 ins_encode %{
13104 FloatRegister src = $src$$FloatRegister;
13105 Register dst = $dst$$Register;
13107 Label Done;
13109 __ trunc_w_d(F30, src);
13110 // max_int: 2147483647
13111 __ move(AT, 0x7fffffff);
13112 __ mfc1(dst, F30);
13114 __ bne(dst, AT, Done);
13115 __ delayed()->mtc1(R0, F30);
13117 __ cvt_d_w(F30, F30);
13118 __ c_ult_d(src, F30);
13119 __ bc1f(Done);
13120 __ delayed()->addiu(T9, R0, -1);
13122 __ c_un_d(src, src); //NaN?
13123 __ subu32(dst, T9, AT);
13124 __ movt(dst, R0);
13126 __ bind(Done);
13127 %}
13128 ins_pipe( pipe_slow );
13129 %}
13132 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
13133 match(Set dst (ConvD2I src));
13135 ins_cost(250);
13136 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
13138 ins_encode %{
13139 FloatRegister src = $src$$FloatRegister;
13140 Register dst = $dst$$Register;
13141 Label L;
13143 __ trunc_w_d(F30, src);
13144 __ cfc1(AT, 31);
13145 __ li(T9, 0x10000);
13146 __ andr(AT, AT, T9);
13147 __ beq(AT, R0, L);
13148 __ delayed()->mfc1(dst, F30);
13150 __ mov_d(F12, src);
13151 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
13152 __ move(dst, V0);
13153 __ bind(L);
13155 %}
13156 ins_pipe( pipe_slow );
13157 %}
13159 // Convert oop pointer into compressed form
13160 instruct encodeHeapOop(mRegN dst, mRegP src) %{
13161 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
13162 match(Set dst (EncodeP src));
13163 format %{ "encode_heap_oop $dst,$src" %}
13164 ins_encode %{
13165 Register src = $src$$Register;
13166 Register dst = $dst$$Register;
13168 __ encode_heap_oop(dst, src);
13169 %}
13170 ins_pipe( ialu_regL_regL );
13171 %}
13173 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
13174 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
13175 match(Set dst (EncodeP src));
13176 format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
13177 ins_encode %{
13178 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
13179 %}
13180 ins_pipe( ialu_regL_regL );
13181 %}
13183 instruct decodeHeapOop(mRegP dst, mRegN src) %{
13184 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
13185 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
13186 match(Set dst (DecodeN src));
13187 format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
13188 ins_encode %{
13189 Register s = $src$$Register;
13190 Register d = $dst$$Register;
13192 __ decode_heap_oop(d, s);
13193 %}
13194 ins_pipe( ialu_regL_regL );
13195 %}
13197 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
13198 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
13199 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
13200 match(Set dst (DecodeN src));
13201 format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
13202 ins_encode %{
13203 Register s = $src$$Register;
13204 Register d = $dst$$Register;
13205 if (s != d) {
13206 __ decode_heap_oop_not_null(d, s);
13207 } else {
13208 __ decode_heap_oop_not_null(d);
13209 }
13210 %}
13211 ins_pipe( ialu_regL_regL );
13212 %}
13214 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
13215 match(Set dst (EncodePKlass src));
13216 format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
13217 ins_encode %{
13218 __ encode_klass_not_null($dst$$Register, $src$$Register);
13219 %}
13220 ins_pipe( ialu_regL_regL );
13221 %}
13223 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
13224 match(Set dst (DecodeNKlass src));
13225 format %{ "decode_heap_klass_not_null $dst,$src" %}
13226 ins_encode %{
13227 Register s = $src$$Register;
13228 Register d = $dst$$Register;
13229 if (s != d) {
13230 __ decode_klass_not_null(d, s);
13231 } else {
13232 __ decode_klass_not_null(d);
13233 }
13234 %}
13235 ins_pipe( ialu_regL_regL );
13236 %}
13238 //FIXME
13239 instruct tlsLoadP(mRegP dst) %{
13240 match(Set dst (ThreadLocal));
13242 ins_cost(0);
13243 format %{ " get_thread in $dst #@tlsLoadP" %}
13244 ins_encode %{
13245 Register dst = $dst$$Register;
13246 #ifdef OPT_THREAD
13247 __ move(dst, TREG);
13248 #else
13249 __ get_thread(dst);
13250 #endif
13251 %}
13253 ins_pipe( ialu_loadI );
13254 %}
13257 instruct checkCastPP( mRegP dst ) %{
13258 match(Set dst (CheckCastPP dst));
13260 format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
13261 ins_encode( /*empty encoding*/ );
13262 ins_pipe( empty );
13263 %}
13265 instruct castPP(mRegP dst)
13266 %{
13267 match(Set dst (CastPP dst));
13269 size(0);
13270 format %{ "# castPP of $dst" %}
13271 ins_encode(/* empty encoding */);
13272 ins_pipe(empty);
13273 %}
13275 instruct castII( mRegI dst ) %{
13276 match(Set dst (CastII dst));
13277 format %{ "#castII of $dst empty encoding" %}
13278 ins_encode( /*empty encoding*/ );
13279 ins_cost(0);
13280 ins_pipe( empty );
13281 %}
13283 // Return Instruction
13284 // Remove the return address & jump to it.
13285 instruct Ret() %{
13286 match(Return);
13287 format %{ "RET #@Ret" %}
13289 ins_encode %{
13290 __ jr(RA);
13291 __ delayed()->nop();
13292 %}
13294 ins_pipe( pipe_jump );
13295 %}
13297 /*
13298 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
13299 instruct jumpXtnd(mRegL switch_val) %{
13300 match(Jump switch_val);
13302 ins_cost(350);
13304 format %{ "load T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
13305 "jr T9\n\t"
13306 "nop" %}
13307 ins_encode %{
13308 Register table_base = $constanttablebase;
13309 int con_offset = $constantoffset;
13310 Register switch_reg = $switch_val$$Register;
13312 if (UseLoongsonISA) {
13313 if (Assembler::is_simm(con_offset, 8)) {
13314 __ gsldx(T9, table_base, switch_reg, con_offset);
13315 } else if (Assembler::is_simm16(con_offset)) {
13316 __ daddu(T9, table_base, switch_reg);
13317 __ ld(T9, T9, con_offset);
13318 } else {
13319 __ move(T9, con_offset);
13320 __ daddu(AT, table_base, switch_reg);
13321 __ gsldx(T9, AT, T9, 0);
13322 }
13323 } else {
13324 if (Assembler::is_simm16(con_offset)) {
13325 __ daddu(T9, table_base, switch_reg);
13326 __ ld(T9, T9, con_offset);
13327 } else {
13328 __ move(T9, con_offset);
13329 __ daddu(AT, table_base, switch_reg);
13330 __ daddu(AT, T9, AT);
13331 __ ld(T9, AT, 0);
13332 }
13333 }
13335 __ jr(T9);
13336 __ delayed()->nop();
13338 %}
13339 ins_pipe(pipe_jump);
13340 %}
13341 */
13344 // Tail Jump; remove the return address; jump to target.
13345 // TailCall above leaves the return address around.
13346 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13347 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13348 // "restore" before this instruction (in Epilogue), we need to materialize it
13349 // in %i0.
13350 //FIXME
13351 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
13352 match( TailJump jump_target ex_oop );
13353 ins_cost(200);
13354 format %{ "Jmp $jump_target ; ex_oop = $ex_oop #@tailjmpInd" %}
13355 ins_encode %{
13356 Register target = $jump_target$$Register;
13358 // V0, V1 are indicated in:
13359 // [stubGenerator_mips.cpp] generate_forward_exception()
13360 // [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
13361 //
13362 Register oop = $ex_oop$$Register;
13363 Register exception_oop = V0;
13364 Register exception_pc = V1;
13366 __ move(exception_pc, RA);
13367 __ move(exception_oop, oop);
13369 __ jr(target);
13370 __ delayed()->nop();
13371 %}
13372 ins_pipe( pipe_jump );
13373 %}
13375 // ============================================================================
13376 // Procedure Call/Return Instructions
13377 // Call Java Static Instruction
13378 // Note: If this code changes, the corresponding ret_addr_offset() and
13379 // compute_padding() functions will have to be adjusted.
13380 instruct CallStaticJavaDirect(method meth) %{
13381 match(CallStaticJava);
13382 effect(USE meth);
13384 ins_cost(300);
13385 format %{ "CALL,static #@CallStaticJavaDirect " %}
13386 ins_encode( Java_Static_Call( meth ) );
13387 ins_pipe( pipe_slow );
13388 ins_pc_relative(1);
13389 %}
13391 // Call Java Dynamic Instruction
13392 // Note: If this code changes, the corresponding ret_addr_offset() and
13393 // compute_padding() functions will have to be adjusted.
13394 instruct CallDynamicJavaDirect(method meth) %{
13395 match(CallDynamicJava);
13396 effect(USE meth);
13398 ins_cost(300);
13399 format %{"MOV IC_Klass, #Universe::non_oop_word()\n\t"
13400 "CallDynamic @ CallDynamicJavaDirect" %}
13401 ins_encode( Java_Dynamic_Call( meth ) );
13402 ins_pipe( pipe_slow );
13403 ins_pc_relative(1);
13404 %}
13406 instruct CallLeafNoFPDirect(method meth) %{
13407 match(CallLeafNoFP);
13408 effect(USE meth);
13410 ins_cost(300);
13411 format %{ "CALL_LEAF_NOFP,runtime " %}
13412 ins_encode(Java_To_Runtime(meth));
13413 ins_pipe( pipe_slow );
13414 ins_pc_relative(1);
13415 ins_alignment(16);
13416 %}
13418 // Prefetch instructions.
13420 instruct prefetchrNTA( memory mem ) %{
13421 match(PrefetchRead mem);
13422 ins_cost(125);
13424 format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
13425 ins_encode %{
13426 int base = $mem$$base;
13427 int index = $mem$$index;
13428 int scale = $mem$$scale;
13429 int disp = $mem$$disp;
13431 if( index != 0 ) {
13432 if (scale == 0) {
13433 __ daddu(AT, as_Register(base), as_Register(index));
13434 } else {
13435 __ dsll(AT, as_Register(index), scale);
13436 __ daddu(AT, as_Register(base), AT);
13437 }
13438 } else {
13439 __ move(AT, as_Register(base));
13440 }
13441 if( Assembler::is_simm16(disp) ) {
13442 __ daddiu(AT, as_Register(base), disp);
13443 __ daddiu(AT, AT, disp);
13444 } else {
13445 __ move(T9, disp);
13446 __ daddu(AT, as_Register(base), T9);
13447 }
13448 __ pref(0, AT, 0); //hint: 0:load
13449 %}
13450 ins_pipe(pipe_slow);
13451 %}
13453 instruct prefetchwNTA( memory mem ) %{
13454 match(PrefetchWrite mem);
13455 ins_cost(125);
13456 format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
13457 ins_encode %{
13458 int base = $mem$$base;
13459 int index = $mem$$index;
13460 int scale = $mem$$scale;
13461 int disp = $mem$$disp;
13463 if( index != 0 ) {
13464 if (scale == 0) {
13465 __ daddu(AT, as_Register(base), as_Register(index));
13466 } else {
13467 __ dsll(AT, as_Register(index), scale);
13468 __ daddu(AT, as_Register(base), AT);
13469 }
13470 } else {
13471 __ move(AT, as_Register(base));
13472 }
13473 if( Assembler::is_simm16(disp) ) {
13474 __ daddiu(AT, as_Register(base), disp);
13475 __ daddiu(AT, AT, disp);
13476 } else {
13477 __ move(T9, disp);
13478 __ daddu(AT, as_Register(base), T9);
13479 }
13480 __ pref(1, AT, 0); //hint: 1:store
13481 %}
13482 ins_pipe(pipe_slow);
13483 %}
13485 // Prefetch instructions for allocation.
13487 instruct prefetchAllocNTA( memory mem ) %{
13488 match(PrefetchAllocation mem);
13489 ins_cost(125);
13490 format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
13491 ins_encode %{
13492 int base = $mem$$base;
13493 int index = $mem$$index;
13494 int scale = $mem$$scale;
13495 int disp = $mem$$disp;
13497 Register dst = R0;
13499 if( index != 0 ) {
13500 if( Assembler::is_simm16(disp) ) {
13501 if( UseLoongsonISA ) {
13502 if (scale == 0) {
13503 __ gslbx(dst, as_Register(base), as_Register(index), disp);
13504 } else {
13505 __ dsll(AT, as_Register(index), scale);
13506 __ gslbx(dst, as_Register(base), AT, disp);
13507 }
13508 } else {
13509 if (scale == 0) {
13510 __ addu(AT, as_Register(base), as_Register(index));
13511 } else {
13512 __ dsll(AT, as_Register(index), scale);
13513 __ addu(AT, as_Register(base), AT);
13514 }
13515 __ lb(dst, AT, disp);
13516 }
13517 } else {
13518 if (scale == 0) {
13519 __ addu(AT, as_Register(base), as_Register(index));
13520 } else {
13521 __ dsll(AT, as_Register(index), scale);
13522 __ addu(AT, as_Register(base), AT);
13523 }
13524 __ move(T9, disp);
13525 if( UseLoongsonISA ) {
13526 __ gslbx(dst, AT, T9, 0);
13527 } else {
13528 __ addu(AT, AT, T9);
13529 __ lb(dst, AT, 0);
13530 }
13531 }
13532 } else {
13533 if( Assembler::is_simm16(disp) ) {
13534 __ lb(dst, as_Register(base), disp);
13535 } else {
13536 __ move(T9, disp);
13537 if( UseLoongsonISA ) {
13538 __ gslbx(dst, as_Register(base), T9, 0);
13539 } else {
13540 __ addu(AT, as_Register(base), T9);
13541 __ lb(dst, AT, 0);
13542 }
13543 }
13544 }
13545 %}
13546 ins_pipe(pipe_slow);
13547 %}
13550 // Call runtime without safepoint
13551 instruct CallLeafDirect(method meth) %{
13552 match(CallLeaf);
13553 effect(USE meth);
13555 ins_cost(300);
13556 format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
13557 ins_encode(Java_To_Runtime(meth));
13558 ins_pipe( pipe_slow );
13559 ins_pc_relative(1);
13560 ins_alignment(16);
13561 %}
13563 // Load Char (16bit unsigned)
13564 instruct loadUS(mRegI dst, memory mem) %{
13565 match(Set dst (LoadUS mem));
13567 ins_cost(125);
13568 format %{ "loadUS $dst,$mem @ loadC" %}
13569 ins_encode(load_C_enc(dst, mem));
13570 ins_pipe( ialu_loadI );
13571 %}
13573 instruct loadUS_convI2L(mRegL dst, memory mem) %{
13574 match(Set dst (ConvI2L (LoadUS mem)));
13576 ins_cost(125);
13577 format %{ "loadUS $dst,$mem @ loadUS_convI2L" %}
13578 ins_encode(load_C_enc(dst, mem));
13579 ins_pipe( ialu_loadI );
13580 %}
13582 // Store Char (16bit unsigned)
13583 instruct storeC(memory mem, mRegI src) %{
13584 match(Set mem (StoreC mem src));
13586 ins_cost(125);
13587 format %{ "storeC $src, $mem @ storeC" %}
13588 ins_encode(store_C_reg_enc(mem, src));
13589 ins_pipe( ialu_loadI );
13590 %}
13592 instruct storeC0(memory mem, immI0 zero) %{
13593 match(Set mem (StoreC mem zero));
13595 ins_cost(125);
13596 format %{ "storeC $zero, $mem @ storeC0" %}
13597 ins_encode(store_C0_enc(mem));
13598 ins_pipe( ialu_loadI );
13599 %}
13602 instruct loadConF0(regF dst, immF0 zero) %{
13603 match(Set dst zero);
13604 ins_cost(100);
13606 format %{ "mov $dst, zero @ loadConF0\n"%}
13607 ins_encode %{
13608 FloatRegister dst = $dst$$FloatRegister;
13610 __ mtc1(R0, dst);
13611 %}
13612 ins_pipe( fpu_loadF );
13613 %}
13616 instruct loadConF(regF dst, immF src) %{
13617 match(Set dst src);
13618 ins_cost(125);
13620 format %{ "lwc1 $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
13621 ins_encode %{
13622 int con_offset = $constantoffset($src);
13624 if (Assembler::is_simm16(con_offset)) {
13625 __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
13626 } else {
13627 __ set64(AT, con_offset);
13628 if (UseLoongsonISA) {
13629 __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
13630 } else {
13631 __ daddu(AT, $constanttablebase, AT);
13632 __ lwc1($dst$$FloatRegister, AT, 0);
13633 }
13634 }
13635 %}
13636 ins_pipe( fpu_loadF );
13637 %}
13640 instruct loadConD0(regD dst, immD0 zero) %{
13641 match(Set dst zero);
13642 ins_cost(100);
13644 format %{ "mov $dst, zero @ loadConD0"%}
13645 ins_encode %{
13646 FloatRegister dst = as_FloatRegister($dst$$reg);
13648 __ dmtc1(R0, dst);
13649 %}
13650 ins_pipe( fpu_loadF );
13651 %}
13653 instruct loadConD(regD dst, immD src) %{
13654 match(Set dst src);
13655 ins_cost(125);
13657 format %{ "ldc1 $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
13658 ins_encode %{
13659 int con_offset = $constantoffset($src);
13661 if (Assembler::is_simm16(con_offset)) {
13662 __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
13663 } else {
13664 __ set64(AT, con_offset);
13665 if (UseLoongsonISA) {
13666 __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
13667 } else {
13668 __ daddu(AT, $constanttablebase, AT);
13669 __ ldc1($dst$$FloatRegister, AT, 0);
13670 }
13671 }
13672 %}
13673 ins_pipe( fpu_loadF );
13674 %}
13676 // Store register Float value (it is faster than store from FPU register)
13677 instruct storeF_reg( memory mem, regF src) %{
13678 match(Set mem (StoreF mem src));
13680 ins_cost(50);
13681 format %{ "store $mem, $src\t# store float @ storeF_reg" %}
13682 ins_encode(store_F_reg_enc(mem, src));
13683 ins_pipe( fpu_storeF );
13684 %}
13686 instruct storeF_imm0( memory mem, immF0 zero) %{
13687 match(Set mem (StoreF mem zero));
13689 ins_cost(40);
13690 format %{ "store $mem, zero\t# store float @ storeF_imm0" %}
13691 ins_encode %{
13692 int base = $mem$$base;
13693 int index = $mem$$index;
13694 int scale = $mem$$scale;
13695 int disp = $mem$$disp;
13697 if( index != 0 ) {
13698 if ( UseLoongsonISA ) {
13699 if ( Assembler::is_simm(disp, 8) ) {
13700 if ( scale == 0 ) {
13701 __ gsswx(R0, as_Register(base), as_Register(index), disp);
13702 } else {
13703 __ dsll(T9, as_Register(index), scale);
13704 __ gsswx(R0, as_Register(base), T9, disp);
13705 }
13706 } else if ( Assembler::is_simm16(disp) ) {
13707 if ( scale == 0 ) {
13708 __ daddu(AT, as_Register(base), as_Register(index));
13709 } else {
13710 __ dsll(T9, as_Register(index), scale);
13711 __ daddu(AT, as_Register(base), T9);
13712 }
13713 __ sw(R0, AT, disp);
13714 } else {
13715 if ( scale == 0 ) {
13716 __ move(T9, disp);
13717 __ daddu(AT, as_Register(index), T9);
13718 __ gsswx(R0, as_Register(base), AT, 0);
13719 } else {
13720 __ dsll(T9, as_Register(index), scale);
13721 __ move(AT, disp);
13722 __ daddu(AT, AT, T9);
13723 __ gsswx(R0, as_Register(base), AT, 0);
13724 }
13725 }
13726 } else { //not use loongson isa
13727 if(scale != 0) {
13728 __ dsll(T9, as_Register(index), scale);
13729 __ daddu(AT, as_Register(base), T9);
13730 } else {
13731 __ daddu(AT, as_Register(base), as_Register(index));
13732 }
13733 if( Assembler::is_simm16(disp) ) {
13734 __ sw(R0, AT, disp);
13735 } else {
13736 __ move(T9, disp);
13737 __ daddu(AT, AT, T9);
13738 __ sw(R0, AT, 0);
13739 }
13740 }
13741 } else { //index is 0
13742 if ( UseLoongsonISA ) {
13743 if ( Assembler::is_simm16(disp) ) {
13744 __ sw(R0, as_Register(base), disp);
13745 } else {
13746 __ move(T9, disp);
13747 __ gsswx(R0, as_Register(base), T9, 0);
13748 }
13749 } else {
13750 if( Assembler::is_simm16(disp) ) {
13751 __ sw(R0, as_Register(base), disp);
13752 } else {
13753 __ move(T9, disp);
13754 __ daddu(AT, as_Register(base), T9);
13755 __ sw(R0, AT, 0);
13756 }
13757 }
13758 }
13759 %}
13760 ins_pipe( ialu_storeI );
13761 %}
13763 // Load Double
13764 instruct loadD(regD dst, memory mem) %{
13765 match(Set dst (LoadD mem));
13767 ins_cost(150);
13768 format %{ "loadD $dst, $mem #@loadD" %}
13769 ins_encode(load_D_enc(dst, mem));
13770 ins_pipe( ialu_loadI );
13771 %}
13773 // Load Double - UNaligned
13774 instruct loadD_unaligned(regD dst, memory mem ) %{
13775 match(Set dst (LoadD_unaligned mem));
13776 ins_cost(250);
13777 // FIXME: Need more effective ldl/ldr
13778 format %{ "loadD_unaligned $dst, $mem #@loadD_unaligned" %}
13779 ins_encode(load_D_enc(dst, mem));
13780 ins_pipe( ialu_loadI );
13781 %}
13783 instruct storeD_reg( memory mem, regD src) %{
13784 match(Set mem (StoreD mem src));
13786 ins_cost(50);
13787 format %{ "store $mem, $src\t# store float @ storeD_reg" %}
13788 ins_encode(store_D_reg_enc(mem, src));
13789 ins_pipe( fpu_storeF );
13790 %}
13792 instruct storeD_imm0( memory mem, immD0 zero) %{
13793 match(Set mem (StoreD mem zero));
13795 ins_cost(40);
13796 format %{ "store $mem, zero\t# store float @ storeD_imm0" %}
13797 ins_encode %{
13798 int base = $mem$$base;
13799 int index = $mem$$index;
13800 int scale = $mem$$scale;
13801 int disp = $mem$$disp;
13803 __ mtc1(R0, F30);
13804 __ cvt_d_w(F30, F30);
13806 if( index != 0 ) {
13807 if ( UseLoongsonISA ) {
13808 if ( Assembler::is_simm(disp, 8) ) {
13809 if (scale == 0) {
13810 __ gssdxc1(F30, as_Register(base), as_Register(index), disp);
13811 } else {
13812 __ dsll(T9, as_Register(index), scale);
13813 __ gssdxc1(F30, as_Register(base), T9, disp);
13814 }
13815 } else if ( Assembler::is_simm16(disp) ) {
13816 if (scale == 0) {
13817 __ daddu(AT, as_Register(base), as_Register(index));
13818 __ sdc1(F30, AT, disp);
13819 } else {
13820 __ dsll(T9, as_Register(index), scale);
13821 __ daddu(AT, as_Register(base), T9);
13822 __ sdc1(F30, AT, disp);
13823 }
13824 } else {
13825 if (scale == 0) {
13826 __ move(T9, disp);
13827 __ daddu(AT, as_Register(index), T9);
13828 __ gssdxc1(F30, as_Register(base), AT, 0);
13829 } else {
13830 __ move(T9, disp);
13831 __ dsll(AT, as_Register(index), scale);
13832 __ daddu(AT, AT, T9);
13833 __ gssdxc1(F30, as_Register(base), AT, 0);
13834 }
13835 }
13836 } else { // not use loongson isa
13837 if(scale != 0) {
13838 __ dsll(T9, as_Register(index), scale);
13839 __ daddu(AT, as_Register(base), T9);
13840 } else {
13841 __ daddu(AT, as_Register(base), as_Register(index));
13842 }
13843 if( Assembler::is_simm16(disp) ) {
13844 __ sdc1(F30, AT, disp);
13845 } else {
13846 __ move(T9, disp);
13847 __ daddu(AT, AT, T9);
13848 __ sdc1(F30, AT, 0);
13849 }
13850 }
13851 } else {// index is 0
13852 if ( UseLoongsonISA ) {
13853 if ( Assembler::is_simm16(disp) ) {
13854 __ sdc1(F30, as_Register(base), disp);
13855 } else {
13856 __ move(T9, disp);
13857 __ gssdxc1(F30, as_Register(base), T9, 0);
13858 }
13859 } else {
13860 if( Assembler::is_simm16(disp) ) {
13861 __ sdc1(F30, as_Register(base), disp);
13862 } else {
13863 __ move(T9, disp);
13864 __ daddu(AT, as_Register(base), T9);
13865 __ sdc1(F30, AT, 0);
13866 }
13867 }
13868 }
13869 %}
13870 ins_pipe( ialu_storeI );
13871 %}
13873 instruct loadSSI(mRegI dst, stackSlotI src)
13874 %{
13875 match(Set dst src);
13877 ins_cost(125);
13878 format %{ "lw $dst, $src\t# int stk @ loadSSI" %}
13879 ins_encode %{
13880 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
13881 __ lw($dst$$Register, SP, $src$$disp);
13882 %}
13883 ins_pipe(ialu_loadI);
13884 %}
13886 instruct storeSSI(stackSlotI dst, mRegI src)
13887 %{
13888 match(Set dst src);
13890 ins_cost(100);
13891 format %{ "sw $dst, $src\t# int stk @ storeSSI" %}
13892 ins_encode %{
13893 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
13894 __ sw($src$$Register, SP, $dst$$disp);
13895 %}
13896 ins_pipe(ialu_storeI);
13897 %}
13899 instruct loadSSL(mRegL dst, stackSlotL src)
13900 %{
13901 match(Set dst src);
13903 ins_cost(125);
13904 format %{ "ld $dst, $src\t# long stk @ loadSSL" %}
13905 ins_encode %{
13906 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
13907 __ ld($dst$$Register, SP, $src$$disp);
13908 %}
13909 ins_pipe(ialu_loadI);
13910 %}
13912 instruct storeSSL(stackSlotL dst, mRegL src)
13913 %{
13914 match(Set dst src);
13916 ins_cost(100);
13917 format %{ "sd $dst, $src\t# long stk @ storeSSL" %}
13918 ins_encode %{
13919 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
13920 __ sd($src$$Register, SP, $dst$$disp);
13921 %}
13922 ins_pipe(ialu_storeI);
13923 %}
13925 instruct loadSSP(mRegP dst, stackSlotP src)
13926 %{
13927 match(Set dst src);
13929 ins_cost(125);
13930 format %{ "ld $dst, $src\t# ptr stk @ loadSSP" %}
13931 ins_encode %{
13932 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
13933 __ ld($dst$$Register, SP, $src$$disp);
13934 %}
13935 ins_pipe(ialu_loadI);
13936 %}
13938 instruct storeSSP(stackSlotP dst, mRegP src)
13939 %{
13940 match(Set dst src);
13942 ins_cost(100);
13943 format %{ "sd $dst, $src\t# ptr stk @ storeSSP" %}
13944 ins_encode %{
13945 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
13946 __ sd($src$$Register, SP, $dst$$disp);
13947 %}
13948 ins_pipe(ialu_storeI);
13949 %}
13951 instruct loadSSF(regF dst, stackSlotF src)
13952 %{
13953 match(Set dst src);
13955 ins_cost(125);
13956 format %{ "lwc1 $dst, $src\t# float stk @ loadSSF" %}
13957 ins_encode %{
13958 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
13959 __ lwc1($dst$$FloatRegister, SP, $src$$disp);
13960 %}
13961 ins_pipe(ialu_loadI);
13962 %}
13964 instruct storeSSF(stackSlotF dst, regF src)
13965 %{
13966 match(Set dst src);
13968 ins_cost(100);
13969 format %{ "swc1 $dst, $src\t# float stk @ storeSSF" %}
13970 ins_encode %{
13971 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
13972 __ swc1($src$$FloatRegister, SP, $dst$$disp);
13973 %}
13974 ins_pipe(fpu_storeF);
13975 %}
13977 // Use the same format since predicate() can not be used here.
13978 instruct loadSSD(regD dst, stackSlotD src)
13979 %{
13980 match(Set dst src);
13982 ins_cost(125);
13983 format %{ "ldc1 $dst, $src\t# double stk @ loadSSD" %}
13984 ins_encode %{
13985 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
13986 __ ldc1($dst$$FloatRegister, SP, $src$$disp);
13987 %}
13988 ins_pipe(ialu_loadI);
13989 %}
13991 instruct storeSSD(stackSlotD dst, regD src)
13992 %{
13993 match(Set dst src);
13995 ins_cost(100);
13996 format %{ "sdc1 $dst, $src\t# double stk @ storeSSD" %}
13997 ins_encode %{
13998 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
13999 __ sdc1($src$$FloatRegister, SP, $dst$$disp);
14000 %}
14001 ins_pipe(fpu_storeF);
14002 %}
14004 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
14005 match( Set cr (FastLock object box) );
14006 effect( TEMP tmp, TEMP scr, USE_KILL box );
14007 ins_cost(300);
14008 format %{ "FASTLOCK $cr <-- $object, $box, $tmp, $scr #@ cmpFastLock" %}
14009 ins_encode %{
14010 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
14011 %}
14013 ins_pipe( pipe_slow );
14014 ins_pc_relative(1);
14015 %}
14017 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
14018 match( Set cr (FastUnlock object box) );
14019 effect( TEMP tmp, USE_KILL box );
14020 ins_cost(300);
14021 format %{ "FASTUNLOCK $cr <-- $object, $box, $tmp #@cmpFastUnlock" %}
14022 ins_encode %{
14023 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
14024 %}
14026 ins_pipe( pipe_slow );
14027 ins_pc_relative(1);
14028 %}
14030 // Store CMS card-mark Immediate
14031 instruct storeImmCM(memory mem, immI8 src) %{
14032 match(Set mem (StoreCM mem src));
14034 ins_cost(150);
14035 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %}
14036 // opcode(0xC6);
14037 ins_encode(store_B_immI_enc_sync(mem, src));
14038 ins_pipe( ialu_storeI );
14039 %}
14041 // Die now
14042 instruct ShouldNotReachHere( )
14043 %{
14044 match(Halt);
14045 ins_cost(300);
14047 // Use the following format syntax
14048 format %{ "ILLTRAP ;#@ShouldNotReachHere" %}
14049 ins_encode %{
14050 // Here we should emit illtrap !
14052 __ stop("in ShoudNotReachHere");
14054 %}
14055 ins_pipe( pipe_jump );
14056 %}
14058 instruct leaP8Narrow(mRegP dst, indOffset8Narrow mem)
14059 %{
14060 predicate(Universe::narrow_oop_shift() == 0);
14061 match(Set dst mem);
14063 ins_cost(110);
14064 format %{ "leaq $dst, $mem\t# ptr off8narrow @ leaP8Narrow" %}
14065 ins_encode %{
14066 Register dst = $dst$$Register;
14067 Register base = as_Register($mem$$base);
14068 int disp = $mem$$disp;
14070 __ daddiu(dst, base, disp);
14071 %}
14072 ins_pipe( ialu_regI_imm16 );
14073 %}
14075 instruct leaPPosIdxScaleOff8(mRegP dst, basePosIndexScaleOffset8 mem)
14076 %{
14077 match(Set dst mem);
14079 ins_cost(110);
14080 format %{ "leaq $dst, $mem\t# @ PosIdxScaleOff8" %}
14081 ins_encode %{
14082 Register dst = $dst$$Register;
14083 Register base = as_Register($mem$$base);
14084 Register index = as_Register($mem$$index);
14085 int scale = $mem$$scale;
14086 int disp = $mem$$disp;
14088 if (scale == 0) {
14089 __ daddu(AT, base, index);
14090 __ daddiu(dst, AT, disp);
14091 } else {
14092 __ dsll(AT, index, scale);
14093 __ daddu(AT, base, AT);
14094 __ daddiu(dst, AT, disp);
14095 }
14096 %}
14098 ins_pipe( ialu_regI_imm16 );
14099 %}
14101 instruct leaPIdxScale(mRegP dst, indIndexScale mem)
14102 %{
14103 match(Set dst mem);
14105 ins_cost(110);
14106 format %{ "leaq $dst, $mem\t# @ leaPIdxScale" %}
14107 ins_encode %{
14108 Register dst = $dst$$Register;
14109 Register base = as_Register($mem$$base);
14110 Register index = as_Register($mem$$index);
14111 int scale = $mem$$scale;
14113 if (scale == 0) {
14114 __ daddu(dst, base, index);
14115 } else {
14116 __ dsll(AT, index, scale);
14117 __ daddu(dst, base, AT);
14118 }
14119 %}
14121 ins_pipe( ialu_regI_imm16 );
14122 %}
14125 // ============================================================================
14126 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
14127 // array for an instance of the superklass. Set a hidden internal cache on a
14128 // hit (cache is checked with exposed code in gen_subtype_check()). Return
14129 // NZ for a miss or zero for a hit. The encoding ALSO sets flags.
14130 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
14131 match(Set result (PartialSubtypeCheck sub super));
14132 effect(KILL tmp);
14133 ins_cost(1100); // slightly larger than the next version
14134 format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
14136 ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
14137 ins_pipe( pipe_slow );
14138 %}
14140 // Conditional-store of the updated heap-top.
14141 // Used during allocation of the shared heap.
14143 instruct storePConditional( memory heap_top_ptr, mRegP oldval, mRegP newval, FlagsReg cr ) %{
14144 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
14146 format %{ "CMPXCHG $heap_top_ptr, $newval\t# (ptr) @storePConditional "
14147 "If $oldval == $heap_top_ptr then store $newval into $heap_top_ptr" %}
14148 ins_encode%{
14149 Register oldval = $oldval$$Register;
14150 Register newval = $newval$$Register;
14151 Address addr(as_Register($heap_top_ptr$$base), $heap_top_ptr$$disp);
14153 int index = $heap_top_ptr$$index;
14154 int scale = $heap_top_ptr$$scale;
14155 int disp = $heap_top_ptr$$disp;
14157 guarantee(Assembler::is_simm16(disp), "");
14159 if( index != 0 ) {
14160 __ stop("in storePConditional: index != 0");
14161 } else {
14162 __ cmpxchg(newval, addr, oldval);
14163 }
14164 %}
14165 ins_pipe( long_memory_op );
14166 %}
14168 // Conditional-store of an int value.
14169 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
14170 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
14171 match(Set cr (StoreIConditional mem (Binary oldval newval)));
14172 // effect(KILL oldval);
14173 format %{ "CMPXCHG $newval, $mem, $oldval \t# @storeIConditional" %}
14175 ins_encode %{
14176 Register oldval = $oldval$$Register;
14177 Register newval = $newval$$Register;
14178 Address addr(as_Register($mem$$base), $mem$$disp);
14179 Label again, failure;
14181 int index = $mem$$index;
14182 int scale = $mem$$scale;
14183 int disp = $mem$$disp;
14185 guarantee(Assembler::is_simm16(disp), "");
14187 if( index != 0 ) {
14188 __ stop("in storeIConditional: index != 0");
14189 } else {
14190 __ bind(again);
14191 if(UseSyncLevel >= 3000 || UseSyncLevel < 2000) __ sync();
14192 __ ll(AT, addr);
14193 __ bne(AT, oldval, failure);
14194 __ delayed()->addu(AT, R0, R0);
14196 __ addu(AT, newval, R0);
14197 __ sc(AT, addr);
14198 __ beq(AT, R0, again);
14199 __ delayed()->addiu(AT, R0, 0xFF);
14200 __ bind(failure);
14201 __ sync();
14202 }
14203 %}
14205 ins_pipe( long_memory_op );
14206 %}
14208 // Conditional-store of a long value.
14209 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
14210 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
14211 %{
14212 match(Set cr (StoreLConditional mem (Binary oldval newval)));
14213 effect(KILL oldval);
14215 format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
14216 ins_encode%{
14217 Register oldval = $oldval$$Register;
14218 Register newval = $newval$$Register;
14219 Address addr(as_Register($mem$$base), $mem$$disp);
14221 int index = $mem$$index;
14222 int scale = $mem$$scale;
14223 int disp = $mem$$disp;
14225 guarantee(Assembler::is_simm16(disp), "");
14227 if( index != 0 ) {
14228 __ stop("in storeIConditional: index != 0");
14229 } else {
14230 __ cmpxchg(newval, addr, oldval);
14231 }
14232 %}
14233 ins_pipe( long_memory_op );
14234 %}
14236 // Implement LoadPLocked. Must be ordered against changes of the memory location
14237 // by storePConditional.
14238 instruct loadPLocked(mRegP dst, memory mem) %{
14239 match(Set dst (LoadPLocked mem));
14240 ins_cost(MEMORY_REF_COST);
14242 format %{ "ld $dst, $mem #@loadPLocked\n\t"
14243 "sync" %}
14244 size(12);
14245 ins_encode (load_P_enc_ac(dst, mem));
14246 ins_pipe( ialu_loadI );
14247 %}
14250 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
14251 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
14252 effect(KILL oldval);
14253 // match(CompareAndSwapI mem_ptr (Binary oldval newval));
14254 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapL\n\t"
14255 "MOV $res, 1 @ compareAndSwapI\n\t"
14256 "BNE AT, R0 @ compareAndSwapI\n\t"
14257 "MOV $res, 0 @ compareAndSwapI\n"
14258 "L:" %}
14259 ins_encode %{
14260 Register newval = $newval$$Register;
14261 Register oldval = $oldval$$Register;
14262 Register res = $res$$Register;
14263 Address addr($mem_ptr$$Register, 0);
14264 Label L;
14266 __ cmpxchg32(newval, addr, oldval);
14267 __ move(res, AT);
14268 %}
14269 ins_pipe( long_memory_op );
14270 %}
14272 instruct compareAndSwapL( mRegI res, mRegP mem_ptr, s2RegL oldval, mRegL newval) %{
14273 predicate(VM_Version::supports_cx8());
14274 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
14275 effect(KILL oldval);
14276 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
14277 "MOV $res, 1 @ compareAndSwapI\n\t"
14278 "BNE AT, R0 @ compareAndSwapI\n\t"
14279 "MOV $res, 0 @ compareAndSwapI\n"
14280 "L:" %}
14281 ins_encode %{
14282 Register newval = $newval$$Register;
14283 Register oldval = $oldval$$Register;
14284 Register res = $res$$Register;
14285 Address addr($mem_ptr$$Register, 0);
14286 Label L;
14288 __ cmpxchg(newval, addr, oldval);
14289 __ move(res, AT);
14290 %}
14291 ins_pipe( long_memory_op );
14292 %}
14294 //FIXME:
14295 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
14296 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
14297 effect(KILL oldval);
14298 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
14299 "MOV $res, AT @ compareAndSwapP\n\t"
14300 "L:" %}
14301 ins_encode %{
14302 Register newval = $newval$$Register;
14303 Register oldval = $oldval$$Register;
14304 Register res = $res$$Register;
14305 Address addr($mem_ptr$$Register, 0);
14306 Label L;
14308 __ cmpxchg(newval, addr, oldval);
14309 __ move(res, AT);
14310 %}
14311 ins_pipe( long_memory_op );
14312 %}
14314 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
14315 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
14316 effect(KILL oldval);
14317 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
14318 "MOV $res, AT @ compareAndSwapN\n\t"
14319 "L:" %}
14320 ins_encode %{
14321 Register newval = $newval$$Register;
14322 Register oldval = $oldval$$Register;
14323 Register res = $res$$Register;
14324 Address addr($mem_ptr$$Register, 0);
14325 Label L;
14327 // cmpxchg32 is implemented with ll/sc, which will do sign extension.
14328 // Thus, we should extend oldval's sign for correct comparision.
14329 //
14330 __ sll(oldval, oldval, 0);
14332 __ cmpxchg32(newval, addr, oldval);
14333 __ move(res, AT);
14334 %}
14335 ins_pipe( long_memory_op );
14336 %}
14338 //----------Max and Min--------------------------------------------------------
14339 // Min Instructions
14340 ////
14341 // *** Min and Max using the conditional move are slower than the
14342 // *** branch version on a Pentium III.
14343 // // Conditional move for min
14344 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
14345 // effect( USE_DEF op2, USE op1, USE cr );
14346 // format %{ "CMOVlt $op2,$op1\t! min" %}
14347 // opcode(0x4C,0x0F);
14348 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
14349 // ins_pipe( pipe_cmov_reg );
14350 //%}
14351 //
14352 //// Min Register with Register (P6 version)
14353 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
14354 // predicate(VM_Version::supports_cmov() );
14355 // match(Set op2 (MinI op1 op2));
14356 // ins_cost(200);
14357 // expand %{
14358 // eFlagsReg cr;
14359 // compI_eReg(cr,op1,op2);
14360 // cmovI_reg_lt(op2,op1,cr);
14361 // %}
14362 //%}
14364 // Min Register with Register (generic version)
14365 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
14366 match(Set dst (MinI dst src));
14367 //effect(KILL flags);
14368 ins_cost(80);
14370 format %{ "MIN $dst, $src @minI_Reg_Reg" %}
14371 ins_encode %{
14372 Register dst = $dst$$Register;
14373 Register src = $src$$Register;
14375 __ slt(AT, src, dst);
14376 __ movn(dst, src, AT);
14378 %}
14380 ins_pipe( pipe_slow );
14381 %}
14383 // Max Register with Register
14384 // *** Min and Max using the conditional move are slower than the
14385 // *** branch version on a Pentium III.
14386 // // Conditional move for max
14387 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
14388 // effect( USE_DEF op2, USE op1, USE cr );
14389 // format %{ "CMOVgt $op2,$op1\t! max" %}
14390 // opcode(0x4F,0x0F);
14391 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
14392 // ins_pipe( pipe_cmov_reg );
14393 //%}
14394 //
14395 // // Max Register with Register (P6 version)
14396 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
14397 // predicate(VM_Version::supports_cmov() );
14398 // match(Set op2 (MaxI op1 op2));
14399 // ins_cost(200);
14400 // expand %{
14401 // eFlagsReg cr;
14402 // compI_eReg(cr,op1,op2);
14403 // cmovI_reg_gt(op2,op1,cr);
14404 // %}
14405 //%}
14407 // Max Register with Register (generic version)
14408 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
14409 match(Set dst (MaxI dst src));
14410 ins_cost(80);
14412 format %{ "MAX $dst, $src @maxI_Reg_Reg" %}
14414 ins_encode %{
14415 Register dst = $dst$$Register;
14416 Register src = $src$$Register;
14418 __ slt(AT, dst, src);
14419 __ movn(dst, src, AT);
14421 %}
14423 ins_pipe( pipe_slow );
14424 %}
14426 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
14427 match(Set dst (MaxI dst zero));
14428 ins_cost(50);
14430 format %{ "MAX $dst, 0 @maxI_Reg_zero" %}
14432 ins_encode %{
14433 Register dst = $dst$$Register;
14435 __ slt(AT, dst, R0);
14436 __ movn(dst, R0, AT);
14438 %}
14440 ins_pipe( pipe_slow );
14441 %}
14443 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
14444 %{
14445 match(Set dst (AndL src mask));
14447 format %{ "movl $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
14448 ins_encode %{
14449 Register dst = $dst$$Register;
14450 Register src = $src$$Register;
14452 __ dext(dst, src, 0, 32);
14453 %}
14454 ins_pipe(ialu_regI_regI);
14455 %}
14457 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
14458 %{
14459 match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
14461 format %{ "combine_i2l $dst, $src2(H), $src1(L) @ combine_i2l" %}
14462 ins_encode %{
14463 Register dst = $dst$$Register;
14464 Register src1 = $src1$$Register;
14465 Register src2 = $src2$$Register;
14467 if (src1 == dst) {
14468 __ dinsu(dst, src2, 32, 32);
14469 } else if (src2 == dst) {
14470 __ dsll32(dst, dst, 0);
14471 __ dins(dst, src1, 0, 32);
14472 } else {
14473 __ dext(dst, src1, 0, 32);
14474 __ dinsu(dst, src2, 32, 32);
14475 }
14476 %}
14477 ins_pipe(ialu_regI_regI);
14478 %}
14480 // Zero-extend convert int to long
14481 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
14482 %{
14483 match(Set dst (AndL (ConvI2L src) mask));
14485 format %{ "movl $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
14486 ins_encode %{
14487 Register dst = $dst$$Register;
14488 Register src = $src$$Register;
14490 __ dext(dst, src, 0, 32);
14491 %}
14492 ins_pipe(ialu_regI_regI);
14493 %}
14495 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
14496 %{
14497 match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
14499 format %{ "movl $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
14500 ins_encode %{
14501 Register dst = $dst$$Register;
14502 Register src = $src$$Register;
14504 __ dext(dst, src, 0, 32);
14505 %}
14506 ins_pipe(ialu_regI_regI);
14507 %}
14509 // Match loading integer and casting it to unsigned int in long register.
14510 // LoadI + ConvI2L + AndL 0xffffffff.
14511 instruct loadUI2L_rmask(mRegL dst, memory mem, immL_32bits mask) %{
14512 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
14514 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
14515 ins_encode (load_N_enc(dst, mem));
14516 ins_pipe(ialu_loadI);
14517 %}
14519 instruct loadUI2L_lmask(mRegL dst, memory mem, immL_32bits mask) %{
14520 match(Set dst (AndL mask (ConvI2L (LoadI mem))));
14522 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
14523 ins_encode (load_N_enc(dst, mem));
14524 ins_pipe(ialu_loadI);
14525 %}
14528 // ============================================================================
14529 // Safepoint Instruction
14530 instruct safePoint_poll_reg(mRegP poll) %{
14531 match(SafePoint poll);
14532 predicate(false);
14533 effect(USE poll);
14535 ins_cost(125);
14536 format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
14538 ins_encode %{
14539 Register poll_reg = $poll$$Register;
14541 __ block_comment("Safepoint:");
14542 __ relocate(relocInfo::poll_type);
14543 __ lw(AT, poll_reg, 0);
14544 %}
14546 ins_pipe( ialu_storeI );
14547 %}
14549 instruct safePoint_poll() %{
14550 match(SafePoint);
14552 ins_cost(105);
14553 format %{ "poll for GC @ safePoint_poll" %}
14555 ins_encode %{
14556 __ block_comment("Safepoint:");
14557 __ set64(T9, (long)os::get_polling_page());
14558 __ relocate(relocInfo::poll_type);
14559 __ lw(AT, T9, 0);
14560 %}
14562 ins_pipe( ialu_storeI );
14563 %}
14565 //----------Arithmetic Conversion Instructions---------------------------------
14567 instruct roundFloat_nop(regF dst)
14568 %{
14569 match(Set dst (RoundFloat dst));
14571 ins_cost(0);
14572 ins_encode();
14573 ins_pipe(empty);
14574 %}
14576 instruct roundDouble_nop(regD dst)
14577 %{
14578 match(Set dst (RoundDouble dst));
14580 ins_cost(0);
14581 ins_encode();
14582 ins_pipe(empty);
14583 %}
14585 //---------- Zeros Count Instructions ------------------------------------------
14586 // CountLeadingZerosINode CountTrailingZerosINode
14587 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
14588 predicate(UseCountLeadingZerosInstructionMIPS64);
14589 match(Set dst (CountLeadingZerosI src));
14591 format %{ "clz $dst, $src\t# count leading zeros (int)" %}
14592 ins_encode %{
14593 __ clz($dst$$Register, $src$$Register);
14594 %}
14595 ins_pipe( ialu_regL_regL );
14596 %}
14598 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
14599 predicate(UseCountLeadingZerosInstructionMIPS64);
14600 match(Set dst (CountLeadingZerosL src));
14602 format %{ "dclz $dst, $src\t# count leading zeros (long)" %}
14603 ins_encode %{
14604 __ dclz($dst$$Register, $src$$Register);
14605 %}
14606 ins_pipe( ialu_regL_regL );
14607 %}
14609 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
14610 predicate(UseCountTrailingZerosInstructionMIPS64);
14611 match(Set dst (CountTrailingZerosI src));
14613 format %{ "ctz $dst, $src\t# count trailing zeros (int)" %}
14614 ins_encode %{
14615 // ctz and dctz is gs instructions.
14616 __ ctz($dst$$Register, $src$$Register);
14617 %}
14618 ins_pipe( ialu_regL_regL );
14619 %}
14621 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
14622 predicate(UseCountTrailingZerosInstructionMIPS64);
14623 match(Set dst (CountTrailingZerosL src));
14625 format %{ "dcto $dst, $src\t# count trailing zeros (long)" %}
14626 ins_encode %{
14627 __ dctz($dst$$Register, $src$$Register);
14628 %}
14629 ins_pipe( ialu_regL_regL );
14630 %}
14632 // ====================VECTOR INSTRUCTIONS=====================================
14634 // Load vectors (8 bytes long)
14635 instruct loadV8(vecD dst, memory mem) %{
14636 predicate(n->as_LoadVector()->memory_size() == 8);
14637 match(Set dst (LoadVector mem));
14638 ins_cost(125);
14639 format %{ "load $dst, $mem\t! load vector (8 bytes)" %}
14640 ins_encode(load_D_enc(dst, mem));
14641 ins_pipe( fpu_loadF );
14642 %}
14644 // Store vectors (8 bytes long)
14645 instruct storeV8(memory mem, vecD src) %{
14646 predicate(n->as_StoreVector()->memory_size() == 8);
14647 match(Set mem (StoreVector mem src));
14648 ins_cost(145);
14649 format %{ "store $mem, $src\t! store vector (8 bytes)" %}
14650 ins_encode(store_D_reg_enc(mem, src));
14651 ins_pipe( fpu_storeF );
14652 %}
14654 instruct Repl8B_DSP(vecD dst, mRegI src) %{
14655 predicate(n->as_Vector()->length() == 8 && Use3A2000);
14656 match(Set dst (ReplicateB src));
14657 ins_cost(100);
14658 format %{ "replv_ob AT, $src\n\t"
14659 "dmtc1 AT, $dst\t! replicate8B" %}
14660 ins_encode %{
14661 __ replv_ob(AT, $src$$Register);
14662 __ dmtc1(AT, $dst$$FloatRegister);
14663 %}
14664 ins_pipe( pipe_mtc1 );
14665 %}
14667 instruct Repl8B(vecD dst, mRegI src) %{
14668 predicate(n->as_Vector()->length() == 8);
14669 match(Set dst (ReplicateB src));
14670 ins_cost(140);
14671 format %{ "move AT, $src\n\t"
14672 "dins AT, AT, 8, 8\n\t"
14673 "dins AT, AT, 16, 16\n\t"
14674 "dinsu AT, AT, 32, 32\n\t"
14675 "dmtc1 AT, $dst\t! replicate8B" %}
14676 ins_encode %{
14677 __ move(AT, $src$$Register);
14678 __ dins(AT, AT, 8, 8);
14679 __ dins(AT, AT, 16, 16);
14680 __ dinsu(AT, AT, 32, 32);
14681 __ dmtc1(AT, $dst$$FloatRegister);
14682 %}
14683 ins_pipe( pipe_mtc1 );
14684 %}
14686 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
14687 predicate(n->as_Vector()->length() == 8 && Use3A2000);
14688 match(Set dst (ReplicateB con));
14689 ins_cost(110);
14690 format %{ "repl_ob AT, [$con]\n\t"
14691 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
14692 ins_encode %{
14693 int val = $con$$constant;
14694 __ repl_ob(AT, val);
14695 __ dmtc1(AT, $dst$$FloatRegister);
14696 %}
14697 ins_pipe( pipe_mtc1 );
14698 %}
14700 instruct Repl8B_imm(vecD dst, immI con) %{
14701 predicate(n->as_Vector()->length() == 8);
14702 match(Set dst (ReplicateB con));
14703 ins_cost(150);
14704 format %{ "move AT, [$con]\n\t"
14705 "dins AT, AT, 8, 8\n\t"
14706 "dins AT, AT, 16, 16\n\t"
14707 "dinsu AT, AT, 32, 32\n\t"
14708 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
14709 ins_encode %{
14710 __ move(AT, $con$$constant);
14711 __ dins(AT, AT, 8, 8);
14712 __ dins(AT, AT, 16, 16);
14713 __ dinsu(AT, AT, 32, 32);
14714 __ dmtc1(AT, $dst$$FloatRegister);
14715 %}
14716 ins_pipe( pipe_mtc1 );
14717 %}
14719 instruct Repl8B_zero(vecD dst, immI0 zero) %{
14720 predicate(n->as_Vector()->length() == 8);
14721 match(Set dst (ReplicateB zero));
14722 ins_cost(90);
14723 format %{ "dmtc1 R0, $dst\t! replicate8B zero" %}
14724 ins_encode %{
14725 __ dmtc1(R0, $dst$$FloatRegister);
14726 %}
14727 ins_pipe( pipe_mtc1 );
14728 %}
14730 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
14731 predicate(n->as_Vector()->length() == 8);
14732 match(Set dst (ReplicateB M1));
14733 ins_cost(80);
14734 format %{ "dmtc1 -1, $dst\t! replicate8B -1" %}
14735 ins_encode %{
14736 __ nor(AT, R0, R0);
14737 __ dmtc1(AT, $dst$$FloatRegister);
14738 %}
14739 ins_pipe( pipe_mtc1 );
14740 %}
14742 instruct Repl4S_DSP(vecD dst, mRegI src) %{
14743 predicate(n->as_Vector()->length() == 4 && Use3A2000);
14744 match(Set dst (ReplicateS src));
14745 ins_cost(100);
14746 format %{ "replv_qh AT, $src\n\t"
14747 "dmtc1 AT, $dst\t! replicate4S" %}
14748 ins_encode %{
14749 __ replv_qh(AT, $src$$Register);
14750 __ dmtc1(AT, $dst$$FloatRegister);
14751 %}
14752 ins_pipe( pipe_mtc1 );
14753 %}
14755 instruct Repl4S(vecD dst, mRegI src) %{
14756 predicate(n->as_Vector()->length() == 4);
14757 match(Set dst (ReplicateS src));
14758 ins_cost(120);
14759 format %{ "move AT, $src \n\t"
14760 "dins AT, AT, 16, 16\n\t"
14761 "dinsu AT, AT, 32, 32\n\t"
14762 "dmtc1 AT, $dst\t! replicate4S" %}
14763 ins_encode %{
14764 __ move(AT, $src$$Register);
14765 __ dins(AT, AT, 16, 16);
14766 __ dinsu(AT, AT, 32, 32);
14767 __ dmtc1(AT, $dst$$FloatRegister);
14768 %}
14769 ins_pipe( pipe_mtc1 );
14770 %}
14772 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
14773 predicate(n->as_Vector()->length() == 4 && Use3A2000);
14774 match(Set dst (ReplicateS con));
14775 ins_cost(100);
14776 format %{ "repl_qh AT, [$con]\n\t"
14777 "dmtc1 AT, $dst\t! replicate4S($con)" %}
14778 ins_encode %{
14779 int val = $con$$constant;
14780 if ( Assembler::is_simm(val, 10)) {
14781 //repl_qh supports 10 bits immediate
14782 __ repl_qh(AT, val);
14783 } else {
14784 __ li32(AT, val);
14785 __ replv_qh(AT, AT);
14786 }
14787 __ dmtc1(AT, $dst$$FloatRegister);
14788 %}
14789 ins_pipe( pipe_mtc1 );
14790 %}
14792 instruct Repl4S_imm(vecD dst, immI con) %{
14793 predicate(n->as_Vector()->length() == 4);
14794 match(Set dst (ReplicateS con));
14795 ins_cost(110);
14796 format %{ "move AT, [$con]\n\t"
14797 "dins AT, AT, 16, 16\n\t"
14798 "dinsu AT, AT, 32, 32\n\t"
14799 "dmtc1 AT, $dst\t! replicate4S($con)" %}
14800 ins_encode %{
14801 __ move(AT, $con$$constant);
14802 __ dins(AT, AT, 16, 16);
14803 __ dinsu(AT, AT, 32, 32);
14804 __ dmtc1(AT, $dst$$FloatRegister);
14805 %}
14806 ins_pipe( pipe_mtc1 );
14807 %}
14809 instruct Repl4S_zero(vecD dst, immI0 zero) %{
14810 predicate(n->as_Vector()->length() == 4);
14811 match(Set dst (ReplicateS zero));
14812 format %{ "dmtc1 R0, $dst\t! replicate4S zero" %}
14813 ins_encode %{
14814 __ dmtc1(R0, $dst$$FloatRegister);
14815 %}
14816 ins_pipe( pipe_mtc1 );
14817 %}
14819 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
14820 predicate(n->as_Vector()->length() == 4);
14821 match(Set dst (ReplicateS M1));
14822 format %{ "dmtc1 -1, $dst\t! replicate4S -1" %}
14823 ins_encode %{
14824 __ nor(AT, R0, R0);
14825 __ dmtc1(AT, $dst$$FloatRegister);
14826 %}
14827 ins_pipe( pipe_mtc1 );
14828 %}
14830 // Replicate integer (4 byte) scalar to be vector
14831 instruct Repl2I(vecD dst, mRegI src) %{
14832 predicate(n->as_Vector()->length() == 2);
14833 match(Set dst (ReplicateI src));
14834 format %{ "dins AT, $src, 0, 32\n\t"
14835 "dinsu AT, $src, 32, 32\n\t"
14836 "dmtc1 AT, $dst\t! replicate2I" %}
14837 ins_encode %{
14838 __ dins(AT, $src$$Register, 0, 32);
14839 __ dinsu(AT, $src$$Register, 32, 32);
14840 __ dmtc1(AT, $dst$$FloatRegister);
14841 %}
14842 ins_pipe( pipe_mtc1 );
14843 %}
14845 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
14846 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
14847 predicate(n->as_Vector()->length() == 2);
14848 match(Set dst (ReplicateI con));
14849 effect(KILL tmp);
14850 format %{ "li32 AT, [$con], 32\n\t"
14851 "dinsu AT, AT\n\t"
14852 "dmtc1 AT, $dst\t! replicate2I($con)" %}
14853 ins_encode %{
14854 int val = $con$$constant;
14855 __ li32(AT, val);
14856 __ dinsu(AT, AT, 32, 32);
14857 __ dmtc1(AT, $dst$$FloatRegister);
14858 %}
14859 ins_pipe( pipe_mtc1 );
14860 %}
14862 // Replicate integer (4 byte) scalar zero to be vector
14863 instruct Repl2I_zero(vecD dst, immI0 zero) %{
14864 predicate(n->as_Vector()->length() == 2);
14865 match(Set dst (ReplicateI zero));
14866 format %{ "dmtc1 R0, $dst\t! replicate2I zero" %}
14867 ins_encode %{
14868 __ dmtc1(R0, $dst$$FloatRegister);
14869 %}
14870 ins_pipe( pipe_mtc1 );
14871 %}
14873 // Replicate integer (4 byte) scalar -1 to be vector
14874 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
14875 predicate(n->as_Vector()->length() == 2);
14876 match(Set dst (ReplicateI M1));
14877 format %{ "dmtc1 -1, $dst\t! replicate2I -1, use AT" %}
14878 ins_encode %{
14879 __ nor(AT, R0, R0);
14880 __ dmtc1(AT, $dst$$FloatRegister);
14881 %}
14882 ins_pipe( pipe_mtc1 );
14883 %}
14885 // Replicate float (4 byte) scalar to be vector
14886 instruct Repl2F(vecD dst, regF src) %{
14887 predicate(n->as_Vector()->length() == 2);
14888 match(Set dst (ReplicateF src));
14889 format %{ "cvt.ps $dst, $src, $src\t! replicate2F" %}
14890 ins_encode %{
14891 __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
14892 %}
14893 ins_pipe( pipe_slow );
14894 %}
14896 // Replicate float (4 byte) scalar zero to be vector
14897 instruct Repl2F_zero(vecD dst, immF0 zero) %{
14898 predicate(n->as_Vector()->length() == 2);
14899 match(Set dst (ReplicateF zero));
14900 format %{ "dmtc1 R0, $dst\t! replicate2F zero" %}
14901 ins_encode %{
14902 __ dmtc1(R0, $dst$$FloatRegister);
14903 %}
14904 ins_pipe( pipe_mtc1 );
14905 %}
14908 // ====================VECTOR ARITHMETIC=======================================
14910 // --------------------------------- ADD --------------------------------------
14912 // Floats vector add
14913 // kernel does not have emulation of PS instructions yet, so PS instructions is disabled.
14914 instruct vadd2F(vecD dst, vecD src) %{
14915 predicate(n->as_Vector()->length() == 2);
14916 match(Set dst (AddVF dst src));
14917 format %{ "add.ps $dst,$src\t! add packed2F" %}
14918 ins_encode %{
14919 __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14920 %}
14921 ins_pipe( pipe_slow );
14922 %}
14924 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
14925 predicate(n->as_Vector()->length() == 2);
14926 match(Set dst (AddVF src1 src2));
14927 format %{ "add.ps $dst,$src1,$src2\t! add packed2F" %}
14928 ins_encode %{
14929 __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14930 %}
14931 ins_pipe( fpu_regF_regF );
14932 %}
14934 // --------------------------------- SUB --------------------------------------
14936 // Floats vector sub
14937 instruct vsub2F(vecD dst, vecD src) %{
14938 predicate(n->as_Vector()->length() == 2);
14939 match(Set dst (SubVF dst src));
14940 format %{ "sub.ps $dst,$src\t! sub packed2F" %}
14941 ins_encode %{
14942 __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14943 %}
14944 ins_pipe( fpu_regF_regF );
14945 %}
14947 // --------------------------------- MUL --------------------------------------
14949 // Floats vector mul
14950 instruct vmul2F(vecD dst, vecD src) %{
14951 predicate(n->as_Vector()->length() == 2);
14952 match(Set dst (MulVF dst src));
14953 format %{ "mul.ps $dst, $src\t! mul packed2F" %}
14954 ins_encode %{
14955 __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14956 %}
14957 ins_pipe( fpu_regF_regF );
14958 %}
14960 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
14961 predicate(n->as_Vector()->length() == 2);
14962 match(Set dst (MulVF src1 src2));
14963 format %{ "mul.ps $dst, $src1, $src2\t! mul packed2F" %}
14964 ins_encode %{
14965 __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14966 %}
14967 ins_pipe( fpu_regF_regF );
14968 %}
14970 // --------------------------------- DIV --------------------------------------
14971 // MIPS do not have div.ps
14973 // --------------------------------- MADD --------------------------------------
14974 // Floats vector madd
14975 //instruct vmadd2F(vecD dst, vecD src1, vecD src2, vecD src3) %{
14976 // predicate(n->as_Vector()->length() == 2);
14977 // match(Set dst (AddVF (MulVF src1 src2) src3));
14978 // ins_cost(50);
14979 // format %{ "madd.ps $dst, $src3, $src1, $src2\t! madd packed2F" %}
14980 // ins_encode %{
14981 // __ madd_ps($dst$$FloatRegister, $src3$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14982 // %}
14983 // ins_pipe( fpu_regF_regF );
14984 //%}
14987 //----------PEEPHOLE RULES-----------------------------------------------------
14988 // These must follow all instruction definitions as they use the names
14989 // defined in the instructions definitions.
14990 //
14991 // peepmatch ( root_instr_name [preceeding_instruction]* );
14992 //
14993 // peepconstraint %{
14994 // (instruction_number.operand_name relational_op instruction_number.operand_name
14995 // [, ...] );
14996 // // instruction numbers are zero-based using left to right order in peepmatch
14997 //
14998 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14999 // // provide an instruction_number.operand_name for each operand that appears
15000 // // in the replacement instruction's match rule
15001 //
15002 // ---------VM FLAGS---------------------------------------------------------
15003 //
15004 // All peephole optimizations can be turned off using -XX:-OptoPeephole
15005 //
15006 // Each peephole rule is given an identifying number starting with zero and
15007 // increasing by one in the order seen by the parser. An individual peephole
15008 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
15009 // on the command-line.
15010 //
15011 // ---------CURRENT LIMITATIONS----------------------------------------------
15012 //
15013 // Only match adjacent instructions in same basic block
15014 // Only equality constraints
15015 // Only constraints between operands, not (0.dest_reg == EAX_enc)
15016 // Only one replacement instruction
15017 //
15018 // ---------EXAMPLE----------------------------------------------------------
15019 //
15020 // // pertinent parts of existing instructions in architecture description
15021 // instruct movI(eRegI dst, eRegI src) %{
15022 // match(Set dst (CopyI src));
15023 // %}
15024 //
15025 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
15026 // match(Set dst (AddI dst src));
15027 // effect(KILL cr);
15028 // %}
15029 //
15030 // // Change (inc mov) to lea
15031 // peephole %{
15032 // // increment preceeded by register-register move
15033 // peepmatch ( incI_eReg movI );
15034 // // require that the destination register of the increment
15035 // // match the destination register of the move
15036 // peepconstraint ( 0.dst == 1.dst );
15037 // // construct a replacement instruction that sets
15038 // // the destination to ( move's source register + one )
15039 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
15040 // %}
15041 //
15042 // Implementation no longer uses movX instructions since
15043 // machine-independent system no longer uses CopyX nodes.
15044 //
15045 // peephole %{
15046 // peepmatch ( incI_eReg movI );
15047 // peepconstraint ( 0.dst == 1.dst );
15048 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
15049 // %}
15050 //
15051 // peephole %{
15052 // peepmatch ( decI_eReg movI );
15053 // peepconstraint ( 0.dst == 1.dst );
15054 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
15055 // %}
15056 //
15057 // peephole %{
15058 // peepmatch ( addI_eReg_imm movI );
15059 // peepconstraint ( 0.dst == 1.dst );
15060 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
15061 // %}
15062 //
15063 // peephole %{
15064 // peepmatch ( addP_eReg_imm movP );
15065 // peepconstraint ( 0.dst == 1.dst );
15066 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
15067 // %}
15069 // // Change load of spilled value to only a spill
15070 // instruct storeI(memory mem, eRegI src) %{
15071 // match(Set mem (StoreI mem src));
15072 // %}
15073 //
15074 // instruct loadI(eRegI dst, memory mem) %{
15075 // match(Set dst (LoadI mem));
15076 // %}
15077 //
15078 //peephole %{
15079 // peepmatch ( loadI storeI );
15080 // peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
15081 // peepreplace ( storeI( 1.mem 1.mem 1.src ) );
15082 //%}
15084 //----------SMARTSPILL RULES---------------------------------------------------
15085 // These must follow all instruction definitions as they use the names
15086 // defined in the instructions definitions.