Tue, 28 Mar 2017 16:09:10 -0400
Add UseCodeCacheAllocOpt for MIPS.
1 //
2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 // Copyright (c) 2015, 2016, 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 // 2012/8/23 Fu: F30/F31 are used as temporary registers in D2I
384 // 2016/12/1 aoqi: F31 are not used as temporary registers in D2I
385 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);
386 reg_class dbl_reg( F0, F0_H,
387 F1, F1_H,
388 F2, F2_H,
389 F3, F3_H,
390 F4, F4_H,
391 F5, F5_H,
392 F6, F6_H,
393 F7, F7_H,
394 F8, F8_H,
395 F9, F9_H,
396 F10, F10_H,
397 F11, F11_H,
398 F12, F12_H,
399 F13, F13_H,
400 F14, F14_H,
401 F15, F15_H,
402 F16, F16_H,
403 F17, F17_H,
404 F18, F18_H,
405 F19, F19_H,
406 F20, F20_H,
407 F21, F21_H,
408 F22, F22_H,
409 F23, F23_H,
410 F24, F24_H,
411 F25, F25_H,
412 F26, F26_H,
413 F27, F27_H,
414 F28, F28_H,
415 F29, F29_H,
416 F31, F31_H);
418 reg_class flt_arg0( F12 );
419 reg_class dbl_arg0( F12, F12_H );
420 reg_class dbl_arg1( F14, F14_H );
422 %}
424 //----------DEFINITION BLOCK---------------------------------------------------
425 // Define name --> value mappings to inform the ADLC of an integer valued name
426 // Current support includes integer values in the range [0, 0x7FFFFFFF]
427 // Format:
428 // int_def <name> ( <int_value>, <expression>);
429 // Generated Code in ad_<arch>.hpp
430 // #define <name> (<expression>)
431 // // value == <int_value>
432 // Generated code in ad_<arch>.cpp adlc_verification()
433 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
434 //
435 definitions %{
436 int_def DEFAULT_COST ( 100, 100);
437 int_def HUGE_COST (1000000, 1000000);
439 // Memory refs are twice as expensive as run-of-the-mill.
440 int_def MEMORY_REF_COST ( 200, DEFAULT_COST * 2);
442 // Branches are even more expensive.
443 int_def BRANCH_COST ( 300, DEFAULT_COST * 3);
444 // we use jr instruction to construct call, so more expensive
445 // by yjl 2/28/2006
446 int_def CALL_COST ( 500, DEFAULT_COST * 5);
447 /*
448 int_def EQUAL ( 1, 1 );
449 int_def NOT_EQUAL ( 2, 2 );
450 int_def GREATER ( 3, 3 );
451 int_def GREATER_EQUAL ( 4, 4 );
452 int_def LESS ( 5, 5 );
453 int_def LESS_EQUAL ( 6, 6 );
454 */
455 %}
459 //----------SOURCE BLOCK-------------------------------------------------------
460 // This is a block of C++ code which provides values, functions, and
461 // definitions necessary in the rest of the architecture description
463 source_hpp %{
464 // Header information of the source block.
465 // Method declarations/definitions which are used outside
466 // the ad-scope can conveniently be defined here.
467 //
468 // To keep related declarations/definitions/uses close together,
469 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
471 class CallStubImpl {
473 //--------------------------------------------------------------
474 //---< Used for optimization in Compile::shorten_branches >---
475 //--------------------------------------------------------------
477 public:
478 // Size of call trampoline stub.
479 static uint size_call_trampoline() {
480 return 0; // no call trampolines on this platform
481 }
483 // number of relocations needed by a call trampoline stub
484 static uint reloc_call_trampoline() {
485 return 0; // no call trampolines on this platform
486 }
487 };
489 class HandlerImpl {
491 public:
493 static int emit_exception_handler(CodeBuffer &cbuf);
494 static int emit_deopt_handler(CodeBuffer& cbuf);
496 static uint size_exception_handler() {
497 // NativeCall instruction size is the same as NativeJump.
498 // exception handler starts out as jump and can be patched to
499 // a call be deoptimization. (4932387)
500 // Note that this value is also credited (in output.cpp) to
501 // the size of the code section.
502 // return NativeJump::instruction_size;
503 int size = NativeCall::instruction_size;
504 return round_to(size, 16);
505 }
507 #ifdef _LP64
508 static uint size_deopt_handler() {
509 int size = NativeCall::instruction_size;
510 return round_to(size, 16);
511 }
512 #else
513 static uint size_deopt_handler() {
514 // NativeCall instruction size is the same as NativeJump.
515 // exception handler starts out as jump and can be patched to
516 // a call be deoptimization. (4932387)
517 // Note that this value is also credited (in output.cpp) to
518 // the size of the code section.
519 return 5 + NativeJump::instruction_size; // pushl(); jmp;
520 }
521 #endif
522 };
524 %} // end source_hpp
526 source %{
528 #define NO_INDEX 0
529 #define RELOC_IMM64 Assembler::imm_operand
530 #define RELOC_DISP32 Assembler::disp32_operand
533 #define __ _masm.
536 // Emit exception handler code.
537 // Stuff framesize into a register and call a VM stub routine.
538 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
539 // Note that the code buffer's insts_mark is always relative to insts.
540 // That's why we must use the macroassembler to generate a handler.
541 MacroAssembler _masm(&cbuf);
542 address base =
543 __ start_a_stub(size_exception_handler());
544 if (base == NULL) return 0; // CodeBuffer::expand failed
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 =
564 __ start_a_stub(size_deopt_handler());
566 // FIXME
567 if (base == NULL) return 0; // CodeBuffer::expand failed
568 int offset = __ offset();
570 __ block_comment("; emit_deopt_handler");
572 cbuf.set_insts_mark();
573 __ relocate(relocInfo::runtime_call_type);
574 __ patchable_call(SharedRuntime::deopt_blob()->unpack());
575 __ align(16);
576 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
577 __ end_a_stub();
578 return offset;
579 }
582 const bool Matcher::match_rule_supported(int opcode) {
583 if (!has_match_rule(opcode))
584 return false;
586 switch (opcode) {
587 //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
588 case Op_CountLeadingZerosI:
589 case Op_CountLeadingZerosL:
590 if (!UseCountLeadingZerosInstruction)
591 return false;
592 break;
593 case Op_CountTrailingZerosI:
594 case Op_CountTrailingZerosL:
595 if (!UseCountTrailingZerosInstruction)
596 return false;
597 break;
598 }
600 return true; // Per default match rules are supported.
601 }
603 //FIXME
604 // emit call stub, compiled java to interpreter
605 void emit_java_to_interp(CodeBuffer &cbuf ) {
606 // Stub is fixed up when the corresponding call is converted from calling
607 // compiled code to calling interpreted code.
608 // mov rbx,0
609 // jmp -1
611 address mark = cbuf.insts_mark(); // get mark within main instrs section
613 // Note that the code buffer's insts_mark is always relative to insts.
614 // That's why we must use the macroassembler to generate a stub.
615 MacroAssembler _masm(&cbuf);
617 address base =
618 __ start_a_stub(Compile::MAX_stubs_size);
619 if (base == NULL) return; // CodeBuffer::expand failed
620 // static stub relocation stores the instruction address of the call
622 __ relocate(static_stub_Relocation::spec(mark), 0);
624 // static stub relocation also tags the methodOop in the code-stream.
625 __ patchable_set48(S3, (long)0);
626 // This is recognized as unresolved by relocs/nativeInst/ic code
628 __ relocate(relocInfo::runtime_call_type);
630 cbuf.set_insts_mark();
631 address call_pc = (address)-1;
632 __ patchable_jump(call_pc);
633 __ align(16);
634 __ end_a_stub();
635 // Update current stubs pointer and restore code_end.
636 }
638 // size of call stub, compiled java to interpretor
639 uint size_java_to_interp() {
640 int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
641 return round_to(size, 16);
642 }
644 // relocation entries for call stub, compiled java to interpreter
645 uint reloc_java_to_interp() {
646 return 16; // in emit_java_to_interp + in Java_Static_Call
647 }
649 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
650 if( Assembler::is_simm16(offset) ) return true;
651 else {
652 assert(false, "Not implemented yet !" );
653 Unimplemented();
654 }
655 }
658 // No additional cost for CMOVL.
659 const int Matcher::long_cmove_cost() { return 0; }
661 // No CMOVF/CMOVD with SSE2
662 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
664 // Does the CPU require late expand (see block.cpp for description of late expand)?
665 const bool Matcher::require_postalloc_expand = false;
667 // Should the Matcher clone shifts on addressing modes, expecting them
668 // to be subsumed into complex addressing expressions or compute them
669 // into registers? True for Intel but false for most RISCs
670 const bool Matcher::clone_shift_expressions = false;
672 // Do we need to mask the count passed to shift instructions or does
673 // the cpu only look at the lower 5/6 bits anyway?
674 const bool Matcher::need_masked_shift_count = false;
676 bool Matcher::narrow_oop_use_complex_address() {
677 NOT_LP64(ShouldNotCallThis());
678 assert(UseCompressedOops, "only for compressed oops code");
679 return false;
680 }
682 bool Matcher::narrow_klass_use_complex_address() {
683 NOT_LP64(ShouldNotCallThis());
684 assert(UseCompressedClassPointers, "only for compressed klass code");
685 return false;
686 }
688 // This is UltraSparc specific, true just means we have fast l2f conversion
689 const bool Matcher::convL2FSupported(void) {
690 return true;
691 }
693 // Max vector size in bytes. 0 if not supported.
694 const int Matcher::vector_width_in_bytes(BasicType bt) {
695 assert(MaxVectorSize == 8, "");
696 return 8;
697 }
699 // Vector ideal reg
700 const int Matcher::vector_ideal_reg(int size) {
701 assert(MaxVectorSize == 8, "");
702 switch(size) {
703 case 8: return Op_VecD;
704 }
705 ShouldNotReachHere();
706 return 0;
707 }
709 // Only lowest bits of xmm reg are used for vector shift count.
710 const int Matcher::vector_shift_count_ideal_reg(int size) {
711 fatal("vector shift is not supported");
712 return Node::NotAMachineReg;
713 }
715 // Limits on vector size (number of elements) loaded into vector.
716 const int Matcher::max_vector_size(const BasicType bt) {
717 assert(is_java_primitive(bt), "only primitive type vectors");
718 return vector_width_in_bytes(bt)/type2aelembytes(bt);
719 }
721 const int Matcher::min_vector_size(const BasicType bt) {
722 return max_vector_size(bt); // Same as max.
723 }
725 // MIPS supports misaligned vectors store/load? FIXME
726 const bool Matcher::misaligned_vectors_ok() {
727 return false;
728 //return !AlignVector; // can be changed by flag
729 }
731 // Register for DIVI projection of divmodI
732 RegMask Matcher::divI_proj_mask() {
733 ShouldNotReachHere();
734 return RegMask();
735 }
737 // Register for MODI projection of divmodI
738 RegMask Matcher::modI_proj_mask() {
739 ShouldNotReachHere();
740 return RegMask();
741 }
743 // Register for DIVL projection of divmodL
744 RegMask Matcher::divL_proj_mask() {
745 ShouldNotReachHere();
746 return RegMask();
747 }
749 int Matcher::regnum_to_fpu_offset(int regnum) {
750 return regnum - 32; // The FP registers are in the second chunk
751 }
754 const bool Matcher::isSimpleConstant64(jlong value) {
755 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
756 return true;
757 }
760 // Return whether or not this register is ever used as an argument. This
761 // function is used on startup to build the trampoline stubs in generateOptoStub.
762 // Registers not mentioned will be killed by the VM call in the trampoline, and
763 // arguments in those registers not be available to the callee.
764 bool Matcher::can_be_java_arg( int reg ) {
765 /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
766 if ( reg == T0_num || reg == T0_H_num
767 || reg == A0_num || reg == A0_H_num
768 || reg == A1_num || reg == A1_H_num
769 || reg == A2_num || reg == A2_H_num
770 || reg == A3_num || reg == A3_H_num
771 || reg == A4_num || reg == A4_H_num
772 || reg == A5_num || reg == A5_H_num
773 || reg == A6_num || reg == A6_H_num
774 || reg == A7_num || reg == A7_H_num )
775 return true;
777 if ( reg == F12_num || reg == F12_H_num
778 || reg == F13_num || reg == F13_H_num
779 || reg == F14_num || reg == F14_H_num
780 || reg == F15_num || reg == F15_H_num
781 || reg == F16_num || reg == F16_H_num
782 || reg == F17_num || reg == F17_H_num
783 || reg == F18_num || reg == F18_H_num
784 || reg == F19_num || reg == F19_H_num )
785 return true;
787 return false;
788 }
790 bool Matcher::is_spillable_arg( int reg ) {
791 return can_be_java_arg(reg);
792 }
794 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
795 return false;
796 }
798 // Register for MODL projection of divmodL
799 RegMask Matcher::modL_proj_mask() {
800 ShouldNotReachHere();
801 return RegMask();
802 }
804 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
805 return FP_REG_mask();
806 }
808 // MIPS doesn't support AES intrinsics
809 const bool Matcher::pass_original_key_for_aes() {
810 return false;
811 }
813 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
814 //lui
815 //ori
816 //dsll
817 //ori
819 //jalr
820 //nop
822 return round_to(current_offset, alignment_required()) - current_offset;
823 }
825 int CallLeafDirectNode::compute_padding(int current_offset) const {
826 //lui
827 //ori
828 //dsll
829 //ori
831 //jalr
832 //nop
834 return round_to(current_offset, alignment_required()) - current_offset;
835 }
837 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
838 //lui
839 //ori
840 //dsll
841 //ori
843 //jalr
844 //nop
846 return round_to(current_offset, alignment_required()) - current_offset;
847 }
849 // If CPU can load and store mis-aligned doubles directly then no fixup is
850 // needed. Else we split the double into 2 integer pieces and move it
851 // piece-by-piece. Only happens when passing doubles into C code as the
852 // Java calling convention forces doubles to be aligned.
853 const bool Matcher::misaligned_doubles_ok = false;
854 // Do floats take an entire double register or just half?
855 //const bool Matcher::float_in_double = true;
856 bool Matcher::float_in_double() { return false; }
857 // Threshold size for cleararray.
858 const int Matcher::init_array_short_size = 8 * BytesPerLong;
859 // Do ints take an entire long register or just half?
860 const bool Matcher::int_in_long = true;
861 // Is it better to copy float constants, or load them directly from memory?
862 // Intel can load a float constant from a direct address, requiring no
863 // extra registers. Most RISCs will have to materialize an address into a
864 // register first, so they would do better to copy the constant from stack.
865 const bool Matcher::rematerialize_float_constants = false;
866 // Advertise here if the CPU requires explicit rounding operations
867 // to implement the UseStrictFP mode.
868 const bool Matcher::strict_fp_requires_explicit_rounding = false;
869 // The ecx parameter to rep stos for the ClearArray node is in dwords.
870 const bool Matcher::init_array_count_is_in_bytes = false;
873 // Indicate if the safepoint node needs the polling page as an input.
874 // Since MIPS doesn't have absolute addressing, it needs.
875 bool SafePointNode::needs_polling_address_input() {
876 return false;
877 }
879 // !!!!! Special hack to get all type of calls to specify the byte offset
880 // from the start of the call to the point where the return address
881 // will point.
882 int MachCallStaticJavaNode::ret_addr_offset() {
883 //lui
884 //ori
885 //nop
886 //nop
887 //jalr
888 //nop
889 return 24;
890 }
892 int MachCallDynamicJavaNode::ret_addr_offset() {
893 //lui IC_Klass,
894 //ori IC_Klass,
895 //dsll IC_Klass
896 //ori IC_Klass
898 //lui T9
899 //ori T9
900 //nop
901 //nop
902 //jalr T9
903 //nop
904 return 4 * 4 + 4 * 6;
905 }
907 //=============================================================================
909 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
910 enum RC { rc_bad, rc_int, rc_float, rc_stack };
911 static enum RC rc_class( OptoReg::Name reg ) {
912 if( !OptoReg::is_valid(reg) ) return rc_bad;
913 if (OptoReg::is_stack(reg)) return rc_stack;
914 VMReg r = OptoReg::as_VMReg(reg);
915 if (r->is_Register()) return rc_int;
916 assert(r->is_FloatRegister(), "must be");
917 return rc_float;
918 }
920 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
921 // Get registers to move
922 OptoReg::Name src_second = ra_->get_reg_second(in(1));
923 OptoReg::Name src_first = ra_->get_reg_first(in(1));
924 OptoReg::Name dst_second = ra_->get_reg_second(this );
925 OptoReg::Name dst_first = ra_->get_reg_first(this );
927 enum RC src_second_rc = rc_class(src_second);
928 enum RC src_first_rc = rc_class(src_first);
929 enum RC dst_second_rc = rc_class(dst_second);
930 enum RC dst_first_rc = rc_class(dst_first);
932 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
934 // Generate spill code!
935 int size = 0;
937 if( src_first == dst_first && src_second == dst_second )
938 return 0; // Self copy, no move
940 if (src_first_rc == rc_stack) {
941 // mem ->
942 if (dst_first_rc == rc_stack) {
943 // mem -> mem
944 assert(src_second != dst_first, "overlap");
945 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
946 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
947 // 64-bit
948 int src_offset = ra_->reg2offset(src_first);
949 int dst_offset = ra_->reg2offset(dst_first);
950 if (cbuf) {
951 MacroAssembler _masm(cbuf);
952 __ ld(AT, Address(SP, src_offset));
953 __ sd(AT, Address(SP, dst_offset));
954 #ifndef PRODUCT
955 } else {
956 if(!do_size){
957 if (size != 0) st->print("\n\t");
958 st->print("ld AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
959 "sd AT, [SP + #%d]",
960 src_offset, dst_offset);
961 }
962 #endif
963 }
964 size += 8;
965 } else {
966 // 32-bit
967 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
968 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
969 // No pushl/popl, so:
970 int src_offset = ra_->reg2offset(src_first);
971 int dst_offset = ra_->reg2offset(dst_first);
972 if (cbuf) {
973 MacroAssembler _masm(cbuf);
974 __ lw(AT, Address(SP, src_offset));
975 __ sw(AT, Address(SP, dst_offset));
976 #ifndef PRODUCT
977 } else {
978 if(!do_size){
979 if (size != 0) st->print("\n\t");
980 st->print("lw AT, [SP + #%d] spill 2\n\t"
981 "sw AT, [SP + #%d]\n\t",
982 src_offset, dst_offset);
983 }
984 #endif
985 }
986 size += 8;
987 }
988 return size;
989 } else if (dst_first_rc == rc_int) {
990 // mem -> gpr
991 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
992 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
993 // 64-bit
994 int offset = ra_->reg2offset(src_first);
995 if (cbuf) {
996 MacroAssembler _masm(cbuf);
997 __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
998 #ifndef PRODUCT
999 } else {
1000 if(!do_size){
1001 if (size != 0) st->print("\n\t");
1002 st->print("ld %s, [SP + #%d]\t# spill 3",
1003 Matcher::regName[dst_first],
1004 offset);
1005 }
1006 #endif
1007 }
1008 size += 4;
1009 } else {
1010 // 32-bit
1011 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1012 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1013 int offset = ra_->reg2offset(src_first);
1014 if (cbuf) {
1015 MacroAssembler _masm(cbuf);
1016 if (this->ideal_reg() == Op_RegI)
1017 __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1018 else
1019 __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1020 #ifndef PRODUCT
1021 } else {
1022 if(!do_size){
1023 if (size != 0) st->print("\n\t");
1024 if (this->ideal_reg() == Op_RegI)
1025 st->print("lw %s, [SP + #%d]\t# spill 4",
1026 Matcher::regName[dst_first],
1027 offset);
1028 else
1029 st->print("lwu %s, [SP + #%d]\t# spill 5",
1030 Matcher::regName[dst_first],
1031 offset);
1032 }
1033 #endif
1034 }
1035 size += 4;
1036 }
1037 return size;
1038 } else if (dst_first_rc == rc_float) {
1039 // mem-> xmm
1040 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1041 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1042 // 64-bit
1043 int offset = ra_->reg2offset(src_first);
1044 if (cbuf) {
1045 MacroAssembler _masm(cbuf);
1046 __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1047 #ifndef PRODUCT
1048 } else {
1049 if(!do_size){
1050 if (size != 0) st->print("\n\t");
1051 st->print("ldc1 %s, [SP + #%d]\t# spill 6",
1052 Matcher::regName[dst_first],
1053 offset);
1054 }
1055 #endif
1056 }
1057 size += 4;
1058 } else {
1059 // 32-bit
1060 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1061 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1062 int offset = ra_->reg2offset(src_first);
1063 if (cbuf) {
1064 MacroAssembler _masm(cbuf);
1065 __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1066 #ifndef PRODUCT
1067 } else {
1068 if(!do_size){
1069 if (size != 0) st->print("\n\t");
1070 st->print("lwc1 %s, [SP + #%d]\t# spill 7",
1071 Matcher::regName[dst_first],
1072 offset);
1073 }
1074 #endif
1075 }
1076 size += 4;
1077 }
1078 return size;
1079 }
1080 } else if (src_first_rc == rc_int) {
1081 // gpr ->
1082 if (dst_first_rc == rc_stack) {
1083 // gpr -> mem
1084 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1085 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1086 // 64-bit
1087 int offset = ra_->reg2offset(dst_first);
1088 if (cbuf) {
1089 MacroAssembler _masm(cbuf);
1090 __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1091 #ifndef PRODUCT
1092 } else {
1093 if(!do_size){
1094 if (size != 0) st->print("\n\t");
1095 st->print("sd %s, [SP + #%d] # spill 8",
1096 Matcher::regName[src_first],
1097 offset);
1098 }
1099 #endif
1100 }
1101 size += 4;
1102 } else {
1103 // 32-bit
1104 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1105 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1106 int offset = ra_->reg2offset(dst_first);
1107 if (cbuf) {
1108 MacroAssembler _masm(cbuf);
1109 __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1110 #ifndef PRODUCT
1111 } else {
1112 if(!do_size){
1113 if (size != 0) st->print("\n\t");
1114 st->print("sw %s, [SP + #%d]\t# spill 9",
1115 Matcher::regName[src_first], offset);
1116 }
1117 #endif
1118 }
1119 size += 4;
1120 }
1121 return size;
1122 } else if (dst_first_rc == rc_int) {
1123 // gpr -> gpr
1124 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1125 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1126 // 64-bit
1127 if (cbuf) {
1128 MacroAssembler _masm(cbuf);
1129 __ move(as_Register(Matcher::_regEncode[dst_first]),
1130 as_Register(Matcher::_regEncode[src_first]));
1131 #ifndef PRODUCT
1132 } else {
1133 if(!do_size){
1134 if (size != 0) st->print("\n\t");
1135 st->print("move(64bit) %s <-- %s\t# spill 10",
1136 Matcher::regName[dst_first],
1137 Matcher::regName[src_first]);
1138 }
1139 #endif
1140 }
1141 size += 4;
1142 return size;
1143 } else {
1144 // 32-bit
1145 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1146 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1147 if (cbuf) {
1148 MacroAssembler _masm(cbuf);
1149 if (this->ideal_reg() == Op_RegI)
1150 __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1151 else
1152 __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
1154 #ifndef PRODUCT
1155 } else {
1156 if(!do_size){
1157 if (size != 0) st->print("\n\t");
1158 st->print("move(32-bit) %s <-- %s\t# spill 11",
1159 Matcher::regName[dst_first],
1160 Matcher::regName[src_first]);
1161 }
1162 #endif
1163 }
1164 size += 4;
1165 return size;
1166 }
1167 } else if (dst_first_rc == rc_float) {
1168 // gpr -> xmm
1169 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1170 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1171 // 64-bit
1172 if (cbuf) {
1173 MacroAssembler _masm(cbuf);
1174 __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
1175 #ifndef PRODUCT
1176 } else {
1177 if(!do_size){
1178 if (size != 0) st->print("\n\t");
1179 st->print("dmtc1 %s, %s\t# spill 12",
1180 Matcher::regName[dst_first],
1181 Matcher::regName[src_first]);
1182 }
1183 #endif
1184 }
1185 size += 4;
1186 } else {
1187 // 32-bit
1188 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1189 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1190 if (cbuf) {
1191 MacroAssembler _masm(cbuf);
1192 __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
1193 #ifndef PRODUCT
1194 } else {
1195 if(!do_size){
1196 if (size != 0) st->print("\n\t");
1197 st->print("mtc1 %s, %s\t# spill 13",
1198 Matcher::regName[dst_first],
1199 Matcher::regName[src_first]);
1200 }
1201 #endif
1202 }
1203 size += 4;
1204 }
1205 return size;
1206 }
1207 } else if (src_first_rc == rc_float) {
1208 // xmm ->
1209 if (dst_first_rc == rc_stack) {
1210 // xmm -> mem
1211 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1212 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1213 // 64-bit
1214 int offset = ra_->reg2offset(dst_first);
1215 if (cbuf) {
1216 MacroAssembler _masm(cbuf);
1217 __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
1218 #ifndef PRODUCT
1219 } else {
1220 if(!do_size){
1221 if (size != 0) st->print("\n\t");
1222 st->print("sdc1 %s, [SP + #%d]\t# spill 14",
1223 Matcher::regName[src_first],
1224 offset);
1225 }
1226 #endif
1227 }
1228 size += 4;
1229 } else {
1230 // 32-bit
1231 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1232 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1233 int offset = ra_->reg2offset(dst_first);
1234 if (cbuf) {
1235 MacroAssembler _masm(cbuf);
1236 __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
1237 #ifndef PRODUCT
1238 } else {
1239 if(!do_size){
1240 if (size != 0) st->print("\n\t");
1241 st->print("swc1 %s, [SP + #%d]\t# spill 15",
1242 Matcher::regName[src_first],
1243 offset);
1244 }
1245 #endif
1246 }
1247 size += 4;
1248 }
1249 return size;
1250 } else if (dst_first_rc == rc_int) {
1251 // xmm -> gpr
1252 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1253 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1254 // 64-bit
1255 if (cbuf) {
1256 MacroAssembler _masm(cbuf);
1257 __ dmfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1258 #ifndef PRODUCT
1259 } else {
1260 if(!do_size){
1261 if (size != 0) st->print("\n\t");
1262 st->print("dmfc1 %s, %s\t# spill 16",
1263 Matcher::regName[dst_first],
1264 Matcher::regName[src_first]);
1265 }
1266 #endif
1267 }
1268 size += 4;
1269 } else {
1270 // 32-bit
1271 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1272 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1273 if (cbuf) {
1274 MacroAssembler _masm(cbuf);
1275 __ mfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1276 #ifndef PRODUCT
1277 } else {
1278 if(!do_size){
1279 if (size != 0) st->print("\n\t");
1280 st->print("mfc1 %s, %s\t# spill 17",
1281 Matcher::regName[dst_first],
1282 Matcher::regName[src_first]);
1283 }
1284 #endif
1285 }
1286 size += 4;
1287 }
1288 return size;
1289 } else if (dst_first_rc == rc_float) {
1290 // xmm -> xmm
1291 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1292 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1293 // 64-bit
1294 if (cbuf) {
1295 MacroAssembler _masm(cbuf);
1296 __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1297 #ifndef PRODUCT
1298 } else {
1299 if(!do_size){
1300 if (size != 0) st->print("\n\t");
1301 st->print("mov_d %s <-- %s\t# spill 18",
1302 Matcher::regName[dst_first],
1303 Matcher::regName[src_first]);
1304 }
1305 #endif
1306 }
1307 size += 4;
1308 } else {
1309 // 32-bit
1310 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1311 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1312 if (cbuf) {
1313 MacroAssembler _masm(cbuf);
1314 __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1315 #ifndef PRODUCT
1316 } else {
1317 if(!do_size){
1318 if (size != 0) st->print("\n\t");
1319 st->print("mov_s %s <-- %s\t# spill 19",
1320 Matcher::regName[dst_first],
1321 Matcher::regName[src_first]);
1322 }
1323 #endif
1324 }
1325 size += 4;
1326 }
1327 return size;
1328 }
1329 }
1331 assert(0," foo ");
1332 Unimplemented();
1333 return size;
1335 }
1337 #ifndef PRODUCT
1338 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1339 implementation( NULL, ra_, false, st );
1340 }
1341 #endif
1343 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1344 implementation( &cbuf, ra_, false, NULL );
1345 }
1347 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1348 return implementation( NULL, ra_, true, NULL );
1349 }
1351 //=============================================================================
1352 #
1354 #ifndef PRODUCT
1355 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
1356 st->print("INT3");
1357 }
1358 #endif
1360 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
1361 MacroAssembler _masm(&cbuf);
1362 __ int3();
1363 }
1365 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
1366 return MachNode::size(ra_);
1367 }
1370 //=============================================================================
1371 #ifndef PRODUCT
1372 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1373 Compile *C = ra_->C;
1374 int framesize = C->frame_size_in_bytes();
1376 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1378 st->print("daddiu SP, SP, %d # Rlease stack @ MachEpilogNode",framesize);
1379 st->cr(); st->print("\t");
1380 if (UseLoongsonISA) {
1381 st->print("gslq RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
1382 } else {
1383 st->print("ld RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
1384 st->cr(); st->print("\t");
1385 st->print("ld FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
1386 }
1388 if( do_polling() && C->is_method_compilation() ) {
1389 st->print("Poll Safepoint # MachEpilogNode");
1390 }
1391 }
1392 #endif
1394 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1395 Compile *C = ra_->C;
1396 MacroAssembler _masm(&cbuf);
1397 int framesize = C->frame_size_in_bytes();
1399 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1401 __ daddiu(SP, SP, framesize);
1403 if (UseLoongsonISA) {
1404 __ gslq(RA, FP, SP, -wordSize*2);
1405 } else {
1406 __ ld(RA, SP, -wordSize );
1407 __ ld(FP, SP, -wordSize*2 );
1408 }
1410 if( do_polling() && C->is_method_compilation() ) {
1411 __ set64(AT, (long)os::get_polling_page());
1412 __ relocate(relocInfo::poll_return_type);
1413 __ lw(AT, AT, 0);
1414 }
1415 }
1417 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1418 return MachNode::size(ra_); // too many variables; just compute it the hard way fujie debug
1419 }
1421 int MachEpilogNode::reloc() const {
1422 return 0; // a large enough number
1423 }
1425 const Pipeline * MachEpilogNode::pipeline() const {
1426 return MachNode::pipeline_class();
1427 }
1429 int MachEpilogNode::safepoint_offset() const { return 0; }
1431 //=============================================================================
1433 #ifndef PRODUCT
1434 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1435 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1436 int reg = ra_->get_reg_first(this);
1437 st->print("ADDI %s, SP, %d @BoxLockNode",Matcher::regName[reg],offset);
1438 }
1439 #endif
1442 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1443 return 4;
1444 }
1446 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1447 MacroAssembler _masm(&cbuf);
1448 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1449 int reg = ra_->get_encode(this);
1451 __ addi(as_Register(reg), SP, offset);
1452 /*
1453 if( offset >= 128 ) {
1454 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1455 emit_rm(cbuf, 0x2, reg, 0x04);
1456 emit_rm(cbuf, 0x0, 0x04, SP_enc);
1457 emit_d32(cbuf, offset);
1458 }
1459 else {
1460 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1461 emit_rm(cbuf, 0x1, reg, 0x04);
1462 emit_rm(cbuf, 0x0, 0x04, SP_enc);
1463 emit_d8(cbuf, offset);
1464 }
1465 */
1466 }
1469 //static int sizeof_FFree_Float_Stack_All = -1;
1471 int MachCallRuntimeNode::ret_addr_offset() {
1472 //lui
1473 //ori
1474 //dsll
1475 //ori
1476 //jalr
1477 //nop
1478 assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
1479 return NativeCall::instruction_size;
1480 // return 16;
1481 }
1487 //=============================================================================
1488 #ifndef PRODUCT
1489 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
1490 st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
1491 }
1492 #endif
1494 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
1495 MacroAssembler _masm(&cbuf);
1496 int i = 0;
1497 for(i = 0; i < _count; i++)
1498 __ nop();
1499 }
1501 uint MachNopNode::size(PhaseRegAlloc *) const {
1502 return 4 * _count;
1503 }
1504 const Pipeline* MachNopNode::pipeline() const {
1505 return MachNode::pipeline_class();
1506 }
1508 //=============================================================================
1510 //=============================================================================
1511 #ifndef PRODUCT
1512 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1513 st->print_cr("load_klass(T9, T0)");
1514 st->print_cr("\tbeq(T9, iCache, L)");
1515 st->print_cr("\tnop");
1516 st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
1517 st->print_cr("\tnop");
1518 st->print_cr("\tnop");
1519 st->print_cr(" L:");
1520 }
1521 #endif
1524 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1525 MacroAssembler _masm(&cbuf);
1526 #ifdef ASSERT
1527 //uint code_size = cbuf.code_size();
1528 #endif
1529 int ic_reg = Matcher::inline_cache_reg_encode();
1530 Label L;
1531 Register receiver = T0;
1532 Register iCache = as_Register(ic_reg);
1533 __ load_klass(T9, receiver);
1534 __ beq(T9, iCache, L);
1535 __ nop();
1537 __ relocate(relocInfo::runtime_call_type);
1538 __ patchable_jump((address)SharedRuntime::get_ic_miss_stub());
1540 /* WARNING these NOPs are critical so that verified entry point is properly
1541 * 8 bytes aligned for patching by NativeJump::patch_verified_entry() */
1542 __ align(CodeEntryAlignment);
1543 __ bind(L);
1544 }
1546 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1547 return MachNode::size(ra_);
1548 }
1552 //=============================================================================
1554 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
1556 int Compile::ConstantTable::calculate_table_base_offset() const {
1557 return 0; // absolute addressing, no offset
1558 }
1560 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1561 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1562 ShouldNotReachHere();
1563 }
1565 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1566 Compile* C = ra_->C;
1567 Compile::ConstantTable& constant_table = C->constant_table();
1568 MacroAssembler _masm(&cbuf);
1570 Register Rtoc = as_Register(ra_->get_encode(this));
1571 CodeSection* consts_section = __ code()->consts();
1572 int consts_size = consts_section->align_at_start(consts_section->size());
1573 assert(constant_table.size() == consts_size, "must be equal");
1575 if (consts_section->size()) {
1576 // Materialize the constant table base.
1577 address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
1578 // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
1579 __ relocate(relocInfo::internal_pc_type);
1580 __ patchable_set48(Rtoc, (long)baseaddr);
1581 }
1582 }
1584 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1585 // patchable_set48 (4 insts)
1586 return 4 * 4;
1587 }
1589 #ifndef PRODUCT
1590 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1591 Register r = as_Register(ra_->get_encode(this));
1592 st->print("patchable_set48 %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
1593 }
1594 #endif
1597 //=============================================================================
1598 #ifndef PRODUCT
1599 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1600 Compile* C = ra_->C;
1602 int framesize = C->frame_size_in_bytes();
1603 int bangsize = C->bang_size_in_bytes();
1604 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1606 // Calls to C2R adapters often do not accept exceptional returns.
1607 // We require that their callers must bang for them. But be careful, because
1608 // some VM calls (such as call site linkage) can use several kilobytes of
1609 // stack. But the stack safety zone should account for that.
1610 // See bugs 4446381, 4468289, 4497237.
1611 if (C->need_stack_bang(bangsize)) {
1612 st->print_cr("# stack bang"); st->print("\t");
1613 }
1614 if (UseLoongsonISA) {
1615 st->print("gssq RA, FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1616 } else {
1617 st->print("sd RA, %d(SP) @ MachPrologNode\n\t", -wordSize);
1618 st->print("sd FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1619 }
1620 st->print("daddiu FP, SP, -%d \n\t", wordSize*2);
1621 st->print("daddiu SP, SP, -%d \t",framesize);
1622 }
1623 #endif
1626 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1627 Compile* C = ra_->C;
1628 MacroAssembler _masm(&cbuf);
1630 int framesize = C->frame_size_in_bytes();
1631 int bangsize = C->bang_size_in_bytes();
1633 // __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false);
1635 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1637 if (C->need_stack_bang(framesize)) {
1638 __ generate_stack_overflow_check(framesize);
1639 }
1641 if (UseLoongsonISA) {
1642 __ gssq(RA, FP, SP, -wordSize*2);
1643 } else {
1644 __ sd(RA, SP, -wordSize);
1645 __ sd(FP, SP, -wordSize*2);
1646 }
1647 __ daddiu(FP, SP, -wordSize*2);
1648 __ daddiu(SP, SP, -framesize);
1649 __ nop(); /* 2013.10.22 Jin: Make enough room for patch_verified_entry() */
1650 __ nop();
1652 C->set_frame_complete(cbuf.insts_size());
1653 if (C->has_mach_constant_base_node()) {
1654 // NOTE: We set the table base offset here because users might be
1655 // emitted before MachConstantBaseNode.
1656 Compile::ConstantTable& constant_table = C->constant_table();
1657 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1658 }
1660 }
1663 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1664 //fprintf(stderr, "\nPrologNode::size(ra_)= %d \n", MachNode::size(ra_));//fujie debug
1665 return MachNode::size(ra_); // too many variables; just compute it the hard way
1666 }
1668 int MachPrologNode::reloc() const {
1669 return 0; // a large enough number
1670 }
1672 %}
1674 //----------ENCODING BLOCK-----------------------------------------------------
1675 // This block specifies the encoding classes used by the compiler to output
1676 // byte streams. Encoding classes generate functions which are called by
1677 // Machine Instruction Nodes in order to generate the bit encoding of the
1678 // instruction. Operands specify their base encoding interface with the
1679 // interface keyword. There are currently supported four interfaces,
1680 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
1681 // operand to generate a function which returns its register number when
1682 // queried. CONST_INTER causes an operand to generate a function which
1683 // returns the value of the constant when queried. MEMORY_INTER causes an
1684 // operand to generate four functions which return the Base Register, the
1685 // Index Register, the Scale Value, and the Offset Value of the operand when
1686 // queried. COND_INTER causes an operand to generate six functions which
1687 // return the encoding code (ie - encoding bits for the instruction)
1688 // associated with each basic boolean condition for a conditional instruction.
1689 // Instructions specify two basic values for encoding. They use the
1690 // ins_encode keyword to specify their encoding class (which must be one of
1691 // the class names specified in the encoding block), and they use the
1692 // opcode keyword to specify, in order, their primary, secondary, and
1693 // tertiary opcode. Only the opcode sections which a particular instruction
1694 // needs for encoding need to be specified.
1695 encode %{
1697 //Load byte signed
1698 enc_class load_B_enc (mRegI dst, memory mem) %{
1699 MacroAssembler _masm(&cbuf);
1700 int dst = $dst$$reg;
1701 int base = $mem$$base;
1702 int index = $mem$$index;
1703 int scale = $mem$$scale;
1704 int disp = $mem$$disp;
1706 if( index != 0 ) {
1707 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1708 __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
1709 } else {
1710 __ lb(as_Register(dst), as_Register(base), disp);
1711 }
1712 %}
1714 //Load byte unsigned
1715 enc_class load_UB_enc (mRegI dst, umemory mem) %{
1716 MacroAssembler _masm(&cbuf);
1717 int dst = $dst$$reg;
1718 int base = $mem$$base;
1719 int index = $mem$$index;
1720 int scale = $mem$$scale;
1721 int disp = $mem$$disp;
1723 assert(index == 0, "no index");
1724 __ lbu(as_Register(dst), as_Register(base), disp);
1725 %}
1727 enc_class store_B_reg_enc (memory mem, mRegI src) %{
1728 MacroAssembler _masm(&cbuf);
1729 int src = $src$$reg;
1730 int base = $mem$$base;
1731 int index = $mem$$index;
1732 int scale = $mem$$scale;
1733 int disp = $mem$$disp;
1735 if( index != 0 ) {
1736 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1737 __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
1738 } else {
1739 __ sb(as_Register(src), as_Register(base), disp);
1740 }
1741 %}
1743 enc_class store_B0_enc (memory mem) %{
1744 MacroAssembler _masm(&cbuf);
1745 int base = $mem$$base;
1746 int index = $mem$$index;
1747 int scale = $mem$$scale;
1748 int disp = $mem$$disp;
1750 if( index != 0 ) {
1751 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1752 __ gssbx(R0, as_Register(base), as_Register(index), disp);
1753 } else {
1754 __ sb(R0, as_Register(base), disp);
1755 }
1756 %}
1758 enc_class store_B_reg_sync_enc (memory mem, mRegI src) %{
1759 MacroAssembler _masm(&cbuf);
1760 int src = $src$$reg;
1761 int base = $mem$$base;
1762 int index = $mem$$index;
1763 int scale = $mem$$scale;
1764 int disp = $mem$$disp;
1766 if( index != 0 ) {
1767 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1768 __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
1769 } else {
1770 __ sb(as_Register(src), as_Register(base), disp);
1771 }
1772 __ sync();
1773 %}
1775 enc_class store_B0_sync_enc (memory mem) %{
1776 MacroAssembler _masm(&cbuf);
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 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1784 __ gssbx(R0, as_Register(base), as_Register(index), disp);
1785 } else {
1786 __ sb(R0, as_Register(base), disp);
1787 }
1788 __ sync();
1789 %}
1791 // Load Short (16bit signed)
1792 enc_class load_S_enc (mRegI dst, memory mem) %{
1793 MacroAssembler _masm(&cbuf);
1794 int dst = $dst$$reg;
1795 int base = $mem$$base;
1796 int index = $mem$$index;
1797 int scale = $mem$$scale;
1798 int disp = $mem$$disp;
1800 if( index != 0 ) {
1801 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1802 __ gslhx(as_Register(dst), as_Register(base), as_Register(index), disp);
1803 } else {
1804 __ lh(as_Register(dst), as_Register(base), disp);
1805 }
1806 %}
1808 // Load Char (16bit unsigned)
1809 enc_class load_C_enc (mRegI dst, umemory mem) %{
1810 MacroAssembler _masm(&cbuf);
1811 int dst = $dst$$reg;
1812 int base = $mem$$base;
1813 int index = $mem$$index;
1814 int scale = $mem$$scale;
1815 int disp = $mem$$disp;
1817 assert(index == 0, "no index");
1818 __ lhu(as_Register(dst), as_Register(base), disp);
1819 %}
1821 // Store Char (16bit unsigned)
1822 enc_class store_C_reg_enc (memory mem, mRegI src) %{
1823 MacroAssembler _masm(&cbuf);
1824 int src = $src$$reg;
1825 int base = $mem$$base;
1826 int index = $mem$$index;
1827 int scale = $mem$$scale;
1828 int disp = $mem$$disp;
1830 if( index != 0 ) {
1831 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1832 __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
1833 } else {
1834 __ sh(as_Register(src), as_Register(base), disp);
1835 }
1836 %}
1838 enc_class store_C0_enc (memory mem) %{
1839 MacroAssembler _masm(&cbuf);
1840 int base = $mem$$base;
1841 int index = $mem$$index;
1842 int scale = $mem$$scale;
1843 int disp = $mem$$disp;
1845 if( index != 0 ) {
1846 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1847 __ gsshx(R0, as_Register(base), as_Register(index), disp);
1848 } else {
1849 __ sh(R0, as_Register(base), disp);
1850 }
1851 %}
1853 enc_class load_I_enc (mRegI dst, memory mem) %{
1854 MacroAssembler _masm(&cbuf);
1855 int dst = $dst$$reg;
1856 int base = $mem$$base;
1857 int index = $mem$$index;
1858 int scale = $mem$$scale;
1859 int disp = $mem$$disp;
1861 if( index != 0 ) {
1862 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1863 __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
1864 } else {
1865 __ lw(as_Register(dst), as_Register(base), disp);
1866 }
1867 %}
1869 enc_class store_I_reg_enc (memory mem, mRegI src) %{
1870 MacroAssembler _masm(&cbuf);
1871 int src = $src$$reg;
1872 int base = $mem$$base;
1873 int index = $mem$$index;
1874 int scale = $mem$$scale;
1875 int disp = $mem$$disp;
1877 if( index != 0 ) {
1878 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1879 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
1880 } else {
1881 __ sw(as_Register(src), as_Register(base), disp);
1882 }
1883 %}
1885 enc_class store_I_immI0_enc (memory mem) %{
1886 MacroAssembler _masm(&cbuf);
1887 int base = $mem$$base;
1888 int index = $mem$$index;
1889 int scale = $mem$$scale;
1890 int disp = $mem$$disp;
1892 if( index != 0 ) {
1893 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1894 __ gsswx(R0, as_Register(base), as_Register(index), disp);
1895 } else {
1896 __ sw(R0, as_Register(base), disp);
1897 }
1898 %}
1900 enc_class load_N_enc (mRegN dst, umemory mem) %{
1901 MacroAssembler _masm(&cbuf);
1902 int dst = $dst$$reg;
1903 int base = $mem$$base;
1904 int index = $mem$$index;
1905 int scale = $mem$$scale;
1906 int disp = $mem$$disp;
1908 relocInfo::relocType disp_reloc = $mem->disp_reloc();
1909 assert(disp_reloc == relocInfo::none, "cannot have disp");
1911 assert(index == 0, "no index");
1912 __ lwu(as_Register(dst), as_Register(base), disp);
1913 %}
1916 enc_class load_P_enc (mRegP dst, memory mem) %{
1917 MacroAssembler _masm(&cbuf);
1918 int dst = $dst$$reg;
1919 int base = $mem$$base;
1920 int index = $mem$$index;
1921 int scale = $mem$$scale;
1922 int disp = $mem$$disp;
1924 relocInfo::relocType disp_reloc = $mem->disp_reloc();
1925 assert(disp_reloc == relocInfo::none, "cannot have disp");
1927 if( index != 0 ) {
1928 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1929 __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
1930 } else {
1931 __ ld(as_Register(dst), as_Register(base), disp);
1932 }
1933 %}
1935 enc_class store_P_reg_enc (memory mem, mRegP src) %{
1936 MacroAssembler _masm(&cbuf);
1937 int src = $src$$reg;
1938 int base = $mem$$base;
1939 int index = $mem$$index;
1940 int scale = $mem$$scale;
1941 int disp = $mem$$disp;
1943 if( index != 0 ) {
1944 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1945 __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
1946 } else {
1947 __ sd(as_Register(src), as_Register(base), disp);
1948 }
1949 %}
1951 enc_class store_N_reg_enc (memory mem, mRegN src) %{
1952 MacroAssembler _masm(&cbuf);
1953 int src = $src$$reg;
1954 int base = $mem$$base;
1955 int index = $mem$$index;
1956 int scale = $mem$$scale;
1957 int disp = $mem$$disp;
1959 if( index != 0 ) {
1960 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1961 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
1962 } else {
1963 __ sw(as_Register(src), as_Register(base), disp);
1964 }
1965 %}
1967 enc_class store_P_immP0_enc (memory mem) %{
1968 MacroAssembler _masm(&cbuf);
1969 int base = $mem$$base;
1970 int index = $mem$$index;
1971 int scale = $mem$$scale;
1972 int disp = $mem$$disp;
1974 if( index != 0 ) {
1975 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1976 __ gssdx(R0, as_Register(base), as_Register(index), disp);
1977 } else {
1978 __ sd(R0, as_Register(base), disp);
1979 }
1980 %}
1983 enc_class storeImmN0_enc(memory mem) %{
1984 MacroAssembler _masm(&cbuf);
1985 int base = $mem$$base;
1986 int index = $mem$$index;
1987 int scale = $mem$$scale;
1988 int disp = $mem$$disp;
1990 if(index != 0){
1991 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1992 __ gsswx(R0, as_Register(base), as_Register(index), disp);
1993 } else {
1994 __ sw(R0, as_Register(base), disp);
1995 }
1996 %}
1998 enc_class load_L_enc (mRegL dst, memory mem) %{
1999 MacroAssembler _masm(&cbuf);
2000 int base = $mem$$base;
2001 int index = $mem$$index;
2002 int scale = $mem$$scale;
2003 int disp = $mem$$disp;
2004 Register dst_reg = as_Register($dst$$reg);
2006 if( index != 0 ) {
2007 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2008 __ gsldx(dst_reg, as_Register(base), as_Register(index), disp);
2009 } else {
2010 __ ld(dst_reg, as_Register(base), disp);
2011 }
2012 %}
2014 enc_class store_L_reg_enc (memory mem, mRegL src) %{
2015 MacroAssembler _masm(&cbuf);
2016 int base = $mem$$base;
2017 int index = $mem$$index;
2018 int scale = $mem$$scale;
2019 int disp = $mem$$disp;
2020 Register src_reg = as_Register($src$$reg);
2022 if( index != 0 ) {
2023 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2024 __ gssdx(src_reg, as_Register(base), as_Register(index), disp);
2025 } else {
2026 __ sd(src_reg, as_Register(base), disp);
2027 }
2028 %}
2030 enc_class store_L_immL0_enc (memory mem) %{
2031 MacroAssembler _masm(&cbuf);
2032 int base = $mem$$base;
2033 int index = $mem$$index;
2034 int scale = $mem$$scale;
2035 int disp = $mem$$disp;
2037 if( index != 0 ) {
2038 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2039 __ gssdx(R0, as_Register(base), as_Register(index), disp);
2040 } else {
2041 __ sd(R0, as_Register(base), disp);
2042 }
2043 %}
2045 enc_class load_F_enc (regF dst, memory mem) %{
2046 MacroAssembler _masm(&cbuf);
2047 int base = $mem$$base;
2048 int index = $mem$$index;
2049 int scale = $mem$$scale;
2050 int disp = $mem$$disp;
2051 FloatRegister dst = $dst$$FloatRegister;
2053 if( index != 0 ) {
2054 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2055 __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
2056 } else {
2057 __ lwc1(dst, as_Register(base), disp);
2058 }
2059 %}
2061 enc_class store_F_reg_enc (memory mem, regF src) %{
2062 MacroAssembler _masm(&cbuf);
2063 int base = $mem$$base;
2064 int index = $mem$$index;
2065 int scale = $mem$$scale;
2066 int disp = $mem$$disp;
2067 FloatRegister src = $src$$FloatRegister;
2069 if( index != 0 ) {
2070 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2071 __ gsswxc1(src, as_Register(base), as_Register(index), disp);
2072 } else {
2073 __ swc1(src, as_Register(base), disp);
2074 }
2075 %}
2077 enc_class load_D_enc (regD dst, memory mem) %{
2078 MacroAssembler _masm(&cbuf);
2079 int base = $mem$$base;
2080 int index = $mem$$index;
2081 int scale = $mem$$scale;
2082 int disp = $mem$$disp;
2083 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2085 if( index != 0 ) {
2086 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2087 __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
2088 } else {
2089 __ ldc1(dst_reg, as_Register(base), disp);
2090 }
2091 %}
2093 enc_class store_D_reg_enc (memory mem, regD src) %{
2094 MacroAssembler _masm(&cbuf);
2095 int base = $mem$$base;
2096 int index = $mem$$index;
2097 int scale = $mem$$scale;
2098 int disp = $mem$$disp;
2099 FloatRegister src_reg = as_FloatRegister($src$$reg);
2101 if( index != 0 ) {
2102 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2103 __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
2104 } else {
2105 __ sdc1(src_reg, as_Register(base), disp);
2106 }
2107 %}
2109 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf
2110 MacroAssembler _masm(&cbuf);
2111 // This is the instruction starting address for relocation info.
2112 __ block_comment("Java_To_Runtime");
2113 cbuf.set_insts_mark();
2114 __ relocate(relocInfo::runtime_call_type);
2116 __ patchable_call((address)$meth$$method);
2117 %}
2119 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
2120 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
2121 // who we intended to call.
2122 MacroAssembler _masm(&cbuf);
2123 cbuf.set_insts_mark();
2125 if ( !_method ) {
2126 __ relocate(relocInfo::runtime_call_type);
2127 } else if(_optimized_virtual) {
2128 __ relocate(relocInfo::opt_virtual_call_type);
2129 } else {
2130 __ relocate(relocInfo::static_call_type);
2131 }
2133 __ patchable_call((address)($meth$$method));
2134 if( _method ) { // Emit stub for static call
2135 emit_java_to_interp(cbuf);
2136 }
2137 %}
2140 /*
2141 * [Ref: LIR_Assembler::ic_call() ]
2142 */
2143 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL
2144 MacroAssembler _masm(&cbuf);
2145 __ block_comment("Java_Dynamic_Call");
2146 __ ic_call((address)$meth$$method);
2147 %}
2150 enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
2151 Register flags = $cr$$Register;
2152 Label L;
2154 MacroAssembler _masm(&cbuf);
2156 __ addu(flags, R0, R0);
2157 __ beq(AT, R0, L);
2158 __ delayed()->nop();
2159 __ move(flags, 0xFFFFFFFF);
2160 __ bind(L);
2161 %}
2163 enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
2164 Register result = $result$$Register;
2165 Register sub = $sub$$Register;
2166 Register super = $super$$Register;
2167 Register length = $tmp$$Register;
2168 Register tmp = T9;
2169 Label miss;
2171 /* 2012/9/28 Jin: result may be the same as sub
2172 * 47c B40: # B21 B41 <- B20 Freq: 0.155379
2173 * 47c partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
2174 * 4bc mov S2, NULL #@loadConP
2175 * 4c0 beq S1, S2, B21 #@branchConP P=0.999999 C=-1.000000
2176 */
2177 MacroAssembler _masm(&cbuf);
2178 Label done;
2179 __ check_klass_subtype_slow_path(sub, super, length, tmp,
2180 NULL, &miss,
2181 /*set_cond_codes:*/ true);
2182 /* 2013/7/22 Jin: Refer to X86_64's RDI */
2183 __ move(result, 0);
2184 __ b(done);
2185 __ nop();
2187 __ bind(miss);
2188 __ move(result, 1);
2189 __ bind(done);
2190 %}
2192 %}
2195 //---------MIPS FRAME--------------------------------------------------------------
2196 // Definition of frame structure and management information.
2197 //
2198 // S T A C K L A Y O U T Allocators stack-slot number
2199 // | (to get allocators register number
2200 // G Owned by | | v add SharedInfo::stack0)
2201 // r CALLER | |
2202 // o | +--------+ pad to even-align allocators stack-slot
2203 // w V | pad0 | numbers; owned by CALLER
2204 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
2205 // h ^ | in | 5
2206 // | | args | 4 Holes in incoming args owned by SELF
2207 // | | old | | 3
2208 // | | SP-+--------+----> Matcher::_old_SP, even aligned
2209 // v | | ret | 3 return address
2210 // Owned by +--------+
2211 // Self | pad2 | 2 pad to align old SP
2212 // | +--------+ 1
2213 // | | locks | 0
2214 // | +--------+----> SharedInfo::stack0, even aligned
2215 // | | pad1 | 11 pad to align new SP
2216 // | +--------+
2217 // | | | 10
2218 // | | spills | 9 spills
2219 // V | | 8 (pad0 slot for callee)
2220 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
2221 // ^ | out | 7
2222 // | | args | 6 Holes in outgoing args owned by CALLEE
2223 // Owned by new | |
2224 // Callee SP-+--------+----> Matcher::_new_SP, even aligned
2225 // | |
2226 //
2227 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
2228 // known from SELF's arguments and the Java calling convention.
2229 // Region 6-7 is determined per call site.
2230 // Note 2: If the calling convention leaves holes in the incoming argument
2231 // area, those holes are owned by SELF. Holes in the outgoing area
2232 // are owned by the CALLEE. Holes should not be nessecary in the
2233 // incoming area, as the Java calling convention is completely under
2234 // the control of the AD file. Doubles can be sorted and packed to
2235 // avoid holes. Holes in the outgoing arguments may be nessecary for
2236 // varargs C calling conventions.
2237 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
2238 // even aligned with pad0 as needed.
2239 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
2240 // region 6-11 is even aligned; it may be padded out more so that
2241 // the region from SP to FP meets the minimum stack alignment.
2242 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
2243 // alignment. Region 11, pad1, may be dynamically extended so that
2244 // SP meets the minimum alignment.
2247 frame %{
2249 stack_direction(TOWARDS_LOW);
2251 // These two registers define part of the calling convention
2252 // between compiled code and the interpreter.
2253 // SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention
2254 // for more information. by yjl 3/16/2006
2256 inline_cache_reg(T1); // Inline Cache Register
2257 interpreter_method_oop_reg(S3); // Method Oop Register when calling interpreter
2258 /*
2259 inline_cache_reg(T1); // Inline Cache Register or methodOop for I2C
2260 interpreter_arg_ptr_reg(A0); // Argument pointer for I2C adapters
2261 */
2263 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
2264 cisc_spilling_operand_name(indOffset32);
2266 // Number of stack slots consumed by locking an object
2267 // generate Compile::sync_stack_slots
2268 #ifdef _LP64
2269 sync_stack_slots(2);
2270 #else
2271 sync_stack_slots(1);
2272 #endif
2274 frame_pointer(SP);
2276 // Interpreter stores its frame pointer in a register which is
2277 // stored to the stack by I2CAdaptors.
2278 // I2CAdaptors convert from interpreted java to compiled java.
2280 interpreter_frame_pointer(FP);
2282 // generate Matcher::stack_alignment
2283 stack_alignment(StackAlignmentInBytes); //wordSize = sizeof(char*);
2285 // Number of stack slots between incoming argument block and the start of
2286 // a new frame. The PROLOG must add this many slots to the stack. The
2287 // EPILOG must remove this many slots. Intel needs one slot for
2288 // return address.
2289 // generate Matcher::in_preserve_stack_slots
2290 //in_preserve_stack_slots(VerifyStackAtCalls + 2); //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
2291 in_preserve_stack_slots(4); //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
2293 // Number of outgoing stack slots killed above the out_preserve_stack_slots
2294 // for calls to C. Supports the var-args backing area for register parms.
2295 varargs_C_out_slots_killed(0);
2297 // The after-PROLOG location of the return address. Location of
2298 // return address specifies a type (REG or STACK) and a number
2299 // representing the register number (i.e. - use a register name) or
2300 // stack slot.
2301 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
2302 // Otherwise, it is above the locks and verification slot and alignment word
2303 //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
2304 return_addr(REG RA);
2306 // Body of function which returns an integer array locating
2307 // arguments either in registers or in stack slots. Passed an array
2308 // of ideal registers called "sig" and a "length" count. Stack-slot
2309 // offsets are based on outgoing arguments, i.e. a CALLER setting up
2310 // arguments for a CALLEE. Incoming stack arguments are
2311 // automatically biased by the preserve_stack_slots field above.
2314 // will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
2315 // StartNode::calling_convention call this. by yjl 3/16/2006
2316 calling_convention %{
2317 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
2318 %}
2323 // Body of function which returns an integer array locating
2324 // arguments either in registers or in stack slots. Passed an array
2325 // of ideal registers called "sig" and a "length" count. Stack-slot
2326 // offsets are based on outgoing arguments, i.e. a CALLER setting up
2327 // arguments for a CALLEE. Incoming stack arguments are
2328 // automatically biased by the preserve_stack_slots field above.
2331 // SEE CallRuntimeNode::calling_convention for more information. by yjl 3/16/2006
2332 c_calling_convention %{
2333 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
2334 %}
2337 // Location of C & interpreter return values
2338 // register(s) contain(s) return value for Op_StartI2C and Op_StartOSR.
2339 // SEE Matcher::match. by yjl 3/16/2006
2340 c_return_value %{
2341 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
2342 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
2343 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
2344 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num };
2345 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
2346 %}
2348 // Location of return values
2349 // register(s) contain(s) return value for Op_StartC2I and Op_Start.
2350 // SEE Matcher::match. by yjl 3/16/2006
2352 return_value %{
2353 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
2354 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
2355 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
2356 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num};
2357 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
2358 %}
2360 %}
2362 //----------ATTRIBUTES---------------------------------------------------------
2363 //----------Operand Attributes-------------------------------------------------
2364 op_attrib op_cost(0); // Required cost attribute
2366 //----------Instruction Attributes---------------------------------------------
2367 ins_attrib ins_cost(100); // Required cost attribute
2368 ins_attrib ins_size(32); // Required size attribute (in bits)
2369 ins_attrib ins_pc_relative(0); // Required PC Relative flag
2370 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
2371 // non-matching short branch variant of some
2372 // long branch?
2373 ins_attrib ins_alignment(4); // Required alignment attribute (must be a power of 2)
2374 // specifies the alignment that some part of the instruction (not
2375 // necessarily the start) requires. If > 1, a compute_padding()
2376 // function must be provided for the instruction
2378 //----------OPERANDS-----------------------------------------------------------
2379 // Operand definitions must precede instruction definitions for correct parsing
2380 // in the ADLC because operands constitute user defined types which are used in
2381 // instruction definitions.
2383 // Vectors
2384 operand vecD() %{
2385 constraint(ALLOC_IN_RC(dbl_reg));
2386 match(VecD);
2388 format %{ %}
2389 interface(REG_INTER);
2390 %}
2392 // Flags register, used as output of compare instructions
2393 operand FlagsReg() %{
2394 constraint(ALLOC_IN_RC(mips_flags));
2395 match(RegFlags);
2397 format %{ "EFLAGS" %}
2398 interface(REG_INTER);
2399 %}
2401 //----------Simple Operands----------------------------------------------------
2402 //TODO: Should we need to define some more special immediate number ?
2403 // Immediate Operands
2404 // Integer Immediate
2405 operand immI() %{
2406 match(ConI);
2407 //TODO: should not match immI8 here LEE
2408 match(immI8);
2410 op_cost(20);
2411 format %{ %}
2412 interface(CONST_INTER);
2413 %}
2415 // Long Immediate 8-bit
2416 operand immL8()
2417 %{
2418 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
2419 match(ConL);
2421 op_cost(5);
2422 format %{ %}
2423 interface(CONST_INTER);
2424 %}
2426 // Constant for test vs zero
2427 operand immI0() %{
2428 predicate(n->get_int() == 0);
2429 match(ConI);
2431 op_cost(0);
2432 format %{ %}
2433 interface(CONST_INTER);
2434 %}
2436 // Constant for increment
2437 operand immI1() %{
2438 predicate(n->get_int() == 1);
2439 match(ConI);
2441 op_cost(0);
2442 format %{ %}
2443 interface(CONST_INTER);
2444 %}
2446 // Constant for decrement
2447 operand immI_M1() %{
2448 predicate(n->get_int() == -1);
2449 match(ConI);
2451 op_cost(0);
2452 format %{ %}
2453 interface(CONST_INTER);
2454 %}
2456 operand immI_MaxI() %{
2457 predicate(n->get_int() == 2147483647);
2458 match(ConI);
2460 op_cost(0);
2461 format %{ %}
2462 interface(CONST_INTER);
2463 %}
2465 // Valid scale values for addressing modes
2466 operand immI2() %{
2467 predicate(0 <= n->get_int() && (n->get_int() <= 3));
2468 match(ConI);
2470 format %{ %}
2471 interface(CONST_INTER);
2472 %}
2474 operand immI8() %{
2475 predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
2476 match(ConI);
2478 op_cost(5);
2479 format %{ %}
2480 interface(CONST_INTER);
2481 %}
2483 operand immI16() %{
2484 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
2485 match(ConI);
2487 op_cost(10);
2488 format %{ %}
2489 interface(CONST_INTER);
2490 %}
2492 // Constant for long shifts
2493 operand immI_32() %{
2494 predicate( n->get_int() == 32 );
2495 match(ConI);
2497 op_cost(0);
2498 format %{ %}
2499 interface(CONST_INTER);
2500 %}
2502 operand immI_63() %{
2503 predicate( n->get_int() == 63 );
2504 match(ConI);
2506 op_cost(0);
2507 format %{ %}
2508 interface(CONST_INTER);
2509 %}
2511 operand immI_0_31() %{
2512 predicate( n->get_int() >= 0 && n->get_int() <= 31 );
2513 match(ConI);
2515 op_cost(0);
2516 format %{ %}
2517 interface(CONST_INTER);
2518 %}
2520 // Operand for non-negtive integer mask
2521 operand immI_nonneg_mask() %{
2522 predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
2523 match(ConI);
2525 op_cost(0);
2526 format %{ %}
2527 interface(CONST_INTER);
2528 %}
2530 operand immI_32_63() %{
2531 predicate( n->get_int() >= 32 && n->get_int() <= 63 );
2532 match(ConI);
2533 op_cost(0);
2535 format %{ %}
2536 interface(CONST_INTER);
2537 %}
2539 operand immI16_sub() %{
2540 predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
2541 match(ConI);
2543 op_cost(10);
2544 format %{ %}
2545 interface(CONST_INTER);
2546 %}
2548 operand immI_0_32767() %{
2549 predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
2550 match(ConI);
2551 op_cost(0);
2553 format %{ %}
2554 interface(CONST_INTER);
2555 %}
2557 operand immI_0_65535() %{
2558 predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
2559 match(ConI);
2560 op_cost(0);
2562 format %{ %}
2563 interface(CONST_INTER);
2564 %}
2566 operand immI_1() %{
2567 predicate( n->get_int() == 1 );
2568 match(ConI);
2570 op_cost(0);
2571 format %{ %}
2572 interface(CONST_INTER);
2573 %}
2575 operand immI_2() %{
2576 predicate( n->get_int() == 2 );
2577 match(ConI);
2579 op_cost(0);
2580 format %{ %}
2581 interface(CONST_INTER);
2582 %}
2584 operand immI_3() %{
2585 predicate( n->get_int() == 3 );
2586 match(ConI);
2588 op_cost(0);
2589 format %{ %}
2590 interface(CONST_INTER);
2591 %}
2593 operand immI_7() %{
2594 predicate( n->get_int() == 7 );
2595 match(ConI);
2597 format %{ %}
2598 interface(CONST_INTER);
2599 %}
2601 // Immediates for special shifts (sign extend)
2603 // Constants for increment
2604 operand immI_16() %{
2605 predicate( n->get_int() == 16 );
2606 match(ConI);
2608 format %{ %}
2609 interface(CONST_INTER);
2610 %}
2612 operand immI_24() %{
2613 predicate( n->get_int() == 24 );
2614 match(ConI);
2616 format %{ %}
2617 interface(CONST_INTER);
2618 %}
2620 // Constant for byte-wide masking
2621 operand immI_255() %{
2622 predicate( n->get_int() == 255 );
2623 match(ConI);
2625 op_cost(0);
2626 format %{ %}
2627 interface(CONST_INTER);
2628 %}
2630 operand immI_65535() %{
2631 predicate( n->get_int() == 65535 );
2632 match(ConI);
2634 op_cost(5);
2635 format %{ %}
2636 interface(CONST_INTER);
2637 %}
2639 operand immI_65536() %{
2640 predicate( n->get_int() == 65536 );
2641 match(ConI);
2643 op_cost(5);
2644 format %{ %}
2645 interface(CONST_INTER);
2646 %}
2648 operand immI_M65536() %{
2649 predicate( n->get_int() == -65536 );
2650 match(ConI);
2652 op_cost(5);
2653 format %{ %}
2654 interface(CONST_INTER);
2655 %}
2657 // Pointer Immediate
2658 operand immP() %{
2659 match(ConP);
2661 op_cost(10);
2662 format %{ %}
2663 interface(CONST_INTER);
2664 %}
2666 // NULL Pointer Immediate
2667 operand immP0() %{
2668 predicate( n->get_ptr() == 0 );
2669 match(ConP);
2670 op_cost(0);
2672 format %{ %}
2673 interface(CONST_INTER);
2674 %}
2676 // Pointer Immediate: 64-bit
2677 operand immP_set() %{
2678 match(ConP);
2680 op_cost(5);
2681 // formats are generated automatically for constants and base registers
2682 format %{ %}
2683 interface(CONST_INTER);
2684 %}
2686 // Pointer Immediate: 64-bit
2687 operand immP_load() %{
2688 predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
2689 match(ConP);
2691 op_cost(5);
2692 // formats are generated automatically for constants and base registers
2693 format %{ %}
2694 interface(CONST_INTER);
2695 %}
2697 // Pointer Immediate: 64-bit
2698 operand immP_no_oop_cheap() %{
2699 predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
2700 match(ConP);
2702 op_cost(5);
2703 // formats are generated automatically for constants and base registers
2704 format %{ %}
2705 interface(CONST_INTER);
2706 %}
2708 // Pointer for polling page
2709 operand immP_poll() %{
2710 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
2711 match(ConP);
2712 op_cost(5);
2714 format %{ %}
2715 interface(CONST_INTER);
2716 %}
2718 // Pointer Immediate
2719 operand immN() %{
2720 match(ConN);
2722 op_cost(10);
2723 format %{ %}
2724 interface(CONST_INTER);
2725 %}
2727 operand immNKlass() %{
2728 match(ConNKlass);
2730 op_cost(10);
2731 format %{ %}
2732 interface(CONST_INTER);
2733 %}
2735 // NULL Pointer Immediate
2736 operand immN0() %{
2737 predicate(n->get_narrowcon() == 0);
2738 match(ConN);
2740 op_cost(5);
2741 format %{ %}
2742 interface(CONST_INTER);
2743 %}
2745 // Long Immediate
2746 operand immL() %{
2747 match(ConL);
2749 op_cost(20);
2750 format %{ %}
2751 interface(CONST_INTER);
2752 %}
2754 // Long Immediate zero
2755 operand immL0() %{
2756 predicate( n->get_long() == 0L );
2757 match(ConL);
2758 op_cost(0);
2760 format %{ %}
2761 interface(CONST_INTER);
2762 %}
2764 operand immL7() %{
2765 predicate( n->get_long() == 7L );
2766 match(ConL);
2767 op_cost(0);
2769 format %{ %}
2770 interface(CONST_INTER);
2771 %}
2773 operand immL_M1() %{
2774 predicate( n->get_long() == -1L );
2775 match(ConL);
2776 op_cost(0);
2778 format %{ %}
2779 interface(CONST_INTER);
2780 %}
2782 // bit 0..2 zero
2783 operand immL_M8() %{
2784 predicate( n->get_long() == -8L );
2785 match(ConL);
2786 op_cost(0);
2788 format %{ %}
2789 interface(CONST_INTER);
2790 %}
2792 // bit 2 zero
2793 operand immL_M5() %{
2794 predicate( n->get_long() == -5L );
2795 match(ConL);
2796 op_cost(0);
2798 format %{ %}
2799 interface(CONST_INTER);
2800 %}
2802 // bit 1..2 zero
2803 operand immL_M7() %{
2804 predicate( n->get_long() == -7L );
2805 match(ConL);
2806 op_cost(0);
2808 format %{ %}
2809 interface(CONST_INTER);
2810 %}
2812 // bit 0..1 zero
2813 operand immL_M4() %{
2814 predicate( n->get_long() == -4L );
2815 match(ConL);
2816 op_cost(0);
2818 format %{ %}
2819 interface(CONST_INTER);
2820 %}
2822 // bit 3..6 zero
2823 operand immL_M121() %{
2824 predicate( n->get_long() == -121L );
2825 match(ConL);
2826 op_cost(0);
2828 format %{ %}
2829 interface(CONST_INTER);
2830 %}
2832 // Long immediate from 0 to 127.
2833 // Used for a shorter form of long mul by 10.
2834 operand immL_127() %{
2835 predicate((0 <= n->get_long()) && (n->get_long() <= 127));
2836 match(ConL);
2837 op_cost(0);
2839 format %{ %}
2840 interface(CONST_INTER);
2841 %}
2843 // Operand for non-negtive long mask
2844 operand immL_nonneg_mask() %{
2845 predicate( (n->get_long() >= 0) && (Assembler::is_jlong_mask(n->get_long()) != -1) );
2846 match(ConL);
2848 op_cost(0);
2849 format %{ %}
2850 interface(CONST_INTER);
2851 %}
2853 operand immL_0_65535() %{
2854 predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
2855 match(ConL);
2856 op_cost(0);
2858 format %{ %}
2859 interface(CONST_INTER);
2860 %}
2862 // Long Immediate: cheap (materialize in <= 3 instructions)
2863 operand immL_cheap() %{
2864 predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
2865 match(ConL);
2866 op_cost(0);
2868 format %{ %}
2869 interface(CONST_INTER);
2870 %}
2872 // Long Immediate: expensive (materialize in > 3 instructions)
2873 operand immL_expensive() %{
2874 predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
2875 match(ConL);
2876 op_cost(0);
2878 format %{ %}
2879 interface(CONST_INTER);
2880 %}
2882 operand immL16() %{
2883 predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
2884 match(ConL);
2886 op_cost(10);
2887 format %{ %}
2888 interface(CONST_INTER);
2889 %}
2891 operand immL16_sub() %{
2892 predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
2893 match(ConL);
2895 op_cost(10);
2896 format %{ %}
2897 interface(CONST_INTER);
2898 %}
2900 // Long Immediate: low 32-bit mask
2901 operand immL_32bits() %{
2902 predicate(n->get_long() == 0xFFFFFFFFL);
2903 match(ConL);
2904 op_cost(20);
2906 format %{ %}
2907 interface(CONST_INTER);
2908 %}
2910 // Long Immediate 32-bit signed
2911 operand immL32()
2912 %{
2913 predicate(n->get_long() == (int) (n->get_long()));
2914 match(ConL);
2916 op_cost(15);
2917 format %{ %}
2918 interface(CONST_INTER);
2919 %}
2922 //single-precision floating-point zero
2923 operand immF0() %{
2924 predicate(jint_cast(n->getf()) == 0);
2925 match(ConF);
2927 op_cost(5);
2928 format %{ %}
2929 interface(CONST_INTER);
2930 %}
2932 //single-precision floating-point immediate
2933 operand immF() %{
2934 match(ConF);
2936 op_cost(20);
2937 format %{ %}
2938 interface(CONST_INTER);
2939 %}
2941 //double-precision floating-point zero
2942 operand immD0() %{
2943 predicate(jlong_cast(n->getd()) == 0);
2944 match(ConD);
2946 op_cost(5);
2947 format %{ %}
2948 interface(CONST_INTER);
2949 %}
2951 //double-precision floating-point immediate
2952 operand immD() %{
2953 match(ConD);
2955 op_cost(20);
2956 format %{ %}
2957 interface(CONST_INTER);
2958 %}
2960 // Register Operands
2961 // Integer Register
2962 operand mRegI() %{
2963 constraint(ALLOC_IN_RC(int_reg));
2964 match(RegI);
2966 format %{ %}
2967 interface(REG_INTER);
2968 %}
2970 operand no_Ax_mRegI() %{
2971 constraint(ALLOC_IN_RC(no_Ax_int_reg));
2972 match(RegI);
2973 match(mRegI);
2975 format %{ %}
2976 interface(REG_INTER);
2977 %}
2979 operand mS0RegI() %{
2980 constraint(ALLOC_IN_RC(s0_reg));
2981 match(RegI);
2982 match(mRegI);
2984 format %{ "S0" %}
2985 interface(REG_INTER);
2986 %}
2988 operand mS1RegI() %{
2989 constraint(ALLOC_IN_RC(s1_reg));
2990 match(RegI);
2991 match(mRegI);
2993 format %{ "S1" %}
2994 interface(REG_INTER);
2995 %}
2997 operand mS2RegI() %{
2998 constraint(ALLOC_IN_RC(s2_reg));
2999 match(RegI);
3000 match(mRegI);
3002 format %{ "S2" %}
3003 interface(REG_INTER);
3004 %}
3006 operand mS3RegI() %{
3007 constraint(ALLOC_IN_RC(s3_reg));
3008 match(RegI);
3009 match(mRegI);
3011 format %{ "S3" %}
3012 interface(REG_INTER);
3013 %}
3015 operand mS4RegI() %{
3016 constraint(ALLOC_IN_RC(s4_reg));
3017 match(RegI);
3018 match(mRegI);
3020 format %{ "S4" %}
3021 interface(REG_INTER);
3022 %}
3024 operand mS5RegI() %{
3025 constraint(ALLOC_IN_RC(s5_reg));
3026 match(RegI);
3027 match(mRegI);
3029 format %{ "S5" %}
3030 interface(REG_INTER);
3031 %}
3033 operand mS6RegI() %{
3034 constraint(ALLOC_IN_RC(s6_reg));
3035 match(RegI);
3036 match(mRegI);
3038 format %{ "S6" %}
3039 interface(REG_INTER);
3040 %}
3042 operand mS7RegI() %{
3043 constraint(ALLOC_IN_RC(s7_reg));
3044 match(RegI);
3045 match(mRegI);
3047 format %{ "S7" %}
3048 interface(REG_INTER);
3049 %}
3052 operand mT0RegI() %{
3053 constraint(ALLOC_IN_RC(t0_reg));
3054 match(RegI);
3055 match(mRegI);
3057 format %{ "T0" %}
3058 interface(REG_INTER);
3059 %}
3061 operand mT1RegI() %{
3062 constraint(ALLOC_IN_RC(t1_reg));
3063 match(RegI);
3064 match(mRegI);
3066 format %{ "T1" %}
3067 interface(REG_INTER);
3068 %}
3070 operand mT2RegI() %{
3071 constraint(ALLOC_IN_RC(t2_reg));
3072 match(RegI);
3073 match(mRegI);
3075 format %{ "T2" %}
3076 interface(REG_INTER);
3077 %}
3079 operand mT3RegI() %{
3080 constraint(ALLOC_IN_RC(t3_reg));
3081 match(RegI);
3082 match(mRegI);
3084 format %{ "T3" %}
3085 interface(REG_INTER);
3086 %}
3088 operand mT8RegI() %{
3089 constraint(ALLOC_IN_RC(t8_reg));
3090 match(RegI);
3091 match(mRegI);
3093 format %{ "T8" %}
3094 interface(REG_INTER);
3095 %}
3097 operand mT9RegI() %{
3098 constraint(ALLOC_IN_RC(t9_reg));
3099 match(RegI);
3100 match(mRegI);
3102 format %{ "T9" %}
3103 interface(REG_INTER);
3104 %}
3106 operand mA0RegI() %{
3107 constraint(ALLOC_IN_RC(a0_reg));
3108 match(RegI);
3109 match(mRegI);
3111 format %{ "A0" %}
3112 interface(REG_INTER);
3113 %}
3115 operand mA1RegI() %{
3116 constraint(ALLOC_IN_RC(a1_reg));
3117 match(RegI);
3118 match(mRegI);
3120 format %{ "A1" %}
3121 interface(REG_INTER);
3122 %}
3124 operand mA2RegI() %{
3125 constraint(ALLOC_IN_RC(a2_reg));
3126 match(RegI);
3127 match(mRegI);
3129 format %{ "A2" %}
3130 interface(REG_INTER);
3131 %}
3133 operand mA3RegI() %{
3134 constraint(ALLOC_IN_RC(a3_reg));
3135 match(RegI);
3136 match(mRegI);
3138 format %{ "A3" %}
3139 interface(REG_INTER);
3140 %}
3142 operand mA4RegI() %{
3143 constraint(ALLOC_IN_RC(a4_reg));
3144 match(RegI);
3145 match(mRegI);
3147 format %{ "A4" %}
3148 interface(REG_INTER);
3149 %}
3151 operand mA5RegI() %{
3152 constraint(ALLOC_IN_RC(a5_reg));
3153 match(RegI);
3154 match(mRegI);
3156 format %{ "A5" %}
3157 interface(REG_INTER);
3158 %}
3160 operand mA6RegI() %{
3161 constraint(ALLOC_IN_RC(a6_reg));
3162 match(RegI);
3163 match(mRegI);
3165 format %{ "A6" %}
3166 interface(REG_INTER);
3167 %}
3169 operand mA7RegI() %{
3170 constraint(ALLOC_IN_RC(a7_reg));
3171 match(RegI);
3172 match(mRegI);
3174 format %{ "A7" %}
3175 interface(REG_INTER);
3176 %}
3178 operand mV0RegI() %{
3179 constraint(ALLOC_IN_RC(v0_reg));
3180 match(RegI);
3181 match(mRegI);
3183 format %{ "V0" %}
3184 interface(REG_INTER);
3185 %}
3187 operand mV1RegI() %{
3188 constraint(ALLOC_IN_RC(v1_reg));
3189 match(RegI);
3190 match(mRegI);
3192 format %{ "V1" %}
3193 interface(REG_INTER);
3194 %}
3196 operand mRegN() %{
3197 constraint(ALLOC_IN_RC(int_reg));
3198 match(RegN);
3200 format %{ %}
3201 interface(REG_INTER);
3202 %}
3204 operand t0_RegN() %{
3205 constraint(ALLOC_IN_RC(t0_reg));
3206 match(RegN);
3207 match(mRegN);
3209 format %{ %}
3210 interface(REG_INTER);
3211 %}
3213 operand t1_RegN() %{
3214 constraint(ALLOC_IN_RC(t1_reg));
3215 match(RegN);
3216 match(mRegN);
3218 format %{ %}
3219 interface(REG_INTER);
3220 %}
3222 operand t2_RegN() %{
3223 constraint(ALLOC_IN_RC(t2_reg));
3224 match(RegN);
3225 match(mRegN);
3227 format %{ %}
3228 interface(REG_INTER);
3229 %}
3231 operand t3_RegN() %{
3232 constraint(ALLOC_IN_RC(t3_reg));
3233 match(RegN);
3234 match(mRegN);
3236 format %{ %}
3237 interface(REG_INTER);
3238 %}
3240 operand t8_RegN() %{
3241 constraint(ALLOC_IN_RC(t8_reg));
3242 match(RegN);
3243 match(mRegN);
3245 format %{ %}
3246 interface(REG_INTER);
3247 %}
3249 operand t9_RegN() %{
3250 constraint(ALLOC_IN_RC(t9_reg));
3251 match(RegN);
3252 match(mRegN);
3254 format %{ %}
3255 interface(REG_INTER);
3256 %}
3258 operand a0_RegN() %{
3259 constraint(ALLOC_IN_RC(a0_reg));
3260 match(RegN);
3261 match(mRegN);
3263 format %{ %}
3264 interface(REG_INTER);
3265 %}
3267 operand a1_RegN() %{
3268 constraint(ALLOC_IN_RC(a1_reg));
3269 match(RegN);
3270 match(mRegN);
3272 format %{ %}
3273 interface(REG_INTER);
3274 %}
3276 operand a2_RegN() %{
3277 constraint(ALLOC_IN_RC(a2_reg));
3278 match(RegN);
3279 match(mRegN);
3281 format %{ %}
3282 interface(REG_INTER);
3283 %}
3285 operand a3_RegN() %{
3286 constraint(ALLOC_IN_RC(a3_reg));
3287 match(RegN);
3288 match(mRegN);
3290 format %{ %}
3291 interface(REG_INTER);
3292 %}
3294 operand a4_RegN() %{
3295 constraint(ALLOC_IN_RC(a4_reg));
3296 match(RegN);
3297 match(mRegN);
3299 format %{ %}
3300 interface(REG_INTER);
3301 %}
3303 operand a5_RegN() %{
3304 constraint(ALLOC_IN_RC(a5_reg));
3305 match(RegN);
3306 match(mRegN);
3308 format %{ %}
3309 interface(REG_INTER);
3310 %}
3312 operand a6_RegN() %{
3313 constraint(ALLOC_IN_RC(a6_reg));
3314 match(RegN);
3315 match(mRegN);
3317 format %{ %}
3318 interface(REG_INTER);
3319 %}
3321 operand a7_RegN() %{
3322 constraint(ALLOC_IN_RC(a7_reg));
3323 match(RegN);
3324 match(mRegN);
3326 format %{ %}
3327 interface(REG_INTER);
3328 %}
3330 operand s0_RegN() %{
3331 constraint(ALLOC_IN_RC(s0_reg));
3332 match(RegN);
3333 match(mRegN);
3335 format %{ %}
3336 interface(REG_INTER);
3337 %}
3339 operand s1_RegN() %{
3340 constraint(ALLOC_IN_RC(s1_reg));
3341 match(RegN);
3342 match(mRegN);
3344 format %{ %}
3345 interface(REG_INTER);
3346 %}
3348 operand s2_RegN() %{
3349 constraint(ALLOC_IN_RC(s2_reg));
3350 match(RegN);
3351 match(mRegN);
3353 format %{ %}
3354 interface(REG_INTER);
3355 %}
3357 operand s3_RegN() %{
3358 constraint(ALLOC_IN_RC(s3_reg));
3359 match(RegN);
3360 match(mRegN);
3362 format %{ %}
3363 interface(REG_INTER);
3364 %}
3366 operand s4_RegN() %{
3367 constraint(ALLOC_IN_RC(s4_reg));
3368 match(RegN);
3369 match(mRegN);
3371 format %{ %}
3372 interface(REG_INTER);
3373 %}
3375 operand s5_RegN() %{
3376 constraint(ALLOC_IN_RC(s5_reg));
3377 match(RegN);
3378 match(mRegN);
3380 format %{ %}
3381 interface(REG_INTER);
3382 %}
3384 operand s6_RegN() %{
3385 constraint(ALLOC_IN_RC(s6_reg));
3386 match(RegN);
3387 match(mRegN);
3389 format %{ %}
3390 interface(REG_INTER);
3391 %}
3393 operand s7_RegN() %{
3394 constraint(ALLOC_IN_RC(s7_reg));
3395 match(RegN);
3396 match(mRegN);
3398 format %{ %}
3399 interface(REG_INTER);
3400 %}
3402 operand v0_RegN() %{
3403 constraint(ALLOC_IN_RC(v0_reg));
3404 match(RegN);
3405 match(mRegN);
3407 format %{ %}
3408 interface(REG_INTER);
3409 %}
3411 operand v1_RegN() %{
3412 constraint(ALLOC_IN_RC(v1_reg));
3413 match(RegN);
3414 match(mRegN);
3416 format %{ %}
3417 interface(REG_INTER);
3418 %}
3420 // Pointer Register
3421 operand mRegP() %{
3422 constraint(ALLOC_IN_RC(p_reg));
3423 match(RegP);
3425 format %{ %}
3426 interface(REG_INTER);
3427 %}
3429 operand no_T8_mRegP() %{
3430 constraint(ALLOC_IN_RC(no_T8_p_reg));
3431 match(RegP);
3432 match(mRegP);
3434 format %{ %}
3435 interface(REG_INTER);
3436 %}
3438 operand s0_RegP()
3439 %{
3440 constraint(ALLOC_IN_RC(s0_long_reg));
3441 match(RegP);
3442 match(mRegP);
3443 match(no_T8_mRegP);
3445 format %{ %}
3446 interface(REG_INTER);
3447 %}
3449 operand s1_RegP()
3450 %{
3451 constraint(ALLOC_IN_RC(s1_long_reg));
3452 match(RegP);
3453 match(mRegP);
3454 match(no_T8_mRegP);
3456 format %{ %}
3457 interface(REG_INTER);
3458 %}
3460 operand s2_RegP()
3461 %{
3462 constraint(ALLOC_IN_RC(s2_long_reg));
3463 match(RegP);
3464 match(mRegP);
3465 match(no_T8_mRegP);
3467 format %{ %}
3468 interface(REG_INTER);
3469 %}
3471 operand s3_RegP()
3472 %{
3473 constraint(ALLOC_IN_RC(s3_long_reg));
3474 match(RegP);
3475 match(mRegP);
3476 match(no_T8_mRegP);
3478 format %{ %}
3479 interface(REG_INTER);
3480 %}
3482 operand s4_RegP()
3483 %{
3484 constraint(ALLOC_IN_RC(s4_long_reg));
3485 match(RegP);
3486 match(mRegP);
3487 match(no_T8_mRegP);
3489 format %{ %}
3490 interface(REG_INTER);
3491 %}
3493 operand s5_RegP()
3494 %{
3495 constraint(ALLOC_IN_RC(s5_long_reg));
3496 match(RegP);
3497 match(mRegP);
3498 match(no_T8_mRegP);
3500 format %{ %}
3501 interface(REG_INTER);
3502 %}
3504 operand s6_RegP()
3505 %{
3506 constraint(ALLOC_IN_RC(s6_long_reg));
3507 match(RegP);
3508 match(mRegP);
3509 match(no_T8_mRegP);
3511 format %{ %}
3512 interface(REG_INTER);
3513 %}
3515 operand s7_RegP()
3516 %{
3517 constraint(ALLOC_IN_RC(s7_long_reg));
3518 match(RegP);
3519 match(mRegP);
3520 match(no_T8_mRegP);
3522 format %{ %}
3523 interface(REG_INTER);
3524 %}
3526 operand t0_RegP()
3527 %{
3528 constraint(ALLOC_IN_RC(t0_long_reg));
3529 match(RegP);
3530 match(mRegP);
3531 match(no_T8_mRegP);
3533 format %{ %}
3534 interface(REG_INTER);
3535 %}
3537 operand t1_RegP()
3538 %{
3539 constraint(ALLOC_IN_RC(t1_long_reg));
3540 match(RegP);
3541 match(mRegP);
3542 match(no_T8_mRegP);
3544 format %{ %}
3545 interface(REG_INTER);
3546 %}
3548 operand t2_RegP()
3549 %{
3550 constraint(ALLOC_IN_RC(t2_long_reg));
3551 match(RegP);
3552 match(mRegP);
3553 match(no_T8_mRegP);
3555 format %{ %}
3556 interface(REG_INTER);
3557 %}
3559 operand t3_RegP()
3560 %{
3561 constraint(ALLOC_IN_RC(t3_long_reg));
3562 match(RegP);
3563 match(mRegP);
3564 match(no_T8_mRegP);
3566 format %{ %}
3567 interface(REG_INTER);
3568 %}
3570 operand t8_RegP()
3571 %{
3572 constraint(ALLOC_IN_RC(t8_long_reg));
3573 match(RegP);
3574 match(mRegP);
3576 format %{ %}
3577 interface(REG_INTER);
3578 %}
3580 operand t9_RegP()
3581 %{
3582 constraint(ALLOC_IN_RC(t9_long_reg));
3583 match(RegP);
3584 match(mRegP);
3585 match(no_T8_mRegP);
3587 format %{ %}
3588 interface(REG_INTER);
3589 %}
3591 operand a0_RegP()
3592 %{
3593 constraint(ALLOC_IN_RC(a0_long_reg));
3594 match(RegP);
3595 match(mRegP);
3596 match(no_T8_mRegP);
3598 format %{ %}
3599 interface(REG_INTER);
3600 %}
3602 operand a1_RegP()
3603 %{
3604 constraint(ALLOC_IN_RC(a1_long_reg));
3605 match(RegP);
3606 match(mRegP);
3607 match(no_T8_mRegP);
3609 format %{ %}
3610 interface(REG_INTER);
3611 %}
3613 operand a2_RegP()
3614 %{
3615 constraint(ALLOC_IN_RC(a2_long_reg));
3616 match(RegP);
3617 match(mRegP);
3618 match(no_T8_mRegP);
3620 format %{ %}
3621 interface(REG_INTER);
3622 %}
3624 operand a3_RegP()
3625 %{
3626 constraint(ALLOC_IN_RC(a3_long_reg));
3627 match(RegP);
3628 match(mRegP);
3629 match(no_T8_mRegP);
3631 format %{ %}
3632 interface(REG_INTER);
3633 %}
3635 operand a4_RegP()
3636 %{
3637 constraint(ALLOC_IN_RC(a4_long_reg));
3638 match(RegP);
3639 match(mRegP);
3640 match(no_T8_mRegP);
3642 format %{ %}
3643 interface(REG_INTER);
3644 %}
3647 operand a5_RegP()
3648 %{
3649 constraint(ALLOC_IN_RC(a5_long_reg));
3650 match(RegP);
3651 match(mRegP);
3652 match(no_T8_mRegP);
3654 format %{ %}
3655 interface(REG_INTER);
3656 %}
3658 operand a6_RegP()
3659 %{
3660 constraint(ALLOC_IN_RC(a6_long_reg));
3661 match(RegP);
3662 match(mRegP);
3663 match(no_T8_mRegP);
3665 format %{ %}
3666 interface(REG_INTER);
3667 %}
3669 operand a7_RegP()
3670 %{
3671 constraint(ALLOC_IN_RC(a7_long_reg));
3672 match(RegP);
3673 match(mRegP);
3674 match(no_T8_mRegP);
3676 format %{ %}
3677 interface(REG_INTER);
3678 %}
3680 operand v0_RegP()
3681 %{
3682 constraint(ALLOC_IN_RC(v0_long_reg));
3683 match(RegP);
3684 match(mRegP);
3685 match(no_T8_mRegP);
3687 format %{ %}
3688 interface(REG_INTER);
3689 %}
3691 operand v1_RegP()
3692 %{
3693 constraint(ALLOC_IN_RC(v1_long_reg));
3694 match(RegP);
3695 match(mRegP);
3696 match(no_T8_mRegP);
3698 format %{ %}
3699 interface(REG_INTER);
3700 %}
3702 /*
3703 operand mSPRegP(mRegP reg) %{
3704 constraint(ALLOC_IN_RC(sp_reg));
3705 match(reg);
3707 format %{ "SP" %}
3708 interface(REG_INTER);
3709 %}
3711 operand mFPRegP(mRegP reg) %{
3712 constraint(ALLOC_IN_RC(fp_reg));
3713 match(reg);
3715 format %{ "FP" %}
3716 interface(REG_INTER);
3717 %}
3718 */
3720 operand mRegL() %{
3721 constraint(ALLOC_IN_RC(long_reg));
3722 match(RegL);
3724 format %{ %}
3725 interface(REG_INTER);
3726 %}
3728 operand v0RegL() %{
3729 constraint(ALLOC_IN_RC(v0_long_reg));
3730 match(RegL);
3731 match(mRegL);
3733 format %{ %}
3734 interface(REG_INTER);
3735 %}
3737 operand v1RegL() %{
3738 constraint(ALLOC_IN_RC(v1_long_reg));
3739 match(RegL);
3740 match(mRegL);
3742 format %{ %}
3743 interface(REG_INTER);
3744 %}
3746 operand a0RegL() %{
3747 constraint(ALLOC_IN_RC(a0_long_reg));
3748 match(RegL);
3749 match(mRegL);
3751 format %{ "A0" %}
3752 interface(REG_INTER);
3753 %}
3755 operand a1RegL() %{
3756 constraint(ALLOC_IN_RC(a1_long_reg));
3757 match(RegL);
3758 match(mRegL);
3760 format %{ %}
3761 interface(REG_INTER);
3762 %}
3764 operand a2RegL() %{
3765 constraint(ALLOC_IN_RC(a2_long_reg));
3766 match(RegL);
3767 match(mRegL);
3769 format %{ %}
3770 interface(REG_INTER);
3771 %}
3773 operand a3RegL() %{
3774 constraint(ALLOC_IN_RC(a3_long_reg));
3775 match(RegL);
3776 match(mRegL);
3778 format %{ %}
3779 interface(REG_INTER);
3780 %}
3782 operand t0RegL() %{
3783 constraint(ALLOC_IN_RC(t0_long_reg));
3784 match(RegL);
3785 match(mRegL);
3787 format %{ %}
3788 interface(REG_INTER);
3789 %}
3791 operand t1RegL() %{
3792 constraint(ALLOC_IN_RC(t1_long_reg));
3793 match(RegL);
3794 match(mRegL);
3796 format %{ %}
3797 interface(REG_INTER);
3798 %}
3800 operand t2RegL() %{
3801 constraint(ALLOC_IN_RC(t2_long_reg));
3802 match(RegL);
3803 match(mRegL);
3805 format %{ %}
3806 interface(REG_INTER);
3807 %}
3809 operand t3RegL() %{
3810 constraint(ALLOC_IN_RC(t3_long_reg));
3811 match(RegL);
3812 match(mRegL);
3814 format %{ %}
3815 interface(REG_INTER);
3816 %}
3818 operand t8RegL() %{
3819 constraint(ALLOC_IN_RC(t8_long_reg));
3820 match(RegL);
3821 match(mRegL);
3823 format %{ %}
3824 interface(REG_INTER);
3825 %}
3827 operand a4RegL() %{
3828 constraint(ALLOC_IN_RC(a4_long_reg));
3829 match(RegL);
3830 match(mRegL);
3832 format %{ %}
3833 interface(REG_INTER);
3834 %}
3836 operand a5RegL() %{
3837 constraint(ALLOC_IN_RC(a5_long_reg));
3838 match(RegL);
3839 match(mRegL);
3841 format %{ %}
3842 interface(REG_INTER);
3843 %}
3845 operand a6RegL() %{
3846 constraint(ALLOC_IN_RC(a6_long_reg));
3847 match(RegL);
3848 match(mRegL);
3850 format %{ %}
3851 interface(REG_INTER);
3852 %}
3854 operand a7RegL() %{
3855 constraint(ALLOC_IN_RC(a7_long_reg));
3856 match(RegL);
3857 match(mRegL);
3859 format %{ %}
3860 interface(REG_INTER);
3861 %}
3863 operand s0RegL() %{
3864 constraint(ALLOC_IN_RC(s0_long_reg));
3865 match(RegL);
3866 match(mRegL);
3868 format %{ %}
3869 interface(REG_INTER);
3870 %}
3872 operand s1RegL() %{
3873 constraint(ALLOC_IN_RC(s1_long_reg));
3874 match(RegL);
3875 match(mRegL);
3877 format %{ %}
3878 interface(REG_INTER);
3879 %}
3881 operand s2RegL() %{
3882 constraint(ALLOC_IN_RC(s2_long_reg));
3883 match(RegL);
3884 match(mRegL);
3886 format %{ %}
3887 interface(REG_INTER);
3888 %}
3890 operand s3RegL() %{
3891 constraint(ALLOC_IN_RC(s3_long_reg));
3892 match(RegL);
3893 match(mRegL);
3895 format %{ %}
3896 interface(REG_INTER);
3897 %}
3899 operand s4RegL() %{
3900 constraint(ALLOC_IN_RC(s4_long_reg));
3901 match(RegL);
3902 match(mRegL);
3904 format %{ %}
3905 interface(REG_INTER);
3906 %}
3908 operand s7RegL() %{
3909 constraint(ALLOC_IN_RC(s7_long_reg));
3910 match(RegL);
3911 match(mRegL);
3913 format %{ %}
3914 interface(REG_INTER);
3915 %}
3917 // Floating register operands
3918 operand regF() %{
3919 constraint(ALLOC_IN_RC(flt_reg));
3920 match(RegF);
3922 format %{ %}
3923 interface(REG_INTER);
3924 %}
3926 //Double Precision Floating register operands
3927 operand regD() %{
3928 constraint(ALLOC_IN_RC(dbl_reg));
3929 match(RegD);
3931 format %{ %}
3932 interface(REG_INTER);
3933 %}
3935 //----------Memory Operands----------------------------------------------------
3936 operand baseOffset16(mRegP reg, immL16 off)
3937 %{
3938 constraint(ALLOC_IN_RC(p_reg));
3939 match(AddP reg off);
3941 op_cost(5);
3942 format %{ "[$reg + $off (16-bit)] @ baseOffset16" %}
3943 interface(MEMORY_INTER) %{
3944 base($reg);
3945 index(0x0);
3946 scale(0x0);
3947 disp($off);
3948 %}
3949 %}
3951 operand gsBaseIndexOffset8(mRegP base, mRegL index, immL8 off)
3952 %{
3953 predicate(UseLoongsonISA);
3954 constraint(ALLOC_IN_RC(p_reg));
3955 match(AddP (AddP base index) off);
3957 op_cost(5);
3958 format %{ "[$base + $index + $off (8-bit)] @ gsBaseIndexOffset8" %}
3959 interface(MEMORY_INTER) %{
3960 base($base);
3961 index($index);
3962 scale(0x0);
3963 disp($off);
3964 %}
3965 %}
3967 operand gsBaseIndexI2LOffset8(mRegP base, mRegI index, immL8 off)
3968 %{
3969 predicate(UseLoongsonISA);
3970 constraint(ALLOC_IN_RC(p_reg));
3971 match(AddP (AddP base (ConvI2L index)) off);
3973 op_cost(5);
3974 format %{ "[$base + $index + $off (8-bit)] @ gsBaseIndexI2LOffset8" %}
3975 interface(MEMORY_INTER) %{
3976 base($base);
3977 index($index);
3978 scale(0x0);
3979 disp($off);
3980 %}
3981 %}
3983 operand gsBaseIndexOffset0(mRegP addr, mRegL index) %{
3984 predicate(UseLoongsonISA);
3985 constraint(ALLOC_IN_RC(p_reg));
3986 match(AddP addr index);
3988 op_cost(10);
3989 format %{"[$addr + $index] @ gsBaseIndexOffset0" %}
3990 interface(MEMORY_INTER) %{
3991 base($addr);
3992 index($index);
3993 scale(0x0);
3994 disp(0x0);
3995 %}
3996 %}
3998 operand baseOffset0(mRegP reg) %{
3999 constraint(ALLOC_IN_RC(p_reg));
4000 op_cost(10);
4001 match(reg);
4003 format %{ "[$reg] @ baseOffset0" %}
4004 interface(MEMORY_INTER) %{
4005 base($reg);
4006 index(0x0);
4007 scale(0x0);
4008 disp(0x0);
4009 %}
4010 %}
4012 operand baseOffset16Narrow(mRegN reg, immL16 off)
4013 %{
4014 predicate(Universe::narrow_oop_base() == 0 && Universe::narrow_oop_shift() == 0);
4015 constraint(ALLOC_IN_RC(p_reg));
4016 match(AddP (DecodeN reg) off);
4018 op_cost(5);
4019 format %{ "[$reg + $off (16-bit)] @ baseOffset16Narrow" %}
4020 interface(MEMORY_INTER) %{
4021 base($reg);
4022 index(0x0);
4023 scale(0x0);
4024 disp($off);
4025 %}
4026 %}
4028 operand gsBaseIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
4029 %{
4030 predicate(UseLoongsonISA && Universe::narrow_oop_base() == 0 && Universe::narrow_oop_shift() == 0);
4031 constraint(ALLOC_IN_RC(p_reg));
4032 match(AddP (AddP (DecodeN reg) lreg) off);
4034 op_cost(5);
4035 format %{"[$reg + $off + $lreg] @ gsBaseIndexOffset8Narrow" %}
4036 interface(MEMORY_INTER) %{
4037 base($reg);
4038 index($lreg);
4039 scale(0x0);
4040 disp($off);
4041 %}
4042 %}
4044 operand baseOffset0Narrow(mRegN reg)
4045 %{
4046 predicate(Universe::narrow_oop_base() == 0 && Universe::narrow_oop_shift() == 0);
4047 constraint(ALLOC_IN_RC(p_reg));
4048 match(DecodeN reg);
4050 op_cost(10);
4051 format %{ "[$reg] @ baseOffset0Narrow" %}
4052 interface(MEMORY_INTER) %{
4053 base($reg);
4054 index(0x0);
4055 scale(0x0);
4056 disp(0x0);
4057 %}
4058 %}
4060 operand baseOffset16NarrowKlass(mRegN reg, immL16 off)
4061 %{
4062 predicate(Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
4063 constraint(ALLOC_IN_RC(p_reg));
4064 match(AddP (DecodeNKlass reg) off);
4066 op_cost(5);
4067 format %{ "[$reg + $off (16-bit)] @ baseOffset16NarrowKlass" %}
4068 interface(MEMORY_INTER) %{
4069 base($reg);
4070 index(0x0);
4071 scale(0x0);
4072 disp($off);
4073 %}
4074 %}
4076 operand baseOffset0NarrowKlass(mRegN reg)
4077 %{
4078 predicate(Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
4079 constraint(ALLOC_IN_RC(p_reg));
4080 match(DecodeNKlass reg);
4082 op_cost(10);
4083 format %{ "[$reg] @ baseOffset0NarrowKlass" %}
4084 interface(MEMORY_INTER) %{
4085 base($reg);
4086 index(0x0);
4087 scale(0x0);
4088 disp(0x0);
4089 %}
4090 %}
4092 operand gsBaseIndexOffset8NarrowKlass(mRegN reg, mRegL lreg, immL8 off)
4093 %{
4094 predicate(UseLoongsonISA && Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
4095 constraint(ALLOC_IN_RC(p_reg));
4096 match(AddP (AddP (DecodeNKlass reg) lreg) off);
4098 op_cost(5);
4099 format %{"[$reg + $off + $lreg] @ gsBaseIndexOffset8NarrowKlass" %}
4100 interface(MEMORY_INTER) %{
4101 base($reg);
4102 index($lreg);
4103 scale(0x0);
4104 disp($off);
4105 %}
4106 %}
4108 operand gsBaseIndexOffset0NarrowKlass(mRegN reg, mRegL lreg)
4109 %{
4110 predicate(UseLoongsonISA && Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
4111 constraint(ALLOC_IN_RC(p_reg));
4112 match(AddP (DecodeNKlass reg) lreg);
4114 op_cost(10);
4115 format %{"[$reg + $lreg] @ gsBaseIndexOffset0NarrowKlass" %}
4116 interface(MEMORY_INTER) %{
4117 base($reg);
4118 index($lreg);
4119 scale(0x0);
4120 disp(0x0);
4121 %}
4122 %}
4125 //------------------------OPERAND CLASSES--------------------------------------
4126 opclass memory(
4127 baseOffset16,
4128 gsBaseIndexOffset8,
4129 gsBaseIndexI2LOffset8,
4130 gsBaseIndexOffset0,
4131 baseOffset0,
4133 baseOffset16Narrow,
4134 gsBaseIndexOffset8Narrow,
4135 baseOffset0Narrow,
4137 baseOffset16NarrowKlass,
4138 baseOffset0NarrowKlass,
4139 gsBaseIndexOffset8NarrowKlass,
4140 gsBaseIndexOffset0NarrowKlass
4141 );
4143 // For loading unsigned values
4144 // umemory --> unsigned memory
4145 opclass umemory(
4146 baseOffset16,
4147 baseOffset0,
4149 baseOffset16Narrow,
4150 baseOffset0Narrow,
4152 baseOffset16NarrowKlass,
4153 baseOffset0NarrowKlass
4154 );
4157 //----------Conditional Branch Operands----------------------------------------
4158 // Comparison Op - This is the operation of the comparison, and is limited to
4159 // the following set of codes:
4160 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
4161 //
4162 // Other attributes of the comparison, such as unsignedness, are specified
4163 // by the comparison instruction that sets a condition code flags register.
4164 // That result is represented by a flags operand whose subtype is appropriate
4165 // to the unsignedness (etc.) of the comparison.
4166 //
4167 // Later, the instruction which matches both the Comparison Op (a Bool) and
4168 // the flags (produced by the Cmp) specifies the coding of the comparison op
4169 // by matching a specific subtype of Bool operand below, such as cmpOpU.
4171 // Comparision Code
4172 operand cmpOp() %{
4173 match(Bool);
4175 format %{ "" %}
4176 interface(COND_INTER) %{
4177 equal(0x01);
4178 not_equal(0x02);
4179 greater(0x03);
4180 greater_equal(0x04);
4181 less(0x05);
4182 less_equal(0x06);
4183 overflow(0x7);
4184 no_overflow(0x8);
4185 %}
4186 %}
4189 // Comparision Code
4190 // Comparison Code, unsigned compare. Used by FP also, with
4191 // C2 (unordered) turned into GT or LT already. The other bits
4192 // C0 and C3 are turned into Carry & Zero flags.
4193 operand cmpOpU() %{
4194 match(Bool);
4196 format %{ "" %}
4197 interface(COND_INTER) %{
4198 equal(0x01);
4199 not_equal(0x02);
4200 greater(0x03);
4201 greater_equal(0x04);
4202 less(0x05);
4203 less_equal(0x06);
4204 overflow(0x7);
4205 no_overflow(0x8);
4206 %}
4207 %}
4210 //----------Special Memory Operands--------------------------------------------
4211 // Stack Slot Operand - This operand is used for loading and storing temporary
4212 // values on the stack where a match requires a value to
4213 // flow through memory.
4214 operand stackSlotP(sRegP reg) %{
4215 constraint(ALLOC_IN_RC(stack_slots));
4216 // No match rule because this operand is only generated in matching
4217 op_cost(50);
4218 format %{ "[$reg]" %}
4219 interface(MEMORY_INTER) %{
4220 base(0x1d); // SP
4221 index(0x0); // No Index
4222 scale(0x0); // No Scale
4223 disp($reg); // Stack Offset
4224 %}
4225 %}
4227 operand stackSlotI(sRegI reg) %{
4228 constraint(ALLOC_IN_RC(stack_slots));
4229 // No match rule because this operand is only generated in matching
4230 op_cost(50);
4231 format %{ "[$reg]" %}
4232 interface(MEMORY_INTER) %{
4233 base(0x1d); // SP
4234 index(0x0); // No Index
4235 scale(0x0); // No Scale
4236 disp($reg); // Stack Offset
4237 %}
4238 %}
4240 operand stackSlotF(sRegF reg) %{
4241 constraint(ALLOC_IN_RC(stack_slots));
4242 // No match rule because this operand is only generated in matching
4243 op_cost(50);
4244 format %{ "[$reg]" %}
4245 interface(MEMORY_INTER) %{
4246 base(0x1d); // SP
4247 index(0x0); // No Index
4248 scale(0x0); // No Scale
4249 disp($reg); // Stack Offset
4250 %}
4251 %}
4253 operand stackSlotD(sRegD reg) %{
4254 constraint(ALLOC_IN_RC(stack_slots));
4255 // No match rule because this operand is only generated in matching
4256 op_cost(50);
4257 format %{ "[$reg]" %}
4258 interface(MEMORY_INTER) %{
4259 base(0x1d); // SP
4260 index(0x0); // No Index
4261 scale(0x0); // No Scale
4262 disp($reg); // Stack Offset
4263 %}
4264 %}
4266 operand stackSlotL(sRegL reg) %{
4267 constraint(ALLOC_IN_RC(stack_slots));
4268 // No match rule because this operand is only generated in matching
4269 op_cost(50);
4270 format %{ "[$reg]" %}
4271 interface(MEMORY_INTER) %{
4272 base(0x1d); // SP
4273 index(0x0); // No Index
4274 scale(0x0); // No Scale
4275 disp($reg); // Stack Offset
4276 %}
4277 %}
4279 //----------PIPELINE-----------------------------------------------------------
4280 // Rules which define the behavior of the target architectures pipeline.
4282 pipeline %{
4284 //----------ATTRIBUTES---------------------------------------------------------
4285 attributes %{
4286 fixed_size_instructions; // Fixed size instructions
4287 branch_has_delay_slot; // branch have delay slot in gs2
4288 max_instructions_per_bundle = 1; // 1 instruction per bundle
4289 max_bundles_per_cycle = 4; // Up to 4 bundles per cycle
4290 bundle_unit_size=4;
4291 instruction_unit_size = 4; // An instruction is 4 bytes long
4292 instruction_fetch_unit_size = 16; // The processor fetches one line
4293 instruction_fetch_units = 1; // of 16 bytes
4295 // List of nop instructions
4296 nops( MachNop );
4297 %}
4299 //----------RESOURCES----------------------------------------------------------
4300 // Resources are the functional units available to the machine
4302 resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4, ALU1, ALU2, ALU = ALU1 | ALU2, FPU1, FPU2, FPU = FPU1 | FPU2, MEM, BR);
4304 //----------PIPELINE DESCRIPTION-----------------------------------------------
4305 // Pipeline Description specifies the stages in the machine's pipeline
4307 // IF: fetch
4308 // ID: decode
4309 // RD: read
4310 // CA: caculate
4311 // WB: write back
4312 // CM: commit
4314 pipe_desc(IF, ID, RD, CA, WB, CM);
4317 //----------PIPELINE CLASSES---------------------------------------------------
4318 // Pipeline Classes describe the stages in which input and output are
4319 // referenced by the hardware pipeline.
4321 //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
4322 pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
4323 single_instruction;
4324 src1 : RD(read);
4325 src2 : RD(read);
4326 dst : WB(write)+1;
4327 DECODE : ID;
4328 ALU : CA;
4329 %}
4331 //No.19 Integer mult operation : dst <-- reg1 mult reg2
4332 pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
4333 src1 : RD(read);
4334 src2 : RD(read);
4335 dst : WB(write)+5;
4336 DECODE : ID;
4337 ALU2 : CA;
4338 %}
4340 pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
4341 src1 : RD(read);
4342 src2 : RD(read);
4343 dst : WB(write)+10;
4344 DECODE : ID;
4345 ALU2 : CA;
4346 %}
4348 //No.19 Integer div operation : dst <-- reg1 div reg2
4349 pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
4350 src1 : RD(read);
4351 src2 : RD(read);
4352 dst : WB(write)+10;
4353 DECODE : ID;
4354 ALU2 : CA;
4355 %}
4357 //No.19 Integer mod operation : dst <-- reg1 mod reg2
4358 pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
4359 instruction_count(2);
4360 src1 : RD(read);
4361 src2 : RD(read);
4362 dst : WB(write)+10;
4363 DECODE : ID;
4364 ALU2 : CA;
4365 %}
4367 //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
4368 pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
4369 instruction_count(2);
4370 src1 : RD(read);
4371 src2 : RD(read);
4372 dst : WB(write);
4373 DECODE : ID;
4374 ALU : CA;
4375 %}
4377 //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
4378 pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
4379 instruction_count(2);
4380 src : RD(read);
4381 dst : WB(write);
4382 DECODE : ID;
4383 ALU : CA;
4384 %}
4386 //no.16 load Long from memory :
4387 pipe_class ialu_loadL(mRegL dst, memory mem) %{
4388 instruction_count(2);
4389 mem : RD(read);
4390 dst : WB(write)+5;
4391 DECODE : ID;
4392 MEM : RD;
4393 %}
4395 //No.17 Store Long to Memory :
4396 pipe_class ialu_storeL(mRegL src, memory mem) %{
4397 instruction_count(2);
4398 mem : RD(read);
4399 src : RD(read);
4400 DECODE : ID;
4401 MEM : RD;
4402 %}
4404 //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
4405 pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
4406 single_instruction;
4407 src : RD(read);
4408 dst : WB(write);
4409 DECODE : ID;
4410 ALU : CA;
4411 %}
4413 //No.3 Integer move operation : dst <-- reg
4414 pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
4415 src : RD(read);
4416 dst : WB(write);
4417 DECODE : ID;
4418 ALU : CA;
4419 %}
4421 //No.4 No instructions : do nothing
4422 pipe_class empty( ) %{
4423 instruction_count(0);
4424 %}
4426 //No.5 UnConditional branch :
4427 pipe_class pipe_jump( label labl ) %{
4428 multiple_bundles;
4429 DECODE : ID;
4430 BR : RD;
4431 %}
4433 //No.6 ALU Conditional branch :
4434 pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
4435 multiple_bundles;
4436 src1 : RD(read);
4437 src2 : RD(read);
4438 DECODE : ID;
4439 BR : RD;
4440 %}
4442 //no.7 load integer from memory :
4443 pipe_class ialu_loadI(mRegI dst, memory mem) %{
4444 mem : RD(read);
4445 dst : WB(write)+3;
4446 DECODE : ID;
4447 MEM : RD;
4448 %}
4450 //No.8 Store Integer to Memory :
4451 pipe_class ialu_storeI(mRegI src, memory mem) %{
4452 mem : RD(read);
4453 src : RD(read);
4454 DECODE : ID;
4455 MEM : RD;
4456 %}
4459 //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
4460 pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
4461 src1 : RD(read);
4462 src2 : RD(read);
4463 dst : WB(write);
4464 DECODE : ID;
4465 FPU : CA;
4466 %}
4468 //No.22 Floating div operation : dst <-- reg1 div reg2
4469 pipe_class fpu_div(regF dst, regF src1, regF src2) %{
4470 src1 : RD(read);
4471 src2 : RD(read);
4472 dst : WB(write);
4473 DECODE : ID;
4474 FPU2 : CA;
4475 %}
4477 pipe_class fcvt_I2D(regD dst, mRegI src) %{
4478 src : RD(read);
4479 dst : WB(write);
4480 DECODE : ID;
4481 FPU1 : CA;
4482 %}
4484 pipe_class fcvt_D2I(mRegI dst, regD src) %{
4485 src : RD(read);
4486 dst : WB(write);
4487 DECODE : ID;
4488 FPU1 : CA;
4489 %}
4491 pipe_class pipe_mfc1(mRegI dst, regD src) %{
4492 src : RD(read);
4493 dst : WB(write);
4494 DECODE : ID;
4495 MEM : RD;
4496 %}
4498 pipe_class pipe_mtc1(regD dst, mRegI src) %{
4499 src : RD(read);
4500 dst : WB(write);
4501 DECODE : ID;
4502 MEM : RD(5);
4503 %}
4505 //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
4506 pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
4507 multiple_bundles;
4508 src1 : RD(read);
4509 src2 : RD(read);
4510 dst : WB(write);
4511 DECODE : ID;
4512 FPU2 : CA;
4513 %}
4515 //No.11 Load Floating from Memory :
4516 pipe_class fpu_loadF(regF dst, memory mem) %{
4517 instruction_count(1);
4518 mem : RD(read);
4519 dst : WB(write)+3;
4520 DECODE : ID;
4521 MEM : RD;
4522 %}
4524 //No.12 Store Floating to Memory :
4525 pipe_class fpu_storeF(regF src, memory mem) %{
4526 instruction_count(1);
4527 mem : RD(read);
4528 src : RD(read);
4529 DECODE : ID;
4530 MEM : RD;
4531 %}
4533 //No.13 FPU Conditional branch :
4534 pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
4535 multiple_bundles;
4536 src1 : RD(read);
4537 src2 : RD(read);
4538 DECODE : ID;
4539 BR : RD;
4540 %}
4542 //No.14 Floating FPU reg operation : dst <-- op reg
4543 pipe_class fpu1_regF(regF dst, regF src) %{
4544 src : RD(read);
4545 dst : WB(write);
4546 DECODE : ID;
4547 FPU : CA;
4548 %}
4550 pipe_class long_memory_op() %{
4551 instruction_count(10); multiple_bundles; force_serialization;
4552 fixed_latency(30);
4553 %}
4555 pipe_class simple_call() %{
4556 instruction_count(10); multiple_bundles; force_serialization;
4557 fixed_latency(200);
4558 BR : RD;
4559 %}
4561 pipe_class call() %{
4562 instruction_count(10); multiple_bundles; force_serialization;
4563 fixed_latency(200);
4564 %}
4566 //FIXME:
4567 //No.9 Piple slow : for multi-instructions
4568 pipe_class pipe_slow( ) %{
4569 instruction_count(20);
4570 force_serialization;
4571 multiple_bundles;
4572 fixed_latency(50);
4573 %}
4575 %}
4579 //----------INSTRUCTIONS-------------------------------------------------------
4580 //
4581 // match -- States which machine-independent subtree may be replaced
4582 // by this instruction.
4583 // ins_cost -- The estimated cost of this instruction is used by instruction
4584 // selection to identify a minimum cost tree of machine
4585 // instructions that matches a tree of machine-independent
4586 // instructions.
4587 // format -- A string providing the disassembly for this instruction.
4588 // The value of an instruction's operand may be inserted
4589 // by referring to it with a '$' prefix.
4590 // opcode -- Three instruction opcodes may be provided. These are referred
4591 // to within an encode class as $primary, $secondary, and $tertiary
4592 // respectively. The primary opcode is commonly used to
4593 // indicate the type of machine instruction, while secondary
4594 // and tertiary are often used for prefix options or addressing
4595 // modes.
4596 // ins_encode -- A list of encode classes with parameters. The encode class
4597 // name must have been defined in an 'enc_class' specification
4598 // in the encode section of the architecture description.
4601 // Load Integer
4602 instruct loadI(mRegI dst, memory mem) %{
4603 match(Set dst (LoadI mem));
4605 ins_cost(125);
4606 format %{ "lw $dst, $mem #@loadI" %}
4607 ins_encode (load_I_enc(dst, mem));
4608 ins_pipe( ialu_loadI );
4609 %}
4611 instruct loadI_convI2L(mRegL dst, memory mem) %{
4612 match(Set dst (ConvI2L (LoadI mem)));
4614 ins_cost(125);
4615 format %{ "lw $dst, $mem #@loadI_convI2L" %}
4616 ins_encode (load_I_enc(dst, mem));
4617 ins_pipe( ialu_loadI );
4618 %}
4620 // Load Integer (32 bit signed) to Byte (8 bit signed)
4621 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
4622 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
4624 ins_cost(125);
4625 format %{ "lb $dst, $mem\t# int -> byte #@loadI2B" %}
4626 ins_encode(load_B_enc(dst, mem));
4627 ins_pipe(ialu_loadI);
4628 %}
4630 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
4631 instruct loadI2UB(mRegI dst, umemory mem, immI_255 mask) %{
4632 match(Set dst (AndI (LoadI mem) mask));
4634 ins_cost(125);
4635 format %{ "lbu $dst, $mem\t# int -> ubyte #@loadI2UB" %}
4636 ins_encode(load_UB_enc(dst, mem));
4637 ins_pipe(ialu_loadI);
4638 %}
4640 // Load Integer (32 bit signed) to Short (16 bit signed)
4641 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
4642 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
4644 ins_cost(125);
4645 format %{ "lh $dst, $mem\t# int -> short #@loadI2S" %}
4646 ins_encode(load_S_enc(dst, mem));
4647 ins_pipe(ialu_loadI);
4648 %}
4650 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
4651 instruct loadI2US(mRegI dst, umemory mem, immI_65535 mask) %{
4652 match(Set dst (AndI (LoadI mem) mask));
4654 ins_cost(125);
4655 format %{ "lhu $dst, $mem\t# int -> ushort/char #@loadI2US" %}
4656 ins_encode(load_C_enc(dst, mem));
4657 ins_pipe(ialu_loadI);
4658 %}
4660 // Load Long.
4661 instruct loadL(mRegL dst, memory mem) %{
4662 // predicate(!((LoadLNode*)n)->require_atomic_access());
4663 match(Set dst (LoadL mem));
4665 ins_cost(250);
4666 format %{ "ld $dst, $mem #@loadL" %}
4667 ins_encode(load_L_enc(dst, mem));
4668 ins_pipe( ialu_loadL );
4669 %}
4671 // Load Long - UNaligned
4672 instruct loadL_unaligned(mRegL dst, memory mem) %{
4673 match(Set dst (LoadL_unaligned mem));
4675 // FIXME: Jin: Need more effective ldl/ldr
4676 ins_cost(450);
4677 format %{ "ld $dst, $mem #@loadL_unaligned\n\t" %}
4678 ins_encode(load_L_enc(dst, mem));
4679 ins_pipe( ialu_loadL );
4680 %}
4682 // Store Long
4683 instruct storeL_reg(memory mem, mRegL src) %{
4684 match(Set mem (StoreL mem src));
4686 ins_cost(200);
4687 format %{ "sd $mem, $src #@storeL_reg\n" %}
4688 ins_encode(store_L_reg_enc(mem, src));
4689 ins_pipe( ialu_storeL );
4690 %}
4693 instruct storeL_immL0(memory mem, immL0 zero) %{
4694 match(Set mem (StoreL mem zero));
4696 ins_cost(180);
4697 format %{ "sd $mem, zero #@storeL_immL0" %}
4698 ins_encode(store_L_immL0_enc(mem));
4699 ins_pipe( ialu_storeL );
4700 %}
4702 // Load Compressed Pointer
4703 instruct loadN(mRegN dst, umemory mem)
4704 %{
4705 match(Set dst (LoadN mem));
4707 ins_cost(125); // XXX
4708 format %{ "lwu $dst, $mem\t# compressed ptr @ loadN" %}
4709 ins_encode (load_N_enc(dst, mem));
4710 ins_pipe( ialu_loadI ); // XXX
4711 %}
4713 instruct loadN2P(mRegP dst, umemory mem)
4714 %{
4715 match(Set dst (DecodeN (LoadN mem)));
4716 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
4718 ins_cost(125); // XXX
4719 format %{ "lwu $dst, $mem\t# @ loadN2P" %}
4720 ins_encode (load_N_enc(dst, mem));
4721 ins_pipe( ialu_loadI ); // XXX
4722 %}
4724 // Load Pointer
4725 instruct loadP(mRegP dst, memory mem) %{
4726 match(Set dst (LoadP mem));
4728 ins_cost(125);
4729 format %{ "ld $dst, $mem #@loadP" %}
4730 ins_encode (load_P_enc(dst, mem));
4731 ins_pipe( ialu_loadI );
4732 %}
4734 // Load Klass Pointer
4735 instruct loadKlass(mRegP dst, memory mem) %{
4736 match(Set dst (LoadKlass mem));
4738 ins_cost(125);
4739 format %{ "MOV $dst,$mem @ loadKlass" %}
4740 ins_encode (load_P_enc(dst, mem));
4741 ins_pipe( ialu_loadI );
4742 %}
4744 // Load narrow Klass Pointer
4745 instruct loadNKlass(mRegN dst, umemory mem)
4746 %{
4747 match(Set dst (LoadNKlass mem));
4749 ins_cost(125); // XXX
4750 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
4751 ins_encode (load_N_enc(dst, mem));
4752 ins_pipe( ialu_loadI ); // XXX
4753 %}
4755 instruct loadN2PKlass(mRegP dst, umemory mem)
4756 %{
4757 match(Set dst (DecodeNKlass (LoadNKlass mem)));
4758 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4760 ins_cost(125); // XXX
4761 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
4762 ins_encode (load_N_enc(dst, mem));
4763 ins_pipe( ialu_loadI ); // XXX
4764 %}
4766 // Load Constant
4767 instruct loadConI(mRegI dst, immI src) %{
4768 match(Set dst src);
4770 ins_cost(150);
4771 format %{ "mov $dst, $src #@loadConI" %}
4772 ins_encode %{
4773 Register dst = $dst$$Register;
4774 int value = $src$$constant;
4775 __ move(dst, value);
4776 %}
4777 ins_pipe( ialu_regI_regI );
4778 %}
4781 instruct loadConL_set64(mRegL dst, immL src) %{
4782 match(Set dst src);
4783 ins_cost(120);
4784 format %{ "li $dst, $src @ loadConL_set64" %}
4785 ins_encode %{
4786 __ set64($dst$$Register, $src$$constant);
4787 %}
4788 ins_pipe(ialu_regL_regL);
4789 %}
4791 /*
4792 // Load long value from constant table (predicated by immL_expensive).
4793 instruct loadConL_load(mRegL dst, immL_expensive src) %{
4794 match(Set dst src);
4795 ins_cost(150);
4796 format %{ "ld $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
4797 ins_encode %{
4798 int con_offset = $constantoffset($src);
4800 if (Assembler::is_simm16(con_offset)) {
4801 __ ld($dst$$Register, $constanttablebase, con_offset);
4802 } else {
4803 __ set64(AT, con_offset);
4804 if (UseLoongsonISA) {
4805 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
4806 } else {
4807 __ daddu(AT, $constanttablebase, AT);
4808 __ ld($dst$$Register, AT, 0);
4809 }
4810 }
4811 %}
4812 ins_pipe(ialu_loadI);
4813 %}
4814 */
4816 instruct loadConL16(mRegL dst, immL16 src) %{
4817 match(Set dst src);
4818 ins_cost(105);
4819 format %{ "mov $dst, $src #@loadConL16" %}
4820 ins_encode %{
4821 Register dst_reg = as_Register($dst$$reg);
4822 int value = $src$$constant;
4823 __ daddiu(dst_reg, R0, value);
4824 %}
4825 ins_pipe( ialu_regL_regL );
4826 %}
4829 instruct loadConL0(mRegL dst, immL0 src) %{
4830 match(Set dst src);
4831 ins_cost(100);
4832 format %{ "mov $dst, zero #@loadConL0" %}
4833 ins_encode %{
4834 Register dst_reg = as_Register($dst$$reg);
4835 __ daddu(dst_reg, R0, R0);
4836 %}
4837 ins_pipe( ialu_regL_regL );
4838 %}
4840 // Load Range
4841 instruct loadRange(mRegI dst, memory mem) %{
4842 match(Set dst (LoadRange mem));
4844 ins_cost(125);
4845 format %{ "MOV $dst,$mem @ loadRange" %}
4846 ins_encode(load_I_enc(dst, mem));
4847 ins_pipe( ialu_loadI );
4848 %}
4851 instruct storeP(memory mem, mRegP src ) %{
4852 match(Set mem (StoreP mem src));
4854 ins_cost(125);
4855 format %{ "sd $src, $mem #@storeP" %}
4856 ins_encode(store_P_reg_enc(mem, src));
4857 ins_pipe( ialu_storeI );
4858 %}
4860 // Store NULL Pointer, mark word, or other simple pointer constant.
4861 instruct storeImmP0(memory mem, immP0 zero) %{
4862 match(Set mem (StoreP mem zero));
4864 ins_cost(125);
4865 format %{ "mov $mem, $zero #@storeImmP0" %}
4866 ins_encode(store_P_immP0_enc(mem));
4867 ins_pipe( ialu_storeI );
4868 %}
4870 // Store Compressed Pointer
4871 instruct storeN(memory mem, mRegN src)
4872 %{
4873 match(Set mem (StoreN mem src));
4875 ins_cost(125); // XXX
4876 format %{ "sw $mem, $src\t# compressed ptr @ storeN" %}
4877 ins_encode(store_N_reg_enc(mem, src));
4878 ins_pipe( ialu_storeI );
4879 %}
4881 instruct storeP2N(memory mem, mRegP src)
4882 %{
4883 match(Set mem (StoreN mem (EncodeP src)));
4884 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
4886 ins_cost(125); // XXX
4887 format %{ "sw $mem, $src\t# @ storeP2N" %}
4888 ins_encode(store_N_reg_enc(mem, src));
4889 ins_pipe( ialu_storeI );
4890 %}
4892 instruct storeNKlass(memory mem, mRegN src)
4893 %{
4894 match(Set mem (StoreNKlass mem src));
4896 ins_cost(125); // XXX
4897 format %{ "sw $mem, $src\t# compressed klass ptr @ storeNKlass" %}
4898 ins_encode(store_N_reg_enc(mem, src));
4899 ins_pipe( ialu_storeI );
4900 %}
4902 instruct storeP2NKlass(memory mem, mRegP src)
4903 %{
4904 match(Set mem (StoreNKlass mem (EncodePKlass src)));
4905 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4907 ins_cost(125); // XXX
4908 format %{ "sw $mem, $src\t# @ storeP2NKlass" %}
4909 ins_encode(store_N_reg_enc(mem, src));
4910 ins_pipe( ialu_storeI );
4911 %}
4913 instruct storeImmN0(memory mem, immN0 zero)
4914 %{
4915 match(Set mem (StoreN mem zero));
4917 ins_cost(125); // XXX
4918 format %{ "storeN0 $mem, R12\t# compressed ptr" %}
4919 ins_encode(storeImmN0_enc(mem));
4920 ins_pipe( ialu_storeI );
4921 %}
4923 // Store Byte
4924 instruct storeB(memory mem, mRegI src) %{
4925 match(Set mem (StoreB mem src));
4927 ins_cost(125);
4928 format %{ "sb $src, $mem #@storeB" %}
4929 ins_encode(store_B_reg_enc(mem, src));
4930 ins_pipe( ialu_storeI );
4931 %}
4933 instruct storeB0(memory mem, immI0 zero) %{
4934 match(Set mem (StoreB mem zero));
4936 ins_cost(100);
4937 format %{ "sb $zero, $mem #@storeB0" %}
4938 ins_encode(store_B0_enc(mem));
4939 ins_pipe( ialu_storeI );
4940 %}
4942 instruct storeB_convL2I(memory mem, mRegL src) %{
4943 match(Set mem (StoreB mem (ConvL2I src)));
4945 ins_cost(125);
4946 format %{ "sb $src, $mem #@storeB_convL2I" %}
4947 ins_encode(store_B_reg_enc(mem, src));
4948 ins_pipe( ialu_storeI );
4949 %}
4951 // Load Byte (8bit signed)
4952 instruct loadB(mRegI dst, memory mem) %{
4953 match(Set dst (LoadB mem));
4955 ins_cost(125);
4956 format %{ "lb $dst, $mem #@loadB" %}
4957 ins_encode(load_B_enc(dst, mem));
4958 ins_pipe( ialu_loadI );
4959 %}
4961 instruct loadB_convI2L(mRegL dst, memory mem) %{
4962 match(Set dst (ConvI2L (LoadB mem)));
4964 ins_cost(125);
4965 format %{ "lb $dst, $mem #@loadB_convI2L" %}
4966 ins_encode(load_B_enc(dst, mem));
4967 ins_pipe( ialu_loadI );
4968 %}
4970 // Load Byte (8bit UNsigned)
4971 instruct loadUB(mRegI dst, umemory mem) %{
4972 match(Set dst (LoadUB mem));
4974 ins_cost(125);
4975 format %{ "lbu $dst, $mem #@loadUB" %}
4976 ins_encode(load_UB_enc(dst, mem));
4977 ins_pipe( ialu_loadI );
4978 %}
4980 instruct loadUB_convI2L(mRegL dst, umemory mem) %{
4981 match(Set dst (ConvI2L (LoadUB mem)));
4983 ins_cost(125);
4984 format %{ "lbu $dst, $mem #@loadUB_convI2L" %}
4985 ins_encode(load_UB_enc(dst, mem));
4986 ins_pipe( ialu_loadI );
4987 %}
4989 // Load Short (16bit signed)
4990 instruct loadS(mRegI dst, memory mem) %{
4991 match(Set dst (LoadS mem));
4993 ins_cost(125);
4994 format %{ "lh $dst, $mem #@loadS" %}
4995 ins_encode(load_S_enc(dst, mem));
4996 ins_pipe( ialu_loadI );
4997 %}
4999 // Load Short (16 bit signed) to Byte (8 bit signed)
5000 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
5001 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
5003 ins_cost(125);
5004 format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
5005 ins_encode(load_B_enc(dst, mem));
5006 ins_pipe(ialu_loadI);
5007 %}
5009 instruct loadS_convI2L(mRegL dst, memory mem) %{
5010 match(Set dst (ConvI2L (LoadS mem)));
5012 ins_cost(125);
5013 format %{ "lh $dst, $mem #@loadS_convI2L" %}
5014 ins_encode(load_S_enc(dst, mem));
5015 ins_pipe( ialu_loadI );
5016 %}
5018 // Store Integer Immediate
5019 instruct storeI0(memory mem, immI0 zero) %{
5020 match(Set mem (StoreI mem zero));
5022 ins_cost(100);
5023 format %{ "sw $mem, $zero #@storeI0" %}
5024 ins_encode(store_I_immI0_enc(mem));
5025 ins_pipe( ialu_storeI );
5026 %}
5028 // Store Integer
5029 instruct storeI(memory mem, mRegI src) %{
5030 match(Set mem (StoreI mem src));
5032 ins_cost(125);
5033 format %{ "sw $mem, $src #@storeI" %}
5034 ins_encode(store_I_reg_enc(mem, src));
5035 ins_pipe( ialu_storeI );
5036 %}
5038 instruct storeI_convL2I(memory mem, mRegL src) %{
5039 match(Set mem (StoreI mem (ConvL2I src)));
5041 ins_cost(125);
5042 format %{ "sw $mem, $src #@storeI_convL2I" %}
5043 ins_encode(store_I_reg_enc(mem, src));
5044 ins_pipe( ialu_storeI );
5045 %}
5047 // Load Float
5048 instruct loadF(regF dst, memory mem) %{
5049 match(Set dst (LoadF mem));
5051 ins_cost(150);
5052 format %{ "loadF $dst, $mem #@loadF" %}
5053 ins_encode(load_F_enc(dst, mem));
5054 ins_pipe( ialu_loadI );
5055 %}
5057 instruct loadConP_general(mRegP dst, immP src) %{
5058 match(Set dst src);
5060 ins_cost(120);
5061 format %{ "li $dst, $src #@loadConP_general" %}
5063 ins_encode %{
5064 Register dst = $dst$$Register;
5065 long* value = (long*)$src$$constant;
5067 if($src->constant_reloc() == relocInfo::metadata_type){
5068 int klass_index = __ oop_recorder()->find_index((Klass*)value);
5069 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
5071 __ relocate(rspec);
5072 __ patchable_set48(dst, (long)value);
5073 }else if($src->constant_reloc() == relocInfo::oop_type){
5074 int oop_index = __ oop_recorder()->find_index((jobject)value);
5075 RelocationHolder rspec = oop_Relocation::spec(oop_index);
5077 __ relocate(rspec);
5078 __ patchable_set48(dst, (long)value);
5079 } else if ($src->constant_reloc() == relocInfo::none) {
5080 __ set64(dst, (long)value);
5081 }
5082 %}
5084 ins_pipe( ialu_regI_regI );
5085 %}
5087 /*
5088 instruct loadConP_load(mRegP dst, immP_load src) %{
5089 match(Set dst src);
5091 ins_cost(100);
5092 format %{ "ld $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
5094 ins_encode %{
5096 int con_offset = $constantoffset($src);
5098 if (Assembler::is_simm16(con_offset)) {
5099 __ ld($dst$$Register, $constanttablebase, con_offset);
5100 } else {
5101 __ set64(AT, con_offset);
5102 if (UseLoongsonISA) {
5103 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
5104 } else {
5105 __ daddu(AT, $constanttablebase, AT);
5106 __ ld($dst$$Register, AT, 0);
5107 }
5108 }
5109 %}
5111 ins_pipe(ialu_loadI);
5112 %}
5113 */
5115 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
5116 match(Set dst src);
5118 ins_cost(80);
5119 format %{ "li $dst, $src @ loadConP_no_oop_cheap" %}
5121 ins_encode %{
5122 __ set64($dst$$Register, $src$$constant);
5123 %}
5125 ins_pipe(ialu_regI_regI);
5126 %}
5129 instruct loadConP_poll(mRegP dst, immP_poll src) %{
5130 match(Set dst src);
5132 ins_cost(50);
5133 format %{ "li $dst, $src #@loadConP_poll" %}
5135 ins_encode %{
5136 Register dst = $dst$$Register;
5137 intptr_t value = (intptr_t)$src$$constant;
5139 __ set64(dst, (jlong)value);
5140 %}
5142 ins_pipe( ialu_regI_regI );
5143 %}
5145 instruct loadConP0(mRegP dst, immP0 src)
5146 %{
5147 match(Set dst src);
5149 ins_cost(50);
5150 format %{ "mov $dst, R0\t# ptr" %}
5151 ins_encode %{
5152 Register dst_reg = $dst$$Register;
5153 __ daddu(dst_reg, R0, R0);
5154 %}
5155 ins_pipe( ialu_regI_regI );
5156 %}
5158 instruct loadConN0(mRegN dst, immN0 src) %{
5159 match(Set dst src);
5160 format %{ "move $dst, R0\t# compressed NULL ptr" %}
5161 ins_encode %{
5162 __ move($dst$$Register, R0);
5163 %}
5164 ins_pipe( ialu_regI_regI );
5165 %}
5167 instruct loadConN(mRegN dst, immN src) %{
5168 match(Set dst src);
5170 ins_cost(125);
5171 format %{ "li $dst, $src\t# compressed ptr @ loadConN" %}
5172 ins_encode %{
5173 Register dst = $dst$$Register;
5174 __ set_narrow_oop(dst, (jobject)$src$$constant);
5175 %}
5176 ins_pipe( ialu_regI_regI ); // XXX
5177 %}
5179 instruct loadConNKlass(mRegN dst, immNKlass src) %{
5180 match(Set dst src);
5182 ins_cost(125);
5183 format %{ "li $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
5184 ins_encode %{
5185 Register dst = $dst$$Register;
5186 __ set_narrow_klass(dst, (Klass*)$src$$constant);
5187 %}
5188 ins_pipe( ialu_regI_regI ); // XXX
5189 %}
5191 //FIXME
5192 // Tail Call; Jump from runtime stub to Java code.
5193 // Also known as an 'interprocedural jump'.
5194 // Target of jump will eventually return to caller.
5195 // TailJump below removes the return address.
5196 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
5197 match(TailCall jump_target method_oop );
5198 ins_cost(300);
5199 format %{ "JMP $jump_target \t# @TailCalljmpInd" %}
5201 ins_encode %{
5202 Register target = $jump_target$$Register;
5203 Register oop = $method_oop$$Register;
5205 /* 2012/10/12 Jin: RA will be used in generate_forward_exception() */
5206 __ push(RA);
5208 __ move(S3, oop);
5209 __ jr(target);
5210 __ nop();
5211 %}
5213 ins_pipe( pipe_jump );
5214 %}
5216 // Create exception oop: created by stack-crawling runtime code.
5217 // Created exception is now available to this handler, and is setup
5218 // just prior to jumping to this handler. No code emitted.
5219 instruct CreateException( a0_RegP ex_oop )
5220 %{
5221 match(Set ex_oop (CreateEx));
5223 // use the following format syntax
5224 format %{ "# exception oop is in A0; no code emitted @CreateException" %}
5225 ins_encode %{
5226 /* Jin: X86 leaves this function empty */
5227 __ block_comment("CreateException is empty in X86/MIPS");
5228 %}
5229 ins_pipe( empty );
5230 // ins_pipe( pipe_jump );
5231 %}
5234 /* 2012/9/14 Jin: The mechanism of exception handling is clear now.
5236 - Common try/catch:
5237 2012/9/14 Jin: [stubGenerator_mips.cpp] generate_forward_exception()
5238 |- V0, V1 are created
5239 |- T9 <= SharedRuntime::exception_handler_for_return_address
5240 `- jr T9
5241 `- the caller's exception_handler
5242 `- jr OptoRuntime::exception_blob
5243 `- here
5244 - Rethrow(e.g. 'unwind'):
5245 * The callee:
5246 |- an exception is triggered during execution
5247 `- exits the callee method through RethrowException node
5248 |- The callee pushes exception_oop(T0) and exception_pc(RA)
5249 `- The callee jumps to OptoRuntime::rethrow_stub()
5250 * In OptoRuntime::rethrow_stub:
5251 |- The VM calls _rethrow_Java to determine the return address in the caller method
5252 `- exits the stub with tailjmpInd
5253 |- pops exception_oop(V0) and exception_pc(V1)
5254 `- jumps to the return address(usually an exception_handler)
5255 * The caller:
5256 `- continues processing the exception_blob with V0/V1
5257 */
5259 /*
5260 Disassembling OptoRuntime::rethrow_stub()
5262 ; locals
5263 0x2d3bf320: addiu sp, sp, 0xfffffff8
5264 0x2d3bf324: sw ra, 0x4(sp)
5265 0x2d3bf328: sw fp, 0x0(sp)
5266 0x2d3bf32c: addu fp, sp, zero
5267 0x2d3bf330: addiu sp, sp, 0xfffffff0
5268 0x2d3bf334: sw ra, 0x8(sp)
5269 0x2d3bf338: sw t0, 0x4(sp)
5270 0x2d3bf33c: sw sp, 0x0(sp)
5272 ; get_thread(S2)
5273 0x2d3bf340: addu s2, sp, zero
5274 0x2d3bf344: srl s2, s2, 12
5275 0x2d3bf348: sll s2, s2, 2
5276 0x2d3bf34c: lui at, 0x2c85
5277 0x2d3bf350: addu at, at, s2
5278 0x2d3bf354: lw s2, 0xffffcc80(at)
5280 0x2d3bf358: lw s0, 0x0(sp)
5281 0x2d3bf35c: sw s0, 0x118(s2) // last_sp -> threa
5282 0x2d3bf360: sw s2, 0xc(sp)
5284 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
5285 0x2d3bf364: lw a0, 0x4(sp)
5286 0x2d3bf368: lw a1, 0xc(sp)
5287 0x2d3bf36c: lw a2, 0x8(sp)
5288 ;; Java_To_Runtime
5289 0x2d3bf370: lui t9, 0x2c34
5290 0x2d3bf374: addiu t9, t9, 0xffff8a48
5291 0x2d3bf378: jalr t9
5292 0x2d3bf37c: nop
5294 0x2d3bf380: addu s3, v0, zero ; S3: SharedRuntime::raw_exception_handler_for_return_address()
5296 0x2d3bf384: lw s0, 0xc(sp)
5297 0x2d3bf388: sw zero, 0x118(s0)
5298 0x2d3bf38c: sw zero, 0x11c(s0)
5299 0x2d3bf390: lw s1, 0x144(s0) ; ex_oop: S1
5300 0x2d3bf394: addu s2, s0, zero
5301 0x2d3bf398: sw zero, 0x144(s2)
5302 0x2d3bf39c: lw s0, 0x4(s2)
5303 0x2d3bf3a0: addiu s4, zero, 0x0
5304 0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
5305 0x2d3bf3a8: nop
5306 0x2d3bf3ac: addiu sp, sp, 0x10
5307 0x2d3bf3b0: addiu sp, sp, 0x8
5308 0x2d3bf3b4: lw ra, 0xfffffffc(sp)
5309 0x2d3bf3b8: lw fp, 0xfffffff8(sp)
5310 0x2d3bf3bc: lui at, 0x2b48
5311 0x2d3bf3c0: lw at, 0x100(at)
5313 ; tailjmpInd: Restores exception_oop & exception_pc
5314 0x2d3bf3c4: addu v1, ra, zero
5315 0x2d3bf3c8: addu v0, s1, zero
5316 0x2d3bf3cc: jr s3
5317 0x2d3bf3d0: nop
5318 ; Exception:
5319 0x2d3bf3d4: lui s1, 0x2cc8 ; generate_forward_exception()
5320 0x2d3bf3d8: addiu s1, s1, 0x40
5321 0x2d3bf3dc: addiu s2, zero, 0x0
5322 0x2d3bf3e0: addiu sp, sp, 0x10
5323 0x2d3bf3e4: addiu sp, sp, 0x8
5324 0x2d3bf3e8: lw ra, 0xfffffffc(sp)
5325 0x2d3bf3ec: lw fp, 0xfffffff8(sp)
5326 0x2d3bf3f0: lui at, 0x2b48
5327 0x2d3bf3f4: lw at, 0x100(at)
5328 ; TailCalljmpInd
5329 __ push(RA); ; to be used in generate_forward_exception()
5330 0x2d3bf3f8: addu t7, s2, zero
5331 0x2d3bf3fc: jr s1
5332 0x2d3bf400: nop
5333 */
5334 // Rethrow exception:
5335 // The exception oop will come in the first argument position.
5336 // Then JUMP (not call) to the rethrow stub code.
5337 instruct RethrowException()
5338 %{
5339 match(Rethrow);
5341 // use the following format syntax
5342 format %{ "JMP rethrow_stub #@RethrowException" %}
5343 ins_encode %{
5344 __ block_comment("@ RethrowException");
5346 cbuf.set_insts_mark();
5347 cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
5349 // call OptoRuntime::rethrow_stub to get the exception handler in parent method
5350 __ patchable_jump((address)OptoRuntime::rethrow_stub());
5351 %}
5352 ins_pipe( pipe_jump );
5353 %}
5355 instruct branchConP_zero(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
5356 match(If cmp (CmpP op1 zero));
5357 effect(USE labl);
5359 ins_cost(180);
5360 format %{ "b$cmp $op1, R0, $labl #@branchConP_zero" %}
5362 ins_encode %{
5363 Register op1 = $op1$$Register;
5364 Register op2 = R0;
5365 Label &L = *($labl$$label);
5366 int flag = $cmp$$cmpcode;
5368 switch(flag)
5369 {
5370 case 0x01: //equal
5371 if (&L)
5372 __ beq(op1, op2, L);
5373 else
5374 __ beq(op1, op2, (int)0);
5375 break;
5376 case 0x02: //not_equal
5377 if (&L)
5378 __ bne(op1, op2, L);
5379 else
5380 __ bne(op1, op2, (int)0);
5381 break;
5382 /*
5383 case 0x03: //above
5384 __ sltu(AT, op2, op1);
5385 if(&L)
5386 __ bne(R0, AT, L);
5387 else
5388 __ bne(R0, AT, (int)0);
5389 break;
5390 case 0x04: //above_equal
5391 __ sltu(AT, op1, op2);
5392 if(&L)
5393 __ beq(AT, R0, L);
5394 else
5395 __ beq(AT, R0, (int)0);
5396 break;
5397 case 0x05: //below
5398 __ sltu(AT, op1, op2);
5399 if(&L)
5400 __ bne(R0, AT, L);
5401 else
5402 __ bne(R0, AT, (int)0);
5403 break;
5404 case 0x06: //below_equal
5405 __ sltu(AT, op2, op1);
5406 if(&L)
5407 __ beq(AT, R0, L);
5408 else
5409 __ beq(AT, R0, (int)0);
5410 break;
5411 */
5412 default:
5413 Unimplemented();
5414 }
5415 __ nop();
5416 %}
5418 ins_pc_relative(1);
5419 ins_pipe( pipe_alu_branch );
5420 %}
5422 instruct branchConN2P_zero(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
5423 match(If cmp (CmpP (DecodeN op1) zero));
5424 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
5425 effect(USE labl);
5427 ins_cost(180);
5428 format %{ "b$cmp $op1, R0, $labl #@branchConN2P_zero" %}
5430 ins_encode %{
5431 Register op1 = $op1$$Register;
5432 Register op2 = R0;
5433 Label &L = *($labl$$label);
5434 int flag = $cmp$$cmpcode;
5436 switch(flag)
5437 {
5438 case 0x01: //equal
5439 if (&L)
5440 __ beq(op1, op2, L);
5441 else
5442 __ beq(op1, op2, (int)0);
5443 break;
5444 case 0x02: //not_equal
5445 if (&L)
5446 __ bne(op1, op2, L);
5447 else
5448 __ bne(op1, op2, (int)0);
5449 break;
5450 default:
5451 Unimplemented();
5452 }
5453 __ nop();
5454 %}
5456 ins_pc_relative(1);
5457 ins_pipe( pipe_alu_branch );
5458 %}
5461 instruct branchConP(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
5462 match(If cmp (CmpP op1 op2));
5463 // predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
5464 effect(USE labl);
5466 ins_cost(200);
5467 format %{ "b$cmp $op1, $op2, $labl #@branchConP" %}
5469 ins_encode %{
5470 Register op1 = $op1$$Register;
5471 Register op2 = $op2$$Register;
5472 Label &L = *($labl$$label);
5473 int flag = $cmp$$cmpcode;
5475 switch(flag)
5476 {
5477 case 0x01: //equal
5478 if (&L)
5479 __ beq(op1, op2, L);
5480 else
5481 __ beq(op1, op2, (int)0);
5482 break;
5483 case 0x02: //not_equal
5484 if (&L)
5485 __ bne(op1, op2, L);
5486 else
5487 __ bne(op1, op2, (int)0);
5488 break;
5489 case 0x03: //above
5490 __ sltu(AT, op2, op1);
5491 if(&L)
5492 __ bne(R0, AT, L);
5493 else
5494 __ bne(R0, AT, (int)0);
5495 break;
5496 case 0x04: //above_equal
5497 __ sltu(AT, op1, op2);
5498 if(&L)
5499 __ beq(AT, R0, L);
5500 else
5501 __ beq(AT, R0, (int)0);
5502 break;
5503 case 0x05: //below
5504 __ sltu(AT, op1, op2);
5505 if(&L)
5506 __ bne(R0, AT, L);
5507 else
5508 __ bne(R0, AT, (int)0);
5509 break;
5510 case 0x06: //below_equal
5511 __ sltu(AT, op2, op1);
5512 if(&L)
5513 __ beq(AT, R0, L);
5514 else
5515 __ beq(AT, R0, (int)0);
5516 break;
5517 default:
5518 Unimplemented();
5519 }
5520 __ nop();
5521 %}
5523 ins_pc_relative(1);
5524 ins_pipe( pipe_alu_branch );
5525 %}
5527 instruct cmpN_null_branch(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
5528 match(If cmp (CmpN op1 null));
5529 effect(USE labl);
5531 ins_cost(180);
5532 format %{ "CMP $op1,0\t! compressed ptr\n\t"
5533 "BP$cmp $labl @ cmpN_null_branch" %}
5534 ins_encode %{
5535 Register op1 = $op1$$Register;
5536 Register op2 = R0;
5537 Label &L = *($labl$$label);
5538 int flag = $cmp$$cmpcode;
5540 switch(flag)
5541 {
5542 case 0x01: //equal
5543 if (&L)
5544 __ beq(op1, op2, L);
5545 else
5546 __ beq(op1, op2, (int)0);
5547 break;
5548 case 0x02: //not_equal
5549 if (&L)
5550 __ bne(op1, op2, L);
5551 else
5552 __ bne(op1, op2, (int)0);
5553 break;
5554 default:
5555 Unimplemented();
5556 }
5557 __ nop();
5558 %}
5559 //TODO: pipe_branchP or create pipe_branchN LEE
5560 ins_pc_relative(1);
5561 ins_pipe( pipe_alu_branch );
5562 %}
5564 instruct cmpN_reg_branch(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
5565 match(If cmp (CmpN op1 op2));
5566 effect(USE labl);
5568 ins_cost(180);
5569 format %{ "CMP $op1,$op2\t! compressed ptr\n\t"
5570 "BP$cmp $labl" %}
5571 ins_encode %{
5572 Register op1_reg = $op1$$Register;
5573 Register op2_reg = $op2$$Register;
5574 Label &L = *($labl$$label);
5575 int flag = $cmp$$cmpcode;
5577 switch(flag)
5578 {
5579 case 0x01: //equal
5580 if (&L)
5581 __ beq(op1_reg, op2_reg, L);
5582 else
5583 __ beq(op1_reg, op2_reg, (int)0);
5584 break;
5585 case 0x02: //not_equal
5586 if (&L)
5587 __ bne(op1_reg, op2_reg, L);
5588 else
5589 __ bne(op1_reg, op2_reg, (int)0);
5590 break;
5591 case 0x03: //above
5592 __ sltu(AT, op2_reg, op1_reg);
5593 if(&L)
5594 __ bne(R0, AT, L);
5595 else
5596 __ bne(R0, AT, (int)0);
5597 break;
5598 case 0x04: //above_equal
5599 __ sltu(AT, op1_reg, op2_reg);
5600 if(&L)
5601 __ beq(AT, R0, L);
5602 else
5603 __ beq(AT, R0, (int)0);
5604 break;
5605 case 0x05: //below
5606 __ sltu(AT, op1_reg, op2_reg);
5607 if(&L)
5608 __ bne(R0, AT, L);
5609 else
5610 __ bne(R0, AT, (int)0);
5611 break;
5612 case 0x06: //below_equal
5613 __ sltu(AT, op2_reg, op1_reg);
5614 if(&L)
5615 __ beq(AT, R0, L);
5616 else
5617 __ beq(AT, R0, (int)0);
5618 break;
5619 default:
5620 Unimplemented();
5621 }
5622 __ nop();
5623 %}
5624 ins_pc_relative(1);
5625 ins_pipe( pipe_alu_branch );
5626 %}
5628 instruct branchConIU_reg_reg(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
5629 match( If cmp (CmpU src1 src2) );
5630 effect(USE labl);
5631 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_reg" %}
5633 ins_encode %{
5634 Register op1 = $src1$$Register;
5635 Register op2 = $src2$$Register;
5636 Label &L = *($labl$$label);
5637 int flag = $cmp$$cmpcode;
5639 switch(flag)
5640 {
5641 case 0x01: //equal
5642 if (&L)
5643 __ beq(op1, op2, L);
5644 else
5645 __ beq(op1, op2, (int)0);
5646 break;
5647 case 0x02: //not_equal
5648 if (&L)
5649 __ bne(op1, op2, L);
5650 else
5651 __ bne(op1, op2, (int)0);
5652 break;
5653 case 0x03: //above
5654 __ sltu(AT, op2, op1);
5655 if(&L)
5656 __ bne(AT, R0, L);
5657 else
5658 __ bne(AT, R0, (int)0);
5659 break;
5660 case 0x04: //above_equal
5661 __ sltu(AT, op1, op2);
5662 if(&L)
5663 __ beq(AT, R0, L);
5664 else
5665 __ beq(AT, R0, (int)0);
5666 break;
5667 case 0x05: //below
5668 __ sltu(AT, op1, op2);
5669 if(&L)
5670 __ bne(AT, R0, L);
5671 else
5672 __ bne(AT, R0, (int)0);
5673 break;
5674 case 0x06: //below_equal
5675 __ sltu(AT, op2, op1);
5676 if(&L)
5677 __ beq(AT, R0, L);
5678 else
5679 __ beq(AT, R0, (int)0);
5680 break;
5681 default:
5682 Unimplemented();
5683 }
5684 __ nop();
5685 %}
5687 ins_pc_relative(1);
5688 ins_pipe( pipe_alu_branch );
5689 %}
5692 instruct branchConIU_reg_imm(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
5693 match( If cmp (CmpU src1 src2) );
5694 effect(USE labl);
5695 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_imm" %}
5697 ins_encode %{
5698 Register op1 = $src1$$Register;
5699 int val = $src2$$constant;
5700 Label &L = *($labl$$label);
5701 int flag = $cmp$$cmpcode;
5703 __ move(AT, val);
5704 switch(flag)
5705 {
5706 case 0x01: //equal
5707 if (&L)
5708 __ beq(op1, AT, L);
5709 else
5710 __ beq(op1, AT, (int)0);
5711 break;
5712 case 0x02: //not_equal
5713 if (&L)
5714 __ bne(op1, AT, L);
5715 else
5716 __ bne(op1, AT, (int)0);
5717 break;
5718 case 0x03: //above
5719 __ sltu(AT, AT, op1);
5720 if(&L)
5721 __ bne(R0, AT, L);
5722 else
5723 __ bne(R0, AT, (int)0);
5724 break;
5725 case 0x04: //above_equal
5726 __ sltu(AT, op1, AT);
5727 if(&L)
5728 __ beq(AT, R0, L);
5729 else
5730 __ beq(AT, R0, (int)0);
5731 break;
5732 case 0x05: //below
5733 __ sltu(AT, op1, AT);
5734 if(&L)
5735 __ bne(R0, AT, L);
5736 else
5737 __ bne(R0, AT, (int)0);
5738 break;
5739 case 0x06: //below_equal
5740 __ sltu(AT, AT, op1);
5741 if(&L)
5742 __ beq(AT, R0, L);
5743 else
5744 __ beq(AT, R0, (int)0);
5745 break;
5746 default:
5747 Unimplemented();
5748 }
5749 __ nop();
5750 %}
5752 ins_pc_relative(1);
5753 ins_pipe( pipe_alu_branch );
5754 %}
5756 instruct branchConI_reg_reg(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
5757 match( If cmp (CmpI src1 src2) );
5758 effect(USE labl);
5759 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_reg" %}
5761 ins_encode %{
5762 Register op1 = $src1$$Register;
5763 Register op2 = $src2$$Register;
5764 Label &L = *($labl$$label);
5765 int flag = $cmp$$cmpcode;
5767 switch(flag)
5768 {
5769 case 0x01: //equal
5770 if (&L)
5771 __ beq(op1, op2, L);
5772 else
5773 __ beq(op1, op2, (int)0);
5774 break;
5775 case 0x02: //not_equal
5776 if (&L)
5777 __ bne(op1, op2, L);
5778 else
5779 __ bne(op1, op2, (int)0);
5780 break;
5781 case 0x03: //above
5782 __ slt(AT, op2, op1);
5783 if(&L)
5784 __ bne(R0, AT, L);
5785 else
5786 __ bne(R0, AT, (int)0);
5787 break;
5788 case 0x04: //above_equal
5789 __ slt(AT, op1, op2);
5790 if(&L)
5791 __ beq(AT, R0, L);
5792 else
5793 __ beq(AT, R0, (int)0);
5794 break;
5795 case 0x05: //below
5796 __ slt(AT, op1, op2);
5797 if(&L)
5798 __ bne(R0, AT, L);
5799 else
5800 __ bne(R0, AT, (int)0);
5801 break;
5802 case 0x06: //below_equal
5803 __ slt(AT, op2, op1);
5804 if(&L)
5805 __ beq(AT, R0, L);
5806 else
5807 __ beq(AT, R0, (int)0);
5808 break;
5809 default:
5810 Unimplemented();
5811 }
5812 __ nop();
5813 %}
5815 ins_pc_relative(1);
5816 ins_pipe( pipe_alu_branch );
5817 %}
5819 instruct branchConI_reg_imm0(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
5820 match( If cmp (CmpI src1 src2) );
5821 effect(USE labl);
5822 ins_cost(170);
5823 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm0" %}
5825 ins_encode %{
5826 Register op1 = $src1$$Register;
5827 // int val = $src2$$constant;
5828 Label &L = *($labl$$label);
5829 int flag = $cmp$$cmpcode;
5831 //__ move(AT, val);
5832 switch(flag)
5833 {
5834 case 0x01: //equal
5835 if (&L)
5836 __ beq(op1, R0, L);
5837 else
5838 __ beq(op1, R0, (int)0);
5839 break;
5840 case 0x02: //not_equal
5841 if (&L)
5842 __ bne(op1, R0, L);
5843 else
5844 __ bne(op1, R0, (int)0);
5845 break;
5846 case 0x03: //greater
5847 if(&L)
5848 __ bgtz(op1, L);
5849 else
5850 __ bgtz(op1, (int)0);
5851 break;
5852 case 0x04: //greater_equal
5853 if(&L)
5854 __ bgez(op1, L);
5855 else
5856 __ bgez(op1, (int)0);
5857 break;
5858 case 0x05: //less
5859 if(&L)
5860 __ bltz(op1, L);
5861 else
5862 __ bltz(op1, (int)0);
5863 break;
5864 case 0x06: //less_equal
5865 if(&L)
5866 __ blez(op1, L);
5867 else
5868 __ blez(op1, (int)0);
5869 break;
5870 default:
5871 Unimplemented();
5872 }
5873 __ nop();
5874 %}
5876 ins_pc_relative(1);
5877 ins_pipe( pipe_alu_branch );
5878 %}
5881 instruct branchConI_reg_imm(cmpOp cmp, mRegI src1, immI src2, label labl) %{
5882 match( If cmp (CmpI src1 src2) );
5883 effect(USE labl);
5884 ins_cost(200);
5885 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm" %}
5887 ins_encode %{
5888 Register op1 = $src1$$Register;
5889 int val = $src2$$constant;
5890 Label &L = *($labl$$label);
5891 int flag = $cmp$$cmpcode;
5893 __ move(AT, val);
5894 switch(flag)
5895 {
5896 case 0x01: //equal
5897 if (&L)
5898 __ beq(op1, AT, L);
5899 else
5900 __ beq(op1, AT, (int)0);
5901 break;
5902 case 0x02: //not_equal
5903 if (&L)
5904 __ bne(op1, AT, L);
5905 else
5906 __ bne(op1, AT, (int)0);
5907 break;
5908 case 0x03: //greater
5909 __ slt(AT, AT, op1);
5910 if(&L)
5911 __ bne(R0, AT, L);
5912 else
5913 __ bne(R0, AT, (int)0);
5914 break;
5915 case 0x04: //greater_equal
5916 __ slt(AT, op1, AT);
5917 if(&L)
5918 __ beq(AT, R0, L);
5919 else
5920 __ beq(AT, R0, (int)0);
5921 break;
5922 case 0x05: //less
5923 __ slt(AT, op1, AT);
5924 if(&L)
5925 __ bne(R0, AT, L);
5926 else
5927 __ bne(R0, AT, (int)0);
5928 break;
5929 case 0x06: //less_equal
5930 __ slt(AT, AT, op1);
5931 if(&L)
5932 __ beq(AT, R0, L);
5933 else
5934 __ beq(AT, R0, (int)0);
5935 break;
5936 default:
5937 Unimplemented();
5938 }
5939 __ nop();
5940 %}
5942 ins_pc_relative(1);
5943 ins_pipe( pipe_alu_branch );
5944 %}
5946 instruct branchConIU_reg_imm0(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
5947 match( If cmp (CmpU src1 zero) );
5948 effect(USE labl);
5949 format %{ "BR$cmp $src1, zero, $labl #@branchConIU_reg_imm0" %}
5951 ins_encode %{
5952 Register op1 = $src1$$Register;
5953 Label &L = *($labl$$label);
5954 int flag = $cmp$$cmpcode;
5956 switch(flag)
5957 {
5958 case 0x01: //equal
5959 if (&L)
5960 __ beq(op1, R0, L);
5961 else
5962 __ beq(op1, R0, (int)0);
5963 break;
5964 case 0x02: //not_equal
5965 if (&L)
5966 __ bne(op1, R0, L);
5967 else
5968 __ bne(op1, R0, (int)0);
5969 break;
5970 case 0x03: //above
5971 if(&L)
5972 __ bne(R0, op1, L);
5973 else
5974 __ bne(R0, op1, (int)0);
5975 break;
5976 case 0x04: //above_equal
5977 if(&L)
5978 __ beq(R0, R0, L);
5979 else
5980 __ beq(R0, R0, (int)0);
5981 break;
5982 case 0x05: //below
5983 return;
5984 break;
5985 case 0x06: //below_equal
5986 if(&L)
5987 __ beq(op1, R0, L);
5988 else
5989 __ beq(op1, R0, (int)0);
5990 break;
5991 default:
5992 Unimplemented();
5993 }
5994 __ nop();
5995 %}
5997 ins_pc_relative(1);
5998 ins_pipe( pipe_alu_branch );
5999 %}
6002 instruct branchConIU_reg_immI16(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
6003 match( If cmp (CmpU src1 src2) );
6004 effect(USE labl);
6005 ins_cost(180);
6006 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_immI16" %}
6008 ins_encode %{
6009 Register op1 = $src1$$Register;
6010 int val = $src2$$constant;
6011 Label &L = *($labl$$label);
6012 int flag = $cmp$$cmpcode;
6014 switch(flag)
6015 {
6016 case 0x01: //equal
6017 __ move(AT, val);
6018 if (&L)
6019 __ beq(op1, AT, L);
6020 else
6021 __ beq(op1, AT, (int)0);
6022 break;
6023 case 0x02: //not_equal
6024 __ move(AT, val);
6025 if (&L)
6026 __ bne(op1, AT, L);
6027 else
6028 __ bne(op1, AT, (int)0);
6029 break;
6030 case 0x03: //above
6031 __ move(AT, val);
6032 __ sltu(AT, AT, op1);
6033 if(&L)
6034 __ bne(R0, AT, L);
6035 else
6036 __ bne(R0, AT, (int)0);
6037 break;
6038 case 0x04: //above_equal
6039 __ sltiu(AT, op1, val);
6040 if(&L)
6041 __ beq(AT, R0, L);
6042 else
6043 __ beq(AT, R0, (int)0);
6044 break;
6045 case 0x05: //below
6046 __ sltiu(AT, op1, val);
6047 if(&L)
6048 __ bne(R0, AT, L);
6049 else
6050 __ bne(R0, AT, (int)0);
6051 break;
6052 case 0x06: //below_equal
6053 __ move(AT, val);
6054 __ sltu(AT, AT, op1);
6055 if(&L)
6056 __ beq(AT, R0, L);
6057 else
6058 __ beq(AT, R0, (int)0);
6059 break;
6060 default:
6061 Unimplemented();
6062 }
6063 __ nop();
6064 %}
6066 ins_pc_relative(1);
6067 ins_pipe( pipe_alu_branch );
6068 %}
6071 instruct branchConL_regL_regL(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
6072 match( If cmp (CmpL src1 src2) );
6073 effect(USE labl);
6074 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_regL" %}
6075 ins_cost(250);
6077 ins_encode %{
6078 Register opr1_reg = as_Register($src1$$reg);
6079 Register opr2_reg = as_Register($src2$$reg);
6081 Label &target = *($labl$$label);
6082 int flag = $cmp$$cmpcode;
6084 switch(flag)
6085 {
6086 case 0x01: //equal
6087 if (&target)
6088 __ beq(opr1_reg, opr2_reg, target);
6089 else
6090 __ beq(opr1_reg, opr2_reg, (int)0);
6091 __ delayed()->nop();
6092 break;
6094 case 0x02: //not_equal
6095 if(&target)
6096 __ bne(opr1_reg, opr2_reg, target);
6097 else
6098 __ bne(opr1_reg, opr2_reg, (int)0);
6099 __ delayed()->nop();
6100 break;
6102 case 0x03: //greater
6103 __ slt(AT, opr2_reg, opr1_reg);
6104 if(&target)
6105 __ bne(AT, R0, target);
6106 else
6107 __ bne(AT, R0, (int)0);
6108 __ delayed()->nop();
6109 break;
6111 case 0x04: //greater_equal
6112 __ slt(AT, opr1_reg, opr2_reg);
6113 if(&target)
6114 __ beq(AT, R0, target);
6115 else
6116 __ beq(AT, R0, (int)0);
6117 __ delayed()->nop();
6119 break;
6121 case 0x05: //less
6122 __ slt(AT, opr1_reg, opr2_reg);
6123 if(&target)
6124 __ bne(AT, R0, target);
6125 else
6126 __ bne(AT, R0, (int)0);
6127 __ delayed()->nop();
6129 break;
6131 case 0x06: //less_equal
6132 __ slt(AT, opr2_reg, opr1_reg);
6134 if(&target)
6135 __ beq(AT, R0, target);
6136 else
6137 __ beq(AT, R0, (int)0);
6138 __ delayed()->nop();
6140 break;
6142 default:
6143 Unimplemented();
6144 }
6145 %}
6148 ins_pc_relative(1);
6149 ins_pipe( pipe_alu_branch );
6150 %}
6152 instruct branchConL_reg_immL16_sub(cmpOp cmp, mRegL src1, immL16_sub src2, label labl) %{
6153 match( If cmp (CmpL src1 src2) );
6154 effect(USE labl);
6155 ins_cost(180);
6156 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_reg_immL16_sub" %}
6158 ins_encode %{
6159 Register op1 = $src1$$Register;
6160 int val = $src2$$constant;
6161 Label &L = *($labl$$label);
6162 int flag = $cmp$$cmpcode;
6164 __ daddiu(AT, op1, -1 * val);
6165 switch(flag)
6166 {
6167 case 0x01: //equal
6168 if (&L)
6169 __ beq(R0, AT, L);
6170 else
6171 __ beq(R0, AT, (int)0);
6172 break;
6173 case 0x02: //not_equal
6174 if (&L)
6175 __ bne(R0, AT, L);
6176 else
6177 __ bne(R0, AT, (int)0);
6178 break;
6179 case 0x03: //greater
6180 if(&L)
6181 __ bgtz(AT, L);
6182 else
6183 __ bgtz(AT, (int)0);
6184 break;
6185 case 0x04: //greater_equal
6186 if(&L)
6187 __ bgez(AT, L);
6188 else
6189 __ bgez(AT, (int)0);
6190 break;
6191 case 0x05: //less
6192 if(&L)
6193 __ bltz(AT, L);
6194 else
6195 __ bltz(AT, (int)0);
6196 break;
6197 case 0x06: //less_equal
6198 if(&L)
6199 __ blez(AT, L);
6200 else
6201 __ blez(AT, (int)0);
6202 break;
6203 default:
6204 Unimplemented();
6205 }
6206 __ nop();
6207 %}
6209 ins_pc_relative(1);
6210 ins_pipe( pipe_alu_branch );
6211 %}
6214 instruct branchConI_reg_imm16_sub(cmpOp cmp, mRegI src1, immI16_sub src2, label labl) %{
6215 match( If cmp (CmpI src1 src2) );
6216 effect(USE labl);
6217 ins_cost(180);
6218 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm16_sub" %}
6220 ins_encode %{
6221 Register op1 = $src1$$Register;
6222 int val = $src2$$constant;
6223 Label &L = *($labl$$label);
6224 int flag = $cmp$$cmpcode;
6226 __ addiu32(AT, op1, -1 * val);
6227 switch(flag)
6228 {
6229 case 0x01: //equal
6230 if (&L)
6231 __ beq(R0, AT, L);
6232 else
6233 __ beq(R0, AT, (int)0);
6234 break;
6235 case 0x02: //not_equal
6236 if (&L)
6237 __ bne(R0, AT, L);
6238 else
6239 __ bne(R0, AT, (int)0);
6240 break;
6241 case 0x03: //greater
6242 if(&L)
6243 __ bgtz(AT, L);
6244 else
6245 __ bgtz(AT, (int)0);
6246 break;
6247 case 0x04: //greater_equal
6248 if(&L)
6249 __ bgez(AT, L);
6250 else
6251 __ bgez(AT, (int)0);
6252 break;
6253 case 0x05: //less
6254 if(&L)
6255 __ bltz(AT, L);
6256 else
6257 __ bltz(AT, (int)0);
6258 break;
6259 case 0x06: //less_equal
6260 if(&L)
6261 __ blez(AT, L);
6262 else
6263 __ blez(AT, (int)0);
6264 break;
6265 default:
6266 Unimplemented();
6267 }
6268 __ nop();
6269 %}
6271 ins_pc_relative(1);
6272 ins_pipe( pipe_alu_branch );
6273 %}
6275 instruct branchConL_regL_immL0(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
6276 match( If cmp (CmpL src1 zero) );
6277 effect(USE labl);
6278 format %{ "BR$cmp $src1, zero, $labl #@branchConL_regL_immL0" %}
6279 ins_cost(150);
6281 ins_encode %{
6282 Register opr1_reg = as_Register($src1$$reg);
6283 Label &target = *($labl$$label);
6284 int flag = $cmp$$cmpcode;
6286 switch(flag)
6287 {
6288 case 0x01: //equal
6289 if (&target)
6290 __ beq(opr1_reg, R0, target);
6291 else
6292 __ beq(opr1_reg, R0, int(0));
6293 break;
6295 case 0x02: //not_equal
6296 if(&target)
6297 __ bne(opr1_reg, R0, target);
6298 else
6299 __ bne(opr1_reg, R0, (int)0);
6300 break;
6302 case 0x03: //greater
6303 if(&target)
6304 __ bgtz(opr1_reg, target);
6305 else
6306 __ bgtz(opr1_reg, (int)0);
6307 break;
6309 case 0x04: //greater_equal
6310 if(&target)
6311 __ bgez(opr1_reg, target);
6312 else
6313 __ bgez(opr1_reg, (int)0);
6314 break;
6316 case 0x05: //less
6317 __ slt(AT, opr1_reg, R0);
6318 if(&target)
6319 __ bne(AT, R0, target);
6320 else
6321 __ bne(AT, R0, (int)0);
6322 break;
6324 case 0x06: //less_equal
6325 if (&target)
6326 __ blez(opr1_reg, target);
6327 else
6328 __ blez(opr1_reg, int(0));
6329 break;
6331 default:
6332 Unimplemented();
6333 }
6334 __ delayed()->nop();
6335 %}
6338 ins_pc_relative(1);
6339 ins_pipe( pipe_alu_branch );
6340 %}
6343 //FIXME
6344 instruct branchConF_reg_reg(cmpOp cmp, regF src1, regF src2, label labl) %{
6345 match( If cmp (CmpF src1 src2) );
6346 effect(USE labl);
6347 format %{ "BR$cmp $src1, $src2, $labl #@branchConF_reg_reg" %}
6349 ins_encode %{
6350 FloatRegister reg_op1 = $src1$$FloatRegister;
6351 FloatRegister reg_op2 = $src2$$FloatRegister;
6352 Label &L = *($labl$$label);
6353 int flag = $cmp$$cmpcode;
6355 switch(flag)
6356 {
6357 case 0x01: //equal
6358 __ c_eq_s(reg_op1, reg_op2);
6359 if (&L)
6360 __ bc1t(L);
6361 else
6362 __ bc1t((int)0);
6363 break;
6364 case 0x02: //not_equal
6365 __ c_eq_s(reg_op1, reg_op2);
6366 if (&L)
6367 __ bc1f(L);
6368 else
6369 __ bc1f((int)0);
6370 break;
6371 case 0x03: //greater
6372 __ c_ule_s(reg_op1, reg_op2);
6373 if(&L)
6374 __ bc1f(L);
6375 else
6376 __ bc1f((int)0);
6377 break;
6378 case 0x04: //greater_equal
6379 __ c_ult_s(reg_op1, reg_op2);
6380 if(&L)
6381 __ bc1f(L);
6382 else
6383 __ bc1f((int)0);
6384 break;
6385 case 0x05: //less
6386 __ c_ult_s(reg_op1, reg_op2);
6387 if(&L)
6388 __ bc1t(L);
6389 else
6390 __ bc1t((int)0);
6391 break;
6392 case 0x06: //less_equal
6393 __ c_ule_s(reg_op1, reg_op2);
6394 if(&L)
6395 __ bc1t(L);
6396 else
6397 __ bc1t((int)0);
6398 break;
6399 default:
6400 Unimplemented();
6401 }
6402 __ nop();
6403 %}
6405 ins_pc_relative(1);
6406 ins_pipe(pipe_slow);
6407 %}
6409 instruct branchConD_reg_reg(cmpOp cmp, regD src1, regD src2, label labl) %{
6410 match( If cmp (CmpD src1 src2) );
6411 effect(USE labl);
6412 format %{ "BR$cmp $src1, $src2, $labl #@branchConD_reg_reg" %}
6414 ins_encode %{
6415 FloatRegister reg_op1 = $src1$$FloatRegister;
6416 FloatRegister reg_op2 = $src2$$FloatRegister;
6417 Label &L = *($labl$$label);
6418 int flag = $cmp$$cmpcode;
6420 switch(flag)
6421 {
6422 case 0x01: //equal
6423 __ c_eq_d(reg_op1, reg_op2);
6424 if (&L)
6425 __ bc1t(L);
6426 else
6427 __ bc1t((int)0);
6428 break;
6429 case 0x02: //not_equal
6430 //2016/4/19 aoqi: 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.
6431 __ c_eq_d(reg_op1, reg_op2);
6432 if (&L)
6433 __ bc1f(L);
6434 else
6435 __ bc1f((int)0);
6436 break;
6437 case 0x03: //greater
6438 __ c_ule_d(reg_op1, reg_op2);
6439 if(&L)
6440 __ bc1f(L);
6441 else
6442 __ bc1f((int)0);
6443 break;
6444 case 0x04: //greater_equal
6445 __ c_ult_d(reg_op1, reg_op2);
6446 if(&L)
6447 __ bc1f(L);
6448 else
6449 __ bc1f((int)0);
6450 break;
6451 case 0x05: //less
6452 __ c_ult_d(reg_op1, reg_op2);
6453 if(&L)
6454 __ bc1t(L);
6455 else
6456 __ bc1t((int)0);
6457 break;
6458 case 0x06: //less_equal
6459 __ c_ule_d(reg_op1, reg_op2);
6460 if(&L)
6461 __ bc1t(L);
6462 else
6463 __ bc1t((int)0);
6464 break;
6465 default:
6466 Unimplemented();
6467 }
6468 __ nop();
6469 %}
6471 ins_pc_relative(1);
6472 ins_pipe(pipe_slow);
6473 %}
6476 // Call Runtime Instruction
6477 instruct CallRuntimeDirect(method meth) %{
6478 match(CallRuntime );
6479 effect(USE meth);
6481 ins_cost(300);
6482 format %{ "CALL,runtime #@CallRuntimeDirect" %}
6483 ins_encode( Java_To_Runtime( meth ) );
6484 ins_pipe( pipe_slow );
6485 ins_alignment(16);
6486 %}
6490 //------------------------MemBar Instructions-------------------------------
6491 //Memory barrier flavors
6493 instruct membar_acquire() %{
6494 match(MemBarAcquire);
6495 ins_cost(0);
6497 size(0);
6498 format %{ "MEMBAR-acquire (empty) @ membar_acquire" %}
6499 ins_encode();
6500 ins_pipe(empty);
6501 %}
6503 instruct load_fence() %{
6504 match(LoadFence);
6505 ins_cost(400);
6507 format %{ "MEMBAR @ load_fence" %}
6508 ins_encode %{
6509 __ sync();
6510 %}
6511 ins_pipe(pipe_slow);
6512 %}
6514 instruct membar_acquire_lock()
6515 %{
6516 match(MemBarAcquireLock);
6517 ins_cost(0);
6519 size(0);
6520 format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
6521 ins_encode();
6522 ins_pipe(empty);
6523 %}
6525 instruct membar_release() %{
6526 match(MemBarRelease);
6527 ins_cost(0);
6529 size(0);
6530 format %{ "MEMBAR-release (empty) @ membar_release" %}
6531 ins_encode();
6532 ins_pipe(empty);
6533 %}
6535 instruct store_fence() %{
6536 match(StoreFence);
6537 ins_cost(400);
6539 format %{ "MEMBAR @ store_fence" %}
6541 ins_encode %{
6542 __ sync();
6543 %}
6545 ins_pipe(pipe_slow);
6546 %}
6548 instruct membar_release_lock()
6549 %{
6550 match(MemBarReleaseLock);
6551 ins_cost(0);
6553 size(0);
6554 format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
6555 ins_encode();
6556 ins_pipe(empty);
6557 %}
6560 instruct membar_volatile() %{
6561 match(MemBarVolatile);
6562 ins_cost(400);
6564 format %{ "MEMBAR-volatile" %}
6565 ins_encode %{
6566 if( !os::is_MP() ) return; // Not needed on single CPU
6567 __ sync();
6569 %}
6570 ins_pipe(pipe_slow);
6571 %}
6573 instruct unnecessary_membar_volatile() %{
6574 match(MemBarVolatile);
6575 predicate(Matcher::post_store_load_barrier(n));
6576 ins_cost(0);
6578 size(0);
6579 format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
6580 ins_encode( );
6581 ins_pipe(empty);
6582 %}
6584 instruct membar_storestore() %{
6585 match(MemBarStoreStore);
6587 ins_cost(0);
6588 size(0);
6589 format %{ "MEMBAR-storestore (empty encoding) @ membar_storestore" %}
6590 ins_encode( );
6591 ins_pipe(empty);
6592 %}
6594 //----------Move Instructions--------------------------------------------------
6595 instruct castX2P(mRegP dst, mRegL src) %{
6596 match(Set dst (CastX2P src));
6597 format %{ "castX2P $dst, $src @ castX2P" %}
6598 ins_encode %{
6599 Register src = $src$$Register;
6600 Register dst = $dst$$Register;
6602 if(src != dst)
6603 __ move(dst, src);
6604 %}
6605 ins_cost(10);
6606 ins_pipe( ialu_regI_mov );
6607 %}
6609 instruct castP2X(mRegL dst, mRegP src ) %{
6610 match(Set dst (CastP2X src));
6612 format %{ "mov $dst, $src\t #@castP2X" %}
6613 ins_encode %{
6614 Register src = $src$$Register;
6615 Register dst = $dst$$Register;
6617 if(src != dst)
6618 __ move(dst, src);
6619 %}
6620 ins_pipe( ialu_regI_mov );
6621 %}
6623 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
6624 match(Set dst (MoveF2I src));
6625 effect(DEF dst, USE src);
6626 ins_cost(85);
6627 format %{ "MoveF2I $dst, $src @ MoveF2I_reg_reg" %}
6628 ins_encode %{
6629 Register dst = as_Register($dst$$reg);
6630 FloatRegister src = as_FloatRegister($src$$reg);
6632 __ mfc1(dst, src);
6633 %}
6634 ins_pipe( pipe_slow );
6635 %}
6637 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
6638 match(Set dst (MoveI2F src));
6639 effect(DEF dst, USE src);
6640 ins_cost(85);
6641 format %{ "MoveI2F $dst, $src @ MoveI2F_reg_reg" %}
6642 ins_encode %{
6643 Register src = as_Register($src$$reg);
6644 FloatRegister dst = as_FloatRegister($dst$$reg);
6646 __ mtc1(src, dst);
6647 %}
6648 ins_pipe( pipe_slow );
6649 %}
6651 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
6652 match(Set dst (MoveD2L src));
6653 effect(DEF dst, USE src);
6654 ins_cost(85);
6655 format %{ "MoveD2L $dst, $src @ MoveD2L_reg_reg" %}
6656 ins_encode %{
6657 Register dst = as_Register($dst$$reg);
6658 FloatRegister src = as_FloatRegister($src$$reg);
6660 __ dmfc1(dst, src);
6661 %}
6662 ins_pipe( pipe_slow );
6663 %}
6665 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
6666 match(Set dst (MoveL2D src));
6667 effect(DEF dst, USE src);
6668 ins_cost(85);
6669 format %{ "MoveL2D $dst, $src @ MoveL2D_reg_reg" %}
6670 ins_encode %{
6671 FloatRegister dst = as_FloatRegister($dst$$reg);
6672 Register src = as_Register($src$$reg);
6674 __ dmtc1(src, dst);
6675 %}
6676 ins_pipe( pipe_slow );
6677 %}
6679 //----------Conditional Move---------------------------------------------------
6680 // Conditional move
6681 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
6682 match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
6683 ins_cost(80);
6684 format %{
6685 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpI_reg_reg\n"
6686 "\tCMOV $dst,$src \t @cmovI_cmpI_reg_reg"
6687 %}
6689 ins_encode %{
6690 Register op1 = $tmp1$$Register;
6691 Register op2 = $tmp2$$Register;
6692 Register dst = $dst$$Register;
6693 Register src = $src$$Register;
6694 int flag = $cop$$cmpcode;
6696 switch(flag)
6697 {
6698 case 0x01: //equal
6699 __ subu32(AT, op1, op2);
6700 __ movz(dst, src, AT);
6701 break;
6703 case 0x02: //not_equal
6704 __ subu32(AT, op1, op2);
6705 __ movn(dst, src, AT);
6706 break;
6708 case 0x03: //great
6709 __ slt(AT, op2, op1);
6710 __ movn(dst, src, AT);
6711 break;
6713 case 0x04: //great_equal
6714 __ slt(AT, op1, op2);
6715 __ movz(dst, src, AT);
6716 break;
6718 case 0x05: //less
6719 __ slt(AT, op1, op2);
6720 __ movn(dst, src, AT);
6721 break;
6723 case 0x06: //less_equal
6724 __ slt(AT, op2, op1);
6725 __ movz(dst, src, AT);
6726 break;
6728 default:
6729 Unimplemented();
6730 }
6731 %}
6733 ins_pipe( pipe_slow );
6734 %}
6736 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
6737 match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
6738 ins_cost(80);
6739 format %{
6740 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
6741 "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
6742 %}
6743 ins_encode %{
6744 Register op1 = $tmp1$$Register;
6745 Register op2 = $tmp2$$Register;
6746 Register dst = $dst$$Register;
6747 Register src = $src$$Register;
6748 int flag = $cop$$cmpcode;
6750 switch(flag)
6751 {
6752 case 0x01: //equal
6753 __ subu(AT, op1, op2);
6754 __ movz(dst, src, AT);
6755 break;
6757 case 0x02: //not_equal
6758 __ subu(AT, op1, op2);
6759 __ movn(dst, src, AT);
6760 break;
6762 case 0x03: //above
6763 __ sltu(AT, op2, op1);
6764 __ movn(dst, src, AT);
6765 break;
6767 case 0x04: //above_equal
6768 __ sltu(AT, op1, op2);
6769 __ movz(dst, src, AT);
6770 break;
6772 case 0x05: //below
6773 __ sltu(AT, op1, op2);
6774 __ movn(dst, src, AT);
6775 break;
6777 case 0x06: //below_equal
6778 __ sltu(AT, op2, op1);
6779 __ movz(dst, src, AT);
6780 break;
6782 default:
6783 Unimplemented();
6784 }
6785 %}
6787 ins_pipe( pipe_slow );
6788 %}
6790 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
6791 match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
6792 ins_cost(80);
6793 format %{
6794 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
6795 "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
6796 %}
6797 ins_encode %{
6798 Register op1 = $tmp1$$Register;
6799 Register op2 = $tmp2$$Register;
6800 Register dst = $dst$$Register;
6801 Register src = $src$$Register;
6802 int flag = $cop$$cmpcode;
6804 switch(flag)
6805 {
6806 case 0x01: //equal
6807 __ subu32(AT, op1, op2);
6808 __ movz(dst, src, AT);
6809 break;
6811 case 0x02: //not_equal
6812 __ subu32(AT, op1, op2);
6813 __ movn(dst, src, AT);
6814 break;
6816 case 0x03: //above
6817 __ sltu(AT, op2, op1);
6818 __ movn(dst, src, AT);
6819 break;
6821 case 0x04: //above_equal
6822 __ sltu(AT, op1, op2);
6823 __ movz(dst, src, AT);
6824 break;
6826 case 0x05: //below
6827 __ sltu(AT, op1, op2);
6828 __ movn(dst, src, AT);
6829 break;
6831 case 0x06: //below_equal
6832 __ sltu(AT, op2, op1);
6833 __ movz(dst, src, AT);
6834 break;
6836 default:
6837 Unimplemented();
6838 }
6839 %}
6841 ins_pipe( pipe_slow );
6842 %}
6844 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
6845 match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
6846 ins_cost(80);
6847 format %{
6848 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
6849 "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
6850 %}
6851 ins_encode %{
6852 Register op1 = $tmp1$$Register;
6853 Register op2 = $tmp2$$Register;
6854 Register dst = $dst$$Register;
6855 Register src = $src$$Register;
6856 int flag = $cop$$cmpcode;
6858 switch(flag)
6859 {
6860 case 0x01: //equal
6861 __ subu32(AT, op1, op2);
6862 __ movz(dst, src, AT);
6863 break;
6865 case 0x02: //not_equal
6866 __ subu32(AT, op1, op2);
6867 __ movn(dst, src, AT);
6868 break;
6870 case 0x03: //above
6871 __ sltu(AT, op2, op1);
6872 __ movn(dst, src, AT);
6873 break;
6875 case 0x04: //above_equal
6876 __ sltu(AT, op1, op2);
6877 __ movz(dst, src, AT);
6878 break;
6880 case 0x05: //below
6881 __ sltu(AT, op1, op2);
6882 __ movn(dst, src, AT);
6883 break;
6885 case 0x06: //below_equal
6886 __ sltu(AT, op2, op1);
6887 __ movz(dst, src, AT);
6888 break;
6890 default:
6891 Unimplemented();
6892 }
6893 %}
6895 ins_pipe( pipe_slow );
6896 %}
6898 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
6899 match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
6900 ins_cost(80);
6901 format %{
6902 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
6903 "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
6904 %}
6905 ins_encode %{
6906 Register op1 = $tmp1$$Register;
6907 Register op2 = $tmp2$$Register;
6908 Register dst = $dst$$Register;
6909 Register src = $src$$Register;
6910 int flag = $cop$$cmpcode;
6912 switch(flag)
6913 {
6914 case 0x01: //equal
6915 __ subu(AT, op1, op2);
6916 __ movz(dst, src, AT);
6917 break;
6919 case 0x02: //not_equal
6920 __ subu(AT, op1, op2);
6921 __ movn(dst, src, AT);
6922 break;
6924 case 0x03: //above
6925 __ sltu(AT, op2, op1);
6926 __ movn(dst, src, AT);
6927 break;
6929 case 0x04: //above_equal
6930 __ sltu(AT, op1, op2);
6931 __ movz(dst, src, AT);
6932 break;
6934 case 0x05: //below
6935 __ sltu(AT, op1, op2);
6936 __ movn(dst, src, AT);
6937 break;
6939 case 0x06: //below_equal
6940 __ sltu(AT, op2, op1);
6941 __ movz(dst, src, AT);
6942 break;
6944 default:
6945 Unimplemented();
6946 }
6947 %}
6949 ins_pipe( pipe_slow );
6950 %}
6952 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
6953 match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
6954 ins_cost(80);
6955 format %{
6956 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpD_reg_reg\n"
6957 "\tCMOV $dst,$src \t @cmovP_cmpD_reg_reg"
6958 %}
6959 ins_encode %{
6960 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
6961 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
6962 Register dst = as_Register($dst$$reg);
6963 Register src = as_Register($src$$reg);
6965 int flag = $cop$$cmpcode;
6967 switch(flag)
6968 {
6969 case 0x01: //equal
6970 __ c_eq_d(reg_op1, reg_op2);
6971 __ movt(dst, src);
6972 break;
6973 case 0x02: //not_equal
6974 __ c_eq_d(reg_op1, reg_op2);
6975 __ movf(dst, src);
6976 break;
6977 case 0x03: //greater
6978 __ c_ole_d(reg_op1, reg_op2);
6979 __ movf(dst, src);
6980 break;
6981 case 0x04: //greater_equal
6982 __ c_olt_d(reg_op1, reg_op2);
6983 __ movf(dst, src);
6984 break;
6985 case 0x05: //less
6986 __ c_ult_d(reg_op1, reg_op2);
6987 __ movt(dst, src);
6988 break;
6989 case 0x06: //less_equal
6990 __ c_ule_d(reg_op1, reg_op2);
6991 __ movt(dst, src);
6992 break;
6993 default:
6994 Unimplemented();
6995 }
6996 %}
6998 ins_pipe( pipe_slow );
6999 %}
7002 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
7003 match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
7004 ins_cost(80);
7005 format %{
7006 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
7007 "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
7008 %}
7009 ins_encode %{
7010 Register op1 = $tmp1$$Register;
7011 Register op2 = $tmp2$$Register;
7012 Register dst = $dst$$Register;
7013 Register src = $src$$Register;
7014 int flag = $cop$$cmpcode;
7016 switch(flag)
7017 {
7018 case 0x01: //equal
7019 __ subu32(AT, op1, op2);
7020 __ movz(dst, src, AT);
7021 break;
7023 case 0x02: //not_equal
7024 __ subu32(AT, op1, op2);
7025 __ movn(dst, src, AT);
7026 break;
7028 case 0x03: //above
7029 __ sltu(AT, op2, op1);
7030 __ movn(dst, src, AT);
7031 break;
7033 case 0x04: //above_equal
7034 __ sltu(AT, op1, op2);
7035 __ movz(dst, src, AT);
7036 break;
7038 case 0x05: //below
7039 __ sltu(AT, op1, op2);
7040 __ movn(dst, src, AT);
7041 break;
7043 case 0x06: //below_equal
7044 __ sltu(AT, op2, op1);
7045 __ movz(dst, src, AT);
7046 break;
7048 default:
7049 Unimplemented();
7050 }
7051 %}
7053 ins_pipe( pipe_slow );
7054 %}
7057 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
7058 match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
7059 ins_cost(80);
7060 format %{
7061 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
7062 "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
7063 %}
7064 ins_encode %{
7065 Register op1 = $tmp1$$Register;
7066 Register op2 = $tmp2$$Register;
7067 Register dst = $dst$$Register;
7068 Register src = $src$$Register;
7069 int flag = $cop$$cmpcode;
7071 switch(flag)
7072 {
7073 case 0x01: //equal
7074 __ subu(AT, op1, op2);
7075 __ movz(dst, src, AT);
7076 break;
7078 case 0x02: //not_equal
7079 __ subu(AT, op1, op2);
7080 __ movn(dst, src, AT);
7081 break;
7083 case 0x03: //above
7084 __ sltu(AT, op2, op1);
7085 __ movn(dst, src, AT);
7086 break;
7088 case 0x04: //above_equal
7089 __ sltu(AT, op1, op2);
7090 __ movz(dst, src, AT);
7091 break;
7093 case 0x05: //below
7094 __ sltu(AT, op1, op2);
7095 __ movn(dst, src, AT);
7096 break;
7098 case 0x06: //below_equal
7099 __ sltu(AT, op2, op1);
7100 __ movz(dst, src, AT);
7101 break;
7103 default:
7104 Unimplemented();
7105 }
7106 %}
7108 ins_pipe( pipe_slow );
7109 %}
7111 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
7112 match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
7113 ins_cost(80);
7114 format %{
7115 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpL_reg_reg\n"
7116 "\tCMOV $dst,$src \t @cmovI_cmpL_reg_reg"
7117 %}
7118 ins_encode %{
7119 Register opr1 = as_Register($tmp1$$reg);
7120 Register opr2 = as_Register($tmp2$$reg);
7121 Register dst = $dst$$Register;
7122 Register src = $src$$Register;
7123 int flag = $cop$$cmpcode;
7125 switch(flag)
7126 {
7127 case 0x01: //equal
7128 __ subu(AT, opr1, opr2);
7129 __ movz(dst, src, AT);
7130 break;
7132 case 0x02: //not_equal
7133 __ subu(AT, opr1, opr2);
7134 __ movn(dst, src, AT);
7135 break;
7137 case 0x03: //greater
7138 __ slt(AT, opr2, opr1);
7139 __ movn(dst, src, AT);
7140 break;
7142 case 0x04: //greater_equal
7143 __ slt(AT, opr1, opr2);
7144 __ movz(dst, src, AT);
7145 break;
7147 case 0x05: //less
7148 __ slt(AT, opr1, opr2);
7149 __ movn(dst, src, AT);
7150 break;
7152 case 0x06: //less_equal
7153 __ slt(AT, opr2, opr1);
7154 __ movz(dst, src, AT);
7155 break;
7157 default:
7158 Unimplemented();
7159 }
7160 %}
7162 ins_pipe( pipe_slow );
7163 %}
7165 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
7166 match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
7167 ins_cost(80);
7168 format %{
7169 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpL_reg_reg\n"
7170 "\tCMOV $dst,$src \t @cmovP_cmpL_reg_reg"
7171 %}
7172 ins_encode %{
7173 Register opr1 = as_Register($tmp1$$reg);
7174 Register opr2 = as_Register($tmp2$$reg);
7175 Register dst = $dst$$Register;
7176 Register src = $src$$Register;
7177 int flag = $cop$$cmpcode;
7179 switch(flag)
7180 {
7181 case 0x01: //equal
7182 __ subu(AT, opr1, opr2);
7183 __ movz(dst, src, AT);
7184 break;
7186 case 0x02: //not_equal
7187 __ subu(AT, opr1, opr2);
7188 __ movn(dst, src, AT);
7189 break;
7191 case 0x03: //greater
7192 __ slt(AT, opr2, opr1);
7193 __ movn(dst, src, AT);
7194 break;
7196 case 0x04: //greater_equal
7197 __ slt(AT, opr1, opr2);
7198 __ movz(dst, src, AT);
7199 break;
7201 case 0x05: //less
7202 __ slt(AT, opr1, opr2);
7203 __ movn(dst, src, AT);
7204 break;
7206 case 0x06: //less_equal
7207 __ slt(AT, opr2, opr1);
7208 __ movz(dst, src, AT);
7209 break;
7211 default:
7212 Unimplemented();
7213 }
7214 %}
7216 ins_pipe( pipe_slow );
7217 %}
7219 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
7220 match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
7221 ins_cost(80);
7222 format %{
7223 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpD_reg_reg\n"
7224 "\tCMOV $dst,$src \t @cmovI_cmpD_reg_reg"
7225 %}
7226 ins_encode %{
7227 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
7228 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
7229 Register dst = as_Register($dst$$reg);
7230 Register src = as_Register($src$$reg);
7232 int flag = $cop$$cmpcode;
7234 switch(flag)
7235 {
7236 case 0x01: //equal
7237 __ c_eq_d(reg_op1, reg_op2);
7238 __ movt(dst, src);
7239 break;
7240 case 0x02: //not_equal
7241 //2016/4/19 aoqi: See instruct branchConD_reg_reg. The change in branchConD_reg_reg fixed a bug. It seems similar here, so I made thesame change.
7242 __ c_eq_d(reg_op1, reg_op2);
7243 __ movf(dst, src);
7244 break;
7245 case 0x03: //greater
7246 __ c_ole_d(reg_op1, reg_op2);
7247 __ movf(dst, src);
7248 break;
7249 case 0x04: //greater_equal
7250 __ c_olt_d(reg_op1, reg_op2);
7251 __ movf(dst, src);
7252 break;
7253 case 0x05: //less
7254 __ c_ult_d(reg_op1, reg_op2);
7255 __ movt(dst, src);
7256 break;
7257 case 0x06: //less_equal
7258 __ c_ule_d(reg_op1, reg_op2);
7259 __ movt(dst, src);
7260 break;
7261 default:
7262 Unimplemented();
7263 }
7264 %}
7266 ins_pipe( pipe_slow );
7267 %}
7270 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
7271 match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
7272 ins_cost(80);
7273 format %{
7274 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
7275 "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
7276 %}
7277 ins_encode %{
7278 Register op1 = $tmp1$$Register;
7279 Register op2 = $tmp2$$Register;
7280 Register dst = $dst$$Register;
7281 Register src = $src$$Register;
7282 int flag = $cop$$cmpcode;
7284 switch(flag)
7285 {
7286 case 0x01: //equal
7287 __ subu(AT, op1, op2);
7288 __ movz(dst, src, AT);
7289 break;
7291 case 0x02: //not_equal
7292 __ subu(AT, op1, op2);
7293 __ movn(dst, src, AT);
7294 break;
7296 case 0x03: //above
7297 __ sltu(AT, op2, op1);
7298 __ movn(dst, src, AT);
7299 break;
7301 case 0x04: //above_equal
7302 __ sltu(AT, op1, op2);
7303 __ movz(dst, src, AT);
7304 break;
7306 case 0x05: //below
7307 __ sltu(AT, op1, op2);
7308 __ movn(dst, src, AT);
7309 break;
7311 case 0x06: //below_equal
7312 __ sltu(AT, op2, op1);
7313 __ movz(dst, src, AT);
7314 break;
7316 default:
7317 Unimplemented();
7318 }
7319 %}
7321 ins_pipe( pipe_slow );
7322 %}
7324 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7325 match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7326 ins_cost(80);
7327 format %{
7328 "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
7329 "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
7330 %}
7331 ins_encode %{
7332 Register op1 = $tmp1$$Register;
7333 Register op2 = $tmp2$$Register;
7334 Register dst = $dst$$Register;
7335 Register src = $src$$Register;
7336 int flag = $cop$$cmpcode;
7338 switch(flag)
7339 {
7340 case 0x01: //equal
7341 __ subu32(AT, op1, op2);
7342 __ movz(dst, src, AT);
7343 break;
7345 case 0x02: //not_equal
7346 __ subu32(AT, op1, op2);
7347 __ movn(dst, src, AT);
7348 break;
7350 case 0x03: //above
7351 __ slt(AT, op2, op1);
7352 __ movn(dst, src, AT);
7353 break;
7355 case 0x04: //above_equal
7356 __ slt(AT, op1, op2);
7357 __ movz(dst, src, AT);
7358 break;
7360 case 0x05: //below
7361 __ slt(AT, op1, op2);
7362 __ movn(dst, src, AT);
7363 break;
7365 case 0x06: //below_equal
7366 __ slt(AT, op2, op1);
7367 __ movz(dst, src, AT);
7368 break;
7370 default:
7371 Unimplemented();
7372 }
7373 %}
7375 ins_pipe( pipe_slow );
7376 %}
7378 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7379 match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7380 ins_cost(80);
7381 format %{
7382 "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
7383 "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
7384 %}
7385 ins_encode %{
7386 Register op1 = $tmp1$$Register;
7387 Register op2 = $tmp2$$Register;
7388 Register dst = $dst$$Register;
7389 Register src = $src$$Register;
7390 int flag = $cop$$cmpcode;
7392 switch(flag)
7393 {
7394 case 0x01: //equal
7395 __ subu32(AT, op1, op2);
7396 __ movz(dst, src, AT);
7397 break;
7399 case 0x02: //not_equal
7400 __ subu32(AT, op1, op2);
7401 __ movn(dst, src, AT);
7402 break;
7404 case 0x03: //above
7405 __ slt(AT, op2, op1);
7406 __ movn(dst, src, AT);
7407 break;
7409 case 0x04: //above_equal
7410 __ slt(AT, op1, op2);
7411 __ movz(dst, src, AT);
7412 break;
7414 case 0x05: //below
7415 __ slt(AT, op1, op2);
7416 __ movn(dst, src, AT);
7417 break;
7419 case 0x06: //below_equal
7420 __ slt(AT, op2, op1);
7421 __ movz(dst, src, AT);
7422 break;
7424 default:
7425 Unimplemented();
7426 }
7427 %}
7429 ins_pipe( pipe_slow );
7430 %}
7433 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7434 match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7435 ins_cost(80);
7436 format %{
7437 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpI_reg_reg\n"
7438 "\tCMOV $dst,$src \t @cmovL_cmpI_reg_reg"
7439 %}
7441 ins_encode %{
7442 Register op1 = $tmp1$$Register;
7443 Register op2 = $tmp2$$Register;
7444 Register dst = as_Register($dst$$reg);
7445 Register src = as_Register($src$$reg);
7446 int flag = $cop$$cmpcode;
7448 switch(flag)
7449 {
7450 case 0x01: //equal
7451 __ subu32(AT, op1, op2);
7452 __ movz(dst, src, AT);
7453 break;
7455 case 0x02: //not_equal
7456 __ subu32(AT, op1, op2);
7457 __ movn(dst, src, AT);
7458 break;
7460 case 0x03: //great
7461 __ slt(AT, op2, op1);
7462 __ movn(dst, src, AT);
7463 break;
7465 case 0x04: //great_equal
7466 __ slt(AT, op1, op2);
7467 __ movz(dst, src, AT);
7468 break;
7470 case 0x05: //less
7471 __ slt(AT, op1, op2);
7472 __ movn(dst, src, AT);
7473 break;
7475 case 0x06: //less_equal
7476 __ slt(AT, op2, op1);
7477 __ movz(dst, src, AT);
7478 break;
7480 default:
7481 Unimplemented();
7482 }
7483 %}
7485 ins_pipe( pipe_slow );
7486 %}
7488 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
7489 match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
7490 ins_cost(80);
7491 format %{
7492 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpL_reg_reg\n"
7493 "\tCMOV $dst,$src \t @cmovL_cmpL_reg_reg"
7494 %}
7495 ins_encode %{
7496 Register opr1 = as_Register($tmp1$$reg);
7497 Register opr2 = as_Register($tmp2$$reg);
7498 Register dst = as_Register($dst$$reg);
7499 Register src = as_Register($src$$reg);
7500 int flag = $cop$$cmpcode;
7502 switch(flag)
7503 {
7504 case 0x01: //equal
7505 __ subu(AT, opr1, opr2);
7506 __ movz(dst, src, AT);
7507 break;
7509 case 0x02: //not_equal
7510 __ subu(AT, opr1, opr2);
7511 __ movn(dst, src, AT);
7512 break;
7514 case 0x03: //greater
7515 __ slt(AT, opr2, opr1);
7516 __ movn(dst, src, AT);
7517 break;
7519 case 0x04: //greater_equal
7520 __ slt(AT, opr1, opr2);
7521 __ movz(dst, src, AT);
7522 break;
7524 case 0x05: //less
7525 __ slt(AT, opr1, opr2);
7526 __ movn(dst, src, AT);
7527 break;
7529 case 0x06: //less_equal
7530 __ slt(AT, opr2, opr1);
7531 __ movz(dst, src, AT);
7532 break;
7534 default:
7535 Unimplemented();
7536 }
7537 %}
7539 ins_pipe( pipe_slow );
7540 %}
7542 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
7543 match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
7544 ins_cost(80);
7545 format %{
7546 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
7547 "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
7548 %}
7549 ins_encode %{
7550 Register op1 = $tmp1$$Register;
7551 Register op2 = $tmp2$$Register;
7552 Register dst = $dst$$Register;
7553 Register src = $src$$Register;
7554 int flag = $cop$$cmpcode;
7556 switch(flag)
7557 {
7558 case 0x01: //equal
7559 __ subu32(AT, op1, op2);
7560 __ movz(dst, src, AT);
7561 break;
7563 case 0x02: //not_equal
7564 __ subu32(AT, op1, op2);
7565 __ movn(dst, src, AT);
7566 break;
7568 case 0x03: //above
7569 __ sltu(AT, op2, op1);
7570 __ movn(dst, src, AT);
7571 break;
7573 case 0x04: //above_equal
7574 __ sltu(AT, op1, op2);
7575 __ movz(dst, src, AT);
7576 break;
7578 case 0x05: //below
7579 __ sltu(AT, op1, op2);
7580 __ movn(dst, src, AT);
7581 break;
7583 case 0x06: //below_equal
7584 __ sltu(AT, op2, op1);
7585 __ movz(dst, src, AT);
7586 break;
7588 default:
7589 Unimplemented();
7590 }
7591 %}
7593 ins_pipe( pipe_slow );
7594 %}
7597 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
7598 match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
7599 ins_cost(80);
7600 format %{
7601 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpD_reg_reg\n"
7602 "\tCMOV $dst,$src \t @cmovL_cmpD_reg_reg"
7603 %}
7604 ins_encode %{
7605 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
7606 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
7607 Register dst = as_Register($dst$$reg);
7608 Register src = as_Register($src$$reg);
7610 int flag = $cop$$cmpcode;
7612 switch(flag)
7613 {
7614 case 0x01: //equal
7615 __ c_eq_d(reg_op1, reg_op2);
7616 __ movt(dst, src);
7617 break;
7618 case 0x02: //not_equal
7619 __ c_eq_d(reg_op1, reg_op2);
7620 __ movf(dst, src);
7621 break;
7622 case 0x03: //greater
7623 __ c_ole_d(reg_op1, reg_op2);
7624 __ movf(dst, src);
7625 break;
7626 case 0x04: //greater_equal
7627 __ c_olt_d(reg_op1, reg_op2);
7628 __ movf(dst, src);
7629 break;
7630 case 0x05: //less
7631 __ c_ult_d(reg_op1, reg_op2);
7632 __ movt(dst, src);
7633 break;
7634 case 0x06: //less_equal
7635 __ c_ule_d(reg_op1, reg_op2);
7636 __ movt(dst, src);
7637 break;
7638 default:
7639 Unimplemented();
7640 }
7641 %}
7643 ins_pipe( pipe_slow );
7644 %}
7646 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
7647 match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
7648 ins_cost(200);
7649 format %{
7650 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpD_reg_reg\n"
7651 "\tCMOV $dst,$src \t @cmovD_cmpD_reg_reg"
7652 %}
7653 ins_encode %{
7654 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
7655 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
7656 FloatRegister dst = as_FloatRegister($dst$$reg);
7657 FloatRegister src = as_FloatRegister($src$$reg);
7659 int flag = $cop$$cmpcode;
7661 Label L;
7663 switch(flag)
7664 {
7665 case 0x01: //equal
7666 __ c_eq_d(reg_op1, reg_op2);
7667 __ bc1f(L);
7668 __ nop();
7669 __ mov_d(dst, src);
7670 __ bind(L);
7671 break;
7672 case 0x02: //not_equal
7673 //2016/4/19 aoqi: See instruct branchConD_reg_reg. The change in branchConD_reg_reg fixed a bug. It seems similar here, so I made thesame change.
7674 __ c_eq_d(reg_op1, reg_op2);
7675 __ bc1t(L);
7676 __ nop();
7677 __ mov_d(dst, src);
7678 __ bind(L);
7679 break;
7680 case 0x03: //greater
7681 __ c_ole_d(reg_op1, reg_op2);
7682 __ bc1t(L);
7683 __ nop();
7684 __ mov_d(dst, src);
7685 __ bind(L);
7686 break;
7687 case 0x04: //greater_equal
7688 __ c_olt_d(reg_op1, reg_op2);
7689 __ bc1t(L);
7690 __ nop();
7691 __ mov_d(dst, src);
7692 __ bind(L);
7693 break;
7694 case 0x05: //less
7695 __ c_ult_d(reg_op1, reg_op2);
7696 __ bc1f(L);
7697 __ nop();
7698 __ mov_d(dst, src);
7699 __ bind(L);
7700 break;
7701 case 0x06: //less_equal
7702 __ c_ule_d(reg_op1, reg_op2);
7703 __ bc1f(L);
7704 __ nop();
7705 __ mov_d(dst, src);
7706 __ bind(L);
7707 break;
7708 default:
7709 Unimplemented();
7710 }
7711 %}
7713 ins_pipe( pipe_slow );
7714 %}
7716 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7717 match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7718 ins_cost(200);
7719 format %{
7720 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpI_reg_reg\n"
7721 "\tCMOV $dst, $src \t @cmovF_cmpI_reg_reg"
7722 %}
7724 ins_encode %{
7725 Register op1 = $tmp1$$Register;
7726 Register op2 = $tmp2$$Register;
7727 FloatRegister dst = as_FloatRegister($dst$$reg);
7728 FloatRegister src = as_FloatRegister($src$$reg);
7729 int flag = $cop$$cmpcode;
7730 Label L;
7732 switch(flag)
7733 {
7734 case 0x01: //equal
7735 __ bne(op1, op2, L);
7736 __ nop();
7737 __ mov_s(dst, src);
7738 __ bind(L);
7739 break;
7740 case 0x02: //not_equal
7741 __ beq(op1, op2, L);
7742 __ nop();
7743 __ mov_s(dst, src);
7744 __ bind(L);
7745 break;
7746 case 0x03: //great
7747 __ slt(AT, op2, op1);
7748 __ beq(AT, R0, L);
7749 __ nop();
7750 __ mov_s(dst, src);
7751 __ bind(L);
7752 break;
7753 case 0x04: //great_equal
7754 __ slt(AT, op1, op2);
7755 __ bne(AT, R0, L);
7756 __ nop();
7757 __ mov_s(dst, src);
7758 __ bind(L);
7759 break;
7760 case 0x05: //less
7761 __ slt(AT, op1, op2);
7762 __ beq(AT, R0, L);
7763 __ nop();
7764 __ mov_s(dst, src);
7765 __ bind(L);
7766 break;
7767 case 0x06: //less_equal
7768 __ slt(AT, op2, op1);
7769 __ bne(AT, R0, L);
7770 __ nop();
7771 __ mov_s(dst, src);
7772 __ bind(L);
7773 break;
7774 default:
7775 Unimplemented();
7776 }
7777 %}
7779 ins_pipe( pipe_slow );
7780 %}
7782 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7783 match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7784 ins_cost(200);
7785 format %{
7786 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpI_reg_reg\n"
7787 "\tCMOV $dst, $src \t @cmovD_cmpI_reg_reg"
7788 %}
7790 ins_encode %{
7791 Register op1 = $tmp1$$Register;
7792 Register op2 = $tmp2$$Register;
7793 FloatRegister dst = as_FloatRegister($dst$$reg);
7794 FloatRegister src = as_FloatRegister($src$$reg);
7795 int flag = $cop$$cmpcode;
7796 Label L;
7798 switch(flag)
7799 {
7800 case 0x01: //equal
7801 __ bne(op1, op2, L);
7802 __ nop();
7803 __ mov_d(dst, src);
7804 __ bind(L);
7805 break;
7806 case 0x02: //not_equal
7807 __ beq(op1, op2, L);
7808 __ nop();
7809 __ mov_d(dst, src);
7810 __ bind(L);
7811 break;
7812 case 0x03: //great
7813 __ slt(AT, op2, op1);
7814 __ beq(AT, R0, L);
7815 __ nop();
7816 __ mov_d(dst, src);
7817 __ bind(L);
7818 break;
7819 case 0x04: //great_equal
7820 __ slt(AT, op1, op2);
7821 __ bne(AT, R0, L);
7822 __ nop();
7823 __ mov_d(dst, src);
7824 __ bind(L);
7825 break;
7826 case 0x05: //less
7827 __ slt(AT, op1, op2);
7828 __ beq(AT, R0, L);
7829 __ nop();
7830 __ mov_d(dst, src);
7831 __ bind(L);
7832 break;
7833 case 0x06: //less_equal
7834 __ slt(AT, op2, op1);
7835 __ bne(AT, R0, L);
7836 __ nop();
7837 __ mov_d(dst, src);
7838 __ bind(L);
7839 break;
7840 default:
7841 Unimplemented();
7842 }
7843 %}
7845 ins_pipe( pipe_slow );
7846 %}
7848 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
7849 match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
7850 ins_cost(200);
7851 format %{
7852 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpP_reg_reg\n"
7853 "\tCMOV $dst, $src \t @cmovD_cmpP_reg_reg"
7854 %}
7856 ins_encode %{
7857 Register op1 = $tmp1$$Register;
7858 Register op2 = $tmp2$$Register;
7859 FloatRegister dst = as_FloatRegister($dst$$reg);
7860 FloatRegister src = as_FloatRegister($src$$reg);
7861 int flag = $cop$$cmpcode;
7862 Label L;
7864 switch(flag)
7865 {
7866 case 0x01: //equal
7867 __ bne(op1, op2, L);
7868 __ nop();
7869 __ mov_d(dst, src);
7870 __ bind(L);
7871 break;
7872 case 0x02: //not_equal
7873 __ beq(op1, op2, L);
7874 __ nop();
7875 __ mov_d(dst, src);
7876 __ bind(L);
7877 break;
7878 case 0x03: //great
7879 __ slt(AT, op2, op1);
7880 __ beq(AT, R0, L);
7881 __ nop();
7882 __ mov_d(dst, src);
7883 __ bind(L);
7884 break;
7885 case 0x04: //great_equal
7886 __ slt(AT, op1, op2);
7887 __ bne(AT, R0, L);
7888 __ nop();
7889 __ mov_d(dst, src);
7890 __ bind(L);
7891 break;
7892 case 0x05: //less
7893 __ slt(AT, op1, op2);
7894 __ beq(AT, R0, L);
7895 __ nop();
7896 __ mov_d(dst, src);
7897 __ bind(L);
7898 break;
7899 case 0x06: //less_equal
7900 __ slt(AT, op2, op1);
7901 __ bne(AT, R0, L);
7902 __ nop();
7903 __ mov_d(dst, src);
7904 __ bind(L);
7905 break;
7906 default:
7907 Unimplemented();
7908 }
7909 %}
7911 ins_pipe( pipe_slow );
7912 %}
7914 //FIXME
7915 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
7916 match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
7917 ins_cost(80);
7918 format %{
7919 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpF_reg_reg\n"
7920 "\tCMOV $dst,$src \t @cmovI_cmpF_reg_reg"
7921 %}
7923 ins_encode %{
7924 FloatRegister reg_op1 = $tmp1$$FloatRegister;
7925 FloatRegister reg_op2 = $tmp2$$FloatRegister;
7926 Register dst = $dst$$Register;
7927 Register src = $src$$Register;
7928 int flag = $cop$$cmpcode;
7930 switch(flag)
7931 {
7932 case 0x01: //equal
7933 __ c_eq_s(reg_op1, reg_op2);
7934 __ movt(dst, src);
7935 break;
7936 case 0x02: //not_equal
7937 __ c_eq_s(reg_op1, reg_op2);
7938 __ movf(dst, src);
7939 break;
7940 case 0x03: //greater
7941 __ c_ole_s(reg_op1, reg_op2);
7942 __ movf(dst, src);
7943 break;
7944 case 0x04: //greater_equal
7945 __ c_olt_s(reg_op1, reg_op2);
7946 __ movf(dst, src);
7947 break;
7948 case 0x05: //less
7949 __ c_ult_s(reg_op1, reg_op2);
7950 __ movt(dst, src);
7951 break;
7952 case 0x06: //less_equal
7953 __ c_ule_s(reg_op1, reg_op2);
7954 __ movt(dst, src);
7955 break;
7956 default:
7957 Unimplemented();
7958 }
7959 %}
7960 ins_pipe( pipe_slow );
7961 %}
7963 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
7964 match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
7965 ins_cost(200);
7966 format %{
7967 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpF_reg_reg\n"
7968 "\tCMOV $dst,$src \t @cmovF_cmpF_reg_reg"
7969 %}
7971 ins_encode %{
7972 FloatRegister reg_op1 = $tmp1$$FloatRegister;
7973 FloatRegister reg_op2 = $tmp2$$FloatRegister;
7974 FloatRegister dst = $dst$$FloatRegister;
7975 FloatRegister src = $src$$FloatRegister;
7976 Label L;
7977 int flag = $cop$$cmpcode;
7979 switch(flag)
7980 {
7981 case 0x01: //equal
7982 __ c_eq_s(reg_op1, reg_op2);
7983 __ bc1f(L);
7984 __ nop();
7985 __ mov_s(dst, src);
7986 __ bind(L);
7987 break;
7988 case 0x02: //not_equal
7989 __ c_eq_s(reg_op1, reg_op2);
7990 __ bc1t(L);
7991 __ nop();
7992 __ mov_s(dst, src);
7993 __ bind(L);
7994 break;
7995 case 0x03: //greater
7996 __ c_ole_s(reg_op1, reg_op2);
7997 __ bc1t(L);
7998 __ nop();
7999 __ mov_s(dst, src);
8000 __ bind(L);
8001 break;
8002 case 0x04: //greater_equal
8003 __ c_olt_s(reg_op1, reg_op2);
8004 __ bc1t(L);
8005 __ nop();
8006 __ mov_s(dst, src);
8007 __ bind(L);
8008 break;
8009 case 0x05: //less
8010 __ c_ult_s(reg_op1, reg_op2);
8011 __ bc1f(L);
8012 __ nop();
8013 __ mov_s(dst, src);
8014 __ bind(L);
8015 break;
8016 case 0x06: //less_equal
8017 __ c_ule_s(reg_op1, reg_op2);
8018 __ bc1f(L);
8019 __ nop();
8020 __ mov_s(dst, src);
8021 __ bind(L);
8022 break;
8023 default:
8024 Unimplemented();
8025 }
8026 %}
8027 ins_pipe( pipe_slow );
8028 %}
8030 // Manifest a CmpL result in an integer register. Very painful.
8031 // This is the test to avoid.
8032 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
8033 match(Set dst (CmpL3 src1 src2));
8034 ins_cost(1000);
8035 format %{ "cmpL3 $dst, $src1, $src2 @ cmpL3_reg_reg" %}
8036 ins_encode %{
8037 Register opr1 = as_Register($src1$$reg);
8038 Register opr2 = as_Register($src2$$reg);
8039 Register dst = as_Register($dst$$reg);
8041 Label Done;
8043 __ subu(AT, opr1, opr2);
8044 __ bltz(AT, Done);
8045 __ delayed()->daddiu(dst, R0, -1);
8047 __ move(dst, 1);
8048 __ movz(dst, R0, AT);
8050 __ bind(Done);
8051 %}
8052 ins_pipe( pipe_slow );
8053 %}
8055 //
8056 // less_rsult = -1
8057 // greater_result = 1
8058 // equal_result = 0
8059 // nan_result = -1
8060 //
8061 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
8062 match(Set dst (CmpF3 src1 src2));
8063 ins_cost(1000);
8064 format %{ "cmpF3 $dst, $src1, $src2 @ cmpF3_reg_reg" %}
8065 ins_encode %{
8066 FloatRegister src1 = as_FloatRegister($src1$$reg);
8067 FloatRegister src2 = as_FloatRegister($src2$$reg);
8068 Register dst = as_Register($dst$$reg);
8070 Label Done;
8072 __ c_ult_s(src1, src2);
8073 __ bc1t(Done);
8074 __ delayed()->daddiu(dst, R0, -1);
8076 __ c_eq_s(src1, src2);
8077 __ move(dst, 1);
8078 __ movt(dst, R0);
8080 __ bind(Done);
8081 %}
8082 ins_pipe( pipe_slow );
8083 %}
8085 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
8086 match(Set dst (CmpD3 src1 src2));
8087 ins_cost(1000);
8088 format %{ "cmpD3 $dst, $src1, $src2 @ cmpD3_reg_reg" %}
8089 ins_encode %{
8090 FloatRegister src1 = as_FloatRegister($src1$$reg);
8091 FloatRegister src2 = as_FloatRegister($src2$$reg);
8092 Register dst = as_Register($dst$$reg);
8094 Label Done;
8096 __ c_ult_d(src1, src2);
8097 __ bc1t(Done);
8098 __ delayed()->daddiu(dst, R0, -1);
8100 __ c_eq_d(src1, src2);
8101 __ move(dst, 1);
8102 __ movt(dst, R0);
8104 __ bind(Done);
8105 %}
8106 ins_pipe( pipe_slow );
8107 %}
8109 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
8110 match(Set dummy (ClearArray cnt base));
8111 format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
8112 ins_encode %{
8113 //Assume cnt is the number of bytes in an array to be cleared,
8114 //and base points to the starting address of the array.
8115 Register base = $base$$Register;
8116 Register num = $cnt$$Register;
8117 Label Loop, done;
8119 __ beq(num, R0, done);
8120 __ delayed()->daddu(AT, base, R0);
8122 __ move(T9, num); /* T9 = words */
8124 __ bind(Loop);
8125 __ sd(R0, AT, 0);
8126 __ daddi(T9, T9, -1);
8127 __ bne(T9, R0, Loop);
8128 __ delayed()->daddi(AT, AT, wordSize);
8130 __ bind(done);
8131 %}
8132 ins_pipe( pipe_slow );
8133 %}
8135 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2, mA7RegI cnt2, no_Ax_mRegI result) %{
8136 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
8137 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
8139 format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
8140 ins_encode %{
8141 // Get the first character position in both strings
8142 // [8] char array, [12] offset, [16] count
8143 Register str1 = $str1$$Register;
8144 Register str2 = $str2$$Register;
8145 Register cnt1 = $cnt1$$Register;
8146 Register cnt2 = $cnt2$$Register;
8147 Register result = $result$$Register;
8149 Label L, Loop, haveResult, done;
8151 // compute the and difference of lengths (in result)
8152 __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
8154 // compute the shorter length (in cnt1)
8155 __ slt(AT, cnt2, cnt1);
8156 __ movn(cnt1, cnt2, AT);
8158 // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
8159 __ bind(Loop); // Loop begin
8160 __ beq(cnt1, R0, done);
8161 __ delayed()->lhu(AT, str1, 0);;
8163 // compare current character
8164 __ lhu(cnt2, str2, 0);
8165 __ bne(AT, cnt2, haveResult);
8166 __ delayed()->addi(str1, str1, 2);
8167 __ addi(str2, str2, 2);
8168 __ b(Loop);
8169 __ delayed()->addi(cnt1, cnt1, -1); // Loop end
8171 __ bind(haveResult);
8172 __ subu(result, AT, cnt2);
8174 __ bind(done);
8175 %}
8177 ins_pipe( pipe_slow );
8178 %}
8180 // intrinsic optimization
8181 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
8182 match(Set result (StrEquals (Binary str1 str2) cnt));
8183 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
8185 format %{ "String Equal $str1, $str2, len:$cnt tmp:$temp -> $result @ string_equals" %}
8186 ins_encode %{
8187 // Get the first character position in both strings
8188 // [8] char array, [12] offset, [16] count
8189 Register str1 = $str1$$Register;
8190 Register str2 = $str2$$Register;
8191 Register cnt = $cnt$$Register;
8192 Register tmp = $temp$$Register;
8193 Register result = $result$$Register;
8195 Label Loop, done;
8198 __ beq(str1, str2, done); // same char[] ?
8199 __ daddiu(result, R0, 1);
8201 __ bind(Loop); // Loop begin
8202 __ beq(cnt, R0, done);
8203 __ daddiu(result, R0, 1); // count == 0
8205 // compare current character
8206 __ lhu(AT, str1, 0);;
8207 __ lhu(tmp, str2, 0);
8208 __ bne(AT, tmp, done);
8209 __ delayed()->daddi(result, R0, 0);
8210 __ addi(str1, str1, 2);
8211 __ addi(str2, str2, 2);
8212 __ b(Loop);
8213 __ delayed()->addi(cnt, cnt, -1); // Loop end
8215 __ bind(done);
8216 %}
8218 ins_pipe( pipe_slow );
8219 %}
8221 //----------Arithmetic Instructions-------------------------------------------
8222 //----------Addition Instructions---------------------------------------------
8223 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
8224 match(Set dst (AddI src1 src2));
8226 format %{ "add $dst, $src1, $src2 #@addI_Reg_Reg" %}
8227 ins_encode %{
8228 Register dst = $dst$$Register;
8229 Register src1 = $src1$$Register;
8230 Register src2 = $src2$$Register;
8231 __ addu32(dst, src1, src2);
8232 %}
8233 ins_pipe( ialu_regI_regI );
8234 %}
8236 instruct addI_Reg_imm(mRegI dst, mRegI src1, immI src2) %{
8237 match(Set dst (AddI src1 src2));
8239 format %{ "add $dst, $src1, $src2 #@addI_Reg_imm" %}
8240 ins_encode %{
8241 Register dst = $dst$$Register;
8242 Register src1 = $src1$$Register;
8243 int imm = $src2$$constant;
8245 if(Assembler::is_simm16(imm)) {
8246 __ addiu32(dst, src1, imm);
8247 } else {
8248 __ move(AT, imm);
8249 __ addu32(dst, src1, AT);
8250 }
8251 %}
8252 ins_pipe( ialu_regI_regI );
8253 %}
8255 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
8256 match(Set dst (AddP src1 src2));
8258 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg" %}
8260 ins_encode %{
8261 Register dst = $dst$$Register;
8262 Register src1 = $src1$$Register;
8263 Register src2 = $src2$$Register;
8264 __ daddu(dst, src1, src2);
8265 %}
8267 ins_pipe( ialu_regI_regI );
8268 %}
8270 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
8271 match(Set dst (AddP src1 (ConvI2L src2)));
8273 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
8275 ins_encode %{
8276 Register dst = $dst$$Register;
8277 Register src1 = $src1$$Register;
8278 Register src2 = $src2$$Register;
8279 __ daddu(dst, src1, src2);
8280 %}
8282 ins_pipe( ialu_regI_regI );
8283 %}
8285 instruct addP_reg_imm(mRegP dst, mRegP src1, immL src2) %{
8286 match(Set dst (AddP src1 src2));
8288 format %{ "daddi $dst, $src1, $src2 #@addP_reg_imm" %}
8289 ins_encode %{
8290 Register src1 = $src1$$Register;
8291 long src2 = $src2$$constant;
8292 Register dst = $dst$$Register;
8294 if(Assembler::is_simm16(src2)) {
8295 __ daddiu(dst, src1, src2);
8296 } else {
8297 __ set64(AT, src2);
8298 __ daddu(dst, src1, AT);
8299 }
8300 %}
8301 ins_pipe( ialu_regI_imm16 );
8302 %}
8304 // Add Long Register with Register
8305 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
8306 match(Set dst (AddL src1 src2));
8307 ins_cost(200);
8308 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
8310 ins_encode %{
8311 Register dst_reg = as_Register($dst$$reg);
8312 Register src1_reg = as_Register($src1$$reg);
8313 Register src2_reg = as_Register($src2$$reg);
8315 __ daddu(dst_reg, src1_reg, src2_reg);
8316 %}
8318 ins_pipe( ialu_regL_regL );
8319 %}
8321 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
8322 %{
8323 match(Set dst (AddL src1 src2));
8325 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_imm " %}
8326 ins_encode %{
8327 Register dst_reg = as_Register($dst$$reg);
8328 Register src1_reg = as_Register($src1$$reg);
8329 int src2_imm = $src2$$constant;
8331 __ daddiu(dst_reg, src1_reg, src2_imm);
8332 %}
8334 ins_pipe( ialu_regL_regL );
8335 %}
8337 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
8338 %{
8339 match(Set dst (AddL (ConvI2L src1) src2));
8341 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_imm " %}
8342 ins_encode %{
8343 Register dst_reg = as_Register($dst$$reg);
8344 Register src1_reg = as_Register($src1$$reg);
8345 int src2_imm = $src2$$constant;
8347 __ daddiu(dst_reg, src1_reg, src2_imm);
8348 %}
8350 ins_pipe( ialu_regL_regL );
8351 %}
8353 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
8354 match(Set dst (AddL (ConvI2L src1) src2));
8355 ins_cost(200);
8356 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
8358 ins_encode %{
8359 Register dst_reg = as_Register($dst$$reg);
8360 Register src1_reg = as_Register($src1$$reg);
8361 Register src2_reg = as_Register($src2$$reg);
8363 __ daddu(dst_reg, src1_reg, src2_reg);
8364 %}
8366 ins_pipe( ialu_regL_regL );
8367 %}
8369 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
8370 match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
8371 ins_cost(200);
8372 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
8374 ins_encode %{
8375 Register dst_reg = as_Register($dst$$reg);
8376 Register src1_reg = as_Register($src1$$reg);
8377 Register src2_reg = as_Register($src2$$reg);
8379 __ daddu(dst_reg, src1_reg, src2_reg);
8380 %}
8382 ins_pipe( ialu_regL_regL );
8383 %}
8385 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
8386 match(Set dst (AddL src1 (ConvI2L src2)));
8387 ins_cost(200);
8388 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
8390 ins_encode %{
8391 Register dst_reg = as_Register($dst$$reg);
8392 Register src1_reg = as_Register($src1$$reg);
8393 Register src2_reg = as_Register($src2$$reg);
8395 __ daddu(dst_reg, src1_reg, src2_reg);
8396 %}
8398 ins_pipe( ialu_regL_regL );
8399 %}
8401 //----------Subtraction Instructions-------------------------------------------
8402 // Integer Subtraction Instructions
8403 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
8404 match(Set dst (SubI src1 src2));
8405 ins_cost(100);
8407 format %{ "sub $dst, $src1, $src2 #@subI_Reg_Reg" %}
8408 ins_encode %{
8409 Register dst = $dst$$Register;
8410 Register src1 = $src1$$Register;
8411 Register src2 = $src2$$Register;
8412 __ subu32(dst, src1, src2);
8413 %}
8414 ins_pipe( ialu_regI_regI );
8415 %}
8417 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1, immI16_sub src2) %{
8418 match(Set dst (SubI src1 src2));
8419 ins_cost(80);
8421 format %{ "sub $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
8422 ins_encode %{
8423 Register dst = $dst$$Register;
8424 Register src1 = $src1$$Register;
8425 __ addiu32(dst, src1, -1 * $src2$$constant);
8426 %}
8427 ins_pipe( ialu_regI_regI );
8428 %}
8430 instruct negI_Reg(mRegI dst, immI0 zero, mRegI src) %{
8431 match(Set dst (SubI zero src));
8432 ins_cost(80);
8434 format %{ "neg $dst, $src #@negI_Reg" %}
8435 ins_encode %{
8436 Register dst = $dst$$Register;
8437 Register src = $src$$Register;
8438 __ subu32(dst, R0, src);
8439 %}
8440 ins_pipe( ialu_regI_regI );
8441 %}
8443 instruct negL_Reg(mRegL dst, immL0 zero, mRegL src) %{
8444 match(Set dst (SubL zero src));
8445 ins_cost(80);
8447 format %{ "neg $dst, $src #@negL_Reg" %}
8448 ins_encode %{
8449 Register dst = $dst$$Register;
8450 Register src = $src$$Register;
8451 __ subu(dst, R0, src);
8452 %}
8453 ins_pipe( ialu_regI_regI );
8454 %}
8456 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1, immL16_sub src2) %{
8457 match(Set dst (SubL src1 src2));
8458 ins_cost(80);
8460 format %{ "sub $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
8461 ins_encode %{
8462 Register dst = $dst$$Register;
8463 Register src1 = $src1$$Register;
8464 __ daddiu(dst, src1, -1 * $src2$$constant);
8465 %}
8466 ins_pipe( ialu_regI_regI );
8467 %}
8469 // Subtract Long Register with Register.
8470 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
8471 match(Set dst (SubL src1 src2));
8472 ins_cost(100);
8473 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_Reg" %}
8474 ins_encode %{
8475 Register dst = as_Register($dst$$reg);
8476 Register src1 = as_Register($src1$$reg);
8477 Register src2 = as_Register($src2$$reg);
8479 __ subu(dst, src1, src2);
8480 %}
8481 ins_pipe( ialu_regL_regL );
8482 %}
8484 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
8485 match(Set dst (SubL src1 (ConvI2L src2)));
8486 ins_cost(100);
8487 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
8488 ins_encode %{
8489 Register dst = as_Register($dst$$reg);
8490 Register src1 = as_Register($src1$$reg);
8491 Register src2 = as_Register($src2$$reg);
8493 __ subu(dst, src1, src2);
8494 %}
8495 ins_pipe( ialu_regL_regL );
8496 %}
8498 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
8499 match(Set dst (SubL (ConvI2L src1) src2));
8500 ins_cost(200);
8501 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
8502 ins_encode %{
8503 Register dst = as_Register($dst$$reg);
8504 Register src1 = as_Register($src1$$reg);
8505 Register src2 = as_Register($src2$$reg);
8507 __ subu(dst, src1, src2);
8508 %}
8509 ins_pipe( ialu_regL_regL );
8510 %}
8512 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
8513 match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
8514 ins_cost(200);
8515 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
8516 ins_encode %{
8517 Register dst = as_Register($dst$$reg);
8518 Register src1 = as_Register($src1$$reg);
8519 Register src2 = as_Register($src2$$reg);
8521 __ subu(dst, src1, src2);
8522 %}
8523 ins_pipe( ialu_regL_regL );
8524 %}
8526 // Integer MOD with Register
8527 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
8528 match(Set dst (ModI src1 src2));
8529 ins_cost(300);
8530 format %{ "modi $dst, $src1, $src2 @ modI_Reg_Reg" %}
8531 ins_encode %{
8532 Register dst = $dst$$Register;
8533 Register src1 = $src1$$Register;
8534 Register src2 = $src2$$Register;
8536 //if (UseLoongsonISA) {
8537 if (0) {
8538 // 2016.08.10
8539 // Experiments show that gsmod is slower that div+mfhi.
8540 // So I just disable it here.
8541 __ gsmod(dst, src1, src2);
8542 } else {
8543 __ div(src1, src2);
8544 __ mfhi(dst);
8545 }
8546 %}
8548 //ins_pipe( ialu_mod );
8549 ins_pipe( ialu_regI_regI );
8550 %}
8552 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
8553 match(Set dst (ModL src1 src2));
8554 format %{ "modL $dst, $src1, $src2 @modL_reg_reg" %}
8556 ins_encode %{
8557 Register dst = as_Register($dst$$reg);
8558 Register op1 = as_Register($src1$$reg);
8559 Register op2 = as_Register($src2$$reg);
8561 if (UseLoongsonISA) {
8562 __ gsdmod(dst, op1, op2);
8563 } else {
8564 __ ddiv(op1, op2);
8565 __ mfhi(dst);
8566 }
8567 %}
8568 ins_pipe( pipe_slow );
8569 %}
8571 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
8572 match(Set dst (MulI src1 src2));
8574 ins_cost(300);
8575 format %{ "mul $dst, $src1, $src2 @ mulI_Reg_Reg" %}
8576 ins_encode %{
8577 Register src1 = $src1$$Register;
8578 Register src2 = $src2$$Register;
8579 Register dst = $dst$$Register;
8581 __ mul(dst, src1, src2);
8582 %}
8583 ins_pipe( ialu_mult );
8584 %}
8586 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
8587 match(Set dst (AddI (MulI src1 src2) src3));
8589 ins_cost(999);
8590 format %{ "madd $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
8591 ins_encode %{
8592 Register src1 = $src1$$Register;
8593 Register src2 = $src2$$Register;
8594 Register src3 = $src3$$Register;
8595 Register dst = $dst$$Register;
8597 __ mtlo(src3);
8598 __ madd(src1, src2);
8599 __ mflo(dst);
8600 %}
8601 ins_pipe( ialu_mult );
8602 %}
8604 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
8605 match(Set dst (DivI src1 src2));
8607 ins_cost(300);
8608 format %{ "div $dst, $src1, $src2 @ divI_Reg_Reg" %}
8609 ins_encode %{
8610 Register src1 = $src1$$Register;
8611 Register src2 = $src2$$Register;
8612 Register dst = $dst$$Register;
8614 /* 2012/4/21 Jin: In MIPS, div does not cause exception.
8615 We must trap an exception manually. */
8616 __ teq(R0, src2, 0x7);
8618 if (UseLoongsonISA) {
8619 __ gsdiv(dst, src1, src2);
8620 } else {
8621 __ div(src1, src2);
8623 __ nop();
8624 __ nop();
8625 __ mflo(dst);
8626 }
8627 %}
8628 ins_pipe( ialu_mod );
8629 %}
8631 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
8632 match(Set dst (DivF src1 src2));
8634 ins_cost(300);
8635 format %{ "divF $dst, $src1, $src2 @ divF_Reg_Reg" %}
8636 ins_encode %{
8637 FloatRegister src1 = $src1$$FloatRegister;
8638 FloatRegister src2 = $src2$$FloatRegister;
8639 FloatRegister dst = $dst$$FloatRegister;
8641 /* Here do we need to trap an exception manually ? */
8642 __ div_s(dst, src1, src2);
8643 %}
8644 ins_pipe( pipe_slow );
8645 %}
8647 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
8648 match(Set dst (DivD src1 src2));
8650 ins_cost(300);
8651 format %{ "divD $dst, $src1, $src2 @ divD_Reg_Reg" %}
8652 ins_encode %{
8653 FloatRegister src1 = $src1$$FloatRegister;
8654 FloatRegister src2 = $src2$$FloatRegister;
8655 FloatRegister dst = $dst$$FloatRegister;
8657 /* Here do we need to trap an exception manually ? */
8658 __ div_d(dst, src1, src2);
8659 %}
8660 ins_pipe( pipe_slow );
8661 %}
8663 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
8664 match(Set dst (MulL src1 src2));
8665 format %{ "mulL $dst, $src1, $src2 @mulL_reg_reg" %}
8666 ins_encode %{
8667 Register dst = as_Register($dst$$reg);
8668 Register op1 = as_Register($src1$$reg);
8669 Register op2 = as_Register($src2$$reg);
8671 if (UseLoongsonISA) {
8672 __ gsdmult(dst, op1, op2);
8673 } else {
8674 __ dmult(op1, op2);
8675 __ mflo(dst);
8676 }
8677 %}
8678 ins_pipe( pipe_slow );
8679 %}
8681 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
8682 match(Set dst (MulL src1 (ConvI2L src2)));
8683 format %{ "mulL $dst, $src1, $src2 @mulL_reg_regI2L" %}
8684 ins_encode %{
8685 Register dst = as_Register($dst$$reg);
8686 Register op1 = as_Register($src1$$reg);
8687 Register op2 = as_Register($src2$$reg);
8689 if (UseLoongsonISA) {
8690 __ gsdmult(dst, op1, op2);
8691 } else {
8692 __ dmult(op1, op2);
8693 __ mflo(dst);
8694 }
8695 %}
8696 ins_pipe( pipe_slow );
8697 %}
8699 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
8700 match(Set dst (DivL src1 src2));
8701 format %{ "divL $dst, $src1, $src2 @divL_reg_reg" %}
8703 ins_encode %{
8704 Register dst = as_Register($dst$$reg);
8705 Register op1 = as_Register($src1$$reg);
8706 Register op2 = as_Register($src2$$reg);
8708 if (UseLoongsonISA) {
8709 __ gsddiv(dst, op1, op2);
8710 } else {
8711 __ ddiv(op1, op2);
8712 __ mflo(dst);
8713 }
8714 %}
8715 ins_pipe( pipe_slow );
8716 %}
8718 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
8719 match(Set dst (AddF src1 src2));
8720 format %{ "AddF $dst, $src1, $src2 @addF_reg_reg" %}
8721 ins_encode %{
8722 FloatRegister src1 = as_FloatRegister($src1$$reg);
8723 FloatRegister src2 = as_FloatRegister($src2$$reg);
8724 FloatRegister dst = as_FloatRegister($dst$$reg);
8726 __ add_s(dst, src1, src2);
8727 %}
8728 ins_pipe( fpu_regF_regF );
8729 %}
8731 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
8732 match(Set dst (SubF src1 src2));
8733 format %{ "SubF $dst, $src1, $src2 @subF_reg_reg" %}
8734 ins_encode %{
8735 FloatRegister src1 = as_FloatRegister($src1$$reg);
8736 FloatRegister src2 = as_FloatRegister($src2$$reg);
8737 FloatRegister dst = as_FloatRegister($dst$$reg);
8739 __ sub_s(dst, src1, src2);
8740 %}
8741 ins_pipe( fpu_regF_regF );
8742 %}
8743 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
8744 match(Set dst (AddD src1 src2));
8745 format %{ "AddD $dst, $src1, $src2 @addD_reg_reg" %}
8746 ins_encode %{
8747 FloatRegister src1 = as_FloatRegister($src1$$reg);
8748 FloatRegister src2 = as_FloatRegister($src2$$reg);
8749 FloatRegister dst = as_FloatRegister($dst$$reg);
8751 __ add_d(dst, src1, src2);
8752 %}
8753 ins_pipe( fpu_regF_regF );
8754 %}
8756 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
8757 match(Set dst (SubD src1 src2));
8758 format %{ "SubD $dst, $src1, $src2 @subD_reg_reg" %}
8759 ins_encode %{
8760 FloatRegister src1 = as_FloatRegister($src1$$reg);
8761 FloatRegister src2 = as_FloatRegister($src2$$reg);
8762 FloatRegister dst = as_FloatRegister($dst$$reg);
8764 __ sub_d(dst, src1, src2);
8765 %}
8766 ins_pipe( fpu_regF_regF );
8767 %}
8769 instruct negF_reg(regF dst, regF src) %{
8770 match(Set dst (NegF src));
8771 format %{ "negF $dst, $src @negF_reg" %}
8772 ins_encode %{
8773 FloatRegister src = as_FloatRegister($src$$reg);
8774 FloatRegister dst = as_FloatRegister($dst$$reg);
8776 __ neg_s(dst, src);
8777 %}
8778 ins_pipe( fpu_regF_regF );
8779 %}
8781 instruct negD_reg(regD dst, regD src) %{
8782 match(Set dst (NegD src));
8783 format %{ "negD $dst, $src @negD_reg" %}
8784 ins_encode %{
8785 FloatRegister src = as_FloatRegister($src$$reg);
8786 FloatRegister dst = as_FloatRegister($dst$$reg);
8788 __ neg_d(dst, src);
8789 %}
8790 ins_pipe( fpu_regF_regF );
8791 %}
8794 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
8795 match(Set dst (MulF src1 src2));
8796 format %{ "MULF $dst, $src1, $src2 @mulF_reg_reg" %}
8797 ins_encode %{
8798 FloatRegister src1 = $src1$$FloatRegister;
8799 FloatRegister src2 = $src2$$FloatRegister;
8800 FloatRegister dst = $dst$$FloatRegister;
8802 __ mul_s(dst, src1, src2);
8803 %}
8804 ins_pipe( fpu_regF_regF );
8805 %}
8807 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
8808 match(Set dst (AddF (MulF src1 src2) src3));
8809 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
8810 ins_cost(44444);
8811 format %{ "maddF $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
8812 ins_encode %{
8813 FloatRegister src1 = $src1$$FloatRegister;
8814 FloatRegister src2 = $src2$$FloatRegister;
8815 FloatRegister src3 = $src3$$FloatRegister;
8816 FloatRegister dst = $dst$$FloatRegister;
8818 __ madd_s(dst, src1, src2, src3);
8819 %}
8820 ins_pipe( fpu_regF_regF );
8821 %}
8823 // Mul two double precision floating piont number
8824 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
8825 match(Set dst (MulD src1 src2));
8826 format %{ "MULD $dst, $src1, $src2 @mulD_reg_reg" %}
8827 ins_encode %{
8828 FloatRegister src1 = $src1$$FloatRegister;
8829 FloatRegister src2 = $src2$$FloatRegister;
8830 FloatRegister dst = $dst$$FloatRegister;
8832 __ mul_d(dst, src1, src2);
8833 %}
8834 ins_pipe( fpu_regF_regF );
8835 %}
8837 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
8838 match(Set dst (AddD (MulD src1 src2) src3));
8839 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
8840 ins_cost(44444);
8841 format %{ "maddD $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
8842 ins_encode %{
8843 FloatRegister src1 = $src1$$FloatRegister;
8844 FloatRegister src2 = $src2$$FloatRegister;
8845 FloatRegister src3 = $src3$$FloatRegister;
8846 FloatRegister dst = $dst$$FloatRegister;
8848 __ madd_d(dst, src1, src2, src3);
8849 %}
8850 ins_pipe( fpu_regF_regF );
8851 %}
8853 instruct absF_reg(regF dst, regF src) %{
8854 match(Set dst (AbsF src));
8855 ins_cost(100);
8856 format %{ "absF $dst, $src @absF_reg" %}
8857 ins_encode %{
8858 FloatRegister src = as_FloatRegister($src$$reg);
8859 FloatRegister dst = as_FloatRegister($dst$$reg);
8861 __ abs_s(dst, src);
8862 %}
8863 ins_pipe( fpu_regF_regF );
8864 %}
8867 // intrinsics for math_native.
8868 // AbsD SqrtD CosD SinD TanD LogD Log10D
8870 instruct absD_reg(regD dst, regD src) %{
8871 match(Set dst (AbsD src));
8872 ins_cost(100);
8873 format %{ "absD $dst, $src @absD_reg" %}
8874 ins_encode %{
8875 FloatRegister src = as_FloatRegister($src$$reg);
8876 FloatRegister dst = as_FloatRegister($dst$$reg);
8878 __ abs_d(dst, src);
8879 %}
8880 ins_pipe( fpu_regF_regF );
8881 %}
8883 instruct sqrtD_reg(regD dst, regD src) %{
8884 match(Set dst (SqrtD src));
8885 ins_cost(100);
8886 format %{ "SqrtD $dst, $src @sqrtD_reg" %}
8887 ins_encode %{
8888 FloatRegister src = as_FloatRegister($src$$reg);
8889 FloatRegister dst = as_FloatRegister($dst$$reg);
8891 __ sqrt_d(dst, src);
8892 %}
8893 ins_pipe( fpu_regF_regF );
8894 %}
8896 instruct sqrtF_reg(regF dst, regF src) %{
8897 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
8898 ins_cost(100);
8899 format %{ "SqrtF $dst, $src @sqrtF_reg" %}
8900 ins_encode %{
8901 FloatRegister src = as_FloatRegister($src$$reg);
8902 FloatRegister dst = as_FloatRegister($dst$$reg);
8904 __ sqrt_s(dst, src);
8905 %}
8906 ins_pipe( fpu_regF_regF );
8907 %}
8908 //----------------------------------Logical Instructions----------------------
8909 //__________________________________Integer Logical Instructions-------------
8911 //And Instuctions
8912 // And Register with Immediate
8913 instruct andI_Reg_immI(mRegI dst, mRegI src1, immI src2) %{
8914 match(Set dst (AndI src1 src2));
8916 format %{ "and $dst, $src1, $src2 #@andI_Reg_immI" %}
8917 ins_encode %{
8918 Register dst = $dst$$Register;
8919 Register src = $src1$$Register;
8920 int val = $src2$$constant;
8922 __ move(AT, val);
8923 __ andr(dst, src, AT);
8924 %}
8925 ins_pipe( ialu_regI_regI );
8926 %}
8928 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
8929 match(Set dst (AndI src1 src2));
8930 ins_cost(60);
8932 format %{ "and $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
8933 ins_encode %{
8934 Register dst = $dst$$Register;
8935 Register src = $src1$$Register;
8936 int val = $src2$$constant;
8938 __ andi(dst, src, val);
8939 %}
8940 ins_pipe( ialu_regI_regI );
8941 %}
8943 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1, immI_nonneg_mask mask) %{
8944 match(Set dst (AndI src1 mask));
8945 ins_cost(60);
8947 format %{ "and $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
8948 ins_encode %{
8949 Register dst = $dst$$Register;
8950 Register src = $src1$$Register;
8951 int size = Assembler::is_int_mask($mask$$constant);
8953 __ ext(dst, src, 0, size);
8954 %}
8955 ins_pipe( ialu_regI_regI );
8956 %}
8958 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1, immL_nonneg_mask mask) %{
8959 match(Set dst (AndL src1 mask));
8960 ins_cost(60);
8962 format %{ "and $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
8963 ins_encode %{
8964 Register dst = $dst$$Register;
8965 Register src = $src1$$Register;
8966 int size = Assembler::is_jlong_mask($mask$$constant);
8968 __ dext(dst, src, 0, size);
8969 %}
8970 ins_pipe( ialu_regI_regI );
8971 %}
8973 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
8974 match(Set dst (XorI src1 src2));
8975 ins_cost(60);
8977 format %{ "xori $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
8978 ins_encode %{
8979 Register dst = $dst$$Register;
8980 Register src = $src1$$Register;
8981 int val = $src2$$constant;
8983 __ xori(dst, src, val);
8984 %}
8985 ins_pipe( ialu_regI_regI );
8986 %}
8988 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1, immI_M1 M1) %{
8989 match(Set dst (XorI src1 M1));
8990 predicate(UseLoongsonISA && Use3A2000);
8991 ins_cost(60);
8993 format %{ "xor $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
8994 ins_encode %{
8995 Register dst = $dst$$Register;
8996 Register src = $src1$$Register;
8998 __ gsorn(dst, R0, src);
8999 %}
9000 ins_pipe( ialu_regI_regI );
9001 %}
9003 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1, immI_M1 M1) %{
9004 match(Set dst (XorI (ConvL2I src1) M1));
9005 predicate(UseLoongsonISA && Use3A2000);
9006 ins_cost(60);
9008 format %{ "xor $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
9009 ins_encode %{
9010 Register dst = $dst$$Register;
9011 Register src = $src1$$Register;
9013 __ gsorn(dst, R0, src);
9014 %}
9015 ins_pipe( ialu_regI_regI );
9016 %}
9018 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
9019 match(Set dst (XorL src1 src2));
9020 ins_cost(60);
9022 format %{ "xori $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
9023 ins_encode %{
9024 Register dst = $dst$$Register;
9025 Register src = $src1$$Register;
9026 int val = $src2$$constant;
9028 __ xori(dst, src, val);
9029 %}
9030 ins_pipe( ialu_regI_regI );
9031 %}
9033 /*
9034 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1, immL_M1 M1) %{
9035 match(Set dst (XorL src1 M1));
9036 predicate(UseLoongsonISA);
9037 ins_cost(60);
9039 format %{ "xor $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
9040 ins_encode %{
9041 Register dst = $dst$$Register;
9042 Register src = $src1$$Register;
9044 __ gsorn(dst, R0, src);
9045 %}
9046 ins_pipe( ialu_regI_regI );
9047 %}
9048 */
9050 instruct lbu_and_lmask(mRegI dst, umemory mem, immI_255 mask) %{
9051 match(Set dst (AndI mask (LoadB mem)));
9052 ins_cost(60);
9054 format %{ "lbu $dst, $mem #@lbu_and_lmask" %}
9055 ins_encode(load_UB_enc(dst, mem));
9056 ins_pipe( ialu_loadI );
9057 %}
9059 instruct lbu_and_rmask(mRegI dst, umemory mem, immI_255 mask) %{
9060 match(Set dst (AndI (LoadB mem) mask));
9061 ins_cost(60);
9063 format %{ "lbu $dst, $mem #@lbu_and_rmask" %}
9064 ins_encode(load_UB_enc(dst, mem));
9065 ins_pipe( ialu_loadI );
9066 %}
9068 instruct andI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9069 match(Set dst (AndI src1 src2));
9071 format %{ "and $dst, $src1, $src2 #@andI_Reg_Reg" %}
9072 ins_encode %{
9073 Register dst = $dst$$Register;
9074 Register src1 = $src1$$Register;
9075 Register src2 = $src2$$Register;
9076 __ andr(dst, src1, src2);
9077 %}
9078 ins_pipe( ialu_regI_regI );
9079 %}
9081 instruct andnI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
9082 match(Set dst (AndI src1 (XorI src2 M1)));
9083 predicate(UseLoongsonISA && Use3A2000);
9085 format %{ "andn $dst, $src1, $src2 #@andnI_Reg_nReg" %}
9086 ins_encode %{
9087 Register dst = $dst$$Register;
9088 Register src1 = $src1$$Register;
9089 Register src2 = $src2$$Register;
9091 __ gsandn(dst, src1, src2);
9092 %}
9093 ins_pipe( ialu_regI_regI );
9094 %}
9096 instruct ornI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
9097 match(Set dst (OrI src1 (XorI src2 M1)));
9098 predicate(UseLoongsonISA && Use3A2000);
9100 format %{ "orn $dst, $src1, $src2 #@ornI_Reg_nReg" %}
9101 ins_encode %{
9102 Register dst = $dst$$Register;
9103 Register src1 = $src1$$Register;
9104 Register src2 = $src2$$Register;
9106 __ gsorn(dst, src1, src2);
9107 %}
9108 ins_pipe( ialu_regI_regI );
9109 %}
9111 instruct andnI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
9112 match(Set dst (AndI (XorI src1 M1) src2));
9113 predicate(UseLoongsonISA && Use3A2000);
9115 format %{ "andn $dst, $src2, $src1 #@andnI_nReg_Reg" %}
9116 ins_encode %{
9117 Register dst = $dst$$Register;
9118 Register src1 = $src1$$Register;
9119 Register src2 = $src2$$Register;
9121 __ gsandn(dst, src2, src1);
9122 %}
9123 ins_pipe( ialu_regI_regI );
9124 %}
9126 instruct ornI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
9127 match(Set dst (OrI (XorI src1 M1) src2));
9128 predicate(UseLoongsonISA && Use3A2000);
9130 format %{ "orn $dst, $src2, $src1 #@ornI_nReg_Reg" %}
9131 ins_encode %{
9132 Register dst = $dst$$Register;
9133 Register src1 = $src1$$Register;
9134 Register src2 = $src2$$Register;
9136 __ gsorn(dst, src2, src1);
9137 %}
9138 ins_pipe( ialu_regI_regI );
9139 %}
9141 // And Long Register with Register
9142 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
9143 match(Set dst (AndL src1 src2));
9144 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
9145 ins_encode %{
9146 Register dst_reg = as_Register($dst$$reg);
9147 Register src1_reg = as_Register($src1$$reg);
9148 Register src2_reg = as_Register($src2$$reg);
9150 __ andr(dst_reg, src1_reg, src2_reg);
9151 %}
9152 ins_pipe( ialu_regL_regL );
9153 %}
9155 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
9156 match(Set dst (AndL src1 (ConvI2L src2)));
9157 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
9158 ins_encode %{
9159 Register dst_reg = as_Register($dst$$reg);
9160 Register src1_reg = as_Register($src1$$reg);
9161 Register src2_reg = as_Register($src2$$reg);
9163 __ andr(dst_reg, src1_reg, src2_reg);
9164 %}
9165 ins_pipe( ialu_regL_regL );
9166 %}
9168 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
9169 match(Set dst (AndL src1 src2));
9170 ins_cost(60);
9172 format %{ "and $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
9173 ins_encode %{
9174 Register dst = $dst$$Register;
9175 Register src = $src1$$Register;
9176 long val = $src2$$constant;
9178 __ andi(dst, src, val);
9179 %}
9180 ins_pipe( ialu_regI_regI );
9181 %}
9183 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1, immL_0_65535 src2) %{
9184 match(Set dst (ConvL2I (AndL src1 src2)));
9185 ins_cost(60);
9187 format %{ "and $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
9188 ins_encode %{
9189 Register dst = $dst$$Register;
9190 Register src = $src1$$Register;
9191 long val = $src2$$constant;
9193 __ andi(dst, src, val);
9194 %}
9195 ins_pipe( ialu_regI_regI );
9196 %}
9198 /*
9199 instruct andnL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
9200 match(Set dst (AndL src1 (XorL src2 M1)));
9201 predicate(UseLoongsonISA);
9203 format %{ "andn $dst, $src1, $src2 #@andnL_Reg_nReg" %}
9204 ins_encode %{
9205 Register dst = $dst$$Register;
9206 Register src1 = $src1$$Register;
9207 Register src2 = $src2$$Register;
9209 __ gsandn(dst, src1, src2);
9210 %}
9211 ins_pipe( ialu_regI_regI );
9212 %}
9213 */
9215 /*
9216 instruct ornL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
9217 match(Set dst (OrL src1 (XorL src2 M1)));
9218 predicate(UseLoongsonISA);
9220 format %{ "orn $dst, $src1, $src2 #@ornL_Reg_nReg" %}
9221 ins_encode %{
9222 Register dst = $dst$$Register;
9223 Register src1 = $src1$$Register;
9224 Register src2 = $src2$$Register;
9226 __ gsorn(dst, src1, src2);
9227 %}
9228 ins_pipe( ialu_regI_regI );
9229 %}
9230 */
9232 /*
9233 instruct andnL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
9234 match(Set dst (AndL (XorL src1 M1) src2));
9235 predicate(UseLoongsonISA);
9237 format %{ "andn $dst, $src2, $src1 #@andnL_nReg_Reg" %}
9238 ins_encode %{
9239 Register dst = $dst$$Register;
9240 Register src1 = $src1$$Register;
9241 Register src2 = $src2$$Register;
9243 __ gsandn(dst, src2, src1);
9244 %}
9245 ins_pipe( ialu_regI_regI );
9246 %}
9247 */
9249 /*
9250 instruct ornL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
9251 match(Set dst (OrL (XorL src1 M1) src2));
9252 predicate(UseLoongsonISA);
9254 format %{ "orn $dst, $src2, $src1 #@ornL_nReg_Reg" %}
9255 ins_encode %{
9256 Register dst = $dst$$Register;
9257 Register src1 = $src1$$Register;
9258 Register src2 = $src2$$Register;
9260 __ gsorn(dst, src2, src1);
9261 %}
9262 ins_pipe( ialu_regI_regI );
9263 %}
9264 */
9266 instruct andL_Reg_immL_M8(mRegL dst, immL_M8 M8) %{
9267 match(Set dst (AndL dst M8));
9268 ins_cost(60);
9270 format %{ "and $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
9271 ins_encode %{
9272 Register dst = $dst$$Register;
9274 __ dins(dst, R0, 0, 3);
9275 %}
9276 ins_pipe( ialu_regI_regI );
9277 %}
9279 instruct andL_Reg_immL_M5(mRegL dst, immL_M5 M5) %{
9280 match(Set dst (AndL dst M5));
9281 ins_cost(60);
9283 format %{ "and $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
9284 ins_encode %{
9285 Register dst = $dst$$Register;
9287 __ dins(dst, R0, 2, 1);
9288 %}
9289 ins_pipe( ialu_regI_regI );
9290 %}
9292 instruct andL_Reg_immL_M7(mRegL dst, immL_M7 M7) %{
9293 match(Set dst (AndL dst M7));
9294 ins_cost(60);
9296 format %{ "and $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
9297 ins_encode %{
9298 Register dst = $dst$$Register;
9300 __ dins(dst, R0, 1, 2);
9301 %}
9302 ins_pipe( ialu_regI_regI );
9303 %}
9305 instruct andL_Reg_immL_M4(mRegL dst, immL_M4 M4) %{
9306 match(Set dst (AndL dst M4));
9307 ins_cost(60);
9309 format %{ "and $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
9310 ins_encode %{
9311 Register dst = $dst$$Register;
9313 __ dins(dst, R0, 0, 2);
9314 %}
9315 ins_pipe( ialu_regI_regI );
9316 %}
9318 instruct andL_Reg_immL_M121(mRegL dst, immL_M121 M121) %{
9319 match(Set dst (AndL dst M121));
9320 ins_cost(60);
9322 format %{ "and $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
9323 ins_encode %{
9324 Register dst = $dst$$Register;
9326 __ dins(dst, R0, 3, 4);
9327 %}
9328 ins_pipe( ialu_regI_regI );
9329 %}
9331 // Or Long Register with Register
9332 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
9333 match(Set dst (OrL src1 src2));
9334 format %{ "OR $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
9335 ins_encode %{
9336 Register dst_reg = $dst$$Register;
9337 Register src1_reg = $src1$$Register;
9338 Register src2_reg = $src2$$Register;
9340 __ orr(dst_reg, src1_reg, src2_reg);
9341 %}
9342 ins_pipe( ialu_regL_regL );
9343 %}
9345 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
9346 match(Set dst (OrL (CastP2X src1) src2));
9347 format %{ "OR $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
9348 ins_encode %{
9349 Register dst_reg = $dst$$Register;
9350 Register src1_reg = $src1$$Register;
9351 Register src2_reg = $src2$$Register;
9353 __ orr(dst_reg, src1_reg, src2_reg);
9354 %}
9355 ins_pipe( ialu_regL_regL );
9356 %}
9358 // Xor Long Register with Register
9359 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
9360 match(Set dst (XorL src1 src2));
9361 format %{ "XOR $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
9362 ins_encode %{
9363 Register dst_reg = as_Register($dst$$reg);
9364 Register src1_reg = as_Register($src1$$reg);
9365 Register src2_reg = as_Register($src2$$reg);
9367 __ xorr(dst_reg, src1_reg, src2_reg);
9368 %}
9369 ins_pipe( ialu_regL_regL );
9370 %}
9372 // Shift Left by 8-bit immediate
9373 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
9374 match(Set dst (LShiftI src shift));
9376 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm" %}
9377 ins_encode %{
9378 Register src = $src$$Register;
9379 Register dst = $dst$$Register;
9380 int shamt = $shift$$constant;
9382 __ sll(dst, src, shamt);
9383 %}
9384 ins_pipe( ialu_regI_regI );
9385 %}
9387 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
9388 match(Set dst (LShiftI (ConvL2I src) shift));
9390 format %{ "SHL $dst, $src, $shift #@salL2I_Reg_imm" %}
9391 ins_encode %{
9392 Register src = $src$$Register;
9393 Register dst = $dst$$Register;
9394 int shamt = $shift$$constant;
9396 __ sll(dst, src, shamt);
9397 %}
9398 ins_pipe( ialu_regI_regI );
9399 %}
9401 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
9402 match(Set dst (AndI (LShiftI src shift) mask));
9404 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
9405 ins_encode %{
9406 Register src = $src$$Register;
9407 Register dst = $dst$$Register;
9409 __ sll(dst, src, 16);
9410 %}
9411 ins_pipe( ialu_regI_regI );
9412 %}
9414 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
9415 %{
9416 match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
9418 format %{ "andi $dst, $src, 7\t# @land7_2_s" %}
9419 ins_encode %{
9420 Register src = $src$$Register;
9421 Register dst = $dst$$Register;
9423 __ andi(dst, src, 7);
9424 %}
9425 ins_pipe(ialu_regI_regI);
9426 %}
9428 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
9429 %{
9430 match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
9432 format %{ "ori $dst, $src1, $src2\t# @ori2s" %}
9433 ins_encode %{
9434 Register src = $src1$$Register;
9435 int val = $src2$$constant;
9436 Register dst = $dst$$Register;
9438 __ ori(dst, src, val);
9439 %}
9440 ins_pipe(ialu_regI_regI);
9441 %}
9443 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
9444 // This idiom is used by the compiler the i2s bytecode.
9445 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
9446 %{
9447 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
9449 format %{ "i2s $dst, $src\t# @i2s" %}
9450 ins_encode %{
9451 Register src = $src$$Register;
9452 Register dst = $dst$$Register;
9454 __ seh(dst, src);
9455 %}
9456 ins_pipe(ialu_regI_regI);
9457 %}
9459 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
9460 // This idiom is used by the compiler for the i2b bytecode.
9461 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
9462 %{
9463 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
9465 format %{ "i2b $dst, $src\t# @i2b" %}
9466 ins_encode %{
9467 Register src = $src$$Register;
9468 Register dst = $dst$$Register;
9470 __ seb(dst, src);
9471 %}
9472 ins_pipe(ialu_regI_regI);
9473 %}
9476 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
9477 match(Set dst (LShiftI (ConvL2I src) shift));
9479 format %{ "SHL $dst, $src, $shift #@salI_RegL2I_imm" %}
9480 ins_encode %{
9481 Register src = $src$$Register;
9482 Register dst = $dst$$Register;
9483 int shamt = $shift$$constant;
9485 __ sll(dst, src, shamt);
9486 %}
9487 ins_pipe( ialu_regI_regI );
9488 %}
9490 // Shift Left by 8-bit immediate
9491 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
9492 match(Set dst (LShiftI src shift));
9494 format %{ "SHL $dst, $src, $shift #@salI_Reg_Reg" %}
9495 ins_encode %{
9496 Register src = $src$$Register;
9497 Register dst = $dst$$Register;
9498 Register shamt = $shift$$Register;
9499 __ sllv(dst, src, shamt);
9500 %}
9501 ins_pipe( ialu_regI_regI );
9502 %}
9505 // Shift Left Long
9506 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
9507 //predicate(UseNewLongLShift);
9508 match(Set dst (LShiftL src shift));
9509 ins_cost(100);
9510 format %{ "salL $dst, $src, $shift @ salL_Reg_imm" %}
9511 ins_encode %{
9512 Register src_reg = as_Register($src$$reg);
9513 Register dst_reg = as_Register($dst$$reg);
9514 int shamt = $shift$$constant;
9516 if (__ is_simm(shamt, 5))
9517 __ dsll(dst_reg, src_reg, shamt);
9518 else
9519 {
9520 int sa = Assembler::low(shamt, 6);
9521 if (sa < 32) {
9522 __ dsll(dst_reg, src_reg, sa);
9523 } else {
9524 __ dsll32(dst_reg, src_reg, sa - 32);
9525 }
9526 }
9527 %}
9528 ins_pipe( ialu_regL_regL );
9529 %}
9531 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
9532 //predicate(UseNewLongLShift);
9533 match(Set dst (LShiftL (ConvI2L src) shift));
9534 ins_cost(100);
9535 format %{ "salL $dst, $src, $shift @ salL_RegI2L_imm" %}
9536 ins_encode %{
9537 Register src_reg = as_Register($src$$reg);
9538 Register dst_reg = as_Register($dst$$reg);
9539 int shamt = $shift$$constant;
9541 if (__ is_simm(shamt, 5))
9542 __ dsll(dst_reg, src_reg, shamt);
9543 else
9544 {
9545 int sa = Assembler::low(shamt, 6);
9546 if (sa < 32) {
9547 __ dsll(dst_reg, src_reg, sa);
9548 } else {
9549 __ dsll32(dst_reg, src_reg, sa - 32);
9550 }
9551 }
9552 %}
9553 ins_pipe( ialu_regL_regL );
9554 %}
9556 // Shift Left Long
9557 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
9558 //predicate(UseNewLongLShift);
9559 match(Set dst (LShiftL src shift));
9560 ins_cost(100);
9561 format %{ "salL $dst, $src, $shift @ salL_Reg_Reg" %}
9562 ins_encode %{
9563 Register src_reg = as_Register($src$$reg);
9564 Register dst_reg = as_Register($dst$$reg);
9566 __ dsllv(dst_reg, src_reg, $shift$$Register);
9567 %}
9568 ins_pipe( ialu_regL_regL );
9569 %}
9571 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
9572 match(Set dst (LShiftL (ConvI2L src) shift));
9573 ins_cost(100);
9574 format %{ "salL $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
9575 ins_encode %{
9576 Register src_reg = as_Register($src$$reg);
9577 Register dst_reg = as_Register($dst$$reg);
9578 int shamt = $shift$$constant;
9580 if (__ is_simm(shamt, 5)) {
9581 __ dsll(dst_reg, src_reg, shamt);
9582 } else {
9583 int sa = Assembler::low(shamt, 6);
9584 if (sa < 32) {
9585 __ dsll(dst_reg, src_reg, sa);
9586 } else {
9587 __ dsll32(dst_reg, src_reg, sa - 32);
9588 }
9589 }
9590 %}
9591 ins_pipe( ialu_regL_regL );
9592 %}
9594 // Shift Right Long
9595 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
9596 match(Set dst (RShiftL src shift));
9597 ins_cost(100);
9598 format %{ "sarL $dst, $src, $shift @ sarL_Reg_imm" %}
9599 ins_encode %{
9600 Register src_reg = as_Register($src$$reg);
9601 Register dst_reg = as_Register($dst$$reg);
9602 int shamt = ($shift$$constant & 0x3f);
9603 if (__ is_simm(shamt, 5))
9604 __ dsra(dst_reg, src_reg, shamt);
9605 else {
9606 int sa = Assembler::low(shamt, 6);
9607 if (sa < 32) {
9608 __ dsra(dst_reg, src_reg, sa);
9609 } else {
9610 __ dsra32(dst_reg, src_reg, sa - 32);
9611 }
9612 }
9613 %}
9614 ins_pipe( ialu_regL_regL );
9615 %}
9617 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
9618 match(Set dst (ConvL2I (RShiftL src shift)));
9619 ins_cost(100);
9620 format %{ "sarL $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
9621 ins_encode %{
9622 Register src_reg = as_Register($src$$reg);
9623 Register dst_reg = as_Register($dst$$reg);
9624 int shamt = $shift$$constant;
9626 __ dsra32(dst_reg, src_reg, shamt - 32);
9627 %}
9628 ins_pipe( ialu_regL_regL );
9629 %}
9631 // Shift Right Long arithmetically
9632 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
9633 //predicate(UseNewLongLShift);
9634 match(Set dst (RShiftL src shift));
9635 ins_cost(100);
9636 format %{ "sarL $dst, $src, $shift @ sarL_Reg_Reg" %}
9637 ins_encode %{
9638 Register src_reg = as_Register($src$$reg);
9639 Register dst_reg = as_Register($dst$$reg);
9641 __ dsrav(dst_reg, src_reg, $shift$$Register);
9642 %}
9643 ins_pipe( ialu_regL_regL );
9644 %}
9646 // Shift Right Long logically
9647 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
9648 match(Set dst (URShiftL src shift));
9649 ins_cost(100);
9650 format %{ "slrL $dst, $src, $shift @ slrL_Reg_Reg" %}
9651 ins_encode %{
9652 Register src_reg = as_Register($src$$reg);
9653 Register dst_reg = as_Register($dst$$reg);
9655 __ dsrlv(dst_reg, src_reg, $shift$$Register);
9656 %}
9657 ins_pipe( ialu_regL_regL );
9658 %}
9660 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
9661 match(Set dst (URShiftL src shift));
9662 ins_cost(80);
9663 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
9664 ins_encode %{
9665 Register src_reg = as_Register($src$$reg);
9666 Register dst_reg = as_Register($dst$$reg);
9667 int shamt = $shift$$constant;
9669 __ dsrl(dst_reg, src_reg, shamt);
9670 %}
9671 ins_pipe( ialu_regL_regL );
9672 %}
9674 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
9675 match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
9676 ins_cost(80);
9677 format %{ "dext $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
9678 ins_encode %{
9679 Register src_reg = as_Register($src$$reg);
9680 Register dst_reg = as_Register($dst$$reg);
9681 int shamt = $shift$$constant;
9683 __ dext(dst_reg, src_reg, shamt, 31);
9684 %}
9685 ins_pipe( ialu_regL_regL );
9686 %}
9688 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
9689 match(Set dst (URShiftL (CastP2X src) shift));
9690 ins_cost(80);
9691 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
9692 ins_encode %{
9693 Register src_reg = as_Register($src$$reg);
9694 Register dst_reg = as_Register($dst$$reg);
9695 int shamt = $shift$$constant;
9697 __ dsrl(dst_reg, src_reg, shamt);
9698 %}
9699 ins_pipe( ialu_regL_regL );
9700 %}
9702 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
9703 match(Set dst (URShiftL src shift));
9704 ins_cost(80);
9705 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
9706 ins_encode %{
9707 Register src_reg = as_Register($src$$reg);
9708 Register dst_reg = as_Register($dst$$reg);
9709 int shamt = $shift$$constant;
9711 __ dsrl32(dst_reg, src_reg, shamt - 32);
9712 %}
9713 ins_pipe( ialu_regL_regL );
9714 %}
9716 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
9717 match(Set dst (ConvL2I (URShiftL src shift)));
9718 predicate(n->in(1)->in(2)->get_int() > 32);
9719 ins_cost(80);
9720 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
9721 ins_encode %{
9722 Register src_reg = as_Register($src$$reg);
9723 Register dst_reg = as_Register($dst$$reg);
9724 int shamt = $shift$$constant;
9726 __ dsrl32(dst_reg, src_reg, shamt - 32);
9727 %}
9728 ins_pipe( ialu_regL_regL );
9729 %}
9731 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
9732 match(Set dst (URShiftL (CastP2X src) shift));
9733 ins_cost(80);
9734 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
9735 ins_encode %{
9736 Register src_reg = as_Register($src$$reg);
9737 Register dst_reg = as_Register($dst$$reg);
9738 int shamt = $shift$$constant;
9740 __ dsrl32(dst_reg, src_reg, shamt - 32);
9741 %}
9742 ins_pipe( ialu_regL_regL );
9743 %}
9745 // Xor Instructions
9746 // Xor Register with Register
9747 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9748 match(Set dst (XorI src1 src2));
9750 format %{ "XOR $dst, $src1, $src2 #@xorI_Reg_Reg" %}
9752 ins_encode %{
9753 Register dst = $dst$$Register;
9754 Register src1 = $src1$$Register;
9755 Register src2 = $src2$$Register;
9756 __ xorr(dst, src1, src2);
9757 __ sll(dst, dst, 0); /* long -> int */
9758 %}
9760 ins_pipe( ialu_regI_regI );
9761 %}
9763 // Or Instructions
9764 // Or Register with Register
9765 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9766 match(Set dst (OrI src1 src2));
9768 format %{ "OR $dst, $src1, $src2 #@orI_Reg_Reg" %}
9769 ins_encode %{
9770 Register dst = $dst$$Register;
9771 Register src1 = $src1$$Register;
9772 Register src2 = $src2$$Register;
9773 __ orr(dst, src1, src2);
9774 %}
9776 ins_pipe( ialu_regI_regI );
9777 %}
9779 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
9780 match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
9781 predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
9783 format %{ "rotr $dst, $src, 1 ...\n\t"
9784 "srl $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
9785 ins_encode %{
9786 Register dst = $dst$$Register;
9787 Register src = $src$$Register;
9788 int rshift = $rshift$$constant;
9790 __ rotr(dst, src, 1);
9791 if (rshift - 1) {
9792 __ srl(dst, dst, rshift - 1);
9793 }
9794 %}
9796 ins_pipe( ialu_regI_regI );
9797 %}
9799 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
9800 match(Set dst (OrI src1 (CastP2X src2)));
9802 format %{ "OR $dst, $src1, $src2 #@orI_Reg_castP2X" %}
9803 ins_encode %{
9804 Register dst = $dst$$Register;
9805 Register src1 = $src1$$Register;
9806 Register src2 = $src2$$Register;
9807 __ orr(dst, src1, src2);
9808 %}
9810 ins_pipe( ialu_regI_regI );
9811 %}
9813 // Logical Shift Right by 8-bit immediate
9814 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
9815 match(Set dst (URShiftI src shift));
9816 // effect(KILL cr);
9818 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_imm" %}
9819 ins_encode %{
9820 Register src = $src$$Register;
9821 Register dst = $dst$$Register;
9822 int shift = $shift$$constant;
9824 __ srl(dst, src, shift);
9825 %}
9826 ins_pipe( ialu_regI_regI );
9827 %}
9829 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
9830 match(Set dst (AndI (URShiftI src shift) mask));
9832 format %{ "ext $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
9833 ins_encode %{
9834 Register src = $src$$Register;
9835 Register dst = $dst$$Register;
9836 int pos = $shift$$constant;
9837 int size = Assembler::is_int_mask($mask$$constant);
9839 __ ext(dst, src, pos, size);
9840 %}
9841 ins_pipe( ialu_regI_regI );
9842 %}
9844 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
9845 %{
9846 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9847 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
9849 ins_cost(100);
9850 format %{ "rotr $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
9851 ins_encode %{
9852 Register dst = $dst$$Register;
9853 int sa = $rshift$$constant;
9855 __ rotr(dst, dst, sa);
9856 %}
9857 ins_pipe( ialu_regI_regI );
9858 %}
9860 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
9861 %{
9862 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9863 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
9865 ins_cost(100);
9866 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
9867 ins_encode %{
9868 Register dst = $dst$$Register;
9869 int sa = $rshift$$constant;
9871 __ drotr(dst, dst, sa);
9872 %}
9873 ins_pipe( ialu_regI_regI );
9874 %}
9876 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
9877 %{
9878 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9879 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
9881 ins_cost(100);
9882 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
9883 ins_encode %{
9884 Register dst = $dst$$Register;
9885 int sa = $rshift$$constant;
9887 __ drotr32(dst, dst, sa - 32);
9888 %}
9889 ins_pipe( ialu_regI_regI );
9890 %}
9892 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
9893 %{
9894 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9895 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
9897 ins_cost(100);
9898 format %{ "rotr $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
9899 ins_encode %{
9900 Register dst = $dst$$Register;
9901 int sa = $rshift$$constant;
9903 __ rotr(dst, dst, sa);
9904 %}
9905 ins_pipe( ialu_regI_regI );
9906 %}
9908 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
9909 %{
9910 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9911 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
9913 ins_cost(100);
9914 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
9915 ins_encode %{
9916 Register dst = $dst$$Register;
9917 int sa = $rshift$$constant;
9919 __ drotr(dst, dst, sa);
9920 %}
9921 ins_pipe( ialu_regI_regI );
9922 %}
9924 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
9925 %{
9926 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9927 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
9929 ins_cost(100);
9930 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
9931 ins_encode %{
9932 Register dst = $dst$$Register;
9933 int sa = $rshift$$constant;
9935 __ drotr32(dst, dst, sa - 32);
9936 %}
9937 ins_pipe( ialu_regI_regI );
9938 %}
9940 // Logical Shift Right
9941 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
9942 match(Set dst (URShiftI src shift));
9944 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_Reg" %}
9945 ins_encode %{
9946 Register src = $src$$Register;
9947 Register dst = $dst$$Register;
9948 Register shift = $shift$$Register;
9949 __ srlv(dst, src, shift);
9950 %}
9951 ins_pipe( ialu_regI_regI );
9952 %}
9955 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
9956 match(Set dst (RShiftI src shift));
9957 // effect(KILL cr);
9959 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_imm" %}
9960 ins_encode %{
9961 Register src = $src$$Register;
9962 Register dst = $dst$$Register;
9963 int shift = $shift$$constant;
9964 __ sra(dst, src, shift);
9965 %}
9966 ins_pipe( ialu_regI_regI );
9967 %}
9969 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
9970 match(Set dst (RShiftI src shift));
9971 // effect(KILL cr);
9973 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_Reg" %}
9974 ins_encode %{
9975 Register src = $src$$Register;
9976 Register dst = $dst$$Register;
9977 Register shift = $shift$$Register;
9978 __ srav(dst, src, shift);
9979 %}
9980 ins_pipe( ialu_regI_regI );
9981 %}
9983 //----------Convert Int to Boolean---------------------------------------------
9985 instruct convI2B(mRegI dst, mRegI src) %{
9986 match(Set dst (Conv2B src));
9988 ins_cost(100);
9989 format %{ "convI2B $dst, $src @ convI2B" %}
9990 ins_encode %{
9991 Register dst = as_Register($dst$$reg);
9992 Register src = as_Register($src$$reg);
9994 if (dst != src) {
9995 __ daddiu(dst, R0, 1);
9996 __ movz(dst, R0, src);
9997 } else {
9998 __ move(AT, src);
9999 __ daddiu(dst, R0, 1);
10000 __ movz(dst, R0, AT);
10001 }
10002 %}
10004 ins_pipe( ialu_regL_regL );
10005 %}
10007 instruct convI2L_reg( mRegL dst, mRegI src) %{
10008 match(Set dst (ConvI2L src));
10010 ins_cost(100);
10011 format %{ "SLL $dst, $src @ convI2L_reg\t" %}
10012 ins_encode %{
10013 Register dst = as_Register($dst$$reg);
10014 Register src = as_Register($src$$reg);
10016 if(dst != src) __ sll(dst, src, 0);
10017 %}
10018 ins_pipe( ialu_regL_regL );
10019 %}
10022 instruct convL2I_reg( mRegI dst, mRegL src ) %{
10023 match(Set dst (ConvL2I src));
10025 format %{ "MOV $dst, $src @ convL2I_reg" %}
10026 ins_encode %{
10027 Register dst = as_Register($dst$$reg);
10028 Register src = as_Register($src$$reg);
10030 __ sll(dst, src, 0);
10031 %}
10033 ins_pipe( ialu_regI_regI );
10034 %}
10036 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
10037 match(Set dst (ConvI2L (ConvL2I src)));
10039 format %{ "sll $dst, $src, 0 @ convL2I2L_reg" %}
10040 ins_encode %{
10041 Register dst = as_Register($dst$$reg);
10042 Register src = as_Register($src$$reg);
10044 __ sll(dst, src, 0);
10045 %}
10047 ins_pipe( ialu_regI_regI );
10048 %}
10050 instruct convL2D_reg( regD dst, mRegL src ) %{
10051 match(Set dst (ConvL2D src));
10052 format %{ "convL2D $dst, $src @ convL2D_reg" %}
10053 ins_encode %{
10054 Register src = as_Register($src$$reg);
10055 FloatRegister dst = as_FloatRegister($dst$$reg);
10057 __ dmtc1(src, dst);
10058 __ cvt_d_l(dst, dst);
10059 %}
10061 ins_pipe( pipe_slow );
10062 %}
10064 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
10065 match(Set dst (ConvD2L src));
10066 ins_cost(150);
10067 format %{ "convD2L $dst, $src @ convD2L_reg_fast" %}
10068 ins_encode %{
10069 Register dst = as_Register($dst$$reg);
10070 FloatRegister src = as_FloatRegister($src$$reg);
10072 Label Done;
10074 __ trunc_l_d(F30, src);
10075 // max_long: 0x7fffffffffffffff
10076 // __ set64(AT, 0x7fffffffffffffff);
10077 __ daddiu(AT, R0, -1);
10078 __ dsrl(AT, AT, 1);
10079 __ dmfc1(dst, F30);
10081 __ bne(dst, AT, Done);
10082 __ delayed()->mtc1(R0, F30);
10084 __ cvt_d_w(F30, F30);
10085 __ c_ult_d(src, F30);
10086 __ bc1f(Done);
10087 __ delayed()->daddiu(T9, R0, -1);
10089 __ c_un_d(src, src); //NaN?
10090 __ subu(dst, T9, AT);
10091 __ movt(dst, R0);
10093 __ bind(Done);
10094 %}
10096 ins_pipe( pipe_slow );
10097 %}
10099 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
10100 match(Set dst (ConvD2L src));
10101 ins_cost(250);
10102 format %{ "convD2L $dst, $src @ convD2L_reg_slow" %}
10103 ins_encode %{
10104 Register dst = as_Register($dst$$reg);
10105 FloatRegister src = as_FloatRegister($src$$reg);
10107 Label L;
10109 __ c_un_d(src, src); //NaN?
10110 __ bc1t(L);
10111 __ delayed();
10112 __ move(dst, R0);
10114 __ trunc_l_d(F30, src);
10115 __ cfc1(AT, 31);
10116 __ li(T9, 0x10000);
10117 __ andr(AT, AT, T9);
10118 __ beq(AT, R0, L);
10119 __ delayed()->dmfc1(dst, F30);
10121 __ mov_d(F12, src);
10122 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
10123 __ move(dst, V0);
10124 __ bind(L);
10125 %}
10127 ins_pipe( pipe_slow );
10128 %}
10130 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
10131 match(Set dst (ConvF2I src));
10132 ins_cost(150);
10133 format %{ "convf2i $dst, $src @ convF2I_reg_fast" %}
10134 ins_encode %{
10135 Register dreg = $dst$$Register;
10136 FloatRegister fval = $src$$FloatRegister;
10138 __ trunc_w_s(F30, fval);
10139 __ mfc1(dreg, F30);
10140 __ c_un_s(fval, fval); //NaN?
10141 __ movt(dreg, R0);
10142 %}
10144 ins_pipe( pipe_slow );
10145 %}
10147 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
10148 match(Set dst (ConvF2I src));
10149 ins_cost(250);
10150 format %{ "convf2i $dst, $src @ convF2I_reg_slow" %}
10151 ins_encode %{
10152 Register dreg = $dst$$Register;
10153 FloatRegister fval = $src$$FloatRegister;
10154 Label L;
10156 __ c_un_s(fval, fval); //NaN?
10157 __ bc1t(L);
10158 __ delayed();
10159 __ move(dreg, R0);
10161 __ trunc_w_s(F30, fval);
10163 /* Call SharedRuntime:f2i() to do valid convention */
10164 __ cfc1(AT, 31);
10165 __ li(T9, 0x10000);
10166 __ andr(AT, AT, T9);
10167 __ beq(AT, R0, L);
10168 __ delayed()->mfc1(dreg, F30);
10170 __ mov_s(F12, fval);
10172 /* 2014/01/08 Fu : This bug was found when running ezDS's control-panel.
10173 * J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
10174 *
10175 * An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
10176 * V0 is corrupted during call_VM_leaf(), and should be preserved.
10177 */
10178 if(dreg != V0) {
10179 __ push(V0);
10180 }
10181 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
10182 if(dreg != V0) {
10183 __ move(dreg, V0);
10184 __ pop(V0);
10185 }
10186 __ bind(L);
10187 %}
10189 ins_pipe( pipe_slow );
10190 %}
10192 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
10193 match(Set dst (ConvF2L src));
10194 ins_cost(150);
10195 format %{ "convf2l $dst, $src @ convF2L_reg_fast" %}
10196 ins_encode %{
10197 Register dreg = $dst$$Register;
10198 FloatRegister fval = $src$$FloatRegister;
10200 __ trunc_l_s(F30, fval);
10201 __ dmfc1(dreg, F30);
10202 __ c_un_s(fval, fval); //NaN?
10203 __ movt(dreg, R0);
10204 %}
10206 ins_pipe( pipe_slow );
10207 %}
10209 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
10210 match(Set dst (ConvF2L src));
10211 ins_cost(250);
10212 format %{ "convf2l $dst, $src @ convF2L_reg_slow" %}
10213 ins_encode %{
10214 Register dst = as_Register($dst$$reg);
10215 FloatRegister fval = $src$$FloatRegister;
10216 Label L;
10218 __ c_un_s(fval, fval); //NaN?
10219 __ bc1t(L);
10220 __ delayed();
10221 __ move(dst, R0);
10223 __ trunc_l_s(F30, fval);
10224 __ cfc1(AT, 31);
10225 __ li(T9, 0x10000);
10226 __ andr(AT, AT, T9);
10227 __ beq(AT, R0, L);
10228 __ delayed()->dmfc1(dst, F30);
10230 __ mov_s(F12, fval);
10231 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
10232 __ move(dst, V0);
10233 __ bind(L);
10234 %}
10236 ins_pipe( pipe_slow );
10237 %}
10239 instruct convL2F_reg( regF dst, mRegL src ) %{
10240 match(Set dst (ConvL2F src));
10241 format %{ "convl2f $dst, $src @ convL2F_reg" %}
10242 ins_encode %{
10243 FloatRegister dst = $dst$$FloatRegister;
10244 Register src = as_Register($src$$reg);
10245 Label L;
10247 __ dmtc1(src, dst);
10248 __ cvt_s_l(dst, dst);
10249 %}
10251 ins_pipe( pipe_slow );
10252 %}
10254 instruct convI2F_reg( regF dst, mRegI src ) %{
10255 match(Set dst (ConvI2F src));
10256 format %{ "convi2f $dst, $src @ convI2F_reg" %}
10257 ins_encode %{
10258 Register src = $src$$Register;
10259 FloatRegister dst = $dst$$FloatRegister;
10261 __ mtc1(src, dst);
10262 __ cvt_s_w(dst, dst);
10263 %}
10265 ins_pipe( fpu_regF_regF );
10266 %}
10268 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
10269 match(Set dst (CmpLTMask p zero));
10270 ins_cost(100);
10272 format %{ "sra $dst, $p, 31 @ cmpLTMask_immI0" %}
10273 ins_encode %{
10274 Register src = $p$$Register;
10275 Register dst = $dst$$Register;
10277 __ sra(dst, src, 31);
10278 %}
10279 ins_pipe( pipe_slow );
10280 %}
10283 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
10284 match(Set dst (CmpLTMask p q));
10285 ins_cost(400);
10287 format %{ "cmpLTMask $dst, $p, $q @ cmpLTMask" %}
10288 ins_encode %{
10289 Register p = $p$$Register;
10290 Register q = $q$$Register;
10291 Register dst = $dst$$Register;
10293 __ slt(dst, p, q);
10294 __ subu(dst, R0, dst);
10295 %}
10296 ins_pipe( pipe_slow );
10297 %}
10299 instruct convP2B(mRegI dst, mRegP src) %{
10300 match(Set dst (Conv2B src));
10302 ins_cost(100);
10303 format %{ "convP2B $dst, $src @ convP2B" %}
10304 ins_encode %{
10305 Register dst = as_Register($dst$$reg);
10306 Register src = as_Register($src$$reg);
10308 if (dst != src) {
10309 __ daddiu(dst, R0, 1);
10310 __ movz(dst, R0, src);
10311 } else {
10312 __ move(AT, src);
10313 __ daddiu(dst, R0, 1);
10314 __ movz(dst, R0, AT);
10315 }
10316 %}
10318 ins_pipe( ialu_regL_regL );
10319 %}
10322 instruct convI2D_reg_reg(regD dst, mRegI src) %{
10323 match(Set dst (ConvI2D src));
10324 format %{ "conI2D $dst, $src @convI2D_reg" %}
10325 ins_encode %{
10326 Register src = $src$$Register;
10327 FloatRegister dst = $dst$$FloatRegister;
10328 __ mtc1(src, dst);
10329 __ cvt_d_w(dst, dst);
10330 %}
10331 ins_pipe( fpu_regF_regF );
10332 %}
10334 instruct convF2D_reg_reg(regD dst, regF src) %{
10335 match(Set dst (ConvF2D src));
10336 format %{ "convF2D $dst, $src\t# @convF2D_reg_reg" %}
10337 ins_encode %{
10338 FloatRegister dst = $dst$$FloatRegister;
10339 FloatRegister src = $src$$FloatRegister;
10341 __ cvt_d_s(dst, src);
10342 %}
10343 ins_pipe( fpu_regF_regF );
10344 %}
10346 instruct convD2F_reg_reg(regF dst, regD src) %{
10347 match(Set dst (ConvD2F src));
10348 format %{ "convD2F $dst, $src\t# @convD2F_reg_reg" %}
10349 ins_encode %{
10350 FloatRegister dst = $dst$$FloatRegister;
10351 FloatRegister src = $src$$FloatRegister;
10353 __ cvt_s_d(dst, src);
10354 %}
10355 ins_pipe( fpu_regF_regF );
10356 %}
10358 // Convert a double to an int. If the double is a NAN, stuff a zero in instead.
10359 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
10360 match(Set dst (ConvD2I src));
10362 ins_cost(150);
10363 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
10365 ins_encode %{
10366 FloatRegister src = $src$$FloatRegister;
10367 Register dst = $dst$$Register;
10369 Label Done;
10371 __ trunc_w_d(F30, src);
10372 // max_int: 2147483647
10373 __ move(AT, 0x7fffffff);
10374 __ mfc1(dst, F30);
10376 __ bne(dst, AT, Done);
10377 __ delayed()->mtc1(R0, F30);
10379 __ cvt_d_w(F30, F30);
10380 __ c_ult_d(src, F30);
10381 __ bc1f(Done);
10382 __ delayed()->addiu(T9, R0, -1);
10384 __ c_un_d(src, src); //NaN?
10385 __ subu32(dst, T9, AT);
10386 __ movt(dst, R0);
10388 __ bind(Done);
10389 %}
10390 ins_pipe( pipe_slow );
10391 %}
10393 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
10394 match(Set dst (ConvD2I src));
10396 ins_cost(250);
10397 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
10399 ins_encode %{
10400 FloatRegister src = $src$$FloatRegister;
10401 Register dst = $dst$$Register;
10402 Label L;
10404 __ trunc_w_d(F30, src);
10405 __ cfc1(AT, 31);
10406 __ li(T9, 0x10000);
10407 __ andr(AT, AT, T9);
10408 __ beq(AT, R0, L);
10409 __ delayed()->mfc1(dst, F30);
10411 __ mov_d(F12, src);
10412 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
10413 __ move(dst, V0);
10414 __ bind(L);
10416 %}
10417 ins_pipe( pipe_slow );
10418 %}
10420 // Convert oop pointer into compressed form
10421 instruct encodeHeapOop(mRegN dst, mRegP src) %{
10422 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
10423 match(Set dst (EncodeP src));
10424 format %{ "encode_heap_oop $dst,$src" %}
10425 ins_encode %{
10426 Register src = $src$$Register;
10427 Register dst = $dst$$Register;
10428 if (src != dst) {
10429 __ move(dst, src);
10430 }
10431 __ encode_heap_oop(dst);
10432 %}
10433 ins_pipe( ialu_regL_regL );
10434 %}
10436 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
10437 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
10438 match(Set dst (EncodeP src));
10439 format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
10440 ins_encode %{
10441 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
10442 %}
10443 ins_pipe( ialu_regL_regL );
10444 %}
10446 instruct decodeHeapOop(mRegP dst, mRegN src) %{
10447 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
10448 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
10449 match(Set dst (DecodeN src));
10450 format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
10451 ins_encode %{
10452 Register s = $src$$Register;
10453 Register d = $dst$$Register;
10454 if (s != d) {
10455 __ move(d, s);
10456 }
10457 __ decode_heap_oop(d);
10458 %}
10459 ins_pipe( ialu_regL_regL );
10460 %}
10462 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
10463 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
10464 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
10465 match(Set dst (DecodeN src));
10466 format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
10467 ins_encode %{
10468 Register s = $src$$Register;
10469 Register d = $dst$$Register;
10470 if (s != d) {
10471 __ decode_heap_oop_not_null(d, s);
10472 } else {
10473 __ decode_heap_oop_not_null(d);
10474 }
10475 %}
10476 ins_pipe( ialu_regL_regL );
10477 %}
10479 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
10480 match(Set dst (EncodePKlass src));
10481 format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
10482 ins_encode %{
10483 __ encode_klass_not_null($dst$$Register, $src$$Register);
10484 %}
10485 ins_pipe( ialu_regL_regL );
10486 %}
10488 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
10489 match(Set dst (DecodeNKlass src));
10490 format %{ "decode_heap_klass_not_null $dst,$src" %}
10491 ins_encode %{
10492 Register s = $src$$Register;
10493 Register d = $dst$$Register;
10494 if (s != d) {
10495 __ decode_klass_not_null(d, s);
10496 } else {
10497 __ decode_klass_not_null(d);
10498 }
10499 %}
10500 ins_pipe( ialu_regL_regL );
10501 %}
10503 //FIXME
10504 instruct tlsLoadP(mRegP dst) %{
10505 match(Set dst (ThreadLocal));
10507 ins_cost(0);
10508 format %{ " get_thread in $dst #@tlsLoadP" %}
10509 ins_encode %{
10510 Register dst = $dst$$Register;
10511 #ifdef OPT_THREAD
10512 __ move(dst, TREG);
10513 #else
10514 __ get_thread(dst);
10515 #endif
10516 %}
10518 ins_pipe( ialu_loadI );
10519 %}
10522 instruct checkCastPP( mRegP dst ) %{
10523 match(Set dst (CheckCastPP dst));
10525 format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
10526 ins_encode( /*empty encoding*/ );
10527 ins_pipe( empty );
10528 %}
10530 instruct castPP(mRegP dst)
10531 %{
10532 match(Set dst (CastPP dst));
10534 size(0);
10535 format %{ "# castPP of $dst" %}
10536 ins_encode(/* empty encoding */);
10537 ins_pipe(empty);
10538 %}
10540 instruct castII( mRegI dst ) %{
10541 match(Set dst (CastII dst));
10542 format %{ "#castII of $dst empty encoding" %}
10543 ins_encode( /*empty encoding*/ );
10544 ins_cost(0);
10545 ins_pipe( empty );
10546 %}
10548 // Return Instruction
10549 // Remove the return address & jump to it.
10550 instruct Ret() %{
10551 match(Return);
10552 format %{ "RET #@Ret" %}
10554 ins_encode %{
10555 __ jr(RA);
10556 __ nop();
10557 %}
10559 ins_pipe( pipe_jump );
10560 %}
10562 /*
10563 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
10564 instruct jumpXtnd(mRegL switch_val) %{
10565 match(Jump switch_val);
10567 ins_cost(350);
10569 format %{ "load T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
10570 "jr T9\n\t"
10571 "nop" %}
10572 ins_encode %{
10573 Register table_base = $constanttablebase;
10574 int con_offset = $constantoffset;
10575 Register switch_reg = $switch_val$$Register;
10577 if (UseLoongsonISA) {
10578 if (Assembler::is_simm(con_offset, 8)) {
10579 __ gsldx(T9, table_base, switch_reg, con_offset);
10580 } else if (Assembler::is_simm16(con_offset)) {
10581 __ daddu(T9, table_base, switch_reg);
10582 __ ld(T9, T9, con_offset);
10583 } else {
10584 __ move(T9, con_offset);
10585 __ daddu(AT, table_base, switch_reg);
10586 __ gsldx(T9, AT, T9, 0);
10587 }
10588 } else {
10589 if (Assembler::is_simm16(con_offset)) {
10590 __ daddu(T9, table_base, switch_reg);
10591 __ ld(T9, T9, con_offset);
10592 } else {
10593 __ move(T9, con_offset);
10594 __ daddu(AT, table_base, switch_reg);
10595 __ daddu(AT, T9, AT);
10596 __ ld(T9, AT, 0);
10597 }
10598 }
10600 __ jr(T9);
10601 __ nop();
10603 %}
10604 ins_pipe(pipe_jump);
10605 %}
10606 */
10608 // Jump Direct - Label defines a relative address from JMP
10609 instruct jmpDir(label labl) %{
10610 match(Goto);
10611 effect(USE labl);
10613 ins_cost(300);
10614 format %{ "JMP $labl #@jmpDir" %}
10616 ins_encode %{
10617 Label &L = *($labl$$label);
10618 if(&L)
10619 __ b(L);
10620 else
10621 __ b(int(0));
10622 __ nop();
10623 %}
10625 ins_pipe( pipe_jump );
10626 ins_pc_relative(1);
10627 %}
10631 // Tail Jump; remove the return address; jump to target.
10632 // TailCall above leaves the return address around.
10633 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
10634 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
10635 // "restore" before this instruction (in Epilogue), we need to materialize it
10636 // in %i0.
10637 //FIXME
10638 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
10639 match( TailJump jump_target ex_oop );
10640 ins_cost(200);
10641 format %{ "Jmp $jump_target ; ex_oop = $ex_oop #@tailjmpInd" %}
10642 ins_encode %{
10643 Register target = $jump_target$$Register;
10645 /* 2012/9/14 Jin: V0, V1 are indicated in:
10646 * [stubGenerator_mips.cpp] generate_forward_exception()
10647 * [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
10648 */
10649 Register oop = $ex_oop$$Register;
10650 Register exception_oop = V0;
10651 Register exception_pc = V1;
10653 __ move(exception_pc, RA);
10654 __ move(exception_oop, oop);
10656 __ jr(target);
10657 __ nop();
10658 %}
10659 ins_pipe( pipe_jump );
10660 %}
10662 // ============================================================================
10663 // Procedure Call/Return Instructions
10664 // Call Java Static Instruction
10665 // Note: If this code changes, the corresponding ret_addr_offset() and
10666 // compute_padding() functions will have to be adjusted.
10667 instruct CallStaticJavaDirect(method meth) %{
10668 match(CallStaticJava);
10669 effect(USE meth);
10671 ins_cost(300);
10672 format %{ "CALL,static #@CallStaticJavaDirect " %}
10673 ins_encode( Java_Static_Call( meth ) );
10674 ins_pipe( pipe_slow );
10675 ins_pc_relative(1);
10676 %}
10678 // Call Java Dynamic Instruction
10679 // Note: If this code changes, the corresponding ret_addr_offset() and
10680 // compute_padding() functions will have to be adjusted.
10681 instruct CallDynamicJavaDirect(method meth) %{
10682 match(CallDynamicJava);
10683 effect(USE meth);
10685 ins_cost(300);
10686 format %{"MOV IC_Klass, (oop)-1\n\t"
10687 "CallDynamic @ CallDynamicJavaDirect" %}
10688 ins_encode( Java_Dynamic_Call( meth ) );
10689 ins_pipe( pipe_slow );
10690 ins_pc_relative(1);
10691 %}
10693 instruct CallLeafNoFPDirect(method meth) %{
10694 match(CallLeafNoFP);
10695 effect(USE meth);
10697 ins_cost(300);
10698 format %{ "CALL_LEAF_NOFP,runtime " %}
10699 ins_encode(Java_To_Runtime(meth));
10700 ins_pipe( pipe_slow );
10701 ins_pc_relative(1);
10702 ins_alignment(16);
10703 %}
10705 // Prefetch instructions.
10707 instruct prefetchrNTA( umemory mem ) %{
10708 match(PrefetchRead mem);
10709 ins_cost(125);
10711 format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
10712 ins_encode %{
10713 int base = $mem$$base;
10714 int index = $mem$$index;
10715 int scale = $mem$$scale;
10716 int disp = $mem$$disp;
10718 assert(index == 0, "no index");
10719 __ daddiu(AT, as_Register(base), disp);
10720 __ pref(0, AT, 0); //hint: 0:load
10721 %}
10722 ins_pipe(pipe_slow);
10723 %}
10725 instruct prefetchwNTA( umemory mem ) %{
10726 match(PrefetchWrite mem);
10727 ins_cost(125);
10728 format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
10729 ins_encode %{
10730 int base = $mem$$base;
10731 int index = $mem$$index;
10732 int scale = $mem$$scale;
10733 int disp = $mem$$disp;
10735 assert(index == 0, "no index");
10736 __ daddiu(AT, as_Register(base), disp);
10737 __ pref(1, AT, 0); //hint: 1:store
10738 %}
10739 ins_pipe(pipe_slow);
10740 %}
10742 // Prefetch instructions for allocation.
10744 instruct prefetchAllocNTA( memory mem ) %{
10745 match(PrefetchAllocation mem);
10746 ins_cost(125);
10747 format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
10748 ins_encode %{
10749 int base = $mem$$base;
10750 int index = $mem$$index;
10751 int scale = $mem$$scale;
10752 int disp = $mem$$disp;
10754 Register dst = R0;
10756 if( index != 0 ) {
10757 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
10758 __ gslbx(dst, as_Register(base), as_Register(index), disp);
10759 } else {
10760 __ lb(dst, as_Register(base), disp);
10761 }
10762 %}
10763 ins_pipe(pipe_slow);
10764 %}
10767 // Call runtime without safepoint
10768 instruct CallLeafDirect(method meth) %{
10769 match(CallLeaf);
10770 effect(USE meth);
10772 ins_cost(300);
10773 format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
10774 ins_encode(Java_To_Runtime(meth));
10775 ins_pipe( pipe_slow );
10776 ins_pc_relative(1);
10777 ins_alignment(16);
10778 %}
10780 // Load Char (16bit unsigned)
10781 instruct loadUS(mRegI dst, umemory mem) %{
10782 match(Set dst (LoadUS mem));
10784 ins_cost(125);
10785 format %{ "loadUS $dst,$mem @ loadC" %}
10786 ins_encode(load_C_enc(dst, mem));
10787 ins_pipe( ialu_loadI );
10788 %}
10790 instruct loadUS_convI2L(mRegL dst, umemory mem) %{
10791 match(Set dst (ConvI2L (LoadUS mem)));
10793 ins_cost(125);
10794 format %{ "loadUS $dst,$mem @ loadUS_convI2L" %}
10795 ins_encode(load_C_enc(dst, mem));
10796 ins_pipe( ialu_loadI );
10797 %}
10799 // Store Char (16bit unsigned)
10800 instruct storeC(memory mem, mRegI src) %{
10801 match(Set mem (StoreC mem src));
10803 ins_cost(125);
10804 format %{ "storeC $src, $mem @ storeC" %}
10805 ins_encode(store_C_reg_enc(mem, src));
10806 ins_pipe( ialu_loadI );
10807 %}
10809 instruct storeC0(memory mem, immI0 zero) %{
10810 match(Set mem (StoreC mem zero));
10812 ins_cost(125);
10813 format %{ "storeC $zero, $mem @ storeC0" %}
10814 ins_encode(store_C0_enc(mem));
10815 ins_pipe( ialu_loadI );
10816 %}
10819 instruct loadConF0(regF dst, immF0 zero) %{
10820 match(Set dst zero);
10821 ins_cost(100);
10823 format %{ "mov $dst, zero @ loadConF0\n"%}
10824 ins_encode %{
10825 FloatRegister dst = $dst$$FloatRegister;
10827 __ mtc1(R0, dst);
10828 %}
10829 ins_pipe( fpu_loadF );
10830 %}
10833 instruct loadConF(regF dst, immF src) %{
10834 match(Set dst src);
10835 ins_cost(125);
10837 format %{ "lwc1 $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
10838 ins_encode %{
10839 int con_offset = $constantoffset($src);
10841 if (Assembler::is_simm16(con_offset)) {
10842 __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
10843 } else {
10844 __ set64(AT, con_offset);
10845 if (UseLoongsonISA) {
10846 __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
10847 } else {
10848 __ daddu(AT, $constanttablebase, AT);
10849 __ lwc1($dst$$FloatRegister, AT, 0);
10850 }
10851 }
10852 %}
10853 ins_pipe( fpu_loadF );
10854 %}
10857 instruct loadConD0(regD dst, immD0 zero) %{
10858 match(Set dst zero);
10859 ins_cost(100);
10861 format %{ "mov $dst, zero @ loadConD0"%}
10862 ins_encode %{
10863 FloatRegister dst = as_FloatRegister($dst$$reg);
10865 __ dmtc1(R0, dst);
10866 %}
10867 ins_pipe( fpu_loadF );
10868 %}
10870 instruct loadConD(regD dst, immD src) %{
10871 match(Set dst src);
10872 ins_cost(125);
10874 format %{ "ldc1 $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
10875 ins_encode %{
10876 int con_offset = $constantoffset($src);
10878 if (Assembler::is_simm16(con_offset)) {
10879 __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
10880 } else {
10881 __ set64(AT, con_offset);
10882 if (UseLoongsonISA) {
10883 __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
10884 } else {
10885 __ daddu(AT, $constanttablebase, AT);
10886 __ ldc1($dst$$FloatRegister, AT, 0);
10887 }
10888 }
10889 %}
10890 ins_pipe( fpu_loadF );
10891 %}
10893 // Store register Float value (it is faster than store from FPU register)
10894 instruct storeF_reg( memory mem, regF src) %{
10895 match(Set mem (StoreF mem src));
10897 ins_cost(50);
10898 format %{ "store $mem, $src\t# store float @ storeF_reg" %}
10899 ins_encode(store_F_reg_enc(mem, src));
10900 ins_pipe( fpu_storeF );
10901 %}
10903 instruct storeF_imm0( memory mem, immF0 zero) %{
10904 match(Set mem (StoreF mem zero));
10906 ins_cost(40);
10907 format %{ "store $mem, zero\t# store float @ storeF_imm0" %}
10908 ins_encode %{
10909 int base = $mem$$base;
10910 int index = $mem$$index;
10911 int scale = $mem$$scale;
10912 int disp = $mem$$disp;
10914 if( index != 0 ) {
10915 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
10916 __ gsswx(R0, as_Register(base), as_Register(index), disp);
10917 } else {
10918 __ sw(R0, as_Register(base), disp);
10919 }
10920 %}
10921 ins_pipe( ialu_storeI );
10922 %}
10924 // Load Double
10925 instruct loadD(regD dst, memory mem) %{
10926 match(Set dst (LoadD mem));
10928 ins_cost(150);
10929 format %{ "loadD $dst, $mem #@loadD" %}
10930 ins_encode(load_D_enc(dst, mem));
10931 ins_pipe( ialu_loadI );
10932 %}
10934 // Load Double - UNaligned
10935 instruct loadD_unaligned(regD dst, memory mem ) %{
10936 match(Set dst (LoadD_unaligned mem));
10937 ins_cost(250);
10938 // FIXME: Jin: Need more effective ldl/ldr
10939 format %{ "loadD_unaligned $dst, $mem #@loadD_unaligned" %}
10940 ins_encode(load_D_enc(dst, mem));
10941 ins_pipe( ialu_loadI );
10942 %}
10944 instruct storeD_reg( memory mem, regD src) %{
10945 match(Set mem (StoreD mem src));
10947 ins_cost(50);
10948 format %{ "store $mem, $src\t# store float @ storeD_reg" %}
10949 ins_encode(store_D_reg_enc(mem, src));
10950 ins_pipe( fpu_storeF );
10951 %}
10953 instruct loadSSI(mRegI dst, stackSlotI src)
10954 %{
10955 match(Set dst src);
10957 ins_cost(125);
10958 format %{ "lw $dst, $src\t# int stk @ loadSSI" %}
10959 ins_encode %{
10960 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
10961 __ lw($dst$$Register, SP, $src$$disp);
10962 %}
10963 ins_pipe(ialu_loadI);
10964 %}
10966 instruct storeSSI(stackSlotI dst, mRegI src)
10967 %{
10968 match(Set dst src);
10970 ins_cost(100);
10971 format %{ "sw $dst, $src\t# int stk @ storeSSI" %}
10972 ins_encode %{
10973 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
10974 __ sw($src$$Register, SP, $dst$$disp);
10975 %}
10976 ins_pipe(ialu_storeI);
10977 %}
10979 instruct loadSSL(mRegL dst, stackSlotL src)
10980 %{
10981 match(Set dst src);
10983 ins_cost(125);
10984 format %{ "ld $dst, $src\t# long stk @ loadSSL" %}
10985 ins_encode %{
10986 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
10987 __ ld($dst$$Register, SP, $src$$disp);
10988 %}
10989 ins_pipe(ialu_loadI);
10990 %}
10992 instruct storeSSL(stackSlotL dst, mRegL src)
10993 %{
10994 match(Set dst src);
10996 ins_cost(100);
10997 format %{ "sd $dst, $src\t# long stk @ storeSSL" %}
10998 ins_encode %{
10999 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
11000 __ sd($src$$Register, SP, $dst$$disp);
11001 %}
11002 ins_pipe(ialu_storeI);
11003 %}
11005 instruct loadSSP(mRegP dst, stackSlotP src)
11006 %{
11007 match(Set dst src);
11009 ins_cost(125);
11010 format %{ "ld $dst, $src\t# ptr stk @ loadSSP" %}
11011 ins_encode %{
11012 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
11013 __ ld($dst$$Register, SP, $src$$disp);
11014 %}
11015 ins_pipe(ialu_loadI);
11016 %}
11018 instruct storeSSP(stackSlotP dst, mRegP src)
11019 %{
11020 match(Set dst src);
11022 ins_cost(100);
11023 format %{ "sd $dst, $src\t# ptr stk @ storeSSP" %}
11024 ins_encode %{
11025 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
11026 __ sd($src$$Register, SP, $dst$$disp);
11027 %}
11028 ins_pipe(ialu_storeI);
11029 %}
11031 instruct loadSSF(regF dst, stackSlotF src)
11032 %{
11033 match(Set dst src);
11035 ins_cost(125);
11036 format %{ "lwc1 $dst, $src\t# float stk @ loadSSF" %}
11037 ins_encode %{
11038 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
11039 __ lwc1($dst$$FloatRegister, SP, $src$$disp);
11040 %}
11041 ins_pipe(ialu_loadI);
11042 %}
11044 instruct storeSSF(stackSlotF dst, regF src)
11045 %{
11046 match(Set dst src);
11048 ins_cost(100);
11049 format %{ "swc1 $dst, $src\t# float stk @ storeSSF" %}
11050 ins_encode %{
11051 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
11052 __ swc1($src$$FloatRegister, SP, $dst$$disp);
11053 %}
11054 ins_pipe(fpu_storeF);
11055 %}
11057 // Use the same format since predicate() can not be used here.
11058 instruct loadSSD(regD dst, stackSlotD src)
11059 %{
11060 match(Set dst src);
11062 ins_cost(125);
11063 format %{ "ldc1 $dst, $src\t# double stk @ loadSSD" %}
11064 ins_encode %{
11065 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
11066 __ ldc1($dst$$FloatRegister, SP, $src$$disp);
11067 %}
11068 ins_pipe(ialu_loadI);
11069 %}
11071 instruct storeSSD(stackSlotD dst, regD src)
11072 %{
11073 match(Set dst src);
11075 ins_cost(100);
11076 format %{ "sdc1 $dst, $src\t# double stk @ storeSSD" %}
11077 ins_encode %{
11078 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
11079 __ sdc1($src$$FloatRegister, SP, $dst$$disp);
11080 %}
11081 ins_pipe(fpu_storeF);
11082 %}
11084 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
11085 match( Set cr (FastLock object box) );
11086 effect( TEMP tmp, TEMP scr, USE_KILL box );
11087 ins_cost(300);
11088 format %{ "FASTLOCK $cr $object, $box, $tmp #@ cmpFastLock" %}
11089 ins_encode %{
11090 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
11091 %}
11093 ins_pipe( pipe_slow );
11094 ins_pc_relative(1);
11095 %}
11097 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
11098 match( Set cr (FastUnlock object box) );
11099 effect( TEMP tmp, USE_KILL box );
11100 ins_cost(300);
11101 format %{ "FASTUNLOCK $object, $box, $tmp #@cmpFastUnlock" %}
11102 ins_encode %{
11103 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
11104 %}
11106 ins_pipe( pipe_slow );
11107 ins_pc_relative(1);
11108 %}
11110 // Store CMS card-mark Immediate
11111 instruct storeImmCM(memory mem, mRegI src) %{
11112 match(Set mem (StoreCM mem src));
11114 ins_cost(500);
11115 format %{ "sb $src, $mem (CMS card-mark) @ storeImmCM" %}
11116 ins_encode(store_B_reg_sync_enc(mem, src));
11117 ins_pipe( ialu_storeI );
11118 %}
11120 instruct storeI0CM(memory mem, immI0 zero) %{
11121 match(Set mem (StoreCM mem zero));
11123 ins_cost(450);
11124 format %{ "sb $zero, $mem (CMS card-mark) @ storeI0CM" %}
11125 ins_encode(store_B0_sync_enc(mem));
11126 ins_pipe( ialu_storeI );
11127 %}
11129 // Die now
11130 instruct ShouldNotReachHere( )
11131 %{
11132 match(Halt);
11133 ins_cost(300);
11135 // Use the following format syntax
11136 format %{ "ILLTRAP ;#@ShouldNotReachHere" %}
11137 ins_encode %{
11138 // Here we should emit illtrap !
11140 __ stop("in ShoudNotReachHere");
11142 %}
11143 ins_pipe( pipe_jump );
11144 %}
11146 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11147 instruct jmpLoopEnd(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
11148 match(CountedLoopEnd cop (CmpI src1 src2));
11149 effect(USE labl);
11151 ins_cost(300);
11152 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd" %}
11153 ins_encode %{
11154 Register op1 = $src1$$Register;
11155 Register op2 = $src2$$Register;
11156 Label &L = *($labl$$label);
11157 int flag = $cop$$cmpcode;
11159 switch(flag)
11160 {
11161 case 0x01: //equal
11162 if (&L)
11163 __ beq(op1, op2, L);
11164 else
11165 __ beq(op1, op2, (int)0);
11166 break;
11167 case 0x02: //not_equal
11168 if (&L)
11169 __ bne(op1, op2, L);
11170 else
11171 __ bne(op1, op2, (int)0);
11172 break;
11173 case 0x03: //above
11174 __ slt(AT, op2, op1);
11175 if(&L)
11176 __ bne(AT, R0, L);
11177 else
11178 __ bne(AT, R0, (int)0);
11179 break;
11180 case 0x04: //above_equal
11181 __ slt(AT, op1, op2);
11182 if(&L)
11183 __ beq(AT, R0, L);
11184 else
11185 __ beq(AT, R0, (int)0);
11186 break;
11187 case 0x05: //below
11188 __ slt(AT, op1, op2);
11189 if(&L)
11190 __ bne(AT, R0, L);
11191 else
11192 __ bne(AT, R0, (int)0);
11193 break;
11194 case 0x06: //below_equal
11195 __ slt(AT, op2, op1);
11196 if(&L)
11197 __ beq(AT, R0, L);
11198 else
11199 __ beq(AT, R0, (int)0);
11200 break;
11201 default:
11202 Unimplemented();
11203 }
11204 __ nop();
11205 %}
11206 ins_pipe( pipe_jump );
11207 ins_pc_relative(1);
11208 %}
11211 instruct jmpLoopEnd_reg_imm16_sub(cmpOp cop, mRegI src1, immI16_sub src2, label labl) %{
11212 match(CountedLoopEnd cop (CmpI src1 src2));
11213 effect(USE labl);
11215 ins_cost(250);
11216 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_imm16_sub" %}
11217 ins_encode %{
11218 Register op1 = $src1$$Register;
11219 int op2 = $src2$$constant;
11220 Label &L = *($labl$$label);
11221 int flag = $cop$$cmpcode;
11223 __ addiu32(AT, op1, -1 * op2);
11225 switch(flag)
11226 {
11227 case 0x01: //equal
11228 if (&L)
11229 __ beq(AT, R0, L);
11230 else
11231 __ beq(AT, R0, (int)0);
11232 break;
11233 case 0x02: //not_equal
11234 if (&L)
11235 __ bne(AT, R0, L);
11236 else
11237 __ bne(AT, R0, (int)0);
11238 break;
11239 case 0x03: //above
11240 if(&L)
11241 __ bgtz(AT, L);
11242 else
11243 __ bgtz(AT, (int)0);
11244 break;
11245 case 0x04: //above_equal
11246 if(&L)
11247 __ bgez(AT, L);
11248 else
11249 __ bgez(AT,(int)0);
11250 break;
11251 case 0x05: //below
11252 if(&L)
11253 __ bltz(AT, L);
11254 else
11255 __ bltz(AT, (int)0);
11256 break;
11257 case 0x06: //below_equal
11258 if(&L)
11259 __ blez(AT, L);
11260 else
11261 __ blez(AT, (int)0);
11262 break;
11263 default:
11264 Unimplemented();
11265 }
11266 __ nop();
11267 %}
11268 ins_pipe( pipe_jump );
11269 ins_pc_relative(1);
11270 %}
11273 /*
11274 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11275 instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
11276 match(CountedLoopEnd cop cmp);
11277 effect(USE labl);
11279 ins_cost(300);
11280 format %{ "J$cop,u $labl\t# Loop end" %}
11281 size(6);
11282 opcode(0x0F, 0x80);
11283 ins_encode( Jcc( cop, labl) );
11284 ins_pipe( pipe_jump );
11285 ins_pc_relative(1);
11286 %}
11288 instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
11289 match(CountedLoopEnd cop cmp);
11290 effect(USE labl);
11292 ins_cost(200);
11293 format %{ "J$cop,u $labl\t# Loop end" %}
11294 opcode(0x0F, 0x80);
11295 ins_encode( Jcc( cop, labl) );
11296 ins_pipe( pipe_jump );
11297 ins_pc_relative(1);
11298 %}
11299 */
11301 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
11302 instruct jmpCon_flags(cmpOp cop, FlagsReg cr, label labl) %{
11303 match(If cop cr);
11304 effect(USE labl);
11306 ins_cost(300);
11307 format %{ "J$cop $labl #mips uses AT as eflag @jmpCon_flags" %}
11309 ins_encode %{
11310 Label &L = *($labl$$label);
11311 switch($cop$$cmpcode)
11312 {
11313 case 0x01: //equal
11314 if (&L)
11315 __ bne(AT, R0, L);
11316 else
11317 __ bne(AT, R0, (int)0);
11318 break;
11319 case 0x02: //not equal
11320 if (&L)
11321 __ beq(AT, R0, L);
11322 else
11323 __ beq(AT, R0, (int)0);
11324 break;
11325 default:
11326 Unimplemented();
11327 }
11328 __ nop();
11329 %}
11331 ins_pipe( pipe_jump );
11332 ins_pc_relative(1);
11333 %}
11336 // ============================================================================
11337 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
11338 // array for an instance of the superklass. Set a hidden internal cache on a
11339 // hit (cache is checked with exposed code in gen_subtype_check()). Return
11340 // NZ for a miss or zero for a hit. The encoding ALSO sets flags.
11341 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
11342 match(Set result (PartialSubtypeCheck sub super));
11343 effect(KILL tmp);
11344 ins_cost(1100); // slightly larger than the next version
11345 format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
11347 ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
11348 ins_pipe( pipe_slow );
11349 %}
11352 // Conditional-store of an int value.
11353 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
11354 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
11355 match(Set cr (StoreIConditional mem (Binary oldval newval)));
11356 // effect(KILL oldval);
11357 format %{ "CMPXCHG $newval, $mem, $oldval \t# @storeIConditional" %}
11359 ins_encode %{
11360 Register oldval = $oldval$$Register;
11361 Register newval = $newval$$Register;
11362 Address addr(as_Register($mem$$base), $mem$$disp);
11363 Label again, failure;
11365 // int base = $mem$$base;
11366 int index = $mem$$index;
11367 int scale = $mem$$scale;
11368 int disp = $mem$$disp;
11370 guarantee(Assembler::is_simm16(disp), "");
11372 if( index != 0 ) {
11373 __ stop("in storeIConditional: index != 0");
11374 } else {
11375 __ bind(again);
11376 if(!Use3A2000) __ sync();
11377 __ ll(AT, addr);
11378 __ bne(AT, oldval, failure);
11379 __ delayed()->addu(AT, R0, R0);
11381 __ addu(AT, newval, R0);
11382 __ sc(AT, addr);
11383 __ beq(AT, R0, again);
11384 __ delayed()->addiu(AT, R0, 0xFF);
11385 __ bind(failure);
11386 __ sync();
11387 }
11388 %}
11390 ins_pipe( long_memory_op );
11391 %}
11393 // Conditional-store of a long value.
11394 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
11395 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
11396 %{
11397 match(Set cr (StoreLConditional mem (Binary oldval newval)));
11398 effect(KILL oldval);
11400 format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
11401 ins_encode%{
11402 Register oldval = $oldval$$Register;
11403 Register newval = $newval$$Register;
11404 Address addr((Register)$mem$$base, $mem$$disp);
11406 int index = $mem$$index;
11407 int scale = $mem$$scale;
11408 int disp = $mem$$disp;
11410 guarantee(Assembler::is_simm16(disp), "");
11412 if( index != 0 ) {
11413 __ stop("in storeIConditional: index != 0");
11414 } else {
11415 __ cmpxchg(newval, addr, oldval);
11416 }
11417 %}
11418 ins_pipe( long_memory_op );
11419 %}
11422 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
11423 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
11424 effect(KILL oldval);
11425 // match(CompareAndSwapI mem_ptr (Binary oldval newval));
11426 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
11427 "MOV $res, 1 @ compareAndSwapI\n\t"
11428 "BNE AT, R0 @ compareAndSwapI\n\t"
11429 "MOV $res, 0 @ compareAndSwapI\n"
11430 "L:" %}
11431 ins_encode %{
11432 Register newval = $newval$$Register;
11433 Register oldval = $oldval$$Register;
11434 Register res = $res$$Register;
11435 Address addr($mem_ptr$$Register, 0);
11436 Label L;
11438 __ cmpxchg32(newval, addr, oldval);
11439 __ move(res, AT);
11440 %}
11441 ins_pipe( long_memory_op );
11442 %}
11444 //FIXME:
11445 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
11446 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
11447 effect(KILL oldval);
11448 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
11449 "MOV $res, AT @ compareAndSwapP\n\t"
11450 "L:" %}
11451 ins_encode %{
11452 Register newval = $newval$$Register;
11453 Register oldval = $oldval$$Register;
11454 Register res = $res$$Register;
11455 Address addr($mem_ptr$$Register, 0);
11456 Label L;
11458 __ cmpxchg(newval, addr, oldval);
11459 __ move(res, AT);
11460 %}
11461 ins_pipe( long_memory_op );
11462 %}
11464 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
11465 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
11466 effect(KILL oldval);
11467 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
11468 "MOV $res, AT @ compareAndSwapN\n\t"
11469 "L:" %}
11470 ins_encode %{
11471 Register newval = $newval$$Register;
11472 Register oldval = $oldval$$Register;
11473 Register res = $res$$Register;
11474 Address addr($mem_ptr$$Register, 0);
11475 Label L;
11477 /* 2013/7/19 Jin: cmpxchg32 is implemented with ll/sc, which will do sign extension.
11478 * Thus, we should extend oldval's sign for correct comparision.
11479 */
11480 __ sll(oldval, oldval, 0);
11482 __ cmpxchg32(newval, addr, oldval);
11483 __ move(res, AT);
11484 %}
11485 ins_pipe( long_memory_op );
11486 %}
11488 //----------Max and Min--------------------------------------------------------
11489 // Min Instructions
11490 ////
11491 // *** Min and Max using the conditional move are slower than the
11492 // *** branch version on a Pentium III.
11493 // // Conditional move for min
11494 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
11495 // effect( USE_DEF op2, USE op1, USE cr );
11496 // format %{ "CMOVlt $op2,$op1\t! min" %}
11497 // opcode(0x4C,0x0F);
11498 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
11499 // ins_pipe( pipe_cmov_reg );
11500 //%}
11501 //
11502 //// Min Register with Register (P6 version)
11503 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
11504 // predicate(VM_Version::supports_cmov() );
11505 // match(Set op2 (MinI op1 op2));
11506 // ins_cost(200);
11507 // expand %{
11508 // eFlagsReg cr;
11509 // compI_eReg(cr,op1,op2);
11510 // cmovI_reg_lt(op2,op1,cr);
11511 // %}
11512 //%}
11514 // Min Register with Register (generic version)
11515 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
11516 match(Set dst (MinI dst src));
11517 //effect(KILL flags);
11518 ins_cost(80);
11520 format %{ "MIN $dst, $src @minI_Reg_Reg" %}
11521 ins_encode %{
11522 Register dst = $dst$$Register;
11523 Register src = $src$$Register;
11525 __ slt(AT, src, dst);
11526 __ movn(dst, src, AT);
11528 %}
11530 ins_pipe( pipe_slow );
11531 %}
11533 // Max Register with Register
11534 // *** Min and Max using the conditional move are slower than the
11535 // *** branch version on a Pentium III.
11536 // // Conditional move for max
11537 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
11538 // effect( USE_DEF op2, USE op1, USE cr );
11539 // format %{ "CMOVgt $op2,$op1\t! max" %}
11540 // opcode(0x4F,0x0F);
11541 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
11542 // ins_pipe( pipe_cmov_reg );
11543 //%}
11544 //
11545 // // Max Register with Register (P6 version)
11546 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
11547 // predicate(VM_Version::supports_cmov() );
11548 // match(Set op2 (MaxI op1 op2));
11549 // ins_cost(200);
11550 // expand %{
11551 // eFlagsReg cr;
11552 // compI_eReg(cr,op1,op2);
11553 // cmovI_reg_gt(op2,op1,cr);
11554 // %}
11555 //%}
11557 // Max Register with Register (generic version)
11558 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
11559 match(Set dst (MaxI dst src));
11560 ins_cost(80);
11562 format %{ "MAX $dst, $src @maxI_Reg_Reg" %}
11564 ins_encode %{
11565 Register dst = $dst$$Register;
11566 Register src = $src$$Register;
11568 __ slt(AT, dst, src);
11569 __ movn(dst, src, AT);
11571 %}
11573 ins_pipe( pipe_slow );
11574 %}
11576 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
11577 match(Set dst (MaxI dst zero));
11578 ins_cost(50);
11580 format %{ "MAX $dst, 0 @maxI_Reg_zero" %}
11582 ins_encode %{
11583 Register dst = $dst$$Register;
11585 __ slt(AT, dst, R0);
11586 __ movn(dst, R0, AT);
11588 %}
11590 ins_pipe( pipe_slow );
11591 %}
11593 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
11594 %{
11595 match(Set dst (AndL src mask));
11597 format %{ "movl $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
11598 ins_encode %{
11599 Register dst = $dst$$Register;
11600 Register src = $src$$Register;
11602 __ dext(dst, src, 0, 32);
11603 %}
11604 ins_pipe(ialu_regI_regI);
11605 %}
11607 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
11608 %{
11609 match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
11611 format %{ "combine_i2l $dst, $src2(H), $src1(L) @ combine_i2l" %}
11612 ins_encode %{
11613 Register dst = $dst$$Register;
11614 Register src1 = $src1$$Register;
11615 Register src2 = $src2$$Register;
11617 if (src1 == dst) {
11618 __ dinsu(dst, src2, 32, 32);
11619 } else if (src2 == dst) {
11620 __ dsll32(dst, dst, 0);
11621 __ dins(dst, src1, 0, 32);
11622 } else {
11623 __ dext(dst, src1, 0, 32);
11624 __ dinsu(dst, src2, 32, 32);
11625 }
11626 %}
11627 ins_pipe(ialu_regI_regI);
11628 %}
11630 // Zero-extend convert int to long
11631 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
11632 %{
11633 match(Set dst (AndL (ConvI2L src) mask));
11635 format %{ "movl $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
11636 ins_encode %{
11637 Register dst = $dst$$Register;
11638 Register src = $src$$Register;
11640 __ dext(dst, src, 0, 32);
11641 %}
11642 ins_pipe(ialu_regI_regI);
11643 %}
11645 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
11646 %{
11647 match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
11649 format %{ "movl $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
11650 ins_encode %{
11651 Register dst = $dst$$Register;
11652 Register src = $src$$Register;
11654 __ dext(dst, src, 0, 32);
11655 %}
11656 ins_pipe(ialu_regI_regI);
11657 %}
11659 // Match loading integer and casting it to unsigned int in long register.
11660 // LoadI + ConvI2L + AndL 0xffffffff.
11661 instruct loadUI2L_rmask(mRegL dst, umemory mem, immL_32bits mask) %{
11662 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
11664 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
11665 ins_encode (load_N_enc(dst, mem));
11666 ins_pipe(ialu_loadI);
11667 %}
11669 instruct loadUI2L_lmask(mRegL dst, umemory mem, immL_32bits mask) %{
11670 match(Set dst (AndL mask (ConvI2L (LoadI mem))));
11672 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
11673 ins_encode (load_N_enc(dst, mem));
11674 ins_pipe(ialu_loadI);
11675 %}
11678 // ============================================================================
11679 // Safepoint Instruction
11680 instruct safePoint_poll_reg(mRegP poll) %{
11681 match(SafePoint poll);
11682 predicate(false);
11683 effect(USE poll);
11685 ins_cost(125);
11686 format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
11688 ins_encode %{
11689 Register poll_reg = $poll$$Register;
11691 __ block_comment("Safepoint:");
11692 __ relocate(relocInfo::poll_type);
11693 __ lw(AT, poll_reg, 0);
11694 %}
11696 ins_pipe( ialu_storeI );
11697 %}
11699 instruct safePoint_poll() %{
11700 match(SafePoint);
11702 ins_cost(105);
11703 format %{ "poll for GC @ safePoint_poll" %}
11705 ins_encode %{
11706 __ block_comment("Safepoint:");
11707 __ set64(T9, (long)os::get_polling_page());
11708 __ relocate(relocInfo::poll_type);
11709 __ lw(AT, T9, 0);
11710 %}
11712 ins_pipe( ialu_storeI );
11713 %}
11715 //----------Arithmetic Conversion Instructions---------------------------------
11717 instruct roundFloat_nop(regF dst)
11718 %{
11719 match(Set dst (RoundFloat dst));
11721 ins_cost(0);
11722 ins_encode();
11723 ins_pipe(empty);
11724 %}
11726 instruct roundDouble_nop(regD dst)
11727 %{
11728 match(Set dst (RoundDouble dst));
11730 ins_cost(0);
11731 ins_encode();
11732 ins_pipe(empty);
11733 %}
11735 //---------- Zeros Count Instructions ------------------------------------------
11736 // CountLeadingZerosINode CountTrailingZerosINode
11737 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
11738 predicate(UseCountLeadingZerosInstruction);
11739 match(Set dst (CountLeadingZerosI src));
11741 format %{ "clz $dst, $src\t# count leading zeros (int)" %}
11742 ins_encode %{
11743 __ clz($dst$$Register, $src$$Register);
11744 %}
11745 ins_pipe( ialu_regL_regL );
11746 %}
11748 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
11749 predicate(UseCountLeadingZerosInstruction);
11750 match(Set dst (CountLeadingZerosL src));
11752 format %{ "dclz $dst, $src\t# count leading zeros (long)" %}
11753 ins_encode %{
11754 __ dclz($dst$$Register, $src$$Register);
11755 %}
11756 ins_pipe( ialu_regL_regL );
11757 %}
11759 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
11760 predicate(UseCountTrailingZerosInstruction);
11761 match(Set dst (CountTrailingZerosI src));
11763 format %{ "ctz $dst, $src\t# count trailing zeros (int)" %}
11764 ins_encode %{
11765 // ctz and dctz is gs instructions.
11766 __ ctz($dst$$Register, $src$$Register);
11767 %}
11768 ins_pipe( ialu_regL_regL );
11769 %}
11771 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
11772 predicate(UseCountTrailingZerosInstruction);
11773 match(Set dst (CountTrailingZerosL src));
11775 format %{ "dcto $dst, $src\t# count trailing zeros (long)" %}
11776 ins_encode %{
11777 __ dctz($dst$$Register, $src$$Register);
11778 %}
11779 ins_pipe( ialu_regL_regL );
11780 %}
11782 // ====================VECTOR INSTRUCTIONS=====================================
11784 // Load vectors (8 bytes long)
11785 instruct loadV8(vecD dst, memory mem) %{
11786 predicate(n->as_LoadVector()->memory_size() == 8);
11787 match(Set dst (LoadVector mem));
11788 ins_cost(125);
11789 format %{ "load $dst, $mem\t! load vector (8 bytes)" %}
11790 ins_encode(load_D_enc(dst, mem));
11791 ins_pipe( fpu_loadF );
11792 %}
11794 // Store vectors (8 bytes long)
11795 instruct storeV8(memory mem, vecD src) %{
11796 predicate(n->as_StoreVector()->memory_size() == 8);
11797 match(Set mem (StoreVector mem src));
11798 ins_cost(145);
11799 format %{ "store $mem, $src\t! store vector (8 bytes)" %}
11800 ins_encode(store_D_reg_enc(mem, src));
11801 ins_pipe( fpu_storeF );
11802 %}
11804 instruct Repl8B_DSP(vecD dst, mRegI src) %{
11805 predicate(n->as_Vector()->length() == 8 && Use3A2000);
11806 match(Set dst (ReplicateB src));
11807 ins_cost(100);
11808 format %{ "replv_ob AT, $src\n\t"
11809 "dmtc1 AT, $dst\t! replicate8B" %}
11810 ins_encode %{
11811 __ replv_ob(AT, $src$$Register);
11812 __ dmtc1(AT, $dst$$FloatRegister);
11813 %}
11814 ins_pipe( pipe_mtc1 );
11815 %}
11817 instruct Repl8B(vecD dst, mRegI src) %{
11818 predicate(n->as_Vector()->length() == 8);
11819 match(Set dst (ReplicateB src));
11820 ins_cost(140);
11821 format %{ "move AT, $src\n\t"
11822 "dins AT, AT, 8, 8\n\t"
11823 "dins AT, AT, 16, 16\n\t"
11824 "dinsu AT, AT, 32, 32\n\t"
11825 "dmtc1 AT, $dst\t! replicate8B" %}
11826 ins_encode %{
11827 __ move(AT, $src$$Register);
11828 __ dins(AT, AT, 8, 8);
11829 __ dins(AT, AT, 16, 16);
11830 __ dinsu(AT, AT, 32, 32);
11831 __ dmtc1(AT, $dst$$FloatRegister);
11832 %}
11833 ins_pipe( pipe_mtc1 );
11834 %}
11836 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
11837 predicate(n->as_Vector()->length() == 8 && Use3A2000);
11838 match(Set dst (ReplicateB con));
11839 ins_cost(110);
11840 format %{ "repl_ob AT, [$con]\n\t"
11841 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
11842 ins_encode %{
11843 int val = $con$$constant;
11844 __ repl_ob(AT, val);
11845 __ dmtc1(AT, $dst$$FloatRegister);
11846 %}
11847 ins_pipe( pipe_mtc1 );
11848 %}
11850 instruct Repl8B_imm(vecD dst, immI con) %{
11851 predicate(n->as_Vector()->length() == 8);
11852 match(Set dst (ReplicateB con));
11853 ins_cost(150);
11854 format %{ "move AT, [$con]\n\t"
11855 "dins AT, AT, 8, 8\n\t"
11856 "dins AT, AT, 16, 16\n\t"
11857 "dinsu AT, AT, 32, 32\n\t"
11858 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
11859 ins_encode %{
11860 __ move(AT, $con$$constant);
11861 __ dins(AT, AT, 8, 8);
11862 __ dins(AT, AT, 16, 16);
11863 __ dinsu(AT, AT, 32, 32);
11864 __ dmtc1(AT, $dst$$FloatRegister);
11865 %}
11866 ins_pipe( pipe_mtc1 );
11867 %}
11869 instruct Repl8B_zero(vecD dst, immI0 zero) %{
11870 predicate(n->as_Vector()->length() == 8);
11871 match(Set dst (ReplicateB zero));
11872 ins_cost(90);
11873 format %{ "dmtc1 R0, $dst\t! replicate8B zero" %}
11874 ins_encode %{
11875 __ dmtc1(R0, $dst$$FloatRegister);
11876 %}
11877 ins_pipe( pipe_mtc1 );
11878 %}
11880 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
11881 predicate(n->as_Vector()->length() == 8);
11882 match(Set dst (ReplicateB M1));
11883 ins_cost(80);
11884 format %{ "dmtc1 -1, $dst\t! replicate8B -1" %}
11885 ins_encode %{
11886 __ nor(AT, R0, R0);
11887 __ dmtc1(AT, $dst$$FloatRegister);
11888 %}
11889 ins_pipe( pipe_mtc1 );
11890 %}
11892 instruct Repl4S_DSP(vecD dst, mRegI src) %{
11893 predicate(n->as_Vector()->length() == 4 && Use3A2000);
11894 match(Set dst (ReplicateS src));
11895 ins_cost(100);
11896 format %{ "replv_qh AT, $src\n\t"
11897 "dmtc1 AT, $dst\t! replicate4S" %}
11898 ins_encode %{
11899 __ replv_qh(AT, $src$$Register);
11900 __ dmtc1(AT, $dst$$FloatRegister);
11901 %}
11902 ins_pipe( pipe_mtc1 );
11903 %}
11905 instruct Repl4S(vecD dst, mRegI src) %{
11906 predicate(n->as_Vector()->length() == 4);
11907 match(Set dst (ReplicateS src));
11908 ins_cost(120);
11909 format %{ "move AT, $src \n\t"
11910 "dins AT, AT, 16, 16\n\t"
11911 "dinsu AT, AT, 32, 32\n\t"
11912 "dmtc1 AT, $dst\t! replicate4S" %}
11913 ins_encode %{
11914 __ move(AT, $src$$Register);
11915 __ dins(AT, AT, 16, 16);
11916 __ dinsu(AT, AT, 32, 32);
11917 __ dmtc1(AT, $dst$$FloatRegister);
11918 %}
11919 ins_pipe( pipe_mtc1 );
11920 %}
11922 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
11923 predicate(n->as_Vector()->length() == 4 && Use3A2000);
11924 match(Set dst (ReplicateS con));
11925 ins_cost(100);
11926 format %{ "replv_qh AT, [$con]\n\t"
11927 "dmtc1 AT, $dst\t! replicate4S($con)" %}
11928 ins_encode %{
11929 int val = $con$$constant;
11930 if ( Assembler::is_simm(val, 10)) {
11931 //repl_qh supports 10 bits immediate
11932 __ repl_qh(AT, val);
11933 } else {
11934 __ li32(AT, val);
11935 __ replv_qh(AT, AT);
11936 }
11937 __ dmtc1(AT, $dst$$FloatRegister);
11938 %}
11939 ins_pipe( pipe_mtc1 );
11940 %}
11942 instruct Repl4S_imm(vecD dst, immI con) %{
11943 predicate(n->as_Vector()->length() == 4);
11944 match(Set dst (ReplicateS con));
11945 ins_cost(110);
11946 format %{ "move AT, [$con]\n\t"
11947 "dins AT, AT, 16, 16\n\t"
11948 "dinsu AT, AT, 32, 32\n\t"
11949 "dmtc1 AT, $dst\t! replicate4S($con)" %}
11950 ins_encode %{
11951 __ move(AT, $con$$constant);
11952 __ dins(AT, AT, 16, 16);
11953 __ dinsu(AT, AT, 32, 32);
11954 __ dmtc1(AT, $dst$$FloatRegister);
11955 %}
11956 ins_pipe( pipe_mtc1 );
11957 %}
11959 instruct Repl4S_zero(vecD dst, immI0 zero) %{
11960 predicate(n->as_Vector()->length() == 4);
11961 match(Set dst (ReplicateS zero));
11962 format %{ "dmtc1 R0, $dst\t! replicate4S zero" %}
11963 ins_encode %{
11964 __ dmtc1(R0, $dst$$FloatRegister);
11965 %}
11966 ins_pipe( pipe_mtc1 );
11967 %}
11969 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
11970 predicate(n->as_Vector()->length() == 4);
11971 match(Set dst (ReplicateS M1));
11972 format %{ "dmtc1 -1, $dst\t! replicate4S -1" %}
11973 ins_encode %{
11974 __ nor(AT, R0, R0);
11975 __ dmtc1(AT, $dst$$FloatRegister);
11976 %}
11977 ins_pipe( pipe_mtc1 );
11978 %}
11980 // Replicate integer (4 byte) scalar to be vector
11981 instruct Repl2I(vecD dst, mRegI src) %{
11982 predicate(n->as_Vector()->length() == 2);
11983 match(Set dst (ReplicateI src));
11984 format %{ "dins AT, $src, 0, 32\n\t"
11985 "dinsu AT, $src, 32, 32\n\t"
11986 "dmtc1 AT, $dst\t! replicate2I" %}
11987 ins_encode %{
11988 __ dins(AT, $src$$Register, 0, 32);
11989 __ dinsu(AT, $src$$Register, 32, 32);
11990 __ dmtc1(AT, $dst$$FloatRegister);
11991 %}
11992 ins_pipe( pipe_mtc1 );
11993 %}
11995 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
11996 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
11997 predicate(n->as_Vector()->length() == 2);
11998 match(Set dst (ReplicateI con));
11999 effect(KILL tmp);
12000 format %{ "li32 AT, [$con], 32\n\t"
12001 "dinsu AT, AT\n\t"
12002 "dmtc1 AT, $dst\t! replicate2I($con)" %}
12003 ins_encode %{
12004 int val = $con$$constant;
12005 __ li32(AT, val);
12006 __ dinsu(AT, AT, 32, 32);
12007 __ dmtc1(AT, $dst$$FloatRegister);
12008 %}
12009 ins_pipe( pipe_mtc1 );
12010 %}
12012 // Replicate integer (4 byte) scalar zero to be vector
12013 instruct Repl2I_zero(vecD dst, immI0 zero) %{
12014 predicate(n->as_Vector()->length() == 2);
12015 match(Set dst (ReplicateI zero));
12016 format %{ "dmtc1 R0, $dst\t! replicate2I zero" %}
12017 ins_encode %{
12018 __ dmtc1(R0, $dst$$FloatRegister);
12019 %}
12020 ins_pipe( pipe_mtc1 );
12021 %}
12023 // Replicate integer (4 byte) scalar -1 to be vector
12024 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
12025 predicate(n->as_Vector()->length() == 2);
12026 match(Set dst (ReplicateI M1));
12027 format %{ "dmtc1 -1, $dst\t! replicate2I -1, use AT" %}
12028 ins_encode %{
12029 __ nor(AT, R0, R0);
12030 __ dmtc1(AT, $dst$$FloatRegister);
12031 %}
12032 ins_pipe( pipe_mtc1 );
12033 %}
12035 // Replicate float (4 byte) scalar to be vector
12036 instruct Repl2F(vecD dst, regF src) %{
12037 predicate(n->as_Vector()->length() == 2);
12038 match(Set dst (ReplicateF src));
12039 format %{ "cvt.ps $dst, $src, $src\t! replicate2F" %}
12040 ins_encode %{
12041 __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
12042 %}
12043 ins_pipe( pipe_slow );
12044 %}
12046 // Replicate float (4 byte) scalar zero to be vector
12047 instruct Repl2F_zero(vecD dst, immF0 zero) %{
12048 predicate(n->as_Vector()->length() == 2);
12049 match(Set dst (ReplicateF zero));
12050 format %{ "dmtc1 R0, $dst\t! replicate2F zero" %}
12051 ins_encode %{
12052 __ dmtc1(R0, $dst$$FloatRegister);
12053 %}
12054 ins_pipe( pipe_mtc1 );
12055 %}
12058 // ====================VECTOR ARITHMETIC=======================================
12060 // --------------------------------- ADD --------------------------------------
12062 // Floats vector add
12063 instruct vadd2F(vecD dst, vecD src) %{
12064 predicate(n->as_Vector()->length() == 2);
12065 match(Set dst (AddVF dst src));
12066 format %{ "add.ps $dst,$src\t! add packed2F" %}
12067 ins_encode %{
12068 __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
12069 %}
12070 ins_pipe( pipe_slow );
12071 %}
12073 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
12074 predicate(n->as_Vector()->length() == 2);
12075 match(Set dst (AddVF src1 src2));
12076 format %{ "add.ps $dst,$src1,$src2\t! add packed2F" %}
12077 ins_encode %{
12078 __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
12079 %}
12080 ins_pipe( fpu_regF_regF );
12081 %}
12083 // --------------------------------- SUB --------------------------------------
12085 // Floats vector sub
12086 instruct vsub2F(vecD dst, vecD src) %{
12087 predicate(n->as_Vector()->length() == 2);
12088 match(Set dst (SubVF dst src));
12089 format %{ "sub.ps $dst,$src\t! sub packed2F" %}
12090 ins_encode %{
12091 __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
12092 %}
12093 ins_pipe( fpu_regF_regF );
12094 %}
12096 // --------------------------------- MUL --------------------------------------
12098 // Floats vector mul
12099 instruct vmul2F(vecD dst, vecD src) %{
12100 predicate(n->as_Vector()->length() == 2);
12101 match(Set dst (MulVF dst src));
12102 format %{ "mul.ps $dst, $src\t! mul packed2F" %}
12103 ins_encode %{
12104 __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
12105 %}
12106 ins_pipe( fpu_regF_regF );
12107 %}
12109 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
12110 predicate(n->as_Vector()->length() == 2);
12111 match(Set dst (MulVF src1 src2));
12112 format %{ "mul.ps $dst, $src1, $src2\t! mul packed2F" %}
12113 ins_encode %{
12114 __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
12115 %}
12116 ins_pipe( fpu_regF_regF );
12117 %}
12119 // --------------------------------- DIV --------------------------------------
12120 // MIPS do not have div.ps
12123 //----------PEEPHOLE RULES-----------------------------------------------------
12124 // These must follow all instruction definitions as they use the names
12125 // defined in the instructions definitions.
12126 //
12127 // peepmatch ( root_instr_name [preceeding_instruction]* );
12128 //
12129 // peepconstraint %{
12130 // (instruction_number.operand_name relational_op instruction_number.operand_name
12131 // [, ...] );
12132 // // instruction numbers are zero-based using left to right order in peepmatch
12133 //
12134 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
12135 // // provide an instruction_number.operand_name for each operand that appears
12136 // // in the replacement instruction's match rule
12137 //
12138 // ---------VM FLAGS---------------------------------------------------------
12139 //
12140 // All peephole optimizations can be turned off using -XX:-OptoPeephole
12141 //
12142 // Each peephole rule is given an identifying number starting with zero and
12143 // increasing by one in the order seen by the parser. An individual peephole
12144 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
12145 // on the command-line.
12146 //
12147 // ---------CURRENT LIMITATIONS----------------------------------------------
12148 //
12149 // Only match adjacent instructions in same basic block
12150 // Only equality constraints
12151 // Only constraints between operands, not (0.dest_reg == EAX_enc)
12152 // Only one replacement instruction
12153 //
12154 // ---------EXAMPLE----------------------------------------------------------
12155 //
12156 // // pertinent parts of existing instructions in architecture description
12157 // instruct movI(eRegI dst, eRegI src) %{
12158 // match(Set dst (CopyI src));
12159 // %}
12160 //
12161 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
12162 // match(Set dst (AddI dst src));
12163 // effect(KILL cr);
12164 // %}
12165 //
12166 // // Change (inc mov) to lea
12167 // peephole %{
12168 // // increment preceeded by register-register move
12169 // peepmatch ( incI_eReg movI );
12170 // // require that the destination register of the increment
12171 // // match the destination register of the move
12172 // peepconstraint ( 0.dst == 1.dst );
12173 // // construct a replacement instruction that sets
12174 // // the destination to ( move's source register + one )
12175 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
12176 // %}
12177 //
12178 // Implementation no longer uses movX instructions since
12179 // machine-independent system no longer uses CopyX nodes.
12180 //
12181 // peephole %{
12182 // peepmatch ( incI_eReg movI );
12183 // peepconstraint ( 0.dst == 1.dst );
12184 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
12185 // %}
12186 //
12187 // peephole %{
12188 // peepmatch ( decI_eReg movI );
12189 // peepconstraint ( 0.dst == 1.dst );
12190 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
12191 // %}
12192 //
12193 // peephole %{
12194 // peepmatch ( addI_eReg_imm movI );
12195 // peepconstraint ( 0.dst == 1.dst );
12196 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
12197 // %}
12198 //
12199 // peephole %{
12200 // peepmatch ( addP_eReg_imm movP );
12201 // peepconstraint ( 0.dst == 1.dst );
12202 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
12203 // %}
12205 // // Change load of spilled value to only a spill
12206 // instruct storeI(memory mem, eRegI src) %{
12207 // match(Set mem (StoreI mem src));
12208 // %}
12209 //
12210 // instruct loadI(eRegI dst, memory mem) %{
12211 // match(Set dst (LoadI mem));
12212 // %}
12213 //
12214 //peephole %{
12215 // peepmatch ( loadI storeI );
12216 // peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
12217 // peepreplace ( storeI( 1.mem 1.mem 1.src ) );
12218 //%}
12220 //----------SMARTSPILL RULES---------------------------------------------------
12221 // These must follow all instruction definitions as they use the names
12222 // defined in the instructions definitions.