Wed, 22 Mar 2017 11:43:05 -0400
[C2] Fix the addressing modes of MIPS for implicit null check.
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 /*
540 // Note that the code buffer's insts_mark is always relative to insts.
541 // That's why we must use the macroassembler to generate a handler.
542 MacroAssembler _masm(&cbuf);
543 address base = __ start_a_stub(size_exception_handler());
544 if (base == NULL) return 0; // CodeBuffer::expand failed
545 int offset = __ offset();
546 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
547 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
548 __ end_a_stub();
549 return offset;
550 */
551 // Note that the code buffer's insts_mark is always relative to insts.
552 // That's why we must use the macroassembler to generate a handler.
553 MacroAssembler _masm(&cbuf);
554 address base =
555 __ start_a_stub(size_exception_handler());
556 if (base == NULL) return 0; // CodeBuffer::expand failed
557 int offset = __ offset();
559 __ block_comment("; emit_exception_handler");
561 /* 2012/9/25 FIXME Jin: According to X86, we should use direct jumpt.
562 * * However, this will trigger an assert after the 40th method:
563 * *
564 * * 39 b java.lang.Throwable::<init> (25 bytes)
565 * * --- ns java.lang.Throwable::fillInStackTrace
566 * * 40 !b java.net.URLClassLoader::findClass (29 bytes)
567 * * /vm/opto/runtime.cpp, 900 , assert(caller.is_compiled_frame(),"must be")
568 * * 40 made not entrant (2) java.net.URLClassLoader::findClass (29 bytes)
569 * *
570 * * If we change from JR to JALR, the assert will disappear, but WebClient will
571 * * fail after the 403th method with unknown reason.
572 * */
573 cbuf.set_insts_mark();
574 __ relocate(relocInfo::runtime_call_type);
576 __ patchable_set48(T9, (long)OptoRuntime::exception_blob()->entry_point());
577 __ jr(T9);
578 __ delayed()->nop();
579 __ align(16);
580 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
581 __ end_a_stub();
582 return offset;
583 }
585 // Emit deopt handler code.
586 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
587 // Note that the code buffer's insts_mark is always relative to insts.
588 // That's why we must use the macroassembler to generate a handler.
589 MacroAssembler _masm(&cbuf);
590 address base =
591 __ start_a_stub(size_deopt_handler());
593 // FIXME
594 if (base == NULL) return 0; // CodeBuffer::expand failed
595 int offset = __ offset();
597 __ block_comment("; emit_deopt_handler");
599 cbuf.set_insts_mark();
600 __ relocate(relocInfo::runtime_call_type);
602 __ patchable_set48(T9, (long)SharedRuntime::deopt_blob()->unpack());
603 __ jalr(T9);
604 __ delayed()->nop();
605 __ align(16);
606 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
607 __ end_a_stub();
608 return offset;
609 }
612 const bool Matcher::match_rule_supported(int opcode) {
613 if (!has_match_rule(opcode))
614 return false;
616 switch (opcode) {
617 //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
618 case Op_CountLeadingZerosI:
619 case Op_CountLeadingZerosL:
620 if (!UseCountLeadingZerosInstruction)
621 return false;
622 break;
623 case Op_CountTrailingZerosI:
624 case Op_CountTrailingZerosL:
625 if (!UseCountTrailingZerosInstruction)
626 return false;
627 break;
628 }
630 return true; // Per default match rules are supported.
631 }
633 //FIXME
634 // emit call stub, compiled java to interpreter
635 void emit_java_to_interp(CodeBuffer &cbuf ) {
636 // Stub is fixed up when the corresponding call is converted from calling
637 // compiled code to calling interpreted code.
638 // mov rbx,0
639 // jmp -1
641 address mark = cbuf.insts_mark(); // get mark within main instrs section
643 // Note that the code buffer's insts_mark is always relative to insts.
644 // That's why we must use the macroassembler to generate a stub.
645 MacroAssembler _masm(&cbuf);
647 address base =
648 __ start_a_stub(Compile::MAX_stubs_size);
649 if (base == NULL) return; // CodeBuffer::expand failed
650 // static stub relocation stores the instruction address of the call
652 __ relocate(static_stub_Relocation::spec(mark), 0);
654 /* 2012/10/29 Jin: Rmethod contains methodOop, it should be relocated for GC */
655 /*
656 int oop_index = __ oop_recorder()->allocate_index(NULL);
657 RelocationHolder rspec = oop_Relocation::spec(oop_index);
658 __ relocate(rspec);
659 */
661 // static stub relocation also tags the methodOop in the code-stream.
662 __ patchable_set48(S3, (long)0);
663 // This is recognized as unresolved by relocs/nativeInst/ic code
665 __ relocate(relocInfo::runtime_call_type);
667 cbuf.set_insts_mark();
668 address call_pc = (address)-1;
669 __ patchable_set48(AT, (long)call_pc);
670 __ jr(AT);
671 __ nop();
672 __ align(16);
673 __ end_a_stub();
674 // Update current stubs pointer and restore code_end.
675 }
677 // size of call stub, compiled java to interpretor
678 uint size_java_to_interp() {
679 int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
680 return round_to(size, 16);
681 }
683 // relocation entries for call stub, compiled java to interpreter
684 uint reloc_java_to_interp() {
685 return 16; // in emit_java_to_interp + in Java_Static_Call
686 }
688 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
689 if( Assembler::is_simm16(offset) ) return true;
690 else {
691 assert(false, "Not implemented yet !" );
692 Unimplemented();
693 }
694 }
697 // No additional cost for CMOVL.
698 const int Matcher::long_cmove_cost() { return 0; }
700 // No CMOVF/CMOVD with SSE2
701 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
703 // Does the CPU require late expand (see block.cpp for description of late expand)?
704 const bool Matcher::require_postalloc_expand = false;
706 // Should the Matcher clone shifts on addressing modes, expecting them
707 // to be subsumed into complex addressing expressions or compute them
708 // into registers? True for Intel but false for most RISCs
709 const bool Matcher::clone_shift_expressions = false;
711 // Do we need to mask the count passed to shift instructions or does
712 // the cpu only look at the lower 5/6 bits anyway?
713 const bool Matcher::need_masked_shift_count = false;
715 bool Matcher::narrow_oop_use_complex_address() {
716 NOT_LP64(ShouldNotCallThis());
717 assert(UseCompressedOops, "only for compressed oops code");
718 return false;
719 }
721 bool Matcher::narrow_klass_use_complex_address() {
722 NOT_LP64(ShouldNotCallThis());
723 assert(UseCompressedClassPointers, "only for compressed klass code");
724 return false;
725 }
727 // This is UltraSparc specific, true just means we have fast l2f conversion
728 const bool Matcher::convL2FSupported(void) {
729 return true;
730 }
732 // Max vector size in bytes. 0 if not supported.
733 const int Matcher::vector_width_in_bytes(BasicType bt) {
734 assert(MaxVectorSize == 8, "");
735 return 8;
736 }
738 // Vector ideal reg
739 const int Matcher::vector_ideal_reg(int size) {
740 assert(MaxVectorSize == 8, "");
741 switch(size) {
742 case 8: return Op_VecD;
743 }
744 ShouldNotReachHere();
745 return 0;
746 }
748 // Only lowest bits of xmm reg are used for vector shift count.
749 const int Matcher::vector_shift_count_ideal_reg(int size) {
750 fatal("vector shift is not supported");
751 return Node::NotAMachineReg;
752 }
754 // Limits on vector size (number of elements) loaded into vector.
755 const int Matcher::max_vector_size(const BasicType bt) {
756 assert(is_java_primitive(bt), "only primitive type vectors");
757 return vector_width_in_bytes(bt)/type2aelembytes(bt);
758 }
760 const int Matcher::min_vector_size(const BasicType bt) {
761 return max_vector_size(bt); // Same as max.
762 }
764 // MIPS supports misaligned vectors store/load? FIXME
765 const bool Matcher::misaligned_vectors_ok() {
766 return false;
767 //return !AlignVector; // can be changed by flag
768 }
770 // Register for DIVI projection of divmodI
771 RegMask Matcher::divI_proj_mask() {
772 ShouldNotReachHere();
773 return RegMask();
774 }
776 // Register for MODI projection of divmodI
777 RegMask Matcher::modI_proj_mask() {
778 ShouldNotReachHere();
779 return RegMask();
780 }
782 // Register for DIVL projection of divmodL
783 RegMask Matcher::divL_proj_mask() {
784 ShouldNotReachHere();
785 return RegMask();
786 }
788 int Matcher::regnum_to_fpu_offset(int regnum) {
789 return regnum - 32; // The FP registers are in the second chunk
790 }
793 const bool Matcher::isSimpleConstant64(jlong value) {
794 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
795 return true;
796 }
799 // Return whether or not this register is ever used as an argument. This
800 // function is used on startup to build the trampoline stubs in generateOptoStub.
801 // Registers not mentioned will be killed by the VM call in the trampoline, and
802 // arguments in those registers not be available to the callee.
803 bool Matcher::can_be_java_arg( int reg ) {
804 /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
805 if ( reg == T0_num || reg == T0_H_num
806 || reg == A0_num || reg == A0_H_num
807 || reg == A1_num || reg == A1_H_num
808 || reg == A2_num || reg == A2_H_num
809 || reg == A3_num || reg == A3_H_num
810 || reg == A4_num || reg == A4_H_num
811 || reg == A5_num || reg == A5_H_num
812 || reg == A6_num || reg == A6_H_num
813 || reg == A7_num || reg == A7_H_num )
814 return true;
816 if ( reg == F12_num || reg == F12_H_num
817 || reg == F13_num || reg == F13_H_num
818 || reg == F14_num || reg == F14_H_num
819 || reg == F15_num || reg == F15_H_num
820 || reg == F16_num || reg == F16_H_num
821 || reg == F17_num || reg == F17_H_num
822 || reg == F18_num || reg == F18_H_num
823 || reg == F19_num || reg == F19_H_num )
824 return true;
826 return false;
827 }
829 bool Matcher::is_spillable_arg( int reg ) {
830 return can_be_java_arg(reg);
831 }
833 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
834 return false;
835 }
837 // Register for MODL projection of divmodL
838 RegMask Matcher::modL_proj_mask() {
839 ShouldNotReachHere();
840 return RegMask();
841 }
843 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
844 return FP_REG_mask();
845 }
847 // MIPS doesn't support AES intrinsics
848 const bool Matcher::pass_original_key_for_aes() {
849 return false;
850 }
852 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
853 //lui
854 //ori
855 //dsll
856 //ori
858 //jalr
859 //nop
861 return round_to(current_offset, alignment_required()) - current_offset;
862 }
864 int CallLeafDirectNode::compute_padding(int current_offset) const {
865 //lui
866 //ori
867 //dsll
868 //ori
870 //jalr
871 //nop
873 return round_to(current_offset, alignment_required()) - current_offset;
874 }
876 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
877 //lui
878 //ori
879 //dsll
880 //ori
882 //jalr
883 //nop
885 return round_to(current_offset, alignment_required()) - current_offset;
886 }
888 // If CPU can load and store mis-aligned doubles directly then no fixup is
889 // needed. Else we split the double into 2 integer pieces and move it
890 // piece-by-piece. Only happens when passing doubles into C code as the
891 // Java calling convention forces doubles to be aligned.
892 const bool Matcher::misaligned_doubles_ok = false;
893 // Do floats take an entire double register or just half?
894 //const bool Matcher::float_in_double = true;
895 bool Matcher::float_in_double() { return false; }
896 // Threshold size for cleararray.
897 const int Matcher::init_array_short_size = 8 * BytesPerLong;
898 // Do ints take an entire long register or just half?
899 const bool Matcher::int_in_long = true;
900 // Is it better to copy float constants, or load them directly from memory?
901 // Intel can load a float constant from a direct address, requiring no
902 // extra registers. Most RISCs will have to materialize an address into a
903 // register first, so they would do better to copy the constant from stack.
904 const bool Matcher::rematerialize_float_constants = false;
905 // Advertise here if the CPU requires explicit rounding operations
906 // to implement the UseStrictFP mode.
907 const bool Matcher::strict_fp_requires_explicit_rounding = false;
908 // The ecx parameter to rep stos for the ClearArray node is in dwords.
909 const bool Matcher::init_array_count_is_in_bytes = false;
912 // Indicate if the safepoint node needs the polling page as an input.
913 // Since MIPS doesn't have absolute addressing, it needs.
914 bool SafePointNode::needs_polling_address_input() {
915 return false;
916 }
918 // !!!!! Special hack to get all type of calls to specify the byte offset
919 // from the start of the call to the point where the return address
920 // will point.
921 int MachCallStaticJavaNode::ret_addr_offset() {
922 //lui
923 //ori
924 //nop
925 //nop
926 //jalr
927 //nop
928 return 24;
929 }
931 int MachCallDynamicJavaNode::ret_addr_offset() {
932 //lui IC_Klass,
933 //ori IC_Klass,
934 //dsll IC_Klass
935 //ori IC_Klass
937 //lui T9
938 //ori T9
939 //nop
940 //nop
941 //jalr T9
942 //nop
943 return 4 * 4 + 4 * 6;
944 }
946 //=============================================================================
948 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
949 enum RC { rc_bad, rc_int, rc_float, rc_stack };
950 static enum RC rc_class( OptoReg::Name reg ) {
951 if( !OptoReg::is_valid(reg) ) return rc_bad;
952 if (OptoReg::is_stack(reg)) return rc_stack;
953 VMReg r = OptoReg::as_VMReg(reg);
954 if (r->is_Register()) return rc_int;
955 assert(r->is_FloatRegister(), "must be");
956 return rc_float;
957 }
959 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
960 // Get registers to move
961 OptoReg::Name src_second = ra_->get_reg_second(in(1));
962 OptoReg::Name src_first = ra_->get_reg_first(in(1));
963 OptoReg::Name dst_second = ra_->get_reg_second(this );
964 OptoReg::Name dst_first = ra_->get_reg_first(this );
966 enum RC src_second_rc = rc_class(src_second);
967 enum RC src_first_rc = rc_class(src_first);
968 enum RC dst_second_rc = rc_class(dst_second);
969 enum RC dst_first_rc = rc_class(dst_first);
971 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
973 // Generate spill code!
974 int size = 0;
976 if( src_first == dst_first && src_second == dst_second )
977 return 0; // Self copy, no move
979 if (src_first_rc == rc_stack) {
980 // mem ->
981 if (dst_first_rc == rc_stack) {
982 // mem -> mem
983 assert(src_second != dst_first, "overlap");
984 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
985 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
986 // 64-bit
987 int src_offset = ra_->reg2offset(src_first);
988 int dst_offset = ra_->reg2offset(dst_first);
989 if (cbuf) {
990 MacroAssembler _masm(cbuf);
991 __ ld(AT, Address(SP, src_offset));
992 __ sd(AT, Address(SP, dst_offset));
993 #ifndef PRODUCT
994 } else {
995 if(!do_size){
996 if (size != 0) st->print("\n\t");
997 st->print("ld AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
998 "sd AT, [SP + #%d]",
999 src_offset, dst_offset);
1000 }
1001 #endif
1002 }
1003 size += 8;
1004 } else {
1005 // 32-bit
1006 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1007 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1008 // No pushl/popl, so:
1009 int src_offset = ra_->reg2offset(src_first);
1010 int dst_offset = ra_->reg2offset(dst_first);
1011 if (cbuf) {
1012 MacroAssembler _masm(cbuf);
1013 __ lw(AT, Address(SP, src_offset));
1014 __ sw(AT, Address(SP, dst_offset));
1015 #ifndef PRODUCT
1016 } else {
1017 if(!do_size){
1018 if (size != 0) st->print("\n\t");
1019 st->print("lw AT, [SP + #%d] spill 2\n\t"
1020 "sw AT, [SP + #%d]\n\t",
1021 src_offset, dst_offset);
1022 }
1023 #endif
1024 }
1025 size += 8;
1026 }
1027 return size;
1028 } else if (dst_first_rc == rc_int) {
1029 // mem -> gpr
1030 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1031 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1032 // 64-bit
1033 int offset = ra_->reg2offset(src_first);
1034 if (cbuf) {
1035 MacroAssembler _masm(cbuf);
1036 __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1037 #ifndef PRODUCT
1038 } else {
1039 if(!do_size){
1040 if (size != 0) st->print("\n\t");
1041 st->print("ld %s, [SP + #%d]\t# spill 3",
1042 Matcher::regName[dst_first],
1043 offset);
1044 }
1045 #endif
1046 }
1047 size += 4;
1048 } else {
1049 // 32-bit
1050 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1051 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1052 int offset = ra_->reg2offset(src_first);
1053 if (cbuf) {
1054 MacroAssembler _masm(cbuf);
1055 if (this->ideal_reg() == Op_RegI)
1056 __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1057 else
1058 __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1059 #ifndef PRODUCT
1060 } else {
1061 if(!do_size){
1062 if (size != 0) st->print("\n\t");
1063 if (this->ideal_reg() == Op_RegI)
1064 st->print("lw %s, [SP + #%d]\t# spill 4",
1065 Matcher::regName[dst_first],
1066 offset);
1067 else
1068 st->print("lwu %s, [SP + #%d]\t# spill 5",
1069 Matcher::regName[dst_first],
1070 offset);
1071 }
1072 #endif
1073 }
1074 size += 4;
1075 }
1076 return size;
1077 } else if (dst_first_rc == rc_float) {
1078 // mem-> xmm
1079 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1080 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1081 // 64-bit
1082 int offset = ra_->reg2offset(src_first);
1083 if (cbuf) {
1084 MacroAssembler _masm(cbuf);
1085 __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1086 #ifndef PRODUCT
1087 } else {
1088 if(!do_size){
1089 if (size != 0) st->print("\n\t");
1090 st->print("ldc1 %s, [SP + #%d]\t# spill 6",
1091 Matcher::regName[dst_first],
1092 offset);
1093 }
1094 #endif
1095 }
1096 size += 4;
1097 } else {
1098 // 32-bit
1099 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1100 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1101 int offset = ra_->reg2offset(src_first);
1102 if (cbuf) {
1103 MacroAssembler _masm(cbuf);
1104 __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1105 #ifndef PRODUCT
1106 } else {
1107 if(!do_size){
1108 if (size != 0) st->print("\n\t");
1109 st->print("lwc1 %s, [SP + #%d]\t# spill 7",
1110 Matcher::regName[dst_first],
1111 offset);
1112 }
1113 #endif
1114 }
1115 size += 4;
1116 }
1117 return size;
1118 }
1119 } else if (src_first_rc == rc_int) {
1120 // gpr ->
1121 if (dst_first_rc == rc_stack) {
1122 // gpr -> mem
1123 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1124 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1125 // 64-bit
1126 int offset = ra_->reg2offset(dst_first);
1127 if (cbuf) {
1128 MacroAssembler _masm(cbuf);
1129 __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1130 #ifndef PRODUCT
1131 } else {
1132 if(!do_size){
1133 if (size != 0) st->print("\n\t");
1134 st->print("sd %s, [SP + #%d] # spill 8",
1135 Matcher::regName[src_first],
1136 offset);
1137 }
1138 #endif
1139 }
1140 size += 4;
1141 } else {
1142 // 32-bit
1143 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1144 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1145 int offset = ra_->reg2offset(dst_first);
1146 if (cbuf) {
1147 MacroAssembler _masm(cbuf);
1148 __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1149 #ifndef PRODUCT
1150 } else {
1151 if(!do_size){
1152 if (size != 0) st->print("\n\t");
1153 st->print("sw %s, [SP + #%d]\t# spill 9",
1154 Matcher::regName[src_first], offset);
1155 }
1156 #endif
1157 }
1158 size += 4;
1159 }
1160 return size;
1161 } else if (dst_first_rc == rc_int) {
1162 // gpr -> gpr
1163 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1164 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1165 // 64-bit
1166 if (cbuf) {
1167 MacroAssembler _masm(cbuf);
1168 __ move(as_Register(Matcher::_regEncode[dst_first]),
1169 as_Register(Matcher::_regEncode[src_first]));
1170 #ifndef PRODUCT
1171 } else {
1172 if(!do_size){
1173 if (size != 0) st->print("\n\t");
1174 st->print("move(64bit) %s <-- %s\t# spill 10",
1175 Matcher::regName[dst_first],
1176 Matcher::regName[src_first]);
1177 }
1178 #endif
1179 }
1180 size += 4;
1181 return size;
1182 } else {
1183 // 32-bit
1184 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1185 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1186 if (cbuf) {
1187 MacroAssembler _masm(cbuf);
1188 if (this->ideal_reg() == Op_RegI)
1189 __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1190 else
1191 __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
1193 #ifndef PRODUCT
1194 } else {
1195 if(!do_size){
1196 if (size != 0) st->print("\n\t");
1197 st->print("move(32-bit) %s <-- %s\t# spill 11",
1198 Matcher::regName[dst_first],
1199 Matcher::regName[src_first]);
1200 }
1201 #endif
1202 }
1203 size += 4;
1204 return size;
1205 }
1206 } else if (dst_first_rc == rc_float) {
1207 // gpr -> xmm
1208 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1209 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1210 // 64-bit
1211 if (cbuf) {
1212 MacroAssembler _masm(cbuf);
1213 __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
1214 #ifndef PRODUCT
1215 } else {
1216 if(!do_size){
1217 if (size != 0) st->print("\n\t");
1218 st->print("dmtc1 %s, %s\t# spill 12",
1219 Matcher::regName[dst_first],
1220 Matcher::regName[src_first]);
1221 }
1222 #endif
1223 }
1224 size += 4;
1225 } else {
1226 // 32-bit
1227 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1228 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1229 if (cbuf) {
1230 MacroAssembler _masm(cbuf);
1231 __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
1232 #ifndef PRODUCT
1233 } else {
1234 if(!do_size){
1235 if (size != 0) st->print("\n\t");
1236 st->print("mtc1 %s, %s\t# spill 13",
1237 Matcher::regName[dst_first],
1238 Matcher::regName[src_first]);
1239 }
1240 #endif
1241 }
1242 size += 4;
1243 }
1244 return size;
1245 }
1246 } else if (src_first_rc == rc_float) {
1247 // xmm ->
1248 if (dst_first_rc == rc_stack) {
1249 // xmm -> mem
1250 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1251 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1252 // 64-bit
1253 int offset = ra_->reg2offset(dst_first);
1254 if (cbuf) {
1255 MacroAssembler _masm(cbuf);
1256 __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
1257 #ifndef PRODUCT
1258 } else {
1259 if(!do_size){
1260 if (size != 0) st->print("\n\t");
1261 st->print("sdc1 %s, [SP + #%d]\t# spill 14",
1262 Matcher::regName[src_first],
1263 offset);
1264 }
1265 #endif
1266 }
1267 size += 4;
1268 } else {
1269 // 32-bit
1270 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1271 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1272 int offset = ra_->reg2offset(dst_first);
1273 if (cbuf) {
1274 MacroAssembler _masm(cbuf);
1275 __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
1276 #ifndef PRODUCT
1277 } else {
1278 if(!do_size){
1279 if (size != 0) st->print("\n\t");
1280 st->print("swc1 %s, [SP + #%d]\t# spill 15",
1281 Matcher::regName[src_first],
1282 offset);
1283 }
1284 #endif
1285 }
1286 size += 4;
1287 }
1288 return size;
1289 } else if (dst_first_rc == rc_int) {
1290 // xmm -> gpr
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 __ dmfc1( as_Register(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("dmfc1 %s, %s\t# spill 16",
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 __ mfc1( as_Register(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("mfc1 %s, %s\t# spill 17",
1320 Matcher::regName[dst_first],
1321 Matcher::regName[src_first]);
1322 }
1323 #endif
1324 }
1325 size += 4;
1326 }
1327 return size;
1328 } else if (dst_first_rc == rc_float) {
1329 // xmm -> xmm
1330 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1331 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1332 // 64-bit
1333 if (cbuf) {
1334 MacroAssembler _masm(cbuf);
1335 __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1336 #ifndef PRODUCT
1337 } else {
1338 if(!do_size){
1339 if (size != 0) st->print("\n\t");
1340 st->print("mov_d %s <-- %s\t# spill 18",
1341 Matcher::regName[dst_first],
1342 Matcher::regName[src_first]);
1343 }
1344 #endif
1345 }
1346 size += 4;
1347 } else {
1348 // 32-bit
1349 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1350 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1351 if (cbuf) {
1352 MacroAssembler _masm(cbuf);
1353 __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1354 #ifndef PRODUCT
1355 } else {
1356 if(!do_size){
1357 if (size != 0) st->print("\n\t");
1358 st->print("mov_s %s <-- %s\t# spill 19",
1359 Matcher::regName[dst_first],
1360 Matcher::regName[src_first]);
1361 }
1362 #endif
1363 }
1364 size += 4;
1365 }
1366 return size;
1367 }
1368 }
1370 assert(0," foo ");
1371 Unimplemented();
1372 return size;
1374 }
1376 #ifndef PRODUCT
1377 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1378 implementation( NULL, ra_, false, st );
1379 }
1380 #endif
1382 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1383 implementation( &cbuf, ra_, false, NULL );
1384 }
1386 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1387 return implementation( NULL, ra_, true, NULL );
1388 }
1390 //=============================================================================
1391 #
1393 #ifndef PRODUCT
1394 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
1395 st->print("INT3");
1396 }
1397 #endif
1399 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
1400 MacroAssembler _masm(&cbuf);
1401 __ int3();
1402 }
1404 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
1405 return MachNode::size(ra_);
1406 }
1409 //=============================================================================
1410 #ifndef PRODUCT
1411 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1412 Compile *C = ra_->C;
1413 int framesize = C->frame_size_in_bytes();
1415 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1417 st->print("daddiu SP, SP, %d # Rlease stack @ MachEpilogNode",framesize);
1418 st->cr(); st->print("\t");
1419 if (UseLoongsonISA) {
1420 st->print("gslq RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
1421 } else {
1422 st->print("ld RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
1423 st->cr(); st->print("\t");
1424 st->print("ld FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
1425 }
1427 if( do_polling() && C->is_method_compilation() ) {
1428 st->print("Poll Safepoint # MachEpilogNode");
1429 }
1430 }
1431 #endif
1433 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1434 Compile *C = ra_->C;
1435 MacroAssembler _masm(&cbuf);
1436 int framesize = C->frame_size_in_bytes();
1438 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1440 __ daddiu(SP, SP, framesize);
1442 if (UseLoongsonISA) {
1443 __ gslq(RA, FP, SP, -wordSize*2);
1444 } else {
1445 __ ld(RA, SP, -wordSize );
1446 __ ld(FP, SP, -wordSize*2 );
1447 }
1449 if( do_polling() && C->is_method_compilation() ) {
1450 __ set64(AT, (long)os::get_polling_page());
1451 __ relocate(relocInfo::poll_return_type);
1452 __ lw(AT, AT, 0);
1453 }
1454 }
1456 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1457 return MachNode::size(ra_); // too many variables; just compute it the hard way fujie debug
1458 }
1460 int MachEpilogNode::reloc() const {
1461 return 0; // a large enough number
1462 }
1464 const Pipeline * MachEpilogNode::pipeline() const {
1465 return MachNode::pipeline_class();
1466 }
1468 int MachEpilogNode::safepoint_offset() const { return 0; }
1470 //=============================================================================
1472 #ifndef PRODUCT
1473 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1474 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1475 int reg = ra_->get_reg_first(this);
1476 st->print("ADDI %s, SP, %d @BoxLockNode",Matcher::regName[reg],offset);
1477 }
1478 #endif
1481 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1482 return 4;
1483 }
1485 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1486 MacroAssembler _masm(&cbuf);
1487 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1488 int reg = ra_->get_encode(this);
1490 __ addi(as_Register(reg), SP, offset);
1491 /*
1492 if( offset >= 128 ) {
1493 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1494 emit_rm(cbuf, 0x2, reg, 0x04);
1495 emit_rm(cbuf, 0x0, 0x04, SP_enc);
1496 emit_d32(cbuf, offset);
1497 }
1498 else {
1499 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1500 emit_rm(cbuf, 0x1, reg, 0x04);
1501 emit_rm(cbuf, 0x0, 0x04, SP_enc);
1502 emit_d8(cbuf, offset);
1503 }
1504 */
1505 }
1508 //static int sizeof_FFree_Float_Stack_All = -1;
1510 int MachCallRuntimeNode::ret_addr_offset() {
1511 //lui
1512 //ori
1513 //dsll
1514 //ori
1515 //jalr
1516 //nop
1517 assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
1518 return NativeCall::instruction_size;
1519 // return 16;
1520 }
1526 //=============================================================================
1527 #ifndef PRODUCT
1528 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
1529 st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
1530 }
1531 #endif
1533 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
1534 MacroAssembler _masm(&cbuf);
1535 int i = 0;
1536 for(i = 0; i < _count; i++)
1537 __ nop();
1538 }
1540 uint MachNopNode::size(PhaseRegAlloc *) const {
1541 return 4 * _count;
1542 }
1543 const Pipeline* MachNopNode::pipeline() const {
1544 return MachNode::pipeline_class();
1545 }
1547 //=============================================================================
1549 //=============================================================================
1550 #ifndef PRODUCT
1551 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1552 st->print_cr("load_klass(T9, T0)");
1553 st->print_cr("\tbeq(T9, iCache, L)");
1554 st->print_cr("\tnop");
1555 st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
1556 st->print_cr("\tnop");
1557 st->print_cr("\tnop");
1558 st->print_cr(" L:");
1559 }
1560 #endif
1563 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1564 MacroAssembler _masm(&cbuf);
1565 #ifdef ASSERT
1566 //uint code_size = cbuf.code_size();
1567 #endif
1568 int ic_reg = Matcher::inline_cache_reg_encode();
1569 Label L;
1570 Register receiver = T0;
1571 Register iCache = as_Register(ic_reg);
1572 __ load_klass(T9, receiver);
1573 __ beq(T9, iCache, L);
1574 __ nop();
1576 __ relocate(relocInfo::runtime_call_type);
1577 __ patchable_set48(T9, (long)SharedRuntime::get_ic_miss_stub());
1578 __ jr(T9);
1579 __ nop();
1581 /* WARNING these NOPs are critical so that verified entry point is properly
1582 * 8 bytes aligned for patching by NativeJump::patch_verified_entry() */
1583 __ align(CodeEntryAlignment);
1584 __ bind(L);
1585 }
1587 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1588 return MachNode::size(ra_);
1589 }
1593 //=============================================================================
1595 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
1597 int Compile::ConstantTable::calculate_table_base_offset() const {
1598 return 0; // absolute addressing, no offset
1599 }
1601 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1602 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1603 ShouldNotReachHere();
1604 }
1606 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1607 Compile* C = ra_->C;
1608 Compile::ConstantTable& constant_table = C->constant_table();
1609 MacroAssembler _masm(&cbuf);
1611 Register Rtoc = as_Register(ra_->get_encode(this));
1612 CodeSection* consts_section = __ code()->consts();
1613 int consts_size = consts_section->align_at_start(consts_section->size());
1614 assert(constant_table.size() == consts_size, "must be equal");
1616 if (consts_section->size()) {
1617 // Materialize the constant table base.
1618 address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
1619 // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
1620 __ relocate(relocInfo::internal_pc_type);
1621 __ patchable_set48(Rtoc, (long)baseaddr);
1622 }
1623 }
1625 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1626 // patchable_set48 (4 insts)
1627 return 4 * 4;
1628 }
1630 #ifndef PRODUCT
1631 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1632 Register r = as_Register(ra_->get_encode(this));
1633 st->print("patchable_set48 %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
1634 }
1635 #endif
1638 //=============================================================================
1639 #ifndef PRODUCT
1640 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1641 Compile* C = ra_->C;
1643 int framesize = C->frame_size_in_bytes();
1644 int bangsize = C->bang_size_in_bytes();
1645 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1647 // Calls to C2R adapters often do not accept exceptional returns.
1648 // We require that their callers must bang for them. But be careful, because
1649 // some VM calls (such as call site linkage) can use several kilobytes of
1650 // stack. But the stack safety zone should account for that.
1651 // See bugs 4446381, 4468289, 4497237.
1652 if (C->need_stack_bang(bangsize)) {
1653 st->print_cr("# stack bang"); st->print("\t");
1654 }
1655 if (UseLoongsonISA) {
1656 st->print("gssq RA, FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1657 } else {
1658 st->print("sd RA, %d(SP) @ MachPrologNode\n\t", -wordSize);
1659 st->print("sd FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1660 }
1661 st->print("daddiu FP, SP, -%d \n\t", wordSize*2);
1662 st->print("daddiu SP, SP, -%d \t",framesize);
1663 }
1664 #endif
1667 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1668 Compile* C = ra_->C;
1669 MacroAssembler _masm(&cbuf);
1671 int framesize = C->frame_size_in_bytes();
1672 int bangsize = C->bang_size_in_bytes();
1674 // __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false);
1676 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1678 if (C->need_stack_bang(framesize)) {
1679 __ generate_stack_overflow_check(framesize);
1680 }
1682 if (UseLoongsonISA) {
1683 __ gssq(RA, FP, SP, -wordSize*2);
1684 } else {
1685 __ sd(RA, SP, -wordSize);
1686 __ sd(FP, SP, -wordSize*2);
1687 }
1688 __ daddiu(FP, SP, -wordSize*2);
1689 __ daddiu(SP, SP, -framesize);
1690 __ nop(); /* 2013.10.22 Jin: Make enough room for patch_verified_entry() */
1691 __ nop();
1693 C->set_frame_complete(cbuf.insts_size());
1694 if (C->has_mach_constant_base_node()) {
1695 // NOTE: We set the table base offset here because users might be
1696 // emitted before MachConstantBaseNode.
1697 Compile::ConstantTable& constant_table = C->constant_table();
1698 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1699 }
1701 }
1704 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1705 //fprintf(stderr, "\nPrologNode::size(ra_)= %d \n", MachNode::size(ra_));//fujie debug
1706 return MachNode::size(ra_); // too many variables; just compute it the hard way
1707 }
1709 int MachPrologNode::reloc() const {
1710 return 0; // a large enough number
1711 }
1713 %}
1715 //----------ENCODING BLOCK-----------------------------------------------------
1716 // This block specifies the encoding classes used by the compiler to output
1717 // byte streams. Encoding classes generate functions which are called by
1718 // Machine Instruction Nodes in order to generate the bit encoding of the
1719 // instruction. Operands specify their base encoding interface with the
1720 // interface keyword. There are currently supported four interfaces,
1721 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
1722 // operand to generate a function which returns its register number when
1723 // queried. CONST_INTER causes an operand to generate a function which
1724 // returns the value of the constant when queried. MEMORY_INTER causes an
1725 // operand to generate four functions which return the Base Register, the
1726 // Index Register, the Scale Value, and the Offset Value of the operand when
1727 // queried. COND_INTER causes an operand to generate six functions which
1728 // return the encoding code (ie - encoding bits for the instruction)
1729 // associated with each basic boolean condition for a conditional instruction.
1730 // Instructions specify two basic values for encoding. They use the
1731 // ins_encode keyword to specify their encoding class (which must be one of
1732 // the class names specified in the encoding block), and they use the
1733 // opcode keyword to specify, in order, their primary, secondary, and
1734 // tertiary opcode. Only the opcode sections which a particular instruction
1735 // needs for encoding need to be specified.
1736 encode %{
1738 //Load byte signed
1739 enc_class load_B_enc (mRegI dst, memory mem) %{
1740 MacroAssembler _masm(&cbuf);
1741 int dst = $dst$$reg;
1742 int base = $mem$$base;
1743 int index = $mem$$index;
1744 int scale = $mem$$scale;
1745 int disp = $mem$$disp;
1747 if( index != 0 ) {
1748 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1749 __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
1750 } else {
1751 __ lb(as_Register(dst), as_Register(base), disp);
1752 }
1753 %}
1755 //Load byte unsigned
1756 enc_class load_UB_enc (mRegI dst, umemory mem) %{
1757 MacroAssembler _masm(&cbuf);
1758 int dst = $dst$$reg;
1759 int base = $mem$$base;
1760 int index = $mem$$index;
1761 int scale = $mem$$scale;
1762 int disp = $mem$$disp;
1764 assert(index == 0, "no index");
1765 __ lbu(as_Register(dst), as_Register(base), disp);
1766 %}
1768 enc_class store_B_reg_enc (memory mem, mRegI src) %{
1769 MacroAssembler _masm(&cbuf);
1770 int src = $src$$reg;
1771 int base = $mem$$base;
1772 int index = $mem$$index;
1773 int scale = $mem$$scale;
1774 int disp = $mem$$disp;
1776 if( index != 0 ) {
1777 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1778 __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
1779 } else {
1780 __ sb(as_Register(src), as_Register(base), disp);
1781 }
1782 %}
1784 enc_class store_B0_enc (memory mem) %{
1785 MacroAssembler _masm(&cbuf);
1786 int base = $mem$$base;
1787 int index = $mem$$index;
1788 int scale = $mem$$scale;
1789 int disp = $mem$$disp;
1791 if( index != 0 ) {
1792 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1793 __ gssbx(R0, as_Register(base), as_Register(index), disp);
1794 } else {
1795 __ sb(R0, as_Register(base), disp);
1796 }
1797 %}
1799 enc_class store_B_reg_sync_enc (memory mem, mRegI src) %{
1800 MacroAssembler _masm(&cbuf);
1801 int src = $src$$reg;
1802 int base = $mem$$base;
1803 int index = $mem$$index;
1804 int scale = $mem$$scale;
1805 int disp = $mem$$disp;
1807 if( index != 0 ) {
1808 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1809 __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
1810 } else {
1811 __ sb(as_Register(src), as_Register(base), disp);
1812 }
1813 __ sync();
1814 %}
1816 enc_class store_B0_sync_enc (memory mem) %{
1817 MacroAssembler _masm(&cbuf);
1818 int base = $mem$$base;
1819 int index = $mem$$index;
1820 int scale = $mem$$scale;
1821 int disp = $mem$$disp;
1823 if( index != 0 ) {
1824 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1825 __ gssbx(R0, as_Register(base), as_Register(index), disp);
1826 } else {
1827 __ sb(R0, as_Register(base), disp);
1828 }
1829 __ sync();
1830 %}
1832 // Load Short (16bit signed)
1833 enc_class load_S_enc (mRegI dst, memory mem) %{
1834 MacroAssembler _masm(&cbuf);
1835 int dst = $dst$$reg;
1836 int base = $mem$$base;
1837 int index = $mem$$index;
1838 int scale = $mem$$scale;
1839 int disp = $mem$$disp;
1841 if( index != 0 ) {
1842 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1843 __ gslhx(as_Register(dst), as_Register(base), as_Register(index), disp);
1844 } else {
1845 __ lh(as_Register(dst), as_Register(base), disp);
1846 }
1847 %}
1849 // Load Char (16bit unsigned)
1850 enc_class load_C_enc (mRegI dst, umemory mem) %{
1851 MacroAssembler _masm(&cbuf);
1852 int dst = $dst$$reg;
1853 int base = $mem$$base;
1854 int index = $mem$$index;
1855 int scale = $mem$$scale;
1856 int disp = $mem$$disp;
1858 assert(index == 0, "no index");
1859 __ lhu(as_Register(dst), as_Register(base), disp);
1860 %}
1862 // Store Char (16bit unsigned)
1863 enc_class store_C_reg_enc (memory mem, mRegI src) %{
1864 MacroAssembler _masm(&cbuf);
1865 int src = $src$$reg;
1866 int base = $mem$$base;
1867 int index = $mem$$index;
1868 int scale = $mem$$scale;
1869 int disp = $mem$$disp;
1871 if( index != 0 ) {
1872 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1873 __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
1874 } else {
1875 __ sh(as_Register(src), as_Register(base), disp);
1876 }
1877 %}
1879 enc_class store_C0_enc (memory mem) %{
1880 MacroAssembler _masm(&cbuf);
1881 int base = $mem$$base;
1882 int index = $mem$$index;
1883 int scale = $mem$$scale;
1884 int disp = $mem$$disp;
1886 if( index != 0 ) {
1887 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1888 __ gsshx(R0, as_Register(base), as_Register(index), disp);
1889 } else {
1890 __ sh(R0, as_Register(base), disp);
1891 }
1892 %}
1894 enc_class load_I_enc (mRegI dst, memory mem) %{
1895 MacroAssembler _masm(&cbuf);
1896 int dst = $dst$$reg;
1897 int base = $mem$$base;
1898 int index = $mem$$index;
1899 int scale = $mem$$scale;
1900 int disp = $mem$$disp;
1902 if( index != 0 ) {
1903 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1904 __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
1905 } else {
1906 __ lw(as_Register(dst), as_Register(base), disp);
1907 }
1908 %}
1910 enc_class store_I_reg_enc (memory mem, mRegI src) %{
1911 MacroAssembler _masm(&cbuf);
1912 int src = $src$$reg;
1913 int base = $mem$$base;
1914 int index = $mem$$index;
1915 int scale = $mem$$scale;
1916 int disp = $mem$$disp;
1918 if( index != 0 ) {
1919 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1920 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
1921 } else {
1922 __ sw(as_Register(src), as_Register(base), disp);
1923 }
1924 %}
1926 enc_class store_I_immI0_enc (memory mem) %{
1927 MacroAssembler _masm(&cbuf);
1928 int base = $mem$$base;
1929 int index = $mem$$index;
1930 int scale = $mem$$scale;
1931 int disp = $mem$$disp;
1933 if( index != 0 ) {
1934 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1935 __ gsswx(R0, as_Register(base), as_Register(index), disp);
1936 } else {
1937 __ sw(R0, as_Register(base), disp);
1938 }
1939 %}
1941 enc_class load_N_enc (mRegN dst, umemory mem) %{
1942 MacroAssembler _masm(&cbuf);
1943 int dst = $dst$$reg;
1944 int base = $mem$$base;
1945 int index = $mem$$index;
1946 int scale = $mem$$scale;
1947 int disp = $mem$$disp;
1949 relocInfo::relocType disp_reloc = $mem->disp_reloc();
1950 assert(disp_reloc == relocInfo::none, "cannot have disp");
1952 assert(index == 0, "no index");
1953 __ lwu(as_Register(dst), as_Register(base), disp);
1954 %}
1957 enc_class load_P_enc (mRegP dst, memory mem) %{
1958 MacroAssembler _masm(&cbuf);
1959 int dst = $dst$$reg;
1960 int base = $mem$$base;
1961 int index = $mem$$index;
1962 int scale = $mem$$scale;
1963 int disp = $mem$$disp;
1965 relocInfo::relocType disp_reloc = $mem->disp_reloc();
1966 assert(disp_reloc == relocInfo::none, "cannot have disp");
1968 if( index != 0 ) {
1969 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1970 __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
1971 } else {
1972 __ ld(as_Register(dst), as_Register(base), disp);
1973 }
1974 %}
1976 enc_class store_P_reg_enc (memory mem, mRegP src) %{
1977 MacroAssembler _masm(&cbuf);
1978 int src = $src$$reg;
1979 int base = $mem$$base;
1980 int index = $mem$$index;
1981 int scale = $mem$$scale;
1982 int disp = $mem$$disp;
1984 if( index != 0 ) {
1985 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
1986 __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
1987 } else {
1988 __ sd(as_Register(src), as_Register(base), disp);
1989 }
1990 %}
1992 enc_class store_N_reg_enc (memory mem, mRegN src) %{
1993 MacroAssembler _masm(&cbuf);
1994 int src = $src$$reg;
1995 int base = $mem$$base;
1996 int index = $mem$$index;
1997 int scale = $mem$$scale;
1998 int disp = $mem$$disp;
2000 if( index != 0 ) {
2001 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2002 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
2003 } else {
2004 __ sw(as_Register(src), as_Register(base), disp);
2005 }
2006 %}
2008 enc_class store_P_immP0_enc (memory mem) %{
2009 MacroAssembler _masm(&cbuf);
2010 int base = $mem$$base;
2011 int index = $mem$$index;
2012 int scale = $mem$$scale;
2013 int disp = $mem$$disp;
2015 if( index != 0 ) {
2016 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2017 __ gssdx(R0, as_Register(base), as_Register(index), disp);
2018 } else {
2019 __ sd(R0, as_Register(base), disp);
2020 }
2021 %}
2024 enc_class storeImmN0_enc(memory mem) %{
2025 MacroAssembler _masm(&cbuf);
2026 int base = $mem$$base;
2027 int index = $mem$$index;
2028 int scale = $mem$$scale;
2029 int disp = $mem$$disp;
2031 if(index != 0){
2032 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2033 __ gsswx(R0, as_Register(base), as_Register(index), disp);
2034 } else {
2035 __ sw(R0, as_Register(base), disp);
2036 }
2037 %}
2039 enc_class load_L_enc (mRegL dst, memory mem) %{
2040 MacroAssembler _masm(&cbuf);
2041 int base = $mem$$base;
2042 int index = $mem$$index;
2043 int scale = $mem$$scale;
2044 int disp = $mem$$disp;
2045 Register dst_reg = as_Register($dst$$reg);
2047 if( index != 0 ) {
2048 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2049 __ gsldx(dst_reg, as_Register(base), as_Register(index), disp);
2050 } else {
2051 __ ld(dst_reg, as_Register(base), disp);
2052 }
2053 %}
2055 enc_class store_L_reg_enc (memory mem, mRegL src) %{
2056 MacroAssembler _masm(&cbuf);
2057 int base = $mem$$base;
2058 int index = $mem$$index;
2059 int scale = $mem$$scale;
2060 int disp = $mem$$disp;
2061 Register src_reg = as_Register($src$$reg);
2063 if( index != 0 ) {
2064 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2065 __ gssdx(src_reg, as_Register(base), as_Register(index), disp);
2066 } else {
2067 __ sd(src_reg, as_Register(base), disp);
2068 }
2069 %}
2071 enc_class store_L_immL0_enc (memory mem) %{
2072 MacroAssembler _masm(&cbuf);
2073 int base = $mem$$base;
2074 int index = $mem$$index;
2075 int scale = $mem$$scale;
2076 int disp = $mem$$disp;
2078 if( index != 0 ) {
2079 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2080 __ gssdx(R0, as_Register(base), as_Register(index), disp);
2081 } else {
2082 __ sd(R0, as_Register(base), disp);
2083 }
2084 %}
2086 enc_class load_F_enc (regF dst, memory mem) %{
2087 MacroAssembler _masm(&cbuf);
2088 int base = $mem$$base;
2089 int index = $mem$$index;
2090 int scale = $mem$$scale;
2091 int disp = $mem$$disp;
2092 FloatRegister dst = $dst$$FloatRegister;
2094 if( index != 0 ) {
2095 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2096 __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
2097 } else {
2098 __ lwc1(dst, as_Register(base), disp);
2099 }
2100 %}
2102 enc_class store_F_reg_enc (memory mem, regF src) %{
2103 MacroAssembler _masm(&cbuf);
2104 int base = $mem$$base;
2105 int index = $mem$$index;
2106 int scale = $mem$$scale;
2107 int disp = $mem$$disp;
2108 FloatRegister src = $src$$FloatRegister;
2110 if( index != 0 ) {
2111 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2112 __ gsswxc1(src, as_Register(base), as_Register(index), disp);
2113 } else {
2114 __ swc1(src, as_Register(base), disp);
2115 }
2116 %}
2118 enc_class load_D_enc (regD dst, memory mem) %{
2119 MacroAssembler _masm(&cbuf);
2120 int base = $mem$$base;
2121 int index = $mem$$index;
2122 int scale = $mem$$scale;
2123 int disp = $mem$$disp;
2124 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
2126 if( index != 0 ) {
2127 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2128 __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
2129 } else {
2130 __ ldc1(dst_reg, as_Register(base), disp);
2131 }
2132 %}
2134 enc_class store_D_reg_enc (memory mem, regD src) %{
2135 MacroAssembler _masm(&cbuf);
2136 int base = $mem$$base;
2137 int index = $mem$$index;
2138 int scale = $mem$$scale;
2139 int disp = $mem$$disp;
2140 FloatRegister src_reg = as_FloatRegister($src$$reg);
2142 if( index != 0 ) {
2143 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
2144 __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
2145 } else {
2146 __ sdc1(src_reg, as_Register(base), disp);
2147 }
2148 %}
2150 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf
2151 MacroAssembler _masm(&cbuf);
2152 // This is the instruction starting address for relocation info.
2153 __ block_comment("Java_To_Runtime");
2154 cbuf.set_insts_mark();
2155 __ relocate(relocInfo::runtime_call_type);
2157 __ patchable_call((address)$meth$$method);
2158 %}
2160 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
2161 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
2162 // who we intended to call.
2163 MacroAssembler _masm(&cbuf);
2164 cbuf.set_insts_mark();
2166 if ( !_method ) {
2167 __ relocate(relocInfo::runtime_call_type);
2168 } else if(_optimized_virtual) {
2169 __ relocate(relocInfo::opt_virtual_call_type);
2170 } else {
2171 __ relocate(relocInfo::static_call_type);
2172 }
2174 __ patchable_call((address)($meth$$method));
2175 if( _method ) { // Emit stub for static call
2176 emit_java_to_interp(cbuf);
2177 }
2178 %}
2181 /*
2182 * [Ref: LIR_Assembler::ic_call() ]
2183 */
2184 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL
2185 MacroAssembler _masm(&cbuf);
2186 __ block_comment("Java_Dynamic_Call");
2187 __ ic_call((address)$meth$$method);
2188 %}
2191 enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
2192 Register flags = $cr$$Register;
2193 Label L;
2195 MacroAssembler _masm(&cbuf);
2197 __ addu(flags, R0, R0);
2198 __ beq(AT, R0, L);
2199 __ delayed()->nop();
2200 __ move(flags, 0xFFFFFFFF);
2201 __ bind(L);
2202 %}
2204 enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
2205 Register result = $result$$Register;
2206 Register sub = $sub$$Register;
2207 Register super = $super$$Register;
2208 Register length = $tmp$$Register;
2209 Register tmp = T9;
2210 Label miss;
2212 /* 2012/9/28 Jin: result may be the same as sub
2213 * 47c B40: # B21 B41 <- B20 Freq: 0.155379
2214 * 47c partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
2215 * 4bc mov S2, NULL #@loadConP
2216 * 4c0 beq S1, S2, B21 #@branchConP P=0.999999 C=-1.000000
2217 */
2218 MacroAssembler _masm(&cbuf);
2219 Label done;
2220 __ check_klass_subtype_slow_path(sub, super, length, tmp,
2221 NULL, &miss,
2222 /*set_cond_codes:*/ true);
2223 /* 2013/7/22 Jin: Refer to X86_64's RDI */
2224 __ move(result, 0);
2225 __ b(done);
2226 __ nop();
2228 __ bind(miss);
2229 __ move(result, 1);
2230 __ bind(done);
2231 %}
2233 %}
2236 //---------MIPS FRAME--------------------------------------------------------------
2237 // Definition of frame structure and management information.
2238 //
2239 // S T A C K L A Y O U T Allocators stack-slot number
2240 // | (to get allocators register number
2241 // G Owned by | | v add SharedInfo::stack0)
2242 // r CALLER | |
2243 // o | +--------+ pad to even-align allocators stack-slot
2244 // w V | pad0 | numbers; owned by CALLER
2245 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
2246 // h ^ | in | 5
2247 // | | args | 4 Holes in incoming args owned by SELF
2248 // | | old | | 3
2249 // | | SP-+--------+----> Matcher::_old_SP, even aligned
2250 // v | | ret | 3 return address
2251 // Owned by +--------+
2252 // Self | pad2 | 2 pad to align old SP
2253 // | +--------+ 1
2254 // | | locks | 0
2255 // | +--------+----> SharedInfo::stack0, even aligned
2256 // | | pad1 | 11 pad to align new SP
2257 // | +--------+
2258 // | | | 10
2259 // | | spills | 9 spills
2260 // V | | 8 (pad0 slot for callee)
2261 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
2262 // ^ | out | 7
2263 // | | args | 6 Holes in outgoing args owned by CALLEE
2264 // Owned by new | |
2265 // Callee SP-+--------+----> Matcher::_new_SP, even aligned
2266 // | |
2267 //
2268 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
2269 // known from SELF's arguments and the Java calling convention.
2270 // Region 6-7 is determined per call site.
2271 // Note 2: If the calling convention leaves holes in the incoming argument
2272 // area, those holes are owned by SELF. Holes in the outgoing area
2273 // are owned by the CALLEE. Holes should not be nessecary in the
2274 // incoming area, as the Java calling convention is completely under
2275 // the control of the AD file. Doubles can be sorted and packed to
2276 // avoid holes. Holes in the outgoing arguments may be nessecary for
2277 // varargs C calling conventions.
2278 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
2279 // even aligned with pad0 as needed.
2280 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
2281 // region 6-11 is even aligned; it may be padded out more so that
2282 // the region from SP to FP meets the minimum stack alignment.
2283 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
2284 // alignment. Region 11, pad1, may be dynamically extended so that
2285 // SP meets the minimum alignment.
2288 frame %{
2290 stack_direction(TOWARDS_LOW);
2292 // These two registers define part of the calling convention
2293 // between compiled code and the interpreter.
2294 // SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention
2295 // for more information. by yjl 3/16/2006
2297 inline_cache_reg(T1); // Inline Cache Register
2298 interpreter_method_oop_reg(S3); // Method Oop Register when calling interpreter
2299 /*
2300 inline_cache_reg(T1); // Inline Cache Register or methodOop for I2C
2301 interpreter_arg_ptr_reg(A0); // Argument pointer for I2C adapters
2302 */
2304 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
2305 cisc_spilling_operand_name(indOffset32);
2307 // Number of stack slots consumed by locking an object
2308 // generate Compile::sync_stack_slots
2309 #ifdef _LP64
2310 sync_stack_slots(2);
2311 #else
2312 sync_stack_slots(1);
2313 #endif
2315 frame_pointer(SP);
2317 // Interpreter stores its frame pointer in a register which is
2318 // stored to the stack by I2CAdaptors.
2319 // I2CAdaptors convert from interpreted java to compiled java.
2321 interpreter_frame_pointer(FP);
2323 // generate Matcher::stack_alignment
2324 stack_alignment(StackAlignmentInBytes); //wordSize = sizeof(char*);
2326 // Number of stack slots between incoming argument block and the start of
2327 // a new frame. The PROLOG must add this many slots to the stack. The
2328 // EPILOG must remove this many slots. Intel needs one slot for
2329 // return address.
2330 // generate Matcher::in_preserve_stack_slots
2331 //in_preserve_stack_slots(VerifyStackAtCalls + 2); //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
2332 in_preserve_stack_slots(4); //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
2334 // Number of outgoing stack slots killed above the out_preserve_stack_slots
2335 // for calls to C. Supports the var-args backing area for register parms.
2336 varargs_C_out_slots_killed(0);
2338 // The after-PROLOG location of the return address. Location of
2339 // return address specifies a type (REG or STACK) and a number
2340 // representing the register number (i.e. - use a register name) or
2341 // stack slot.
2342 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
2343 // Otherwise, it is above the locks and verification slot and alignment word
2344 //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
2345 return_addr(REG RA);
2347 // Body of function which returns an integer array locating
2348 // arguments either in registers or in stack slots. Passed an array
2349 // of ideal registers called "sig" and a "length" count. Stack-slot
2350 // offsets are based on outgoing arguments, i.e. a CALLER setting up
2351 // arguments for a CALLEE. Incoming stack arguments are
2352 // automatically biased by the preserve_stack_slots field above.
2355 // will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
2356 // StartNode::calling_convention call this. by yjl 3/16/2006
2357 calling_convention %{
2358 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
2359 %}
2364 // Body of function which returns an integer array locating
2365 // arguments either in registers or in stack slots. Passed an array
2366 // of ideal registers called "sig" and a "length" count. Stack-slot
2367 // offsets are based on outgoing arguments, i.e. a CALLER setting up
2368 // arguments for a CALLEE. Incoming stack arguments are
2369 // automatically biased by the preserve_stack_slots field above.
2372 // SEE CallRuntimeNode::calling_convention for more information. by yjl 3/16/2006
2373 c_calling_convention %{
2374 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
2375 %}
2378 // Location of C & interpreter return values
2379 // register(s) contain(s) return value for Op_StartI2C and Op_StartOSR.
2380 // SEE Matcher::match. by yjl 3/16/2006
2381 c_return_value %{
2382 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
2383 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
2384 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
2385 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num };
2386 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
2387 %}
2389 // Location of return values
2390 // register(s) contain(s) return value for Op_StartC2I and Op_Start.
2391 // SEE Matcher::match. by yjl 3/16/2006
2393 return_value %{
2394 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
2395 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
2396 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
2397 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num};
2398 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
2399 %}
2401 %}
2403 //----------ATTRIBUTES---------------------------------------------------------
2404 //----------Operand Attributes-------------------------------------------------
2405 op_attrib op_cost(0); // Required cost attribute
2407 //----------Instruction Attributes---------------------------------------------
2408 ins_attrib ins_cost(100); // Required cost attribute
2409 ins_attrib ins_size(32); // Required size attribute (in bits)
2410 ins_attrib ins_pc_relative(0); // Required PC Relative flag
2411 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
2412 // non-matching short branch variant of some
2413 // long branch?
2414 ins_attrib ins_alignment(4); // Required alignment attribute (must be a power of 2)
2415 // specifies the alignment that some part of the instruction (not
2416 // necessarily the start) requires. If > 1, a compute_padding()
2417 // function must be provided for the instruction
2419 //----------OPERANDS-----------------------------------------------------------
2420 // Operand definitions must precede instruction definitions for correct parsing
2421 // in the ADLC because operands constitute user defined types which are used in
2422 // instruction definitions.
2424 // Vectors
2425 operand vecD() %{
2426 constraint(ALLOC_IN_RC(dbl_reg));
2427 match(VecD);
2429 format %{ %}
2430 interface(REG_INTER);
2431 %}
2433 // Flags register, used as output of compare instructions
2434 operand FlagsReg() %{
2435 constraint(ALLOC_IN_RC(mips_flags));
2436 match(RegFlags);
2438 format %{ "EFLAGS" %}
2439 interface(REG_INTER);
2440 %}
2442 //----------Simple Operands----------------------------------------------------
2443 //TODO: Should we need to define some more special immediate number ?
2444 // Immediate Operands
2445 // Integer Immediate
2446 operand immI() %{
2447 match(ConI);
2448 //TODO: should not match immI8 here LEE
2449 match(immI8);
2451 op_cost(20);
2452 format %{ %}
2453 interface(CONST_INTER);
2454 %}
2456 // Long Immediate 8-bit
2457 operand immL8()
2458 %{
2459 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
2460 match(ConL);
2462 op_cost(5);
2463 format %{ %}
2464 interface(CONST_INTER);
2465 %}
2467 // Constant for test vs zero
2468 operand immI0() %{
2469 predicate(n->get_int() == 0);
2470 match(ConI);
2472 op_cost(0);
2473 format %{ %}
2474 interface(CONST_INTER);
2475 %}
2477 // Constant for increment
2478 operand immI1() %{
2479 predicate(n->get_int() == 1);
2480 match(ConI);
2482 op_cost(0);
2483 format %{ %}
2484 interface(CONST_INTER);
2485 %}
2487 // Constant for decrement
2488 operand immI_M1() %{
2489 predicate(n->get_int() == -1);
2490 match(ConI);
2492 op_cost(0);
2493 format %{ %}
2494 interface(CONST_INTER);
2495 %}
2497 operand immI_MaxI() %{
2498 predicate(n->get_int() == 2147483647);
2499 match(ConI);
2501 op_cost(0);
2502 format %{ %}
2503 interface(CONST_INTER);
2504 %}
2506 // Valid scale values for addressing modes
2507 operand immI2() %{
2508 predicate(0 <= n->get_int() && (n->get_int() <= 3));
2509 match(ConI);
2511 format %{ %}
2512 interface(CONST_INTER);
2513 %}
2515 operand immI8() %{
2516 predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
2517 match(ConI);
2519 op_cost(5);
2520 format %{ %}
2521 interface(CONST_INTER);
2522 %}
2524 operand immI16() %{
2525 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
2526 match(ConI);
2528 op_cost(10);
2529 format %{ %}
2530 interface(CONST_INTER);
2531 %}
2533 // Constant for long shifts
2534 operand immI_32() %{
2535 predicate( n->get_int() == 32 );
2536 match(ConI);
2538 op_cost(0);
2539 format %{ %}
2540 interface(CONST_INTER);
2541 %}
2543 operand immI_63() %{
2544 predicate( n->get_int() == 63 );
2545 match(ConI);
2547 op_cost(0);
2548 format %{ %}
2549 interface(CONST_INTER);
2550 %}
2552 operand immI_0_31() %{
2553 predicate( n->get_int() >= 0 && n->get_int() <= 31 );
2554 match(ConI);
2556 op_cost(0);
2557 format %{ %}
2558 interface(CONST_INTER);
2559 %}
2561 // Operand for non-negtive integer mask
2562 operand immI_nonneg_mask() %{
2563 predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
2564 match(ConI);
2566 op_cost(0);
2567 format %{ %}
2568 interface(CONST_INTER);
2569 %}
2571 operand immI_32_63() %{
2572 predicate( n->get_int() >= 32 && n->get_int() <= 63 );
2573 match(ConI);
2574 op_cost(0);
2576 format %{ %}
2577 interface(CONST_INTER);
2578 %}
2580 operand immI16_sub() %{
2581 predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
2582 match(ConI);
2584 op_cost(10);
2585 format %{ %}
2586 interface(CONST_INTER);
2587 %}
2589 operand immI_0_32767() %{
2590 predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
2591 match(ConI);
2592 op_cost(0);
2594 format %{ %}
2595 interface(CONST_INTER);
2596 %}
2598 operand immI_0_65535() %{
2599 predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
2600 match(ConI);
2601 op_cost(0);
2603 format %{ %}
2604 interface(CONST_INTER);
2605 %}
2607 operand immI_1() %{
2608 predicate( n->get_int() == 1 );
2609 match(ConI);
2611 op_cost(0);
2612 format %{ %}
2613 interface(CONST_INTER);
2614 %}
2616 operand immI_2() %{
2617 predicate( n->get_int() == 2 );
2618 match(ConI);
2620 op_cost(0);
2621 format %{ %}
2622 interface(CONST_INTER);
2623 %}
2625 operand immI_3() %{
2626 predicate( n->get_int() == 3 );
2627 match(ConI);
2629 op_cost(0);
2630 format %{ %}
2631 interface(CONST_INTER);
2632 %}
2634 operand immI_7() %{
2635 predicate( n->get_int() == 7 );
2636 match(ConI);
2638 format %{ %}
2639 interface(CONST_INTER);
2640 %}
2642 // Immediates for special shifts (sign extend)
2644 // Constants for increment
2645 operand immI_16() %{
2646 predicate( n->get_int() == 16 );
2647 match(ConI);
2649 format %{ %}
2650 interface(CONST_INTER);
2651 %}
2653 operand immI_24() %{
2654 predicate( n->get_int() == 24 );
2655 match(ConI);
2657 format %{ %}
2658 interface(CONST_INTER);
2659 %}
2661 // Constant for byte-wide masking
2662 operand immI_255() %{
2663 predicate( n->get_int() == 255 );
2664 match(ConI);
2666 op_cost(0);
2667 format %{ %}
2668 interface(CONST_INTER);
2669 %}
2671 operand immI_65535() %{
2672 predicate( n->get_int() == 65535 );
2673 match(ConI);
2675 op_cost(5);
2676 format %{ %}
2677 interface(CONST_INTER);
2678 %}
2680 operand immI_65536() %{
2681 predicate( n->get_int() == 65536 );
2682 match(ConI);
2684 op_cost(5);
2685 format %{ %}
2686 interface(CONST_INTER);
2687 %}
2689 operand immI_M65536() %{
2690 predicate( n->get_int() == -65536 );
2691 match(ConI);
2693 op_cost(5);
2694 format %{ %}
2695 interface(CONST_INTER);
2696 %}
2698 // Pointer Immediate
2699 operand immP() %{
2700 match(ConP);
2702 op_cost(10);
2703 format %{ %}
2704 interface(CONST_INTER);
2705 %}
2707 // NULL Pointer Immediate
2708 operand immP0() %{
2709 predicate( n->get_ptr() == 0 );
2710 match(ConP);
2711 op_cost(0);
2713 format %{ %}
2714 interface(CONST_INTER);
2715 %}
2717 // Pointer Immediate: 64-bit
2718 operand immP_set() %{
2719 match(ConP);
2721 op_cost(5);
2722 // formats are generated automatically for constants and base registers
2723 format %{ %}
2724 interface(CONST_INTER);
2725 %}
2727 // Pointer Immediate: 64-bit
2728 operand immP_load() %{
2729 predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
2730 match(ConP);
2732 op_cost(5);
2733 // formats are generated automatically for constants and base registers
2734 format %{ %}
2735 interface(CONST_INTER);
2736 %}
2738 // Pointer Immediate: 64-bit
2739 operand immP_no_oop_cheap() %{
2740 predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
2741 match(ConP);
2743 op_cost(5);
2744 // formats are generated automatically for constants and base registers
2745 format %{ %}
2746 interface(CONST_INTER);
2747 %}
2749 // Pointer for polling page
2750 operand immP_poll() %{
2751 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
2752 match(ConP);
2753 op_cost(5);
2755 format %{ %}
2756 interface(CONST_INTER);
2757 %}
2759 // Pointer Immediate
2760 operand immN() %{
2761 match(ConN);
2763 op_cost(10);
2764 format %{ %}
2765 interface(CONST_INTER);
2766 %}
2768 operand immNKlass() %{
2769 match(ConNKlass);
2771 op_cost(10);
2772 format %{ %}
2773 interface(CONST_INTER);
2774 %}
2776 // NULL Pointer Immediate
2777 operand immN0() %{
2778 predicate(n->get_narrowcon() == 0);
2779 match(ConN);
2781 op_cost(5);
2782 format %{ %}
2783 interface(CONST_INTER);
2784 %}
2786 // Long Immediate
2787 operand immL() %{
2788 match(ConL);
2790 op_cost(20);
2791 format %{ %}
2792 interface(CONST_INTER);
2793 %}
2795 // Long Immediate zero
2796 operand immL0() %{
2797 predicate( n->get_long() == 0L );
2798 match(ConL);
2799 op_cost(0);
2801 format %{ %}
2802 interface(CONST_INTER);
2803 %}
2805 operand immL7() %{
2806 predicate( n->get_long() == 7L );
2807 match(ConL);
2808 op_cost(0);
2810 format %{ %}
2811 interface(CONST_INTER);
2812 %}
2814 operand immL_M1() %{
2815 predicate( n->get_long() == -1L );
2816 match(ConL);
2817 op_cost(0);
2819 format %{ %}
2820 interface(CONST_INTER);
2821 %}
2823 // bit 0..2 zero
2824 operand immL_M8() %{
2825 predicate( n->get_long() == -8L );
2826 match(ConL);
2827 op_cost(0);
2829 format %{ %}
2830 interface(CONST_INTER);
2831 %}
2833 // bit 2 zero
2834 operand immL_M5() %{
2835 predicate( n->get_long() == -5L );
2836 match(ConL);
2837 op_cost(0);
2839 format %{ %}
2840 interface(CONST_INTER);
2841 %}
2843 // bit 1..2 zero
2844 operand immL_M7() %{
2845 predicate( n->get_long() == -7L );
2846 match(ConL);
2847 op_cost(0);
2849 format %{ %}
2850 interface(CONST_INTER);
2851 %}
2853 // bit 0..1 zero
2854 operand immL_M4() %{
2855 predicate( n->get_long() == -4L );
2856 match(ConL);
2857 op_cost(0);
2859 format %{ %}
2860 interface(CONST_INTER);
2861 %}
2863 // bit 3..6 zero
2864 operand immL_M121() %{
2865 predicate( n->get_long() == -121L );
2866 match(ConL);
2867 op_cost(0);
2869 format %{ %}
2870 interface(CONST_INTER);
2871 %}
2873 // Long immediate from 0 to 127.
2874 // Used for a shorter form of long mul by 10.
2875 operand immL_127() %{
2876 predicate((0 <= n->get_long()) && (n->get_long() <= 127));
2877 match(ConL);
2878 op_cost(0);
2880 format %{ %}
2881 interface(CONST_INTER);
2882 %}
2884 // Operand for non-negtive long mask
2885 operand immL_nonneg_mask() %{
2886 predicate( (n->get_long() >= 0) && (Assembler::is_jlong_mask(n->get_long()) != -1) );
2887 match(ConL);
2889 op_cost(0);
2890 format %{ %}
2891 interface(CONST_INTER);
2892 %}
2894 operand immL_0_65535() %{
2895 predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
2896 match(ConL);
2897 op_cost(0);
2899 format %{ %}
2900 interface(CONST_INTER);
2901 %}
2903 // Long Immediate: cheap (materialize in <= 3 instructions)
2904 operand immL_cheap() %{
2905 predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
2906 match(ConL);
2907 op_cost(0);
2909 format %{ %}
2910 interface(CONST_INTER);
2911 %}
2913 // Long Immediate: expensive (materialize in > 3 instructions)
2914 operand immL_expensive() %{
2915 predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
2916 match(ConL);
2917 op_cost(0);
2919 format %{ %}
2920 interface(CONST_INTER);
2921 %}
2923 operand immL16() %{
2924 predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
2925 match(ConL);
2927 op_cost(10);
2928 format %{ %}
2929 interface(CONST_INTER);
2930 %}
2932 operand immL16_sub() %{
2933 predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
2934 match(ConL);
2936 op_cost(10);
2937 format %{ %}
2938 interface(CONST_INTER);
2939 %}
2941 // Long Immediate: low 32-bit mask
2942 operand immL_32bits() %{
2943 predicate(n->get_long() == 0xFFFFFFFFL);
2944 match(ConL);
2945 op_cost(20);
2947 format %{ %}
2948 interface(CONST_INTER);
2949 %}
2951 // Long Immediate 32-bit signed
2952 operand immL32()
2953 %{
2954 predicate(n->get_long() == (int) (n->get_long()));
2955 match(ConL);
2957 op_cost(15);
2958 format %{ %}
2959 interface(CONST_INTER);
2960 %}
2963 //single-precision floating-point zero
2964 operand immF0() %{
2965 predicate(jint_cast(n->getf()) == 0);
2966 match(ConF);
2968 op_cost(5);
2969 format %{ %}
2970 interface(CONST_INTER);
2971 %}
2973 //single-precision floating-point immediate
2974 operand immF() %{
2975 match(ConF);
2977 op_cost(20);
2978 format %{ %}
2979 interface(CONST_INTER);
2980 %}
2982 //double-precision floating-point zero
2983 operand immD0() %{
2984 predicate(jlong_cast(n->getd()) == 0);
2985 match(ConD);
2987 op_cost(5);
2988 format %{ %}
2989 interface(CONST_INTER);
2990 %}
2992 //double-precision floating-point immediate
2993 operand immD() %{
2994 match(ConD);
2996 op_cost(20);
2997 format %{ %}
2998 interface(CONST_INTER);
2999 %}
3001 // Register Operands
3002 // Integer Register
3003 operand mRegI() %{
3004 constraint(ALLOC_IN_RC(int_reg));
3005 match(RegI);
3007 format %{ %}
3008 interface(REG_INTER);
3009 %}
3011 operand no_Ax_mRegI() %{
3012 constraint(ALLOC_IN_RC(no_Ax_int_reg));
3013 match(RegI);
3014 match(mRegI);
3016 format %{ %}
3017 interface(REG_INTER);
3018 %}
3020 operand mS0RegI() %{
3021 constraint(ALLOC_IN_RC(s0_reg));
3022 match(RegI);
3023 match(mRegI);
3025 format %{ "S0" %}
3026 interface(REG_INTER);
3027 %}
3029 operand mS1RegI() %{
3030 constraint(ALLOC_IN_RC(s1_reg));
3031 match(RegI);
3032 match(mRegI);
3034 format %{ "S1" %}
3035 interface(REG_INTER);
3036 %}
3038 operand mS2RegI() %{
3039 constraint(ALLOC_IN_RC(s2_reg));
3040 match(RegI);
3041 match(mRegI);
3043 format %{ "S2" %}
3044 interface(REG_INTER);
3045 %}
3047 operand mS3RegI() %{
3048 constraint(ALLOC_IN_RC(s3_reg));
3049 match(RegI);
3050 match(mRegI);
3052 format %{ "S3" %}
3053 interface(REG_INTER);
3054 %}
3056 operand mS4RegI() %{
3057 constraint(ALLOC_IN_RC(s4_reg));
3058 match(RegI);
3059 match(mRegI);
3061 format %{ "S4" %}
3062 interface(REG_INTER);
3063 %}
3065 operand mS5RegI() %{
3066 constraint(ALLOC_IN_RC(s5_reg));
3067 match(RegI);
3068 match(mRegI);
3070 format %{ "S5" %}
3071 interface(REG_INTER);
3072 %}
3074 operand mS6RegI() %{
3075 constraint(ALLOC_IN_RC(s6_reg));
3076 match(RegI);
3077 match(mRegI);
3079 format %{ "S6" %}
3080 interface(REG_INTER);
3081 %}
3083 operand mS7RegI() %{
3084 constraint(ALLOC_IN_RC(s7_reg));
3085 match(RegI);
3086 match(mRegI);
3088 format %{ "S7" %}
3089 interface(REG_INTER);
3090 %}
3093 operand mT0RegI() %{
3094 constraint(ALLOC_IN_RC(t0_reg));
3095 match(RegI);
3096 match(mRegI);
3098 format %{ "T0" %}
3099 interface(REG_INTER);
3100 %}
3102 operand mT1RegI() %{
3103 constraint(ALLOC_IN_RC(t1_reg));
3104 match(RegI);
3105 match(mRegI);
3107 format %{ "T1" %}
3108 interface(REG_INTER);
3109 %}
3111 operand mT2RegI() %{
3112 constraint(ALLOC_IN_RC(t2_reg));
3113 match(RegI);
3114 match(mRegI);
3116 format %{ "T2" %}
3117 interface(REG_INTER);
3118 %}
3120 operand mT3RegI() %{
3121 constraint(ALLOC_IN_RC(t3_reg));
3122 match(RegI);
3123 match(mRegI);
3125 format %{ "T3" %}
3126 interface(REG_INTER);
3127 %}
3129 operand mT8RegI() %{
3130 constraint(ALLOC_IN_RC(t8_reg));
3131 match(RegI);
3132 match(mRegI);
3134 format %{ "T8" %}
3135 interface(REG_INTER);
3136 %}
3138 operand mT9RegI() %{
3139 constraint(ALLOC_IN_RC(t9_reg));
3140 match(RegI);
3141 match(mRegI);
3143 format %{ "T9" %}
3144 interface(REG_INTER);
3145 %}
3147 operand mA0RegI() %{
3148 constraint(ALLOC_IN_RC(a0_reg));
3149 match(RegI);
3150 match(mRegI);
3152 format %{ "A0" %}
3153 interface(REG_INTER);
3154 %}
3156 operand mA1RegI() %{
3157 constraint(ALLOC_IN_RC(a1_reg));
3158 match(RegI);
3159 match(mRegI);
3161 format %{ "A1" %}
3162 interface(REG_INTER);
3163 %}
3165 operand mA2RegI() %{
3166 constraint(ALLOC_IN_RC(a2_reg));
3167 match(RegI);
3168 match(mRegI);
3170 format %{ "A2" %}
3171 interface(REG_INTER);
3172 %}
3174 operand mA3RegI() %{
3175 constraint(ALLOC_IN_RC(a3_reg));
3176 match(RegI);
3177 match(mRegI);
3179 format %{ "A3" %}
3180 interface(REG_INTER);
3181 %}
3183 operand mA4RegI() %{
3184 constraint(ALLOC_IN_RC(a4_reg));
3185 match(RegI);
3186 match(mRegI);
3188 format %{ "A4" %}
3189 interface(REG_INTER);
3190 %}
3192 operand mA5RegI() %{
3193 constraint(ALLOC_IN_RC(a5_reg));
3194 match(RegI);
3195 match(mRegI);
3197 format %{ "A5" %}
3198 interface(REG_INTER);
3199 %}
3201 operand mA6RegI() %{
3202 constraint(ALLOC_IN_RC(a6_reg));
3203 match(RegI);
3204 match(mRegI);
3206 format %{ "A6" %}
3207 interface(REG_INTER);
3208 %}
3210 operand mA7RegI() %{
3211 constraint(ALLOC_IN_RC(a7_reg));
3212 match(RegI);
3213 match(mRegI);
3215 format %{ "A7" %}
3216 interface(REG_INTER);
3217 %}
3219 operand mV0RegI() %{
3220 constraint(ALLOC_IN_RC(v0_reg));
3221 match(RegI);
3222 match(mRegI);
3224 format %{ "V0" %}
3225 interface(REG_INTER);
3226 %}
3228 operand mV1RegI() %{
3229 constraint(ALLOC_IN_RC(v1_reg));
3230 match(RegI);
3231 match(mRegI);
3233 format %{ "V1" %}
3234 interface(REG_INTER);
3235 %}
3237 operand mRegN() %{
3238 constraint(ALLOC_IN_RC(int_reg));
3239 match(RegN);
3241 format %{ %}
3242 interface(REG_INTER);
3243 %}
3245 operand t0_RegN() %{
3246 constraint(ALLOC_IN_RC(t0_reg));
3247 match(RegN);
3248 match(mRegN);
3250 format %{ %}
3251 interface(REG_INTER);
3252 %}
3254 operand t1_RegN() %{
3255 constraint(ALLOC_IN_RC(t1_reg));
3256 match(RegN);
3257 match(mRegN);
3259 format %{ %}
3260 interface(REG_INTER);
3261 %}
3263 operand t2_RegN() %{
3264 constraint(ALLOC_IN_RC(t2_reg));
3265 match(RegN);
3266 match(mRegN);
3268 format %{ %}
3269 interface(REG_INTER);
3270 %}
3272 operand t3_RegN() %{
3273 constraint(ALLOC_IN_RC(t3_reg));
3274 match(RegN);
3275 match(mRegN);
3277 format %{ %}
3278 interface(REG_INTER);
3279 %}
3281 operand t8_RegN() %{
3282 constraint(ALLOC_IN_RC(t8_reg));
3283 match(RegN);
3284 match(mRegN);
3286 format %{ %}
3287 interface(REG_INTER);
3288 %}
3290 operand t9_RegN() %{
3291 constraint(ALLOC_IN_RC(t9_reg));
3292 match(RegN);
3293 match(mRegN);
3295 format %{ %}
3296 interface(REG_INTER);
3297 %}
3299 operand a0_RegN() %{
3300 constraint(ALLOC_IN_RC(a0_reg));
3301 match(RegN);
3302 match(mRegN);
3304 format %{ %}
3305 interface(REG_INTER);
3306 %}
3308 operand a1_RegN() %{
3309 constraint(ALLOC_IN_RC(a1_reg));
3310 match(RegN);
3311 match(mRegN);
3313 format %{ %}
3314 interface(REG_INTER);
3315 %}
3317 operand a2_RegN() %{
3318 constraint(ALLOC_IN_RC(a2_reg));
3319 match(RegN);
3320 match(mRegN);
3322 format %{ %}
3323 interface(REG_INTER);
3324 %}
3326 operand a3_RegN() %{
3327 constraint(ALLOC_IN_RC(a3_reg));
3328 match(RegN);
3329 match(mRegN);
3331 format %{ %}
3332 interface(REG_INTER);
3333 %}
3335 operand a4_RegN() %{
3336 constraint(ALLOC_IN_RC(a4_reg));
3337 match(RegN);
3338 match(mRegN);
3340 format %{ %}
3341 interface(REG_INTER);
3342 %}
3344 operand a5_RegN() %{
3345 constraint(ALLOC_IN_RC(a5_reg));
3346 match(RegN);
3347 match(mRegN);
3349 format %{ %}
3350 interface(REG_INTER);
3351 %}
3353 operand a6_RegN() %{
3354 constraint(ALLOC_IN_RC(a6_reg));
3355 match(RegN);
3356 match(mRegN);
3358 format %{ %}
3359 interface(REG_INTER);
3360 %}
3362 operand a7_RegN() %{
3363 constraint(ALLOC_IN_RC(a7_reg));
3364 match(RegN);
3365 match(mRegN);
3367 format %{ %}
3368 interface(REG_INTER);
3369 %}
3371 operand s0_RegN() %{
3372 constraint(ALLOC_IN_RC(s0_reg));
3373 match(RegN);
3374 match(mRegN);
3376 format %{ %}
3377 interface(REG_INTER);
3378 %}
3380 operand s1_RegN() %{
3381 constraint(ALLOC_IN_RC(s1_reg));
3382 match(RegN);
3383 match(mRegN);
3385 format %{ %}
3386 interface(REG_INTER);
3387 %}
3389 operand s2_RegN() %{
3390 constraint(ALLOC_IN_RC(s2_reg));
3391 match(RegN);
3392 match(mRegN);
3394 format %{ %}
3395 interface(REG_INTER);
3396 %}
3398 operand s3_RegN() %{
3399 constraint(ALLOC_IN_RC(s3_reg));
3400 match(RegN);
3401 match(mRegN);
3403 format %{ %}
3404 interface(REG_INTER);
3405 %}
3407 operand s4_RegN() %{
3408 constraint(ALLOC_IN_RC(s4_reg));
3409 match(RegN);
3410 match(mRegN);
3412 format %{ %}
3413 interface(REG_INTER);
3414 %}
3416 operand s5_RegN() %{
3417 constraint(ALLOC_IN_RC(s5_reg));
3418 match(RegN);
3419 match(mRegN);
3421 format %{ %}
3422 interface(REG_INTER);
3423 %}
3425 operand s6_RegN() %{
3426 constraint(ALLOC_IN_RC(s6_reg));
3427 match(RegN);
3428 match(mRegN);
3430 format %{ %}
3431 interface(REG_INTER);
3432 %}
3434 operand s7_RegN() %{
3435 constraint(ALLOC_IN_RC(s7_reg));
3436 match(RegN);
3437 match(mRegN);
3439 format %{ %}
3440 interface(REG_INTER);
3441 %}
3443 operand v0_RegN() %{
3444 constraint(ALLOC_IN_RC(v0_reg));
3445 match(RegN);
3446 match(mRegN);
3448 format %{ %}
3449 interface(REG_INTER);
3450 %}
3452 operand v1_RegN() %{
3453 constraint(ALLOC_IN_RC(v1_reg));
3454 match(RegN);
3455 match(mRegN);
3457 format %{ %}
3458 interface(REG_INTER);
3459 %}
3461 // Pointer Register
3462 operand mRegP() %{
3463 constraint(ALLOC_IN_RC(p_reg));
3464 match(RegP);
3466 format %{ %}
3467 interface(REG_INTER);
3468 %}
3470 operand no_T8_mRegP() %{
3471 constraint(ALLOC_IN_RC(no_T8_p_reg));
3472 match(RegP);
3473 match(mRegP);
3475 format %{ %}
3476 interface(REG_INTER);
3477 %}
3479 operand s0_RegP()
3480 %{
3481 constraint(ALLOC_IN_RC(s0_long_reg));
3482 match(RegP);
3483 match(mRegP);
3484 match(no_T8_mRegP);
3486 format %{ %}
3487 interface(REG_INTER);
3488 %}
3490 operand s1_RegP()
3491 %{
3492 constraint(ALLOC_IN_RC(s1_long_reg));
3493 match(RegP);
3494 match(mRegP);
3495 match(no_T8_mRegP);
3497 format %{ %}
3498 interface(REG_INTER);
3499 %}
3501 operand s2_RegP()
3502 %{
3503 constraint(ALLOC_IN_RC(s2_long_reg));
3504 match(RegP);
3505 match(mRegP);
3506 match(no_T8_mRegP);
3508 format %{ %}
3509 interface(REG_INTER);
3510 %}
3512 operand s3_RegP()
3513 %{
3514 constraint(ALLOC_IN_RC(s3_long_reg));
3515 match(RegP);
3516 match(mRegP);
3517 match(no_T8_mRegP);
3519 format %{ %}
3520 interface(REG_INTER);
3521 %}
3523 operand s4_RegP()
3524 %{
3525 constraint(ALLOC_IN_RC(s4_long_reg));
3526 match(RegP);
3527 match(mRegP);
3528 match(no_T8_mRegP);
3530 format %{ %}
3531 interface(REG_INTER);
3532 %}
3534 operand s5_RegP()
3535 %{
3536 constraint(ALLOC_IN_RC(s5_long_reg));
3537 match(RegP);
3538 match(mRegP);
3539 match(no_T8_mRegP);
3541 format %{ %}
3542 interface(REG_INTER);
3543 %}
3545 operand s6_RegP()
3546 %{
3547 constraint(ALLOC_IN_RC(s6_long_reg));
3548 match(RegP);
3549 match(mRegP);
3550 match(no_T8_mRegP);
3552 format %{ %}
3553 interface(REG_INTER);
3554 %}
3556 operand s7_RegP()
3557 %{
3558 constraint(ALLOC_IN_RC(s7_long_reg));
3559 match(RegP);
3560 match(mRegP);
3561 match(no_T8_mRegP);
3563 format %{ %}
3564 interface(REG_INTER);
3565 %}
3567 operand t0_RegP()
3568 %{
3569 constraint(ALLOC_IN_RC(t0_long_reg));
3570 match(RegP);
3571 match(mRegP);
3572 match(no_T8_mRegP);
3574 format %{ %}
3575 interface(REG_INTER);
3576 %}
3578 operand t1_RegP()
3579 %{
3580 constraint(ALLOC_IN_RC(t1_long_reg));
3581 match(RegP);
3582 match(mRegP);
3583 match(no_T8_mRegP);
3585 format %{ %}
3586 interface(REG_INTER);
3587 %}
3589 operand t2_RegP()
3590 %{
3591 constraint(ALLOC_IN_RC(t2_long_reg));
3592 match(RegP);
3593 match(mRegP);
3594 match(no_T8_mRegP);
3596 format %{ %}
3597 interface(REG_INTER);
3598 %}
3600 operand t3_RegP()
3601 %{
3602 constraint(ALLOC_IN_RC(t3_long_reg));
3603 match(RegP);
3604 match(mRegP);
3605 match(no_T8_mRegP);
3607 format %{ %}
3608 interface(REG_INTER);
3609 %}
3611 operand t8_RegP()
3612 %{
3613 constraint(ALLOC_IN_RC(t8_long_reg));
3614 match(RegP);
3615 match(mRegP);
3617 format %{ %}
3618 interface(REG_INTER);
3619 %}
3621 operand t9_RegP()
3622 %{
3623 constraint(ALLOC_IN_RC(t9_long_reg));
3624 match(RegP);
3625 match(mRegP);
3626 match(no_T8_mRegP);
3628 format %{ %}
3629 interface(REG_INTER);
3630 %}
3632 operand a0_RegP()
3633 %{
3634 constraint(ALLOC_IN_RC(a0_long_reg));
3635 match(RegP);
3636 match(mRegP);
3637 match(no_T8_mRegP);
3639 format %{ %}
3640 interface(REG_INTER);
3641 %}
3643 operand a1_RegP()
3644 %{
3645 constraint(ALLOC_IN_RC(a1_long_reg));
3646 match(RegP);
3647 match(mRegP);
3648 match(no_T8_mRegP);
3650 format %{ %}
3651 interface(REG_INTER);
3652 %}
3654 operand a2_RegP()
3655 %{
3656 constraint(ALLOC_IN_RC(a2_long_reg));
3657 match(RegP);
3658 match(mRegP);
3659 match(no_T8_mRegP);
3661 format %{ %}
3662 interface(REG_INTER);
3663 %}
3665 operand a3_RegP()
3666 %{
3667 constraint(ALLOC_IN_RC(a3_long_reg));
3668 match(RegP);
3669 match(mRegP);
3670 match(no_T8_mRegP);
3672 format %{ %}
3673 interface(REG_INTER);
3674 %}
3676 operand a4_RegP()
3677 %{
3678 constraint(ALLOC_IN_RC(a4_long_reg));
3679 match(RegP);
3680 match(mRegP);
3681 match(no_T8_mRegP);
3683 format %{ %}
3684 interface(REG_INTER);
3685 %}
3688 operand a5_RegP()
3689 %{
3690 constraint(ALLOC_IN_RC(a5_long_reg));
3691 match(RegP);
3692 match(mRegP);
3693 match(no_T8_mRegP);
3695 format %{ %}
3696 interface(REG_INTER);
3697 %}
3699 operand a6_RegP()
3700 %{
3701 constraint(ALLOC_IN_RC(a6_long_reg));
3702 match(RegP);
3703 match(mRegP);
3704 match(no_T8_mRegP);
3706 format %{ %}
3707 interface(REG_INTER);
3708 %}
3710 operand a7_RegP()
3711 %{
3712 constraint(ALLOC_IN_RC(a7_long_reg));
3713 match(RegP);
3714 match(mRegP);
3715 match(no_T8_mRegP);
3717 format %{ %}
3718 interface(REG_INTER);
3719 %}
3721 operand v0_RegP()
3722 %{
3723 constraint(ALLOC_IN_RC(v0_long_reg));
3724 match(RegP);
3725 match(mRegP);
3726 match(no_T8_mRegP);
3728 format %{ %}
3729 interface(REG_INTER);
3730 %}
3732 operand v1_RegP()
3733 %{
3734 constraint(ALLOC_IN_RC(v1_long_reg));
3735 match(RegP);
3736 match(mRegP);
3737 match(no_T8_mRegP);
3739 format %{ %}
3740 interface(REG_INTER);
3741 %}
3743 /*
3744 operand mSPRegP(mRegP reg) %{
3745 constraint(ALLOC_IN_RC(sp_reg));
3746 match(reg);
3748 format %{ "SP" %}
3749 interface(REG_INTER);
3750 %}
3752 operand mFPRegP(mRegP reg) %{
3753 constraint(ALLOC_IN_RC(fp_reg));
3754 match(reg);
3756 format %{ "FP" %}
3757 interface(REG_INTER);
3758 %}
3759 */
3761 operand mRegL() %{
3762 constraint(ALLOC_IN_RC(long_reg));
3763 match(RegL);
3765 format %{ %}
3766 interface(REG_INTER);
3767 %}
3769 operand v0RegL() %{
3770 constraint(ALLOC_IN_RC(v0_long_reg));
3771 match(RegL);
3772 match(mRegL);
3774 format %{ %}
3775 interface(REG_INTER);
3776 %}
3778 operand v1RegL() %{
3779 constraint(ALLOC_IN_RC(v1_long_reg));
3780 match(RegL);
3781 match(mRegL);
3783 format %{ %}
3784 interface(REG_INTER);
3785 %}
3787 operand a0RegL() %{
3788 constraint(ALLOC_IN_RC(a0_long_reg));
3789 match(RegL);
3790 match(mRegL);
3792 format %{ "A0" %}
3793 interface(REG_INTER);
3794 %}
3796 operand a1RegL() %{
3797 constraint(ALLOC_IN_RC(a1_long_reg));
3798 match(RegL);
3799 match(mRegL);
3801 format %{ %}
3802 interface(REG_INTER);
3803 %}
3805 operand a2RegL() %{
3806 constraint(ALLOC_IN_RC(a2_long_reg));
3807 match(RegL);
3808 match(mRegL);
3810 format %{ %}
3811 interface(REG_INTER);
3812 %}
3814 operand a3RegL() %{
3815 constraint(ALLOC_IN_RC(a3_long_reg));
3816 match(RegL);
3817 match(mRegL);
3819 format %{ %}
3820 interface(REG_INTER);
3821 %}
3823 operand t0RegL() %{
3824 constraint(ALLOC_IN_RC(t0_long_reg));
3825 match(RegL);
3826 match(mRegL);
3828 format %{ %}
3829 interface(REG_INTER);
3830 %}
3832 operand t1RegL() %{
3833 constraint(ALLOC_IN_RC(t1_long_reg));
3834 match(RegL);
3835 match(mRegL);
3837 format %{ %}
3838 interface(REG_INTER);
3839 %}
3841 operand t2RegL() %{
3842 constraint(ALLOC_IN_RC(t2_long_reg));
3843 match(RegL);
3844 match(mRegL);
3846 format %{ %}
3847 interface(REG_INTER);
3848 %}
3850 operand t3RegL() %{
3851 constraint(ALLOC_IN_RC(t3_long_reg));
3852 match(RegL);
3853 match(mRegL);
3855 format %{ %}
3856 interface(REG_INTER);
3857 %}
3859 operand t8RegL() %{
3860 constraint(ALLOC_IN_RC(t8_long_reg));
3861 match(RegL);
3862 match(mRegL);
3864 format %{ %}
3865 interface(REG_INTER);
3866 %}
3868 operand a4RegL() %{
3869 constraint(ALLOC_IN_RC(a4_long_reg));
3870 match(RegL);
3871 match(mRegL);
3873 format %{ %}
3874 interface(REG_INTER);
3875 %}
3877 operand a5RegL() %{
3878 constraint(ALLOC_IN_RC(a5_long_reg));
3879 match(RegL);
3880 match(mRegL);
3882 format %{ %}
3883 interface(REG_INTER);
3884 %}
3886 operand a6RegL() %{
3887 constraint(ALLOC_IN_RC(a6_long_reg));
3888 match(RegL);
3889 match(mRegL);
3891 format %{ %}
3892 interface(REG_INTER);
3893 %}
3895 operand a7RegL() %{
3896 constraint(ALLOC_IN_RC(a7_long_reg));
3897 match(RegL);
3898 match(mRegL);
3900 format %{ %}
3901 interface(REG_INTER);
3902 %}
3904 operand s0RegL() %{
3905 constraint(ALLOC_IN_RC(s0_long_reg));
3906 match(RegL);
3907 match(mRegL);
3909 format %{ %}
3910 interface(REG_INTER);
3911 %}
3913 operand s1RegL() %{
3914 constraint(ALLOC_IN_RC(s1_long_reg));
3915 match(RegL);
3916 match(mRegL);
3918 format %{ %}
3919 interface(REG_INTER);
3920 %}
3922 operand s2RegL() %{
3923 constraint(ALLOC_IN_RC(s2_long_reg));
3924 match(RegL);
3925 match(mRegL);
3927 format %{ %}
3928 interface(REG_INTER);
3929 %}
3931 operand s3RegL() %{
3932 constraint(ALLOC_IN_RC(s3_long_reg));
3933 match(RegL);
3934 match(mRegL);
3936 format %{ %}
3937 interface(REG_INTER);
3938 %}
3940 operand s4RegL() %{
3941 constraint(ALLOC_IN_RC(s4_long_reg));
3942 match(RegL);
3943 match(mRegL);
3945 format %{ %}
3946 interface(REG_INTER);
3947 %}
3949 operand s7RegL() %{
3950 constraint(ALLOC_IN_RC(s7_long_reg));
3951 match(RegL);
3952 match(mRegL);
3954 format %{ %}
3955 interface(REG_INTER);
3956 %}
3958 // Floating register operands
3959 operand regF() %{
3960 constraint(ALLOC_IN_RC(flt_reg));
3961 match(RegF);
3963 format %{ %}
3964 interface(REG_INTER);
3965 %}
3967 //Double Precision Floating register operands
3968 operand regD() %{
3969 constraint(ALLOC_IN_RC(dbl_reg));
3970 match(RegD);
3972 format %{ %}
3973 interface(REG_INTER);
3974 %}
3976 //----------Memory Operands----------------------------------------------------
3977 operand baseOffset16(mRegP reg, immL16 off)
3978 %{
3979 constraint(ALLOC_IN_RC(p_reg));
3980 match(AddP reg off);
3982 op_cost(5);
3983 format %{ "[$reg + $off (16-bit)] @ baseOffset16" %}
3984 interface(MEMORY_INTER) %{
3985 base($reg);
3986 index(0x0);
3987 scale(0x0);
3988 disp($off);
3989 %}
3990 %}
3992 operand gsBaseIndexOffset8(mRegP base, mRegL index, immL8 off)
3993 %{
3994 predicate(UseLoongsonISA);
3995 constraint(ALLOC_IN_RC(p_reg));
3996 match(AddP (AddP base index) off);
3998 op_cost(5);
3999 format %{ "[$base + $index + $off (8-bit)] @ gsBaseIndexOffset8" %}
4000 interface(MEMORY_INTER) %{
4001 base($base);
4002 index($index);
4003 scale(0x0);
4004 disp($off);
4005 %}
4006 %}
4008 operand gsBaseIndexI2LOffset8(mRegP base, mRegI index, immL8 off)
4009 %{
4010 predicate(UseLoongsonISA);
4011 constraint(ALLOC_IN_RC(p_reg));
4012 match(AddP (AddP base (ConvI2L index)) off);
4014 op_cost(5);
4015 format %{ "[$base + $index + $off (8-bit)] @ gsBaseIndexI2LOffset8" %}
4016 interface(MEMORY_INTER) %{
4017 base($base);
4018 index($index);
4019 scale(0x0);
4020 disp($off);
4021 %}
4022 %}
4024 operand gsBaseIndexOffset0(mRegP addr, mRegL index) %{
4025 predicate(UseLoongsonISA);
4026 constraint(ALLOC_IN_RC(p_reg));
4027 match(AddP addr index);
4029 op_cost(10);
4030 format %{"[$addr + $index] @ gsBaseIndexOffset0" %}
4031 interface(MEMORY_INTER) %{
4032 base($addr);
4033 index($index);
4034 scale(0x0);
4035 disp(0x0);
4036 %}
4037 %}
4039 operand baseOffset0(mRegP reg) %{
4040 constraint(ALLOC_IN_RC(p_reg));
4041 op_cost(10);
4042 match(reg);
4044 format %{ "[$reg] @ baseOffset0" %}
4045 interface(MEMORY_INTER) %{
4046 base($reg);
4047 index(0x0);
4048 scale(0x0);
4049 disp(0x0);
4050 %}
4051 %}
4053 operand baseOffset16Narrow(mRegN reg, immL16 off)
4054 %{
4055 predicate(Universe::narrow_oop_base() == 0 && Universe::narrow_oop_shift() == 0);
4056 constraint(ALLOC_IN_RC(p_reg));
4057 match(AddP (DecodeN reg) off);
4059 op_cost(5);
4060 format %{ "[$reg + $off (16-bit)] @ baseOffset16Narrow" %}
4061 interface(MEMORY_INTER) %{
4062 base($reg);
4063 index(0x0);
4064 scale(0x0);
4065 disp($off);
4066 %}
4067 %}
4069 operand gsBaseIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
4070 %{
4071 predicate(UseLoongsonISA && Universe::narrow_oop_base() == 0 && Universe::narrow_oop_shift() == 0);
4072 constraint(ALLOC_IN_RC(p_reg));
4073 match(AddP (AddP (DecodeN reg) lreg) off);
4075 op_cost(5);
4076 format %{"[$reg + $off + $lreg] @ gsBaseIndexOffset8Narrow" %}
4077 interface(MEMORY_INTER) %{
4078 base($reg);
4079 index($lreg);
4080 scale(0x0);
4081 disp($off);
4082 %}
4083 %}
4085 operand baseOffset0Narrow(mRegN reg)
4086 %{
4087 predicate(Universe::narrow_oop_base() == 0 && Universe::narrow_oop_shift() == 0);
4088 constraint(ALLOC_IN_RC(p_reg));
4089 match(DecodeN reg);
4091 op_cost(10);
4092 format %{ "[$reg] @ baseOffset0Narrow" %}
4093 interface(MEMORY_INTER) %{
4094 base($reg);
4095 index(0x0);
4096 scale(0x0);
4097 disp(0x0);
4098 %}
4099 %}
4101 operand baseOffset16NarrowKlass(mRegN reg, immL16 off)
4102 %{
4103 predicate(Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
4104 constraint(ALLOC_IN_RC(p_reg));
4105 match(AddP (DecodeNKlass reg) off);
4107 op_cost(5);
4108 format %{ "[$reg + $off (16-bit)] @ baseOffset16NarrowKlass" %}
4109 interface(MEMORY_INTER) %{
4110 base($reg);
4111 index(0x0);
4112 scale(0x0);
4113 disp($off);
4114 %}
4115 %}
4117 operand baseOffset0NarrowKlass(mRegN reg)
4118 %{
4119 predicate(Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
4120 constraint(ALLOC_IN_RC(p_reg));
4121 match(DecodeNKlass reg);
4123 op_cost(10);
4124 format %{ "[$reg] @ baseOffset0NarrowKlass" %}
4125 interface(MEMORY_INTER) %{
4126 base($reg);
4127 index(0x0);
4128 scale(0x0);
4129 disp(0x0);
4130 %}
4131 %}
4133 operand gsBaseIndexOffset8NarrowKlass(mRegN reg, mRegL lreg, immL8 off)
4134 %{
4135 predicate(UseLoongsonISA && Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
4136 constraint(ALLOC_IN_RC(p_reg));
4137 match(AddP (AddP (DecodeNKlass reg) lreg) off);
4139 op_cost(5);
4140 format %{"[$reg + $off + $lreg] @ gsBaseIndexOffset8NarrowKlass" %}
4141 interface(MEMORY_INTER) %{
4142 base($reg);
4143 index($lreg);
4144 scale(0x0);
4145 disp($off);
4146 %}
4147 %}
4149 operand gsBaseIndexOffset0NarrowKlass(mRegN reg, mRegL lreg)
4150 %{
4151 predicate(UseLoongsonISA && Universe::narrow_klass_base() == 0 && Universe::narrow_klass_shift() == 0);
4152 constraint(ALLOC_IN_RC(p_reg));
4153 match(AddP (DecodeNKlass reg) lreg);
4155 op_cost(10);
4156 format %{"[$reg + $lreg] @ gsBaseIndexOffset0NarrowKlass" %}
4157 interface(MEMORY_INTER) %{
4158 base($reg);
4159 index($lreg);
4160 scale(0x0);
4161 disp(0x0);
4162 %}
4163 %}
4166 //------------------------OPERAND CLASSES--------------------------------------
4167 opclass memory(
4168 baseOffset16,
4169 gsBaseIndexOffset8,
4170 gsBaseIndexI2LOffset8,
4171 gsBaseIndexOffset0,
4172 baseOffset0,
4174 baseOffset16Narrow,
4175 gsBaseIndexOffset8Narrow,
4176 baseOffset0Narrow,
4178 baseOffset16NarrowKlass,
4179 baseOffset0NarrowKlass,
4180 gsBaseIndexOffset8NarrowKlass,
4181 gsBaseIndexOffset0NarrowKlass
4182 );
4184 // For loading unsigned values
4185 // umemory --> unsigned memory
4186 opclass umemory(
4187 baseOffset16,
4188 baseOffset0,
4190 baseOffset16Narrow,
4191 baseOffset0Narrow,
4193 baseOffset16NarrowKlass,
4194 baseOffset0NarrowKlass
4195 );
4198 //----------Conditional Branch Operands----------------------------------------
4199 // Comparison Op - This is the operation of the comparison, and is limited to
4200 // the following set of codes:
4201 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
4202 //
4203 // Other attributes of the comparison, such as unsignedness, are specified
4204 // by the comparison instruction that sets a condition code flags register.
4205 // That result is represented by a flags operand whose subtype is appropriate
4206 // to the unsignedness (etc.) of the comparison.
4207 //
4208 // Later, the instruction which matches both the Comparison Op (a Bool) and
4209 // the flags (produced by the Cmp) specifies the coding of the comparison op
4210 // by matching a specific subtype of Bool operand below, such as cmpOpU.
4212 // Comparision Code
4213 operand cmpOp() %{
4214 match(Bool);
4216 format %{ "" %}
4217 interface(COND_INTER) %{
4218 equal(0x01);
4219 not_equal(0x02);
4220 greater(0x03);
4221 greater_equal(0x04);
4222 less(0x05);
4223 less_equal(0x06);
4224 overflow(0x7);
4225 no_overflow(0x8);
4226 %}
4227 %}
4230 // Comparision Code
4231 // Comparison Code, unsigned compare. Used by FP also, with
4232 // C2 (unordered) turned into GT or LT already. The other bits
4233 // C0 and C3 are turned into Carry & Zero flags.
4234 operand cmpOpU() %{
4235 match(Bool);
4237 format %{ "" %}
4238 interface(COND_INTER) %{
4239 equal(0x01);
4240 not_equal(0x02);
4241 greater(0x03);
4242 greater_equal(0x04);
4243 less(0x05);
4244 less_equal(0x06);
4245 overflow(0x7);
4246 no_overflow(0x8);
4247 %}
4248 %}
4251 //----------Special Memory Operands--------------------------------------------
4252 // Stack Slot Operand - This operand is used for loading and storing temporary
4253 // values on the stack where a match requires a value to
4254 // flow through memory.
4255 operand stackSlotP(sRegP reg) %{
4256 constraint(ALLOC_IN_RC(stack_slots));
4257 // No match rule because this operand is only generated in matching
4258 op_cost(50);
4259 format %{ "[$reg]" %}
4260 interface(MEMORY_INTER) %{
4261 base(0x1d); // SP
4262 index(0x0); // No Index
4263 scale(0x0); // No Scale
4264 disp($reg); // Stack Offset
4265 %}
4266 %}
4268 operand stackSlotI(sRegI reg) %{
4269 constraint(ALLOC_IN_RC(stack_slots));
4270 // No match rule because this operand is only generated in matching
4271 op_cost(50);
4272 format %{ "[$reg]" %}
4273 interface(MEMORY_INTER) %{
4274 base(0x1d); // SP
4275 index(0x0); // No Index
4276 scale(0x0); // No Scale
4277 disp($reg); // Stack Offset
4278 %}
4279 %}
4281 operand stackSlotF(sRegF reg) %{
4282 constraint(ALLOC_IN_RC(stack_slots));
4283 // No match rule because this operand is only generated in matching
4284 op_cost(50);
4285 format %{ "[$reg]" %}
4286 interface(MEMORY_INTER) %{
4287 base(0x1d); // SP
4288 index(0x0); // No Index
4289 scale(0x0); // No Scale
4290 disp($reg); // Stack Offset
4291 %}
4292 %}
4294 operand stackSlotD(sRegD reg) %{
4295 constraint(ALLOC_IN_RC(stack_slots));
4296 // No match rule because this operand is only generated in matching
4297 op_cost(50);
4298 format %{ "[$reg]" %}
4299 interface(MEMORY_INTER) %{
4300 base(0x1d); // SP
4301 index(0x0); // No Index
4302 scale(0x0); // No Scale
4303 disp($reg); // Stack Offset
4304 %}
4305 %}
4307 operand stackSlotL(sRegL reg) %{
4308 constraint(ALLOC_IN_RC(stack_slots));
4309 // No match rule because this operand is only generated in matching
4310 op_cost(50);
4311 format %{ "[$reg]" %}
4312 interface(MEMORY_INTER) %{
4313 base(0x1d); // SP
4314 index(0x0); // No Index
4315 scale(0x0); // No Scale
4316 disp($reg); // Stack Offset
4317 %}
4318 %}
4320 //----------PIPELINE-----------------------------------------------------------
4321 // Rules which define the behavior of the target architectures pipeline.
4323 pipeline %{
4325 //----------ATTRIBUTES---------------------------------------------------------
4326 attributes %{
4327 fixed_size_instructions; // Fixed size instructions
4328 branch_has_delay_slot; // branch have delay slot in gs2
4329 max_instructions_per_bundle = 1; // 1 instruction per bundle
4330 max_bundles_per_cycle = 4; // Up to 4 bundles per cycle
4331 bundle_unit_size=4;
4332 instruction_unit_size = 4; // An instruction is 4 bytes long
4333 instruction_fetch_unit_size = 16; // The processor fetches one line
4334 instruction_fetch_units = 1; // of 16 bytes
4336 // List of nop instructions
4337 nops( MachNop );
4338 %}
4340 //----------RESOURCES----------------------------------------------------------
4341 // Resources are the functional units available to the machine
4343 resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4, ALU1, ALU2, ALU = ALU1 | ALU2, FPU1, FPU2, FPU = FPU1 | FPU2, MEM, BR);
4345 //----------PIPELINE DESCRIPTION-----------------------------------------------
4346 // Pipeline Description specifies the stages in the machine's pipeline
4348 // IF: fetch
4349 // ID: decode
4350 // RD: read
4351 // CA: caculate
4352 // WB: write back
4353 // CM: commit
4355 pipe_desc(IF, ID, RD, CA, WB, CM);
4358 //----------PIPELINE CLASSES---------------------------------------------------
4359 // Pipeline Classes describe the stages in which input and output are
4360 // referenced by the hardware pipeline.
4362 //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
4363 pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
4364 single_instruction;
4365 src1 : RD(read);
4366 src2 : RD(read);
4367 dst : WB(write)+1;
4368 DECODE : ID;
4369 ALU : CA;
4370 %}
4372 //No.19 Integer mult operation : dst <-- reg1 mult reg2
4373 pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
4374 src1 : RD(read);
4375 src2 : RD(read);
4376 dst : WB(write)+5;
4377 DECODE : ID;
4378 ALU2 : CA;
4379 %}
4381 pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
4382 src1 : RD(read);
4383 src2 : RD(read);
4384 dst : WB(write)+10;
4385 DECODE : ID;
4386 ALU2 : CA;
4387 %}
4389 //No.19 Integer div operation : dst <-- reg1 div reg2
4390 pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
4391 src1 : RD(read);
4392 src2 : RD(read);
4393 dst : WB(write)+10;
4394 DECODE : ID;
4395 ALU2 : CA;
4396 %}
4398 //No.19 Integer mod operation : dst <-- reg1 mod reg2
4399 pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
4400 instruction_count(2);
4401 src1 : RD(read);
4402 src2 : RD(read);
4403 dst : WB(write)+10;
4404 DECODE : ID;
4405 ALU2 : CA;
4406 %}
4408 //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
4409 pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
4410 instruction_count(2);
4411 src1 : RD(read);
4412 src2 : RD(read);
4413 dst : WB(write);
4414 DECODE : ID;
4415 ALU : CA;
4416 %}
4418 //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
4419 pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
4420 instruction_count(2);
4421 src : RD(read);
4422 dst : WB(write);
4423 DECODE : ID;
4424 ALU : CA;
4425 %}
4427 //no.16 load Long from memory :
4428 pipe_class ialu_loadL(mRegL dst, memory mem) %{
4429 instruction_count(2);
4430 mem : RD(read);
4431 dst : WB(write)+5;
4432 DECODE : ID;
4433 MEM : RD;
4434 %}
4436 //No.17 Store Long to Memory :
4437 pipe_class ialu_storeL(mRegL src, memory mem) %{
4438 instruction_count(2);
4439 mem : RD(read);
4440 src : RD(read);
4441 DECODE : ID;
4442 MEM : RD;
4443 %}
4445 //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
4446 pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
4447 single_instruction;
4448 src : RD(read);
4449 dst : WB(write);
4450 DECODE : ID;
4451 ALU : CA;
4452 %}
4454 //No.3 Integer move operation : dst <-- reg
4455 pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
4456 src : RD(read);
4457 dst : WB(write);
4458 DECODE : ID;
4459 ALU : CA;
4460 %}
4462 //No.4 No instructions : do nothing
4463 pipe_class empty( ) %{
4464 instruction_count(0);
4465 %}
4467 //No.5 UnConditional branch :
4468 pipe_class pipe_jump( label labl ) %{
4469 multiple_bundles;
4470 DECODE : ID;
4471 BR : RD;
4472 %}
4474 //No.6 ALU Conditional branch :
4475 pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
4476 multiple_bundles;
4477 src1 : RD(read);
4478 src2 : RD(read);
4479 DECODE : ID;
4480 BR : RD;
4481 %}
4483 //no.7 load integer from memory :
4484 pipe_class ialu_loadI(mRegI dst, memory mem) %{
4485 mem : RD(read);
4486 dst : WB(write)+3;
4487 DECODE : ID;
4488 MEM : RD;
4489 %}
4491 //No.8 Store Integer to Memory :
4492 pipe_class ialu_storeI(mRegI src, memory mem) %{
4493 mem : RD(read);
4494 src : RD(read);
4495 DECODE : ID;
4496 MEM : RD;
4497 %}
4500 //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
4501 pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
4502 src1 : RD(read);
4503 src2 : RD(read);
4504 dst : WB(write);
4505 DECODE : ID;
4506 FPU : CA;
4507 %}
4509 //No.22 Floating div operation : dst <-- reg1 div reg2
4510 pipe_class fpu_div(regF dst, regF src1, regF src2) %{
4511 src1 : RD(read);
4512 src2 : RD(read);
4513 dst : WB(write);
4514 DECODE : ID;
4515 FPU2 : CA;
4516 %}
4518 pipe_class fcvt_I2D(regD dst, mRegI src) %{
4519 src : RD(read);
4520 dst : WB(write);
4521 DECODE : ID;
4522 FPU1 : CA;
4523 %}
4525 pipe_class fcvt_D2I(mRegI dst, regD src) %{
4526 src : RD(read);
4527 dst : WB(write);
4528 DECODE : ID;
4529 FPU1 : CA;
4530 %}
4532 pipe_class pipe_mfc1(mRegI dst, regD src) %{
4533 src : RD(read);
4534 dst : WB(write);
4535 DECODE : ID;
4536 MEM : RD;
4537 %}
4539 pipe_class pipe_mtc1(regD dst, mRegI src) %{
4540 src : RD(read);
4541 dst : WB(write);
4542 DECODE : ID;
4543 MEM : RD(5);
4544 %}
4546 //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
4547 pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
4548 multiple_bundles;
4549 src1 : RD(read);
4550 src2 : RD(read);
4551 dst : WB(write);
4552 DECODE : ID;
4553 FPU2 : CA;
4554 %}
4556 //No.11 Load Floating from Memory :
4557 pipe_class fpu_loadF(regF dst, memory mem) %{
4558 instruction_count(1);
4559 mem : RD(read);
4560 dst : WB(write)+3;
4561 DECODE : ID;
4562 MEM : RD;
4563 %}
4565 //No.12 Store Floating to Memory :
4566 pipe_class fpu_storeF(regF src, memory mem) %{
4567 instruction_count(1);
4568 mem : RD(read);
4569 src : RD(read);
4570 DECODE : ID;
4571 MEM : RD;
4572 %}
4574 //No.13 FPU Conditional branch :
4575 pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
4576 multiple_bundles;
4577 src1 : RD(read);
4578 src2 : RD(read);
4579 DECODE : ID;
4580 BR : RD;
4581 %}
4583 //No.14 Floating FPU reg operation : dst <-- op reg
4584 pipe_class fpu1_regF(regF dst, regF src) %{
4585 src : RD(read);
4586 dst : WB(write);
4587 DECODE : ID;
4588 FPU : CA;
4589 %}
4591 pipe_class long_memory_op() %{
4592 instruction_count(10); multiple_bundles; force_serialization;
4593 fixed_latency(30);
4594 %}
4596 pipe_class simple_call() %{
4597 instruction_count(10); multiple_bundles; force_serialization;
4598 fixed_latency(200);
4599 BR : RD;
4600 %}
4602 pipe_class call() %{
4603 instruction_count(10); multiple_bundles; force_serialization;
4604 fixed_latency(200);
4605 %}
4607 //FIXME:
4608 //No.9 Piple slow : for multi-instructions
4609 pipe_class pipe_slow( ) %{
4610 instruction_count(20);
4611 force_serialization;
4612 multiple_bundles;
4613 fixed_latency(50);
4614 %}
4616 %}
4620 //----------INSTRUCTIONS-------------------------------------------------------
4621 //
4622 // match -- States which machine-independent subtree may be replaced
4623 // by this instruction.
4624 // ins_cost -- The estimated cost of this instruction is used by instruction
4625 // selection to identify a minimum cost tree of machine
4626 // instructions that matches a tree of machine-independent
4627 // instructions.
4628 // format -- A string providing the disassembly for this instruction.
4629 // The value of an instruction's operand may be inserted
4630 // by referring to it with a '$' prefix.
4631 // opcode -- Three instruction opcodes may be provided. These are referred
4632 // to within an encode class as $primary, $secondary, and $tertiary
4633 // respectively. The primary opcode is commonly used to
4634 // indicate the type of machine instruction, while secondary
4635 // and tertiary are often used for prefix options or addressing
4636 // modes.
4637 // ins_encode -- A list of encode classes with parameters. The encode class
4638 // name must have been defined in an 'enc_class' specification
4639 // in the encode section of the architecture description.
4642 // Load Integer
4643 instruct loadI(mRegI dst, memory mem) %{
4644 match(Set dst (LoadI mem));
4646 ins_cost(125);
4647 format %{ "lw $dst, $mem #@loadI" %}
4648 ins_encode (load_I_enc(dst, mem));
4649 ins_pipe( ialu_loadI );
4650 %}
4652 instruct loadI_convI2L(mRegL dst, memory mem) %{
4653 match(Set dst (ConvI2L (LoadI mem)));
4655 ins_cost(125);
4656 format %{ "lw $dst, $mem #@loadI_convI2L" %}
4657 ins_encode (load_I_enc(dst, mem));
4658 ins_pipe( ialu_loadI );
4659 %}
4661 // Load Integer (32 bit signed) to Byte (8 bit signed)
4662 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
4663 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
4665 ins_cost(125);
4666 format %{ "lb $dst, $mem\t# int -> byte #@loadI2B" %}
4667 ins_encode(load_B_enc(dst, mem));
4668 ins_pipe(ialu_loadI);
4669 %}
4671 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
4672 instruct loadI2UB(mRegI dst, umemory mem, immI_255 mask) %{
4673 match(Set dst (AndI (LoadI mem) mask));
4675 ins_cost(125);
4676 format %{ "lbu $dst, $mem\t# int -> ubyte #@loadI2UB" %}
4677 ins_encode(load_UB_enc(dst, mem));
4678 ins_pipe(ialu_loadI);
4679 %}
4681 // Load Integer (32 bit signed) to Short (16 bit signed)
4682 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
4683 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
4685 ins_cost(125);
4686 format %{ "lh $dst, $mem\t# int -> short #@loadI2S" %}
4687 ins_encode(load_S_enc(dst, mem));
4688 ins_pipe(ialu_loadI);
4689 %}
4691 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
4692 instruct loadI2US(mRegI dst, umemory mem, immI_65535 mask) %{
4693 match(Set dst (AndI (LoadI mem) mask));
4695 ins_cost(125);
4696 format %{ "lhu $dst, $mem\t# int -> ushort/char #@loadI2US" %}
4697 ins_encode(load_C_enc(dst, mem));
4698 ins_pipe(ialu_loadI);
4699 %}
4701 // Load Long.
4702 instruct loadL(mRegL dst, memory mem) %{
4703 // predicate(!((LoadLNode*)n)->require_atomic_access());
4704 match(Set dst (LoadL mem));
4706 ins_cost(250);
4707 format %{ "ld $dst, $mem #@loadL" %}
4708 ins_encode(load_L_enc(dst, mem));
4709 ins_pipe( ialu_loadL );
4710 %}
4712 // Load Long - UNaligned
4713 instruct loadL_unaligned(mRegL dst, memory mem) %{
4714 match(Set dst (LoadL_unaligned mem));
4716 // FIXME: Jin: Need more effective ldl/ldr
4717 ins_cost(450);
4718 format %{ "ld $dst, $mem #@loadL_unaligned\n\t" %}
4719 ins_encode(load_L_enc(dst, mem));
4720 ins_pipe( ialu_loadL );
4721 %}
4723 // Store Long
4724 instruct storeL_reg(memory mem, mRegL src) %{
4725 match(Set mem (StoreL mem src));
4727 ins_cost(200);
4728 format %{ "sd $mem, $src #@storeL_reg\n" %}
4729 ins_encode(store_L_reg_enc(mem, src));
4730 ins_pipe( ialu_storeL );
4731 %}
4734 instruct storeL_immL0(memory mem, immL0 zero) %{
4735 match(Set mem (StoreL mem zero));
4737 ins_cost(180);
4738 format %{ "sd $mem, zero #@storeL_immL0" %}
4739 ins_encode(store_L_immL0_enc(mem));
4740 ins_pipe( ialu_storeL );
4741 %}
4743 // Load Compressed Pointer
4744 instruct loadN(mRegN dst, umemory mem)
4745 %{
4746 match(Set dst (LoadN mem));
4748 ins_cost(125); // XXX
4749 format %{ "lwu $dst, $mem\t# compressed ptr @ loadN" %}
4750 ins_encode (load_N_enc(dst, mem));
4751 ins_pipe( ialu_loadI ); // XXX
4752 %}
4754 instruct loadN2P(mRegP dst, umemory mem)
4755 %{
4756 match(Set dst (DecodeN (LoadN mem)));
4757 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
4759 ins_cost(125); // XXX
4760 format %{ "lwu $dst, $mem\t# @ loadN2P" %}
4761 ins_encode (load_N_enc(dst, mem));
4762 ins_pipe( ialu_loadI ); // XXX
4763 %}
4765 // Load Pointer
4766 instruct loadP(mRegP dst, memory mem) %{
4767 match(Set dst (LoadP mem));
4769 ins_cost(125);
4770 format %{ "ld $dst, $mem #@loadP" %}
4771 ins_encode (load_P_enc(dst, mem));
4772 ins_pipe( ialu_loadI );
4773 %}
4775 // Load Klass Pointer
4776 instruct loadKlass(mRegP dst, memory mem) %{
4777 match(Set dst (LoadKlass mem));
4779 ins_cost(125);
4780 format %{ "MOV $dst,$mem @ loadKlass" %}
4781 ins_encode (load_P_enc(dst, mem));
4782 ins_pipe( ialu_loadI );
4783 %}
4785 // Load narrow Klass Pointer
4786 instruct loadNKlass(mRegN dst, umemory mem)
4787 %{
4788 match(Set dst (LoadNKlass mem));
4790 ins_cost(125); // XXX
4791 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
4792 ins_encode (load_N_enc(dst, mem));
4793 ins_pipe( ialu_loadI ); // XXX
4794 %}
4796 instruct loadN2PKlass(mRegP dst, umemory mem)
4797 %{
4798 match(Set dst (DecodeNKlass (LoadNKlass mem)));
4799 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4801 ins_cost(125); // XXX
4802 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
4803 ins_encode (load_N_enc(dst, mem));
4804 ins_pipe( ialu_loadI ); // XXX
4805 %}
4807 // Load Constant
4808 instruct loadConI(mRegI dst, immI src) %{
4809 match(Set dst src);
4811 ins_cost(150);
4812 format %{ "mov $dst, $src #@loadConI" %}
4813 ins_encode %{
4814 Register dst = $dst$$Register;
4815 int value = $src$$constant;
4816 __ move(dst, value);
4817 %}
4818 ins_pipe( ialu_regI_regI );
4819 %}
4822 instruct loadConL_set64(mRegL dst, immL src) %{
4823 match(Set dst src);
4824 ins_cost(120);
4825 format %{ "li $dst, $src @ loadConL_set64" %}
4826 ins_encode %{
4827 __ set64($dst$$Register, $src$$constant);
4828 %}
4829 ins_pipe(ialu_regL_regL);
4830 %}
4832 /*
4833 // Load long value from constant table (predicated by immL_expensive).
4834 instruct loadConL_load(mRegL dst, immL_expensive src) %{
4835 match(Set dst src);
4836 ins_cost(150);
4837 format %{ "ld $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
4838 ins_encode %{
4839 int con_offset = $constantoffset($src);
4841 if (Assembler::is_simm16(con_offset)) {
4842 __ ld($dst$$Register, $constanttablebase, con_offset);
4843 } else {
4844 __ set64(AT, con_offset);
4845 if (UseLoongsonISA) {
4846 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
4847 } else {
4848 __ daddu(AT, $constanttablebase, AT);
4849 __ ld($dst$$Register, AT, 0);
4850 }
4851 }
4852 %}
4853 ins_pipe(ialu_loadI);
4854 %}
4855 */
4857 instruct loadConL16(mRegL dst, immL16 src) %{
4858 match(Set dst src);
4859 ins_cost(105);
4860 format %{ "mov $dst, $src #@loadConL16" %}
4861 ins_encode %{
4862 Register dst_reg = as_Register($dst$$reg);
4863 int value = $src$$constant;
4864 __ daddiu(dst_reg, R0, value);
4865 %}
4866 ins_pipe( ialu_regL_regL );
4867 %}
4870 instruct loadConL0(mRegL dst, immL0 src) %{
4871 match(Set dst src);
4872 ins_cost(100);
4873 format %{ "mov $dst, zero #@loadConL0" %}
4874 ins_encode %{
4875 Register dst_reg = as_Register($dst$$reg);
4876 __ daddu(dst_reg, R0, R0);
4877 %}
4878 ins_pipe( ialu_regL_regL );
4879 %}
4881 // Load Range
4882 instruct loadRange(mRegI dst, memory mem) %{
4883 match(Set dst (LoadRange mem));
4885 ins_cost(125);
4886 format %{ "MOV $dst,$mem @ loadRange" %}
4887 ins_encode(load_I_enc(dst, mem));
4888 ins_pipe( ialu_loadI );
4889 %}
4892 instruct storeP(memory mem, mRegP src ) %{
4893 match(Set mem (StoreP mem src));
4895 ins_cost(125);
4896 format %{ "sd $src, $mem #@storeP" %}
4897 ins_encode(store_P_reg_enc(mem, src));
4898 ins_pipe( ialu_storeI );
4899 %}
4901 // Store NULL Pointer, mark word, or other simple pointer constant.
4902 instruct storeImmP0(memory mem, immP0 zero) %{
4903 match(Set mem (StoreP mem zero));
4905 ins_cost(125);
4906 format %{ "mov $mem, $zero #@storeImmP0" %}
4907 ins_encode(store_P_immP0_enc(mem));
4908 ins_pipe( ialu_storeI );
4909 %}
4911 // Store Compressed Pointer
4912 instruct storeN(memory mem, mRegN src)
4913 %{
4914 match(Set mem (StoreN mem src));
4916 ins_cost(125); // XXX
4917 format %{ "sw $mem, $src\t# compressed ptr @ storeN" %}
4918 ins_encode(store_N_reg_enc(mem, src));
4919 ins_pipe( ialu_storeI );
4920 %}
4922 instruct storeP2N(memory mem, mRegP src)
4923 %{
4924 match(Set mem (StoreN mem (EncodeP src)));
4925 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
4927 ins_cost(125); // XXX
4928 format %{ "sw $mem, $src\t# @ storeP2N" %}
4929 ins_encode(store_N_reg_enc(mem, src));
4930 ins_pipe( ialu_storeI );
4931 %}
4933 instruct storeNKlass(memory mem, mRegN src)
4934 %{
4935 match(Set mem (StoreNKlass mem src));
4937 ins_cost(125); // XXX
4938 format %{ "sw $mem, $src\t# compressed klass ptr @ storeNKlass" %}
4939 ins_encode(store_N_reg_enc(mem, src));
4940 ins_pipe( ialu_storeI );
4941 %}
4943 instruct storeP2NKlass(memory mem, mRegP src)
4944 %{
4945 match(Set mem (StoreNKlass mem (EncodePKlass src)));
4946 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
4948 ins_cost(125); // XXX
4949 format %{ "sw $mem, $src\t# @ storeP2NKlass" %}
4950 ins_encode(store_N_reg_enc(mem, src));
4951 ins_pipe( ialu_storeI );
4952 %}
4954 instruct storeImmN0(memory mem, immN0 zero)
4955 %{
4956 match(Set mem (StoreN mem zero));
4958 ins_cost(125); // XXX
4959 format %{ "storeN0 $mem, R12\t# compressed ptr" %}
4960 ins_encode(storeImmN0_enc(mem));
4961 ins_pipe( ialu_storeI );
4962 %}
4964 // Store Byte
4965 instruct storeB(memory mem, mRegI src) %{
4966 match(Set mem (StoreB mem src));
4968 ins_cost(125);
4969 format %{ "sb $src, $mem #@storeB" %}
4970 ins_encode(store_B_reg_enc(mem, src));
4971 ins_pipe( ialu_storeI );
4972 %}
4974 instruct storeB0(memory mem, immI0 zero) %{
4975 match(Set mem (StoreB mem zero));
4977 ins_cost(100);
4978 format %{ "sb $zero, $mem #@storeB0" %}
4979 ins_encode(store_B0_enc(mem));
4980 ins_pipe( ialu_storeI );
4981 %}
4983 instruct storeB_convL2I(memory mem, mRegL src) %{
4984 match(Set mem (StoreB mem (ConvL2I src)));
4986 ins_cost(125);
4987 format %{ "sb $src, $mem #@storeB_convL2I" %}
4988 ins_encode(store_B_reg_enc(mem, src));
4989 ins_pipe( ialu_storeI );
4990 %}
4992 // Load Byte (8bit signed)
4993 instruct loadB(mRegI dst, memory mem) %{
4994 match(Set dst (LoadB mem));
4996 ins_cost(125);
4997 format %{ "lb $dst, $mem #@loadB" %}
4998 ins_encode(load_B_enc(dst, mem));
4999 ins_pipe( ialu_loadI );
5000 %}
5002 instruct loadB_convI2L(mRegL dst, memory mem) %{
5003 match(Set dst (ConvI2L (LoadB mem)));
5005 ins_cost(125);
5006 format %{ "lb $dst, $mem #@loadB_convI2L" %}
5007 ins_encode(load_B_enc(dst, mem));
5008 ins_pipe( ialu_loadI );
5009 %}
5011 // Load Byte (8bit UNsigned)
5012 instruct loadUB(mRegI dst, umemory mem) %{
5013 match(Set dst (LoadUB mem));
5015 ins_cost(125);
5016 format %{ "lbu $dst, $mem #@loadUB" %}
5017 ins_encode(load_UB_enc(dst, mem));
5018 ins_pipe( ialu_loadI );
5019 %}
5021 instruct loadUB_convI2L(mRegL dst, umemory mem) %{
5022 match(Set dst (ConvI2L (LoadUB mem)));
5024 ins_cost(125);
5025 format %{ "lbu $dst, $mem #@loadUB_convI2L" %}
5026 ins_encode(load_UB_enc(dst, mem));
5027 ins_pipe( ialu_loadI );
5028 %}
5030 // Load Short (16bit signed)
5031 instruct loadS(mRegI dst, memory mem) %{
5032 match(Set dst (LoadS mem));
5034 ins_cost(125);
5035 format %{ "lh $dst, $mem #@loadS" %}
5036 ins_encode(load_S_enc(dst, mem));
5037 ins_pipe( ialu_loadI );
5038 %}
5040 // Load Short (16 bit signed) to Byte (8 bit signed)
5041 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
5042 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
5044 ins_cost(125);
5045 format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
5046 ins_encode(load_B_enc(dst, mem));
5047 ins_pipe(ialu_loadI);
5048 %}
5050 instruct loadS_convI2L(mRegL dst, memory mem) %{
5051 match(Set dst (ConvI2L (LoadS mem)));
5053 ins_cost(125);
5054 format %{ "lh $dst, $mem #@loadS_convI2L" %}
5055 ins_encode(load_S_enc(dst, mem));
5056 ins_pipe( ialu_loadI );
5057 %}
5059 // Store Integer Immediate
5060 instruct storeI0(memory mem, immI0 zero) %{
5061 match(Set mem (StoreI mem zero));
5063 ins_cost(100);
5064 format %{ "sw $mem, $zero #@storeI0" %}
5065 ins_encode(store_I_immI0_enc(mem));
5066 ins_pipe( ialu_storeI );
5067 %}
5069 // Store Integer
5070 instruct storeI(memory mem, mRegI src) %{
5071 match(Set mem (StoreI mem src));
5073 ins_cost(125);
5074 format %{ "sw $mem, $src #@storeI" %}
5075 ins_encode(store_I_reg_enc(mem, src));
5076 ins_pipe( ialu_storeI );
5077 %}
5079 instruct storeI_convL2I(memory mem, mRegL src) %{
5080 match(Set mem (StoreI mem (ConvL2I src)));
5082 ins_cost(125);
5083 format %{ "sw $mem, $src #@storeI_convL2I" %}
5084 ins_encode(store_I_reg_enc(mem, src));
5085 ins_pipe( ialu_storeI );
5086 %}
5088 // Load Float
5089 instruct loadF(regF dst, memory mem) %{
5090 match(Set dst (LoadF mem));
5092 ins_cost(150);
5093 format %{ "loadF $dst, $mem #@loadF" %}
5094 ins_encode(load_F_enc(dst, mem));
5095 ins_pipe( ialu_loadI );
5096 %}
5098 instruct loadConP_general(mRegP dst, immP src) %{
5099 match(Set dst src);
5101 ins_cost(120);
5102 format %{ "li $dst, $src #@loadConP_general" %}
5104 ins_encode %{
5105 Register dst = $dst$$Register;
5106 long* value = (long*)$src$$constant;
5108 if($src->constant_reloc() == relocInfo::metadata_type){
5109 int klass_index = __ oop_recorder()->find_index((Klass*)value);
5110 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
5112 __ relocate(rspec);
5113 __ patchable_set48(dst, (long)value);
5114 }else if($src->constant_reloc() == relocInfo::oop_type){
5115 int oop_index = __ oop_recorder()->find_index((jobject)value);
5116 RelocationHolder rspec = oop_Relocation::spec(oop_index);
5118 __ relocate(rspec);
5119 __ patchable_set48(dst, (long)value);
5120 } else if ($src->constant_reloc() == relocInfo::none) {
5121 __ set64(dst, (long)value);
5122 }
5123 %}
5125 ins_pipe( ialu_regI_regI );
5126 %}
5128 /*
5129 instruct loadConP_load(mRegP dst, immP_load src) %{
5130 match(Set dst src);
5132 ins_cost(100);
5133 format %{ "ld $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
5135 ins_encode %{
5137 int con_offset = $constantoffset($src);
5139 if (Assembler::is_simm16(con_offset)) {
5140 __ ld($dst$$Register, $constanttablebase, con_offset);
5141 } else {
5142 __ set64(AT, con_offset);
5143 if (UseLoongsonISA) {
5144 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
5145 } else {
5146 __ daddu(AT, $constanttablebase, AT);
5147 __ ld($dst$$Register, AT, 0);
5148 }
5149 }
5150 %}
5152 ins_pipe(ialu_loadI);
5153 %}
5154 */
5156 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
5157 match(Set dst src);
5159 ins_cost(80);
5160 format %{ "li $dst, $src @ loadConP_no_oop_cheap" %}
5162 ins_encode %{
5163 __ set64($dst$$Register, $src$$constant);
5164 %}
5166 ins_pipe(ialu_regI_regI);
5167 %}
5170 instruct loadConP_poll(mRegP dst, immP_poll src) %{
5171 match(Set dst src);
5173 ins_cost(50);
5174 format %{ "li $dst, $src #@loadConP_poll" %}
5176 ins_encode %{
5177 Register dst = $dst$$Register;
5178 intptr_t value = (intptr_t)$src$$constant;
5180 __ set64(dst, (jlong)value);
5181 %}
5183 ins_pipe( ialu_regI_regI );
5184 %}
5186 instruct loadConP0(mRegP dst, immP0 src)
5187 %{
5188 match(Set dst src);
5190 ins_cost(50);
5191 format %{ "mov $dst, R0\t# ptr" %}
5192 ins_encode %{
5193 Register dst_reg = $dst$$Register;
5194 __ daddu(dst_reg, R0, R0);
5195 %}
5196 ins_pipe( ialu_regI_regI );
5197 %}
5199 instruct loadConN0(mRegN dst, immN0 src) %{
5200 match(Set dst src);
5201 format %{ "move $dst, R0\t# compressed NULL ptr" %}
5202 ins_encode %{
5203 __ move($dst$$Register, R0);
5204 %}
5205 ins_pipe( ialu_regI_regI );
5206 %}
5208 instruct loadConN(mRegN dst, immN src) %{
5209 match(Set dst src);
5211 ins_cost(125);
5212 format %{ "li $dst, $src\t# compressed ptr @ loadConN" %}
5213 ins_encode %{
5214 Register dst = $dst$$Register;
5215 __ set_narrow_oop(dst, (jobject)$src$$constant);
5216 %}
5217 ins_pipe( ialu_regI_regI ); // XXX
5218 %}
5220 instruct loadConNKlass(mRegN dst, immNKlass src) %{
5221 match(Set dst src);
5223 ins_cost(125);
5224 format %{ "li $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
5225 ins_encode %{
5226 Register dst = $dst$$Register;
5227 __ set_narrow_klass(dst, (Klass*)$src$$constant);
5228 %}
5229 ins_pipe( ialu_regI_regI ); // XXX
5230 %}
5232 //FIXME
5233 // Tail Call; Jump from runtime stub to Java code.
5234 // Also known as an 'interprocedural jump'.
5235 // Target of jump will eventually return to caller.
5236 // TailJump below removes the return address.
5237 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
5238 match(TailCall jump_target method_oop );
5239 ins_cost(300);
5240 format %{ "JMP $jump_target \t# @TailCalljmpInd" %}
5242 ins_encode %{
5243 Register target = $jump_target$$Register;
5244 Register oop = $method_oop$$Register;
5246 /* 2012/10/12 Jin: RA will be used in generate_forward_exception() */
5247 __ push(RA);
5249 __ move(S3, oop);
5250 __ jr(target);
5251 __ nop();
5252 %}
5254 ins_pipe( pipe_jump );
5255 %}
5257 // Create exception oop: created by stack-crawling runtime code.
5258 // Created exception is now available to this handler, and is setup
5259 // just prior to jumping to this handler. No code emitted.
5260 instruct CreateException( a0_RegP ex_oop )
5261 %{
5262 match(Set ex_oop (CreateEx));
5264 // use the following format syntax
5265 format %{ "# exception oop is in A0; no code emitted @CreateException" %}
5266 ins_encode %{
5267 /* Jin: X86 leaves this function empty */
5268 __ block_comment("CreateException is empty in X86/MIPS");
5269 %}
5270 ins_pipe( empty );
5271 // ins_pipe( pipe_jump );
5272 %}
5275 /* 2012/9/14 Jin: The mechanism of exception handling is clear now.
5277 - Common try/catch:
5278 2012/9/14 Jin: [stubGenerator_mips.cpp] generate_forward_exception()
5279 |- V0, V1 are created
5280 |- T9 <= SharedRuntime::exception_handler_for_return_address
5281 `- jr T9
5282 `- the caller's exception_handler
5283 `- jr OptoRuntime::exception_blob
5284 `- here
5285 - Rethrow(e.g. 'unwind'):
5286 * The callee:
5287 |- an exception is triggered during execution
5288 `- exits the callee method through RethrowException node
5289 |- The callee pushes exception_oop(T0) and exception_pc(RA)
5290 `- The callee jumps to OptoRuntime::rethrow_stub()
5291 * In OptoRuntime::rethrow_stub:
5292 |- The VM calls _rethrow_Java to determine the return address in the caller method
5293 `- exits the stub with tailjmpInd
5294 |- pops exception_oop(V0) and exception_pc(V1)
5295 `- jumps to the return address(usually an exception_handler)
5296 * The caller:
5297 `- continues processing the exception_blob with V0/V1
5298 */
5300 /*
5301 Disassembling OptoRuntime::rethrow_stub()
5303 ; locals
5304 0x2d3bf320: addiu sp, sp, 0xfffffff8
5305 0x2d3bf324: sw ra, 0x4(sp)
5306 0x2d3bf328: sw fp, 0x0(sp)
5307 0x2d3bf32c: addu fp, sp, zero
5308 0x2d3bf330: addiu sp, sp, 0xfffffff0
5309 0x2d3bf334: sw ra, 0x8(sp)
5310 0x2d3bf338: sw t0, 0x4(sp)
5311 0x2d3bf33c: sw sp, 0x0(sp)
5313 ; get_thread(S2)
5314 0x2d3bf340: addu s2, sp, zero
5315 0x2d3bf344: srl s2, s2, 12
5316 0x2d3bf348: sll s2, s2, 2
5317 0x2d3bf34c: lui at, 0x2c85
5318 0x2d3bf350: addu at, at, s2
5319 0x2d3bf354: lw s2, 0xffffcc80(at)
5321 0x2d3bf358: lw s0, 0x0(sp)
5322 0x2d3bf35c: sw s0, 0x118(s2) // last_sp -> threa
5323 0x2d3bf360: sw s2, 0xc(sp)
5325 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
5326 0x2d3bf364: lw a0, 0x4(sp)
5327 0x2d3bf368: lw a1, 0xc(sp)
5328 0x2d3bf36c: lw a2, 0x8(sp)
5329 ;; Java_To_Runtime
5330 0x2d3bf370: lui t9, 0x2c34
5331 0x2d3bf374: addiu t9, t9, 0xffff8a48
5332 0x2d3bf378: jalr t9
5333 0x2d3bf37c: nop
5335 0x2d3bf380: addu s3, v0, zero ; S3: SharedRuntime::raw_exception_handler_for_return_address()
5337 0x2d3bf384: lw s0, 0xc(sp)
5338 0x2d3bf388: sw zero, 0x118(s0)
5339 0x2d3bf38c: sw zero, 0x11c(s0)
5340 0x2d3bf390: lw s1, 0x144(s0) ; ex_oop: S1
5341 0x2d3bf394: addu s2, s0, zero
5342 0x2d3bf398: sw zero, 0x144(s2)
5343 0x2d3bf39c: lw s0, 0x4(s2)
5344 0x2d3bf3a0: addiu s4, zero, 0x0
5345 0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
5346 0x2d3bf3a8: nop
5347 0x2d3bf3ac: addiu sp, sp, 0x10
5348 0x2d3bf3b0: addiu sp, sp, 0x8
5349 0x2d3bf3b4: lw ra, 0xfffffffc(sp)
5350 0x2d3bf3b8: lw fp, 0xfffffff8(sp)
5351 0x2d3bf3bc: lui at, 0x2b48
5352 0x2d3bf3c0: lw at, 0x100(at)
5354 ; tailjmpInd: Restores exception_oop & exception_pc
5355 0x2d3bf3c4: addu v1, ra, zero
5356 0x2d3bf3c8: addu v0, s1, zero
5357 0x2d3bf3cc: jr s3
5358 0x2d3bf3d0: nop
5359 ; Exception:
5360 0x2d3bf3d4: lui s1, 0x2cc8 ; generate_forward_exception()
5361 0x2d3bf3d8: addiu s1, s1, 0x40
5362 0x2d3bf3dc: addiu s2, zero, 0x0
5363 0x2d3bf3e0: addiu sp, sp, 0x10
5364 0x2d3bf3e4: addiu sp, sp, 0x8
5365 0x2d3bf3e8: lw ra, 0xfffffffc(sp)
5366 0x2d3bf3ec: lw fp, 0xfffffff8(sp)
5367 0x2d3bf3f0: lui at, 0x2b48
5368 0x2d3bf3f4: lw at, 0x100(at)
5369 ; TailCalljmpInd
5370 __ push(RA); ; to be used in generate_forward_exception()
5371 0x2d3bf3f8: addu t7, s2, zero
5372 0x2d3bf3fc: jr s1
5373 0x2d3bf400: nop
5374 */
5375 // Rethrow exception:
5376 // The exception oop will come in the first argument position.
5377 // Then JUMP (not call) to the rethrow stub code.
5378 instruct RethrowException()
5379 %{
5380 match(Rethrow);
5382 // use the following format syntax
5383 format %{ "JMP rethrow_stub #@RethrowException" %}
5384 ins_encode %{
5385 __ block_comment("@ RethrowException");
5387 cbuf.set_insts_mark();
5388 cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
5390 // call OptoRuntime::rethrow_stub to get the exception handler in parent method
5391 __ patchable_set48(T9, (jlong)OptoRuntime::rethrow_stub());
5392 __ jr(T9);
5393 __ nop();
5394 %}
5395 ins_pipe( pipe_jump );
5396 %}
5398 instruct branchConP_zero(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
5399 match(If cmp (CmpP op1 zero));
5400 effect(USE labl);
5402 ins_cost(180);
5403 format %{ "b$cmp $op1, R0, $labl #@branchConP_zero" %}
5405 ins_encode %{
5406 Register op1 = $op1$$Register;
5407 Register op2 = R0;
5408 Label &L = *($labl$$label);
5409 int flag = $cmp$$cmpcode;
5411 switch(flag)
5412 {
5413 case 0x01: //equal
5414 if (&L)
5415 __ beq(op1, op2, L);
5416 else
5417 __ beq(op1, op2, (int)0);
5418 break;
5419 case 0x02: //not_equal
5420 if (&L)
5421 __ bne(op1, op2, L);
5422 else
5423 __ bne(op1, op2, (int)0);
5424 break;
5425 /*
5426 case 0x03: //above
5427 __ sltu(AT, op2, op1);
5428 if(&L)
5429 __ bne(R0, AT, L);
5430 else
5431 __ bne(R0, AT, (int)0);
5432 break;
5433 case 0x04: //above_equal
5434 __ sltu(AT, op1, op2);
5435 if(&L)
5436 __ beq(AT, R0, L);
5437 else
5438 __ beq(AT, R0, (int)0);
5439 break;
5440 case 0x05: //below
5441 __ sltu(AT, op1, op2);
5442 if(&L)
5443 __ bne(R0, AT, L);
5444 else
5445 __ bne(R0, AT, (int)0);
5446 break;
5447 case 0x06: //below_equal
5448 __ sltu(AT, op2, op1);
5449 if(&L)
5450 __ beq(AT, R0, L);
5451 else
5452 __ beq(AT, R0, (int)0);
5453 break;
5454 */
5455 default:
5456 Unimplemented();
5457 }
5458 __ nop();
5459 %}
5461 ins_pc_relative(1);
5462 ins_pipe( pipe_alu_branch );
5463 %}
5465 instruct branchConN2P_zero(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
5466 match(If cmp (CmpP (DecodeN op1) zero));
5467 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
5468 effect(USE labl);
5470 ins_cost(180);
5471 format %{ "b$cmp $op1, R0, $labl #@branchConN2P_zero" %}
5473 ins_encode %{
5474 Register op1 = $op1$$Register;
5475 Register op2 = R0;
5476 Label &L = *($labl$$label);
5477 int flag = $cmp$$cmpcode;
5479 switch(flag)
5480 {
5481 case 0x01: //equal
5482 if (&L)
5483 __ beq(op1, op2, L);
5484 else
5485 __ beq(op1, op2, (int)0);
5486 break;
5487 case 0x02: //not_equal
5488 if (&L)
5489 __ bne(op1, op2, L);
5490 else
5491 __ bne(op1, op2, (int)0);
5492 break;
5493 default:
5494 Unimplemented();
5495 }
5496 __ nop();
5497 %}
5499 ins_pc_relative(1);
5500 ins_pipe( pipe_alu_branch );
5501 %}
5504 instruct branchConP(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
5505 match(If cmp (CmpP op1 op2));
5506 // predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
5507 effect(USE labl);
5509 ins_cost(200);
5510 format %{ "b$cmp $op1, $op2, $labl #@branchConP" %}
5512 ins_encode %{
5513 Register op1 = $op1$$Register;
5514 Register op2 = $op2$$Register;
5515 Label &L = *($labl$$label);
5516 int flag = $cmp$$cmpcode;
5518 switch(flag)
5519 {
5520 case 0x01: //equal
5521 if (&L)
5522 __ beq(op1, op2, L);
5523 else
5524 __ beq(op1, op2, (int)0);
5525 break;
5526 case 0x02: //not_equal
5527 if (&L)
5528 __ bne(op1, op2, L);
5529 else
5530 __ bne(op1, op2, (int)0);
5531 break;
5532 case 0x03: //above
5533 __ sltu(AT, op2, op1);
5534 if(&L)
5535 __ bne(R0, AT, L);
5536 else
5537 __ bne(R0, AT, (int)0);
5538 break;
5539 case 0x04: //above_equal
5540 __ sltu(AT, op1, op2);
5541 if(&L)
5542 __ beq(AT, R0, L);
5543 else
5544 __ beq(AT, R0, (int)0);
5545 break;
5546 case 0x05: //below
5547 __ sltu(AT, op1, op2);
5548 if(&L)
5549 __ bne(R0, AT, L);
5550 else
5551 __ bne(R0, AT, (int)0);
5552 break;
5553 case 0x06: //below_equal
5554 __ sltu(AT, op2, op1);
5555 if(&L)
5556 __ beq(AT, R0, L);
5557 else
5558 __ beq(AT, R0, (int)0);
5559 break;
5560 default:
5561 Unimplemented();
5562 }
5563 __ nop();
5564 %}
5566 ins_pc_relative(1);
5567 ins_pipe( pipe_alu_branch );
5568 %}
5570 instruct cmpN_null_branch(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
5571 match(If cmp (CmpN op1 null));
5572 effect(USE labl);
5574 ins_cost(180);
5575 format %{ "CMP $op1,0\t! compressed ptr\n\t"
5576 "BP$cmp $labl @ cmpN_null_branch" %}
5577 ins_encode %{
5578 Register op1 = $op1$$Register;
5579 Register op2 = R0;
5580 Label &L = *($labl$$label);
5581 int flag = $cmp$$cmpcode;
5583 switch(flag)
5584 {
5585 case 0x01: //equal
5586 if (&L)
5587 __ beq(op1, op2, L);
5588 else
5589 __ beq(op1, op2, (int)0);
5590 break;
5591 case 0x02: //not_equal
5592 if (&L)
5593 __ bne(op1, op2, L);
5594 else
5595 __ bne(op1, op2, (int)0);
5596 break;
5597 default:
5598 Unimplemented();
5599 }
5600 __ nop();
5601 %}
5602 //TODO: pipe_branchP or create pipe_branchN LEE
5603 ins_pc_relative(1);
5604 ins_pipe( pipe_alu_branch );
5605 %}
5607 instruct cmpN_reg_branch(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
5608 match(If cmp (CmpN op1 op2));
5609 effect(USE labl);
5611 ins_cost(180);
5612 format %{ "CMP $op1,$op2\t! compressed ptr\n\t"
5613 "BP$cmp $labl" %}
5614 ins_encode %{
5615 Register op1_reg = $op1$$Register;
5616 Register op2_reg = $op2$$Register;
5617 Label &L = *($labl$$label);
5618 int flag = $cmp$$cmpcode;
5620 switch(flag)
5621 {
5622 case 0x01: //equal
5623 if (&L)
5624 __ beq(op1_reg, op2_reg, L);
5625 else
5626 __ beq(op1_reg, op2_reg, (int)0);
5627 break;
5628 case 0x02: //not_equal
5629 if (&L)
5630 __ bne(op1_reg, op2_reg, L);
5631 else
5632 __ bne(op1_reg, op2_reg, (int)0);
5633 break;
5634 case 0x03: //above
5635 __ sltu(AT, op2_reg, op1_reg);
5636 if(&L)
5637 __ bne(R0, AT, L);
5638 else
5639 __ bne(R0, AT, (int)0);
5640 break;
5641 case 0x04: //above_equal
5642 __ sltu(AT, op1_reg, op2_reg);
5643 if(&L)
5644 __ beq(AT, R0, L);
5645 else
5646 __ beq(AT, R0, (int)0);
5647 break;
5648 case 0x05: //below
5649 __ sltu(AT, op1_reg, op2_reg);
5650 if(&L)
5651 __ bne(R0, AT, L);
5652 else
5653 __ bne(R0, AT, (int)0);
5654 break;
5655 case 0x06: //below_equal
5656 __ sltu(AT, op2_reg, op1_reg);
5657 if(&L)
5658 __ beq(AT, R0, L);
5659 else
5660 __ beq(AT, R0, (int)0);
5661 break;
5662 default:
5663 Unimplemented();
5664 }
5665 __ nop();
5666 %}
5667 ins_pc_relative(1);
5668 ins_pipe( pipe_alu_branch );
5669 %}
5671 instruct branchConIU_reg_reg(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
5672 match( If cmp (CmpU src1 src2) );
5673 effect(USE labl);
5674 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_reg" %}
5676 ins_encode %{
5677 Register op1 = $src1$$Register;
5678 Register op2 = $src2$$Register;
5679 Label &L = *($labl$$label);
5680 int flag = $cmp$$cmpcode;
5682 switch(flag)
5683 {
5684 case 0x01: //equal
5685 if (&L)
5686 __ beq(op1, op2, L);
5687 else
5688 __ beq(op1, op2, (int)0);
5689 break;
5690 case 0x02: //not_equal
5691 if (&L)
5692 __ bne(op1, op2, L);
5693 else
5694 __ bne(op1, op2, (int)0);
5695 break;
5696 case 0x03: //above
5697 __ sltu(AT, op2, op1);
5698 if(&L)
5699 __ bne(AT, R0, L);
5700 else
5701 __ bne(AT, R0, (int)0);
5702 break;
5703 case 0x04: //above_equal
5704 __ sltu(AT, op1, op2);
5705 if(&L)
5706 __ beq(AT, R0, L);
5707 else
5708 __ beq(AT, R0, (int)0);
5709 break;
5710 case 0x05: //below
5711 __ sltu(AT, op1, op2);
5712 if(&L)
5713 __ bne(AT, R0, L);
5714 else
5715 __ bne(AT, R0, (int)0);
5716 break;
5717 case 0x06: //below_equal
5718 __ sltu(AT, op2, op1);
5719 if(&L)
5720 __ beq(AT, R0, L);
5721 else
5722 __ beq(AT, R0, (int)0);
5723 break;
5724 default:
5725 Unimplemented();
5726 }
5727 __ nop();
5728 %}
5730 ins_pc_relative(1);
5731 ins_pipe( pipe_alu_branch );
5732 %}
5735 instruct branchConIU_reg_imm(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
5736 match( If cmp (CmpU src1 src2) );
5737 effect(USE labl);
5738 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_imm" %}
5740 ins_encode %{
5741 Register op1 = $src1$$Register;
5742 int val = $src2$$constant;
5743 Label &L = *($labl$$label);
5744 int flag = $cmp$$cmpcode;
5746 __ move(AT, val);
5747 switch(flag)
5748 {
5749 case 0x01: //equal
5750 if (&L)
5751 __ beq(op1, AT, L);
5752 else
5753 __ beq(op1, AT, (int)0);
5754 break;
5755 case 0x02: //not_equal
5756 if (&L)
5757 __ bne(op1, AT, L);
5758 else
5759 __ bne(op1, AT, (int)0);
5760 break;
5761 case 0x03: //above
5762 __ sltu(AT, AT, op1);
5763 if(&L)
5764 __ bne(R0, AT, L);
5765 else
5766 __ bne(R0, AT, (int)0);
5767 break;
5768 case 0x04: //above_equal
5769 __ sltu(AT, op1, AT);
5770 if(&L)
5771 __ beq(AT, R0, L);
5772 else
5773 __ beq(AT, R0, (int)0);
5774 break;
5775 case 0x05: //below
5776 __ sltu(AT, op1, AT);
5777 if(&L)
5778 __ bne(R0, AT, L);
5779 else
5780 __ bne(R0, AT, (int)0);
5781 break;
5782 case 0x06: //below_equal
5783 __ sltu(AT, AT, op1);
5784 if(&L)
5785 __ beq(AT, R0, L);
5786 else
5787 __ beq(AT, R0, (int)0);
5788 break;
5789 default:
5790 Unimplemented();
5791 }
5792 __ nop();
5793 %}
5795 ins_pc_relative(1);
5796 ins_pipe( pipe_alu_branch );
5797 %}
5799 instruct branchConI_reg_reg(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
5800 match( If cmp (CmpI src1 src2) );
5801 effect(USE labl);
5802 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_reg" %}
5804 ins_encode %{
5805 Register op1 = $src1$$Register;
5806 Register op2 = $src2$$Register;
5807 Label &L = *($labl$$label);
5808 int flag = $cmp$$cmpcode;
5810 switch(flag)
5811 {
5812 case 0x01: //equal
5813 if (&L)
5814 __ beq(op1, op2, L);
5815 else
5816 __ beq(op1, op2, (int)0);
5817 break;
5818 case 0x02: //not_equal
5819 if (&L)
5820 __ bne(op1, op2, L);
5821 else
5822 __ bne(op1, op2, (int)0);
5823 break;
5824 case 0x03: //above
5825 __ slt(AT, op2, op1);
5826 if(&L)
5827 __ bne(R0, AT, L);
5828 else
5829 __ bne(R0, AT, (int)0);
5830 break;
5831 case 0x04: //above_equal
5832 __ slt(AT, op1, op2);
5833 if(&L)
5834 __ beq(AT, R0, L);
5835 else
5836 __ beq(AT, R0, (int)0);
5837 break;
5838 case 0x05: //below
5839 __ slt(AT, op1, op2);
5840 if(&L)
5841 __ bne(R0, AT, L);
5842 else
5843 __ bne(R0, AT, (int)0);
5844 break;
5845 case 0x06: //below_equal
5846 __ slt(AT, op2, op1);
5847 if(&L)
5848 __ beq(AT, R0, L);
5849 else
5850 __ beq(AT, R0, (int)0);
5851 break;
5852 default:
5853 Unimplemented();
5854 }
5855 __ nop();
5856 %}
5858 ins_pc_relative(1);
5859 ins_pipe( pipe_alu_branch );
5860 %}
5862 instruct branchConI_reg_imm0(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
5863 match( If cmp (CmpI src1 src2) );
5864 effect(USE labl);
5865 ins_cost(170);
5866 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm0" %}
5868 ins_encode %{
5869 Register op1 = $src1$$Register;
5870 // int val = $src2$$constant;
5871 Label &L = *($labl$$label);
5872 int flag = $cmp$$cmpcode;
5874 //__ move(AT, val);
5875 switch(flag)
5876 {
5877 case 0x01: //equal
5878 if (&L)
5879 __ beq(op1, R0, L);
5880 else
5881 __ beq(op1, R0, (int)0);
5882 break;
5883 case 0x02: //not_equal
5884 if (&L)
5885 __ bne(op1, R0, L);
5886 else
5887 __ bne(op1, R0, (int)0);
5888 break;
5889 case 0x03: //greater
5890 if(&L)
5891 __ bgtz(op1, L);
5892 else
5893 __ bgtz(op1, (int)0);
5894 break;
5895 case 0x04: //greater_equal
5896 if(&L)
5897 __ bgez(op1, L);
5898 else
5899 __ bgez(op1, (int)0);
5900 break;
5901 case 0x05: //less
5902 if(&L)
5903 __ bltz(op1, L);
5904 else
5905 __ bltz(op1, (int)0);
5906 break;
5907 case 0x06: //less_equal
5908 if(&L)
5909 __ blez(op1, L);
5910 else
5911 __ blez(op1, (int)0);
5912 break;
5913 default:
5914 Unimplemented();
5915 }
5916 __ nop();
5917 %}
5919 ins_pc_relative(1);
5920 ins_pipe( pipe_alu_branch );
5921 %}
5924 instruct branchConI_reg_imm(cmpOp cmp, mRegI src1, immI src2, label labl) %{
5925 match( If cmp (CmpI src1 src2) );
5926 effect(USE labl);
5927 ins_cost(200);
5928 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm" %}
5930 ins_encode %{
5931 Register op1 = $src1$$Register;
5932 int val = $src2$$constant;
5933 Label &L = *($labl$$label);
5934 int flag = $cmp$$cmpcode;
5936 __ move(AT, val);
5937 switch(flag)
5938 {
5939 case 0x01: //equal
5940 if (&L)
5941 __ beq(op1, AT, L);
5942 else
5943 __ beq(op1, AT, (int)0);
5944 break;
5945 case 0x02: //not_equal
5946 if (&L)
5947 __ bne(op1, AT, L);
5948 else
5949 __ bne(op1, AT, (int)0);
5950 break;
5951 case 0x03: //greater
5952 __ slt(AT, AT, op1);
5953 if(&L)
5954 __ bne(R0, AT, L);
5955 else
5956 __ bne(R0, AT, (int)0);
5957 break;
5958 case 0x04: //greater_equal
5959 __ slt(AT, op1, AT);
5960 if(&L)
5961 __ beq(AT, R0, L);
5962 else
5963 __ beq(AT, R0, (int)0);
5964 break;
5965 case 0x05: //less
5966 __ slt(AT, op1, AT);
5967 if(&L)
5968 __ bne(R0, AT, L);
5969 else
5970 __ bne(R0, AT, (int)0);
5971 break;
5972 case 0x06: //less_equal
5973 __ slt(AT, AT, op1);
5974 if(&L)
5975 __ beq(AT, R0, L);
5976 else
5977 __ beq(AT, R0, (int)0);
5978 break;
5979 default:
5980 Unimplemented();
5981 }
5982 __ nop();
5983 %}
5985 ins_pc_relative(1);
5986 ins_pipe( pipe_alu_branch );
5987 %}
5989 instruct branchConIU_reg_imm0(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
5990 match( If cmp (CmpU src1 zero) );
5991 effect(USE labl);
5992 format %{ "BR$cmp $src1, zero, $labl #@branchConIU_reg_imm0" %}
5994 ins_encode %{
5995 Register op1 = $src1$$Register;
5996 Label &L = *($labl$$label);
5997 int flag = $cmp$$cmpcode;
5999 switch(flag)
6000 {
6001 case 0x01: //equal
6002 if (&L)
6003 __ beq(op1, R0, L);
6004 else
6005 __ beq(op1, R0, (int)0);
6006 break;
6007 case 0x02: //not_equal
6008 if (&L)
6009 __ bne(op1, R0, L);
6010 else
6011 __ bne(op1, R0, (int)0);
6012 break;
6013 case 0x03: //above
6014 if(&L)
6015 __ bne(R0, op1, L);
6016 else
6017 __ bne(R0, op1, (int)0);
6018 break;
6019 case 0x04: //above_equal
6020 if(&L)
6021 __ beq(R0, R0, L);
6022 else
6023 __ beq(R0, R0, (int)0);
6024 break;
6025 case 0x05: //below
6026 return;
6027 break;
6028 case 0x06: //below_equal
6029 if(&L)
6030 __ beq(op1, R0, L);
6031 else
6032 __ beq(op1, R0, (int)0);
6033 break;
6034 default:
6035 Unimplemented();
6036 }
6037 __ nop();
6038 %}
6040 ins_pc_relative(1);
6041 ins_pipe( pipe_alu_branch );
6042 %}
6045 instruct branchConIU_reg_immI16(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
6046 match( If cmp (CmpU src1 src2) );
6047 effect(USE labl);
6048 ins_cost(180);
6049 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_immI16" %}
6051 ins_encode %{
6052 Register op1 = $src1$$Register;
6053 int val = $src2$$constant;
6054 Label &L = *($labl$$label);
6055 int flag = $cmp$$cmpcode;
6057 switch(flag)
6058 {
6059 case 0x01: //equal
6060 __ move(AT, val);
6061 if (&L)
6062 __ beq(op1, AT, L);
6063 else
6064 __ beq(op1, AT, (int)0);
6065 break;
6066 case 0x02: //not_equal
6067 __ move(AT, val);
6068 if (&L)
6069 __ bne(op1, AT, L);
6070 else
6071 __ bne(op1, AT, (int)0);
6072 break;
6073 case 0x03: //above
6074 __ move(AT, val);
6075 __ sltu(AT, AT, op1);
6076 if(&L)
6077 __ bne(R0, AT, L);
6078 else
6079 __ bne(R0, AT, (int)0);
6080 break;
6081 case 0x04: //above_equal
6082 __ sltiu(AT, op1, val);
6083 if(&L)
6084 __ beq(AT, R0, L);
6085 else
6086 __ beq(AT, R0, (int)0);
6087 break;
6088 case 0x05: //below
6089 __ sltiu(AT, op1, val);
6090 if(&L)
6091 __ bne(R0, AT, L);
6092 else
6093 __ bne(R0, AT, (int)0);
6094 break;
6095 case 0x06: //below_equal
6096 __ move(AT, val);
6097 __ sltu(AT, AT, op1);
6098 if(&L)
6099 __ beq(AT, R0, L);
6100 else
6101 __ beq(AT, R0, (int)0);
6102 break;
6103 default:
6104 Unimplemented();
6105 }
6106 __ nop();
6107 %}
6109 ins_pc_relative(1);
6110 ins_pipe( pipe_alu_branch );
6111 %}
6114 instruct branchConL_regL_regL(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
6115 match( If cmp (CmpL src1 src2) );
6116 effect(USE labl);
6117 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_regL" %}
6118 ins_cost(250);
6120 ins_encode %{
6121 Register opr1_reg = as_Register($src1$$reg);
6122 Register opr2_reg = as_Register($src2$$reg);
6124 Label &target = *($labl$$label);
6125 int flag = $cmp$$cmpcode;
6127 switch(flag)
6128 {
6129 case 0x01: //equal
6130 if (&target)
6131 __ beq(opr1_reg, opr2_reg, target);
6132 else
6133 __ beq(opr1_reg, opr2_reg, (int)0);
6134 __ delayed()->nop();
6135 break;
6137 case 0x02: //not_equal
6138 if(&target)
6139 __ bne(opr1_reg, opr2_reg, target);
6140 else
6141 __ bne(opr1_reg, opr2_reg, (int)0);
6142 __ delayed()->nop();
6143 break;
6145 case 0x03: //greater
6146 __ slt(AT, opr2_reg, opr1_reg);
6147 if(&target)
6148 __ bne(AT, R0, target);
6149 else
6150 __ bne(AT, R0, (int)0);
6151 __ delayed()->nop();
6152 break;
6154 case 0x04: //greater_equal
6155 __ slt(AT, opr1_reg, opr2_reg);
6156 if(&target)
6157 __ beq(AT, R0, target);
6158 else
6159 __ beq(AT, R0, (int)0);
6160 __ delayed()->nop();
6162 break;
6164 case 0x05: //less
6165 __ slt(AT, opr1_reg, opr2_reg);
6166 if(&target)
6167 __ bne(AT, R0, target);
6168 else
6169 __ bne(AT, R0, (int)0);
6170 __ delayed()->nop();
6172 break;
6174 case 0x06: //less_equal
6175 __ slt(AT, opr2_reg, opr1_reg);
6177 if(&target)
6178 __ beq(AT, R0, target);
6179 else
6180 __ beq(AT, R0, (int)0);
6181 __ delayed()->nop();
6183 break;
6185 default:
6186 Unimplemented();
6187 }
6188 %}
6191 ins_pc_relative(1);
6192 ins_pipe( pipe_alu_branch );
6193 %}
6195 instruct branchConL_reg_immL16_sub(cmpOp cmp, mRegL src1, immL16_sub src2, label labl) %{
6196 match( If cmp (CmpL src1 src2) );
6197 effect(USE labl);
6198 ins_cost(180);
6199 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_reg_immL16_sub" %}
6201 ins_encode %{
6202 Register op1 = $src1$$Register;
6203 int val = $src2$$constant;
6204 Label &L = *($labl$$label);
6205 int flag = $cmp$$cmpcode;
6207 __ daddiu(AT, op1, -1 * val);
6208 switch(flag)
6209 {
6210 case 0x01: //equal
6211 if (&L)
6212 __ beq(R0, AT, L);
6213 else
6214 __ beq(R0, AT, (int)0);
6215 break;
6216 case 0x02: //not_equal
6217 if (&L)
6218 __ bne(R0, AT, L);
6219 else
6220 __ bne(R0, AT, (int)0);
6221 break;
6222 case 0x03: //greater
6223 if(&L)
6224 __ bgtz(AT, L);
6225 else
6226 __ bgtz(AT, (int)0);
6227 break;
6228 case 0x04: //greater_equal
6229 if(&L)
6230 __ bgez(AT, L);
6231 else
6232 __ bgez(AT, (int)0);
6233 break;
6234 case 0x05: //less
6235 if(&L)
6236 __ bltz(AT, L);
6237 else
6238 __ bltz(AT, (int)0);
6239 break;
6240 case 0x06: //less_equal
6241 if(&L)
6242 __ blez(AT, L);
6243 else
6244 __ blez(AT, (int)0);
6245 break;
6246 default:
6247 Unimplemented();
6248 }
6249 __ nop();
6250 %}
6252 ins_pc_relative(1);
6253 ins_pipe( pipe_alu_branch );
6254 %}
6257 instruct branchConI_reg_imm16_sub(cmpOp cmp, mRegI src1, immI16_sub src2, label labl) %{
6258 match( If cmp (CmpI src1 src2) );
6259 effect(USE labl);
6260 ins_cost(180);
6261 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm16_sub" %}
6263 ins_encode %{
6264 Register op1 = $src1$$Register;
6265 int val = $src2$$constant;
6266 Label &L = *($labl$$label);
6267 int flag = $cmp$$cmpcode;
6269 __ addiu32(AT, op1, -1 * val);
6270 switch(flag)
6271 {
6272 case 0x01: //equal
6273 if (&L)
6274 __ beq(R0, AT, L);
6275 else
6276 __ beq(R0, AT, (int)0);
6277 break;
6278 case 0x02: //not_equal
6279 if (&L)
6280 __ bne(R0, AT, L);
6281 else
6282 __ bne(R0, AT, (int)0);
6283 break;
6284 case 0x03: //greater
6285 if(&L)
6286 __ bgtz(AT, L);
6287 else
6288 __ bgtz(AT, (int)0);
6289 break;
6290 case 0x04: //greater_equal
6291 if(&L)
6292 __ bgez(AT, L);
6293 else
6294 __ bgez(AT, (int)0);
6295 break;
6296 case 0x05: //less
6297 if(&L)
6298 __ bltz(AT, L);
6299 else
6300 __ bltz(AT, (int)0);
6301 break;
6302 case 0x06: //less_equal
6303 if(&L)
6304 __ blez(AT, L);
6305 else
6306 __ blez(AT, (int)0);
6307 break;
6308 default:
6309 Unimplemented();
6310 }
6311 __ nop();
6312 %}
6314 ins_pc_relative(1);
6315 ins_pipe( pipe_alu_branch );
6316 %}
6318 instruct branchConL_regL_immL0(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
6319 match( If cmp (CmpL src1 zero) );
6320 effect(USE labl);
6321 format %{ "BR$cmp $src1, zero, $labl #@branchConL_regL_immL0" %}
6322 ins_cost(150);
6324 ins_encode %{
6325 Register opr1_reg = as_Register($src1$$reg);
6326 Label &target = *($labl$$label);
6327 int flag = $cmp$$cmpcode;
6329 switch(flag)
6330 {
6331 case 0x01: //equal
6332 if (&target)
6333 __ beq(opr1_reg, R0, target);
6334 else
6335 __ beq(opr1_reg, R0, int(0));
6336 break;
6338 case 0x02: //not_equal
6339 if(&target)
6340 __ bne(opr1_reg, R0, target);
6341 else
6342 __ bne(opr1_reg, R0, (int)0);
6343 break;
6345 case 0x03: //greater
6346 if(&target)
6347 __ bgtz(opr1_reg, target);
6348 else
6349 __ bgtz(opr1_reg, (int)0);
6350 break;
6352 case 0x04: //greater_equal
6353 if(&target)
6354 __ bgez(opr1_reg, target);
6355 else
6356 __ bgez(opr1_reg, (int)0);
6357 break;
6359 case 0x05: //less
6360 __ slt(AT, opr1_reg, R0);
6361 if(&target)
6362 __ bne(AT, R0, target);
6363 else
6364 __ bne(AT, R0, (int)0);
6365 break;
6367 case 0x06: //less_equal
6368 if (&target)
6369 __ blez(opr1_reg, target);
6370 else
6371 __ blez(opr1_reg, int(0));
6372 break;
6374 default:
6375 Unimplemented();
6376 }
6377 __ delayed()->nop();
6378 %}
6381 ins_pc_relative(1);
6382 ins_pipe( pipe_alu_branch );
6383 %}
6386 //FIXME
6387 instruct branchConF_reg_reg(cmpOp cmp, regF src1, regF src2, label labl) %{
6388 match( If cmp (CmpF src1 src2) );
6389 effect(USE labl);
6390 format %{ "BR$cmp $src1, $src2, $labl #@branchConF_reg_reg" %}
6392 ins_encode %{
6393 FloatRegister reg_op1 = $src1$$FloatRegister;
6394 FloatRegister reg_op2 = $src2$$FloatRegister;
6395 Label &L = *($labl$$label);
6396 int flag = $cmp$$cmpcode;
6398 switch(flag)
6399 {
6400 case 0x01: //equal
6401 __ c_eq_s(reg_op1, reg_op2);
6402 if (&L)
6403 __ bc1t(L);
6404 else
6405 __ bc1t((int)0);
6406 break;
6407 case 0x02: //not_equal
6408 __ c_eq_s(reg_op1, reg_op2);
6409 if (&L)
6410 __ bc1f(L);
6411 else
6412 __ bc1f((int)0);
6413 break;
6414 case 0x03: //greater
6415 __ c_ule_s(reg_op1, reg_op2);
6416 if(&L)
6417 __ bc1f(L);
6418 else
6419 __ bc1f((int)0);
6420 break;
6421 case 0x04: //greater_equal
6422 __ c_ult_s(reg_op1, reg_op2);
6423 if(&L)
6424 __ bc1f(L);
6425 else
6426 __ bc1f((int)0);
6427 break;
6428 case 0x05: //less
6429 __ c_ult_s(reg_op1, reg_op2);
6430 if(&L)
6431 __ bc1t(L);
6432 else
6433 __ bc1t((int)0);
6434 break;
6435 case 0x06: //less_equal
6436 __ c_ule_s(reg_op1, reg_op2);
6437 if(&L)
6438 __ bc1t(L);
6439 else
6440 __ bc1t((int)0);
6441 break;
6442 default:
6443 Unimplemented();
6444 }
6445 __ nop();
6446 %}
6448 ins_pc_relative(1);
6449 ins_pipe(pipe_slow);
6450 %}
6452 instruct branchConD_reg_reg(cmpOp cmp, regD src1, regD src2, label labl) %{
6453 match( If cmp (CmpD src1 src2) );
6454 effect(USE labl);
6455 format %{ "BR$cmp $src1, $src2, $labl #@branchConD_reg_reg" %}
6457 ins_encode %{
6458 FloatRegister reg_op1 = $src1$$FloatRegister;
6459 FloatRegister reg_op2 = $src2$$FloatRegister;
6460 Label &L = *($labl$$label);
6461 int flag = $cmp$$cmpcode;
6463 switch(flag)
6464 {
6465 case 0x01: //equal
6466 __ c_eq_d(reg_op1, reg_op2);
6467 if (&L)
6468 __ bc1t(L);
6469 else
6470 __ bc1t((int)0);
6471 break;
6472 case 0x02: //not_equal
6473 //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.
6474 __ c_eq_d(reg_op1, reg_op2);
6475 if (&L)
6476 __ bc1f(L);
6477 else
6478 __ bc1f((int)0);
6479 break;
6480 case 0x03: //greater
6481 __ c_ule_d(reg_op1, reg_op2);
6482 if(&L)
6483 __ bc1f(L);
6484 else
6485 __ bc1f((int)0);
6486 break;
6487 case 0x04: //greater_equal
6488 __ c_ult_d(reg_op1, reg_op2);
6489 if(&L)
6490 __ bc1f(L);
6491 else
6492 __ bc1f((int)0);
6493 break;
6494 case 0x05: //less
6495 __ c_ult_d(reg_op1, reg_op2);
6496 if(&L)
6497 __ bc1t(L);
6498 else
6499 __ bc1t((int)0);
6500 break;
6501 case 0x06: //less_equal
6502 __ c_ule_d(reg_op1, reg_op2);
6503 if(&L)
6504 __ bc1t(L);
6505 else
6506 __ bc1t((int)0);
6507 break;
6508 default:
6509 Unimplemented();
6510 }
6511 __ nop();
6512 %}
6514 ins_pc_relative(1);
6515 ins_pipe(pipe_slow);
6516 %}
6519 // Call Runtime Instruction
6520 instruct CallRuntimeDirect(method meth) %{
6521 match(CallRuntime );
6522 effect(USE meth);
6524 ins_cost(300);
6525 format %{ "CALL,runtime #@CallRuntimeDirect" %}
6526 ins_encode( Java_To_Runtime( meth ) );
6527 ins_pipe( pipe_slow );
6528 ins_alignment(16);
6529 %}
6533 //------------------------MemBar Instructions-------------------------------
6534 //Memory barrier flavors
6536 instruct membar_acquire() %{
6537 match(MemBarAcquire);
6538 ins_cost(0);
6540 size(0);
6541 format %{ "MEMBAR-acquire (empty) @ membar_acquire" %}
6542 ins_encode();
6543 ins_pipe(empty);
6544 %}
6546 instruct load_fence() %{
6547 match(LoadFence);
6548 ins_cost(400);
6550 format %{ "MEMBAR @ load_fence" %}
6551 ins_encode %{
6552 __ sync();
6553 %}
6554 ins_pipe(pipe_slow);
6555 %}
6557 instruct membar_acquire_lock()
6558 %{
6559 match(MemBarAcquireLock);
6560 ins_cost(0);
6562 size(0);
6563 format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
6564 ins_encode();
6565 ins_pipe(empty);
6566 %}
6568 instruct membar_release() %{
6569 match(MemBarRelease);
6570 ins_cost(0);
6572 size(0);
6573 format %{ "MEMBAR-release (empty) @ membar_release" %}
6574 ins_encode();
6575 ins_pipe(empty);
6576 %}
6578 instruct store_fence() %{
6579 match(StoreFence);
6580 ins_cost(400);
6582 format %{ "MEMBAR @ store_fence" %}
6584 ins_encode %{
6585 __ sync();
6586 %}
6588 ins_pipe(pipe_slow);
6589 %}
6591 instruct membar_release_lock()
6592 %{
6593 match(MemBarReleaseLock);
6594 ins_cost(0);
6596 size(0);
6597 format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
6598 ins_encode();
6599 ins_pipe(empty);
6600 %}
6603 instruct membar_volatile() %{
6604 match(MemBarVolatile);
6605 ins_cost(400);
6607 format %{ "MEMBAR-volatile" %}
6608 ins_encode %{
6609 if( !os::is_MP() ) return; // Not needed on single CPU
6610 __ sync();
6612 %}
6613 ins_pipe(pipe_slow);
6614 %}
6616 instruct unnecessary_membar_volatile() %{
6617 match(MemBarVolatile);
6618 predicate(Matcher::post_store_load_barrier(n));
6619 ins_cost(0);
6621 size(0);
6622 format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
6623 ins_encode( );
6624 ins_pipe(empty);
6625 %}
6627 instruct membar_storestore() %{
6628 match(MemBarStoreStore);
6630 ins_cost(0);
6631 size(0);
6632 format %{ "MEMBAR-storestore (empty encoding) @ membar_storestore" %}
6633 ins_encode( );
6634 ins_pipe(empty);
6635 %}
6637 //----------Move Instructions--------------------------------------------------
6638 instruct castX2P(mRegP dst, mRegL src) %{
6639 match(Set dst (CastX2P src));
6640 format %{ "castX2P $dst, $src @ castX2P" %}
6641 ins_encode %{
6642 Register src = $src$$Register;
6643 Register dst = $dst$$Register;
6645 if(src != dst)
6646 __ move(dst, src);
6647 %}
6648 ins_cost(10);
6649 ins_pipe( ialu_regI_mov );
6650 %}
6652 instruct castP2X(mRegL dst, mRegP src ) %{
6653 match(Set dst (CastP2X src));
6655 format %{ "mov $dst, $src\t #@castP2X" %}
6656 ins_encode %{
6657 Register src = $src$$Register;
6658 Register dst = $dst$$Register;
6660 if(src != dst)
6661 __ move(dst, src);
6662 %}
6663 ins_pipe( ialu_regI_mov );
6664 %}
6666 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
6667 match(Set dst (MoveF2I src));
6668 effect(DEF dst, USE src);
6669 ins_cost(85);
6670 format %{ "MoveF2I $dst, $src @ MoveF2I_reg_reg" %}
6671 ins_encode %{
6672 Register dst = as_Register($dst$$reg);
6673 FloatRegister src = as_FloatRegister($src$$reg);
6675 __ mfc1(dst, src);
6676 %}
6677 ins_pipe( pipe_slow );
6678 %}
6680 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
6681 match(Set dst (MoveI2F src));
6682 effect(DEF dst, USE src);
6683 ins_cost(85);
6684 format %{ "MoveI2F $dst, $src @ MoveI2F_reg_reg" %}
6685 ins_encode %{
6686 Register src = as_Register($src$$reg);
6687 FloatRegister dst = as_FloatRegister($dst$$reg);
6689 __ mtc1(src, dst);
6690 %}
6691 ins_pipe( pipe_slow );
6692 %}
6694 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
6695 match(Set dst (MoveD2L src));
6696 effect(DEF dst, USE src);
6697 ins_cost(85);
6698 format %{ "MoveD2L $dst, $src @ MoveD2L_reg_reg" %}
6699 ins_encode %{
6700 Register dst = as_Register($dst$$reg);
6701 FloatRegister src = as_FloatRegister($src$$reg);
6703 __ dmfc1(dst, src);
6704 %}
6705 ins_pipe( pipe_slow );
6706 %}
6708 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
6709 match(Set dst (MoveL2D src));
6710 effect(DEF dst, USE src);
6711 ins_cost(85);
6712 format %{ "MoveL2D $dst, $src @ MoveL2D_reg_reg" %}
6713 ins_encode %{
6714 FloatRegister dst = as_FloatRegister($dst$$reg);
6715 Register src = as_Register($src$$reg);
6717 __ dmtc1(src, dst);
6718 %}
6719 ins_pipe( pipe_slow );
6720 %}
6722 //----------Conditional Move---------------------------------------------------
6723 // Conditional move
6724 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
6725 match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
6726 ins_cost(80);
6727 format %{
6728 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpI_reg_reg\n"
6729 "\tCMOV $dst,$src \t @cmovI_cmpI_reg_reg"
6730 %}
6732 ins_encode %{
6733 Register op1 = $tmp1$$Register;
6734 Register op2 = $tmp2$$Register;
6735 Register dst = $dst$$Register;
6736 Register src = $src$$Register;
6737 int flag = $cop$$cmpcode;
6739 switch(flag)
6740 {
6741 case 0x01: //equal
6742 __ subu32(AT, op1, op2);
6743 __ movz(dst, src, AT);
6744 break;
6746 case 0x02: //not_equal
6747 __ subu32(AT, op1, op2);
6748 __ movn(dst, src, AT);
6749 break;
6751 case 0x03: //great
6752 __ slt(AT, op2, op1);
6753 __ movn(dst, src, AT);
6754 break;
6756 case 0x04: //great_equal
6757 __ slt(AT, op1, op2);
6758 __ movz(dst, src, AT);
6759 break;
6761 case 0x05: //less
6762 __ slt(AT, op1, op2);
6763 __ movn(dst, src, AT);
6764 break;
6766 case 0x06: //less_equal
6767 __ slt(AT, op2, op1);
6768 __ movz(dst, src, AT);
6769 break;
6771 default:
6772 Unimplemented();
6773 }
6774 %}
6776 ins_pipe( pipe_slow );
6777 %}
6779 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
6780 match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
6781 ins_cost(80);
6782 format %{
6783 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
6784 "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
6785 %}
6786 ins_encode %{
6787 Register op1 = $tmp1$$Register;
6788 Register op2 = $tmp2$$Register;
6789 Register dst = $dst$$Register;
6790 Register src = $src$$Register;
6791 int flag = $cop$$cmpcode;
6793 switch(flag)
6794 {
6795 case 0x01: //equal
6796 __ subu(AT, op1, op2);
6797 __ movz(dst, src, AT);
6798 break;
6800 case 0x02: //not_equal
6801 __ subu(AT, op1, op2);
6802 __ movn(dst, src, AT);
6803 break;
6805 case 0x03: //above
6806 __ sltu(AT, op2, op1);
6807 __ movn(dst, src, AT);
6808 break;
6810 case 0x04: //above_equal
6811 __ sltu(AT, op1, op2);
6812 __ movz(dst, src, AT);
6813 break;
6815 case 0x05: //below
6816 __ sltu(AT, op1, op2);
6817 __ movn(dst, src, AT);
6818 break;
6820 case 0x06: //below_equal
6821 __ sltu(AT, op2, op1);
6822 __ movz(dst, src, AT);
6823 break;
6825 default:
6826 Unimplemented();
6827 }
6828 %}
6830 ins_pipe( pipe_slow );
6831 %}
6833 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
6834 match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
6835 ins_cost(80);
6836 format %{
6837 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
6838 "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
6839 %}
6840 ins_encode %{
6841 Register op1 = $tmp1$$Register;
6842 Register op2 = $tmp2$$Register;
6843 Register dst = $dst$$Register;
6844 Register src = $src$$Register;
6845 int flag = $cop$$cmpcode;
6847 switch(flag)
6848 {
6849 case 0x01: //equal
6850 __ subu32(AT, op1, op2);
6851 __ movz(dst, src, AT);
6852 break;
6854 case 0x02: //not_equal
6855 __ subu32(AT, op1, op2);
6856 __ movn(dst, src, AT);
6857 break;
6859 case 0x03: //above
6860 __ sltu(AT, op2, op1);
6861 __ movn(dst, src, AT);
6862 break;
6864 case 0x04: //above_equal
6865 __ sltu(AT, op1, op2);
6866 __ movz(dst, src, AT);
6867 break;
6869 case 0x05: //below
6870 __ sltu(AT, op1, op2);
6871 __ movn(dst, src, AT);
6872 break;
6874 case 0x06: //below_equal
6875 __ sltu(AT, op2, op1);
6876 __ movz(dst, src, AT);
6877 break;
6879 default:
6880 Unimplemented();
6881 }
6882 %}
6884 ins_pipe( pipe_slow );
6885 %}
6887 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
6888 match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
6889 ins_cost(80);
6890 format %{
6891 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
6892 "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
6893 %}
6894 ins_encode %{
6895 Register op1 = $tmp1$$Register;
6896 Register op2 = $tmp2$$Register;
6897 Register dst = $dst$$Register;
6898 Register src = $src$$Register;
6899 int flag = $cop$$cmpcode;
6901 switch(flag)
6902 {
6903 case 0x01: //equal
6904 __ subu32(AT, op1, op2);
6905 __ movz(dst, src, AT);
6906 break;
6908 case 0x02: //not_equal
6909 __ subu32(AT, op1, op2);
6910 __ movn(dst, src, AT);
6911 break;
6913 case 0x03: //above
6914 __ sltu(AT, op2, op1);
6915 __ movn(dst, src, AT);
6916 break;
6918 case 0x04: //above_equal
6919 __ sltu(AT, op1, op2);
6920 __ movz(dst, src, AT);
6921 break;
6923 case 0x05: //below
6924 __ sltu(AT, op1, op2);
6925 __ movn(dst, src, AT);
6926 break;
6928 case 0x06: //below_equal
6929 __ sltu(AT, op2, op1);
6930 __ movz(dst, src, AT);
6931 break;
6933 default:
6934 Unimplemented();
6935 }
6936 %}
6938 ins_pipe( pipe_slow );
6939 %}
6941 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
6942 match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
6943 ins_cost(80);
6944 format %{
6945 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
6946 "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
6947 %}
6948 ins_encode %{
6949 Register op1 = $tmp1$$Register;
6950 Register op2 = $tmp2$$Register;
6951 Register dst = $dst$$Register;
6952 Register src = $src$$Register;
6953 int flag = $cop$$cmpcode;
6955 switch(flag)
6956 {
6957 case 0x01: //equal
6958 __ subu(AT, op1, op2);
6959 __ movz(dst, src, AT);
6960 break;
6962 case 0x02: //not_equal
6963 __ subu(AT, op1, op2);
6964 __ movn(dst, src, AT);
6965 break;
6967 case 0x03: //above
6968 __ sltu(AT, op2, op1);
6969 __ movn(dst, src, AT);
6970 break;
6972 case 0x04: //above_equal
6973 __ sltu(AT, op1, op2);
6974 __ movz(dst, src, AT);
6975 break;
6977 case 0x05: //below
6978 __ sltu(AT, op1, op2);
6979 __ movn(dst, src, AT);
6980 break;
6982 case 0x06: //below_equal
6983 __ sltu(AT, op2, op1);
6984 __ movz(dst, src, AT);
6985 break;
6987 default:
6988 Unimplemented();
6989 }
6990 %}
6992 ins_pipe( pipe_slow );
6993 %}
6995 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
6996 match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
6997 ins_cost(80);
6998 format %{
6999 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpD_reg_reg\n"
7000 "\tCMOV $dst,$src \t @cmovP_cmpD_reg_reg"
7001 %}
7002 ins_encode %{
7003 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
7004 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
7005 Register dst = as_Register($dst$$reg);
7006 Register src = as_Register($src$$reg);
7008 int flag = $cop$$cmpcode;
7010 switch(flag)
7011 {
7012 case 0x01: //equal
7013 __ c_eq_d(reg_op1, reg_op2);
7014 __ movt(dst, src);
7015 break;
7016 case 0x02: //not_equal
7017 __ c_eq_d(reg_op1, reg_op2);
7018 __ movf(dst, src);
7019 break;
7020 case 0x03: //greater
7021 __ c_ole_d(reg_op1, reg_op2);
7022 __ movf(dst, src);
7023 break;
7024 case 0x04: //greater_equal
7025 __ c_olt_d(reg_op1, reg_op2);
7026 __ movf(dst, src);
7027 break;
7028 case 0x05: //less
7029 __ c_ult_d(reg_op1, reg_op2);
7030 __ movt(dst, src);
7031 break;
7032 case 0x06: //less_equal
7033 __ c_ule_d(reg_op1, reg_op2);
7034 __ movt(dst, src);
7035 break;
7036 default:
7037 Unimplemented();
7038 }
7039 %}
7041 ins_pipe( pipe_slow );
7042 %}
7045 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
7046 match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
7047 ins_cost(80);
7048 format %{
7049 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
7050 "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
7051 %}
7052 ins_encode %{
7053 Register op1 = $tmp1$$Register;
7054 Register op2 = $tmp2$$Register;
7055 Register dst = $dst$$Register;
7056 Register src = $src$$Register;
7057 int flag = $cop$$cmpcode;
7059 switch(flag)
7060 {
7061 case 0x01: //equal
7062 __ subu32(AT, op1, op2);
7063 __ movz(dst, src, AT);
7064 break;
7066 case 0x02: //not_equal
7067 __ subu32(AT, op1, op2);
7068 __ movn(dst, src, AT);
7069 break;
7071 case 0x03: //above
7072 __ sltu(AT, op2, op1);
7073 __ movn(dst, src, AT);
7074 break;
7076 case 0x04: //above_equal
7077 __ sltu(AT, op1, op2);
7078 __ movz(dst, src, AT);
7079 break;
7081 case 0x05: //below
7082 __ sltu(AT, op1, op2);
7083 __ movn(dst, src, AT);
7084 break;
7086 case 0x06: //below_equal
7087 __ sltu(AT, op2, op1);
7088 __ movz(dst, src, AT);
7089 break;
7091 default:
7092 Unimplemented();
7093 }
7094 %}
7096 ins_pipe( pipe_slow );
7097 %}
7100 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
7101 match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
7102 ins_cost(80);
7103 format %{
7104 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
7105 "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
7106 %}
7107 ins_encode %{
7108 Register op1 = $tmp1$$Register;
7109 Register op2 = $tmp2$$Register;
7110 Register dst = $dst$$Register;
7111 Register src = $src$$Register;
7112 int flag = $cop$$cmpcode;
7114 switch(flag)
7115 {
7116 case 0x01: //equal
7117 __ subu(AT, op1, op2);
7118 __ movz(dst, src, AT);
7119 break;
7121 case 0x02: //not_equal
7122 __ subu(AT, op1, op2);
7123 __ movn(dst, src, AT);
7124 break;
7126 case 0x03: //above
7127 __ sltu(AT, op2, op1);
7128 __ movn(dst, src, AT);
7129 break;
7131 case 0x04: //above_equal
7132 __ sltu(AT, op1, op2);
7133 __ movz(dst, src, AT);
7134 break;
7136 case 0x05: //below
7137 __ sltu(AT, op1, op2);
7138 __ movn(dst, src, AT);
7139 break;
7141 case 0x06: //below_equal
7142 __ sltu(AT, op2, op1);
7143 __ movz(dst, src, AT);
7144 break;
7146 default:
7147 Unimplemented();
7148 }
7149 %}
7151 ins_pipe( pipe_slow );
7152 %}
7154 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
7155 match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
7156 ins_cost(80);
7157 format %{
7158 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpL_reg_reg\n"
7159 "\tCMOV $dst,$src \t @cmovI_cmpL_reg_reg"
7160 %}
7161 ins_encode %{
7162 Register opr1 = as_Register($tmp1$$reg);
7163 Register opr2 = as_Register($tmp2$$reg);
7164 Register dst = $dst$$Register;
7165 Register src = $src$$Register;
7166 int flag = $cop$$cmpcode;
7168 switch(flag)
7169 {
7170 case 0x01: //equal
7171 __ subu(AT, opr1, opr2);
7172 __ movz(dst, src, AT);
7173 break;
7175 case 0x02: //not_equal
7176 __ subu(AT, opr1, opr2);
7177 __ movn(dst, src, AT);
7178 break;
7180 case 0x03: //greater
7181 __ slt(AT, opr2, opr1);
7182 __ movn(dst, src, AT);
7183 break;
7185 case 0x04: //greater_equal
7186 __ slt(AT, opr1, opr2);
7187 __ movz(dst, src, AT);
7188 break;
7190 case 0x05: //less
7191 __ slt(AT, opr1, opr2);
7192 __ movn(dst, src, AT);
7193 break;
7195 case 0x06: //less_equal
7196 __ slt(AT, opr2, opr1);
7197 __ movz(dst, src, AT);
7198 break;
7200 default:
7201 Unimplemented();
7202 }
7203 %}
7205 ins_pipe( pipe_slow );
7206 %}
7208 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
7209 match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
7210 ins_cost(80);
7211 format %{
7212 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpL_reg_reg\n"
7213 "\tCMOV $dst,$src \t @cmovP_cmpL_reg_reg"
7214 %}
7215 ins_encode %{
7216 Register opr1 = as_Register($tmp1$$reg);
7217 Register opr2 = as_Register($tmp2$$reg);
7218 Register dst = $dst$$Register;
7219 Register src = $src$$Register;
7220 int flag = $cop$$cmpcode;
7222 switch(flag)
7223 {
7224 case 0x01: //equal
7225 __ subu(AT, opr1, opr2);
7226 __ movz(dst, src, AT);
7227 break;
7229 case 0x02: //not_equal
7230 __ subu(AT, opr1, opr2);
7231 __ movn(dst, src, AT);
7232 break;
7234 case 0x03: //greater
7235 __ slt(AT, opr2, opr1);
7236 __ movn(dst, src, AT);
7237 break;
7239 case 0x04: //greater_equal
7240 __ slt(AT, opr1, opr2);
7241 __ movz(dst, src, AT);
7242 break;
7244 case 0x05: //less
7245 __ slt(AT, opr1, opr2);
7246 __ movn(dst, src, AT);
7247 break;
7249 case 0x06: //less_equal
7250 __ slt(AT, opr2, opr1);
7251 __ movz(dst, src, AT);
7252 break;
7254 default:
7255 Unimplemented();
7256 }
7257 %}
7259 ins_pipe( pipe_slow );
7260 %}
7262 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
7263 match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
7264 ins_cost(80);
7265 format %{
7266 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpD_reg_reg\n"
7267 "\tCMOV $dst,$src \t @cmovI_cmpD_reg_reg"
7268 %}
7269 ins_encode %{
7270 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
7271 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
7272 Register dst = as_Register($dst$$reg);
7273 Register src = as_Register($src$$reg);
7275 int flag = $cop$$cmpcode;
7277 switch(flag)
7278 {
7279 case 0x01: //equal
7280 __ c_eq_d(reg_op1, reg_op2);
7281 __ movt(dst, src);
7282 break;
7283 case 0x02: //not_equal
7284 //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.
7285 __ c_eq_d(reg_op1, reg_op2);
7286 __ movf(dst, src);
7287 break;
7288 case 0x03: //greater
7289 __ c_ole_d(reg_op1, reg_op2);
7290 __ movf(dst, src);
7291 break;
7292 case 0x04: //greater_equal
7293 __ c_olt_d(reg_op1, reg_op2);
7294 __ movf(dst, src);
7295 break;
7296 case 0x05: //less
7297 __ c_ult_d(reg_op1, reg_op2);
7298 __ movt(dst, src);
7299 break;
7300 case 0x06: //less_equal
7301 __ c_ule_d(reg_op1, reg_op2);
7302 __ movt(dst, src);
7303 break;
7304 default:
7305 Unimplemented();
7306 }
7307 %}
7309 ins_pipe( pipe_slow );
7310 %}
7313 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
7314 match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
7315 ins_cost(80);
7316 format %{
7317 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
7318 "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
7319 %}
7320 ins_encode %{
7321 Register op1 = $tmp1$$Register;
7322 Register op2 = $tmp2$$Register;
7323 Register dst = $dst$$Register;
7324 Register src = $src$$Register;
7325 int flag = $cop$$cmpcode;
7327 switch(flag)
7328 {
7329 case 0x01: //equal
7330 __ subu(AT, op1, op2);
7331 __ movz(dst, src, AT);
7332 break;
7334 case 0x02: //not_equal
7335 __ subu(AT, op1, op2);
7336 __ movn(dst, src, AT);
7337 break;
7339 case 0x03: //above
7340 __ sltu(AT, op2, op1);
7341 __ movn(dst, src, AT);
7342 break;
7344 case 0x04: //above_equal
7345 __ sltu(AT, op1, op2);
7346 __ movz(dst, src, AT);
7347 break;
7349 case 0x05: //below
7350 __ sltu(AT, op1, op2);
7351 __ movn(dst, src, AT);
7352 break;
7354 case 0x06: //below_equal
7355 __ sltu(AT, op2, op1);
7356 __ movz(dst, src, AT);
7357 break;
7359 default:
7360 Unimplemented();
7361 }
7362 %}
7364 ins_pipe( pipe_slow );
7365 %}
7367 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7368 match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7369 ins_cost(80);
7370 format %{
7371 "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
7372 "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
7373 %}
7374 ins_encode %{
7375 Register op1 = $tmp1$$Register;
7376 Register op2 = $tmp2$$Register;
7377 Register dst = $dst$$Register;
7378 Register src = $src$$Register;
7379 int flag = $cop$$cmpcode;
7381 switch(flag)
7382 {
7383 case 0x01: //equal
7384 __ subu32(AT, op1, op2);
7385 __ movz(dst, src, AT);
7386 break;
7388 case 0x02: //not_equal
7389 __ subu32(AT, op1, op2);
7390 __ movn(dst, src, AT);
7391 break;
7393 case 0x03: //above
7394 __ slt(AT, op2, op1);
7395 __ movn(dst, src, AT);
7396 break;
7398 case 0x04: //above_equal
7399 __ slt(AT, op1, op2);
7400 __ movz(dst, src, AT);
7401 break;
7403 case 0x05: //below
7404 __ slt(AT, op1, op2);
7405 __ movn(dst, src, AT);
7406 break;
7408 case 0x06: //below_equal
7409 __ slt(AT, op2, op1);
7410 __ movz(dst, src, AT);
7411 break;
7413 default:
7414 Unimplemented();
7415 }
7416 %}
7418 ins_pipe( pipe_slow );
7419 %}
7421 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7422 match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7423 ins_cost(80);
7424 format %{
7425 "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
7426 "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
7427 %}
7428 ins_encode %{
7429 Register op1 = $tmp1$$Register;
7430 Register op2 = $tmp2$$Register;
7431 Register dst = $dst$$Register;
7432 Register src = $src$$Register;
7433 int flag = $cop$$cmpcode;
7435 switch(flag)
7436 {
7437 case 0x01: //equal
7438 __ subu32(AT, op1, op2);
7439 __ movz(dst, src, AT);
7440 break;
7442 case 0x02: //not_equal
7443 __ subu32(AT, op1, op2);
7444 __ movn(dst, src, AT);
7445 break;
7447 case 0x03: //above
7448 __ slt(AT, op2, op1);
7449 __ movn(dst, src, AT);
7450 break;
7452 case 0x04: //above_equal
7453 __ slt(AT, op1, op2);
7454 __ movz(dst, src, AT);
7455 break;
7457 case 0x05: //below
7458 __ slt(AT, op1, op2);
7459 __ movn(dst, src, AT);
7460 break;
7462 case 0x06: //below_equal
7463 __ slt(AT, op2, op1);
7464 __ movz(dst, src, AT);
7465 break;
7467 default:
7468 Unimplemented();
7469 }
7470 %}
7472 ins_pipe( pipe_slow );
7473 %}
7476 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7477 match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7478 ins_cost(80);
7479 format %{
7480 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpI_reg_reg\n"
7481 "\tCMOV $dst,$src \t @cmovL_cmpI_reg_reg"
7482 %}
7484 ins_encode %{
7485 Register op1 = $tmp1$$Register;
7486 Register op2 = $tmp2$$Register;
7487 Register dst = as_Register($dst$$reg);
7488 Register src = as_Register($src$$reg);
7489 int flag = $cop$$cmpcode;
7491 switch(flag)
7492 {
7493 case 0x01: //equal
7494 __ subu32(AT, op1, op2);
7495 __ movz(dst, src, AT);
7496 break;
7498 case 0x02: //not_equal
7499 __ subu32(AT, op1, op2);
7500 __ movn(dst, src, AT);
7501 break;
7503 case 0x03: //great
7504 __ slt(AT, op2, op1);
7505 __ movn(dst, src, AT);
7506 break;
7508 case 0x04: //great_equal
7509 __ slt(AT, op1, op2);
7510 __ movz(dst, src, AT);
7511 break;
7513 case 0x05: //less
7514 __ slt(AT, op1, op2);
7515 __ movn(dst, src, AT);
7516 break;
7518 case 0x06: //less_equal
7519 __ slt(AT, op2, op1);
7520 __ movz(dst, src, AT);
7521 break;
7523 default:
7524 Unimplemented();
7525 }
7526 %}
7528 ins_pipe( pipe_slow );
7529 %}
7531 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
7532 match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
7533 ins_cost(80);
7534 format %{
7535 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpL_reg_reg\n"
7536 "\tCMOV $dst,$src \t @cmovL_cmpL_reg_reg"
7537 %}
7538 ins_encode %{
7539 Register opr1 = as_Register($tmp1$$reg);
7540 Register opr2 = as_Register($tmp2$$reg);
7541 Register dst = as_Register($dst$$reg);
7542 Register src = as_Register($src$$reg);
7543 int flag = $cop$$cmpcode;
7545 switch(flag)
7546 {
7547 case 0x01: //equal
7548 __ subu(AT, opr1, opr2);
7549 __ movz(dst, src, AT);
7550 break;
7552 case 0x02: //not_equal
7553 __ subu(AT, opr1, opr2);
7554 __ movn(dst, src, AT);
7555 break;
7557 case 0x03: //greater
7558 __ slt(AT, opr2, opr1);
7559 __ movn(dst, src, AT);
7560 break;
7562 case 0x04: //greater_equal
7563 __ slt(AT, opr1, opr2);
7564 __ movz(dst, src, AT);
7565 break;
7567 case 0x05: //less
7568 __ slt(AT, opr1, opr2);
7569 __ movn(dst, src, AT);
7570 break;
7572 case 0x06: //less_equal
7573 __ slt(AT, opr2, opr1);
7574 __ movz(dst, src, AT);
7575 break;
7577 default:
7578 Unimplemented();
7579 }
7580 %}
7582 ins_pipe( pipe_slow );
7583 %}
7585 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
7586 match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
7587 ins_cost(80);
7588 format %{
7589 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
7590 "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
7591 %}
7592 ins_encode %{
7593 Register op1 = $tmp1$$Register;
7594 Register op2 = $tmp2$$Register;
7595 Register dst = $dst$$Register;
7596 Register src = $src$$Register;
7597 int flag = $cop$$cmpcode;
7599 switch(flag)
7600 {
7601 case 0x01: //equal
7602 __ subu32(AT, op1, op2);
7603 __ movz(dst, src, AT);
7604 break;
7606 case 0x02: //not_equal
7607 __ subu32(AT, op1, op2);
7608 __ movn(dst, src, AT);
7609 break;
7611 case 0x03: //above
7612 __ sltu(AT, op2, op1);
7613 __ movn(dst, src, AT);
7614 break;
7616 case 0x04: //above_equal
7617 __ sltu(AT, op1, op2);
7618 __ movz(dst, src, AT);
7619 break;
7621 case 0x05: //below
7622 __ sltu(AT, op1, op2);
7623 __ movn(dst, src, AT);
7624 break;
7626 case 0x06: //below_equal
7627 __ sltu(AT, op2, op1);
7628 __ movz(dst, src, AT);
7629 break;
7631 default:
7632 Unimplemented();
7633 }
7634 %}
7636 ins_pipe( pipe_slow );
7637 %}
7640 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
7641 match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
7642 ins_cost(80);
7643 format %{
7644 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpD_reg_reg\n"
7645 "\tCMOV $dst,$src \t @cmovL_cmpD_reg_reg"
7646 %}
7647 ins_encode %{
7648 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
7649 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
7650 Register dst = as_Register($dst$$reg);
7651 Register src = as_Register($src$$reg);
7653 int flag = $cop$$cmpcode;
7655 switch(flag)
7656 {
7657 case 0x01: //equal
7658 __ c_eq_d(reg_op1, reg_op2);
7659 __ movt(dst, src);
7660 break;
7661 case 0x02: //not_equal
7662 __ c_eq_d(reg_op1, reg_op2);
7663 __ movf(dst, src);
7664 break;
7665 case 0x03: //greater
7666 __ c_ole_d(reg_op1, reg_op2);
7667 __ movf(dst, src);
7668 break;
7669 case 0x04: //greater_equal
7670 __ c_olt_d(reg_op1, reg_op2);
7671 __ movf(dst, src);
7672 break;
7673 case 0x05: //less
7674 __ c_ult_d(reg_op1, reg_op2);
7675 __ movt(dst, src);
7676 break;
7677 case 0x06: //less_equal
7678 __ c_ule_d(reg_op1, reg_op2);
7679 __ movt(dst, src);
7680 break;
7681 default:
7682 Unimplemented();
7683 }
7684 %}
7686 ins_pipe( pipe_slow );
7687 %}
7689 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
7690 match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
7691 ins_cost(200);
7692 format %{
7693 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpD_reg_reg\n"
7694 "\tCMOV $dst,$src \t @cmovD_cmpD_reg_reg"
7695 %}
7696 ins_encode %{
7697 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
7698 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
7699 FloatRegister dst = as_FloatRegister($dst$$reg);
7700 FloatRegister src = as_FloatRegister($src$$reg);
7702 int flag = $cop$$cmpcode;
7704 Label L;
7706 switch(flag)
7707 {
7708 case 0x01: //equal
7709 __ c_eq_d(reg_op1, reg_op2);
7710 __ bc1f(L);
7711 __ nop();
7712 __ mov_d(dst, src);
7713 __ bind(L);
7714 break;
7715 case 0x02: //not_equal
7716 //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.
7717 __ c_eq_d(reg_op1, reg_op2);
7718 __ bc1t(L);
7719 __ nop();
7720 __ mov_d(dst, src);
7721 __ bind(L);
7722 break;
7723 case 0x03: //greater
7724 __ c_ole_d(reg_op1, reg_op2);
7725 __ bc1t(L);
7726 __ nop();
7727 __ mov_d(dst, src);
7728 __ bind(L);
7729 break;
7730 case 0x04: //greater_equal
7731 __ c_olt_d(reg_op1, reg_op2);
7732 __ bc1t(L);
7733 __ nop();
7734 __ mov_d(dst, src);
7735 __ bind(L);
7736 break;
7737 case 0x05: //less
7738 __ c_ult_d(reg_op1, reg_op2);
7739 __ bc1f(L);
7740 __ nop();
7741 __ mov_d(dst, src);
7742 __ bind(L);
7743 break;
7744 case 0x06: //less_equal
7745 __ c_ule_d(reg_op1, reg_op2);
7746 __ bc1f(L);
7747 __ nop();
7748 __ mov_d(dst, src);
7749 __ bind(L);
7750 break;
7751 default:
7752 Unimplemented();
7753 }
7754 %}
7756 ins_pipe( pipe_slow );
7757 %}
7759 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7760 match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7761 ins_cost(200);
7762 format %{
7763 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpI_reg_reg\n"
7764 "\tCMOV $dst, $src \t @cmovF_cmpI_reg_reg"
7765 %}
7767 ins_encode %{
7768 Register op1 = $tmp1$$Register;
7769 Register op2 = $tmp2$$Register;
7770 FloatRegister dst = as_FloatRegister($dst$$reg);
7771 FloatRegister src = as_FloatRegister($src$$reg);
7772 int flag = $cop$$cmpcode;
7773 Label L;
7775 switch(flag)
7776 {
7777 case 0x01: //equal
7778 __ bne(op1, op2, L);
7779 __ nop();
7780 __ mov_s(dst, src);
7781 __ bind(L);
7782 break;
7783 case 0x02: //not_equal
7784 __ beq(op1, op2, L);
7785 __ nop();
7786 __ mov_s(dst, src);
7787 __ bind(L);
7788 break;
7789 case 0x03: //great
7790 __ slt(AT, op2, op1);
7791 __ beq(AT, R0, L);
7792 __ nop();
7793 __ mov_s(dst, src);
7794 __ bind(L);
7795 break;
7796 case 0x04: //great_equal
7797 __ slt(AT, op1, op2);
7798 __ bne(AT, R0, L);
7799 __ nop();
7800 __ mov_s(dst, src);
7801 __ bind(L);
7802 break;
7803 case 0x05: //less
7804 __ slt(AT, op1, op2);
7805 __ beq(AT, R0, L);
7806 __ nop();
7807 __ mov_s(dst, src);
7808 __ bind(L);
7809 break;
7810 case 0x06: //less_equal
7811 __ slt(AT, op2, op1);
7812 __ bne(AT, R0, L);
7813 __ nop();
7814 __ mov_s(dst, src);
7815 __ bind(L);
7816 break;
7817 default:
7818 Unimplemented();
7819 }
7820 %}
7822 ins_pipe( pipe_slow );
7823 %}
7825 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7826 match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7827 ins_cost(200);
7828 format %{
7829 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpI_reg_reg\n"
7830 "\tCMOV $dst, $src \t @cmovD_cmpI_reg_reg"
7831 %}
7833 ins_encode %{
7834 Register op1 = $tmp1$$Register;
7835 Register op2 = $tmp2$$Register;
7836 FloatRegister dst = as_FloatRegister($dst$$reg);
7837 FloatRegister src = as_FloatRegister($src$$reg);
7838 int flag = $cop$$cmpcode;
7839 Label L;
7841 switch(flag)
7842 {
7843 case 0x01: //equal
7844 __ bne(op1, op2, L);
7845 __ nop();
7846 __ mov_d(dst, src);
7847 __ bind(L);
7848 break;
7849 case 0x02: //not_equal
7850 __ beq(op1, op2, L);
7851 __ nop();
7852 __ mov_d(dst, src);
7853 __ bind(L);
7854 break;
7855 case 0x03: //great
7856 __ slt(AT, op2, op1);
7857 __ beq(AT, R0, L);
7858 __ nop();
7859 __ mov_d(dst, src);
7860 __ bind(L);
7861 break;
7862 case 0x04: //great_equal
7863 __ slt(AT, op1, op2);
7864 __ bne(AT, R0, L);
7865 __ nop();
7866 __ mov_d(dst, src);
7867 __ bind(L);
7868 break;
7869 case 0x05: //less
7870 __ slt(AT, op1, op2);
7871 __ beq(AT, R0, L);
7872 __ nop();
7873 __ mov_d(dst, src);
7874 __ bind(L);
7875 break;
7876 case 0x06: //less_equal
7877 __ slt(AT, op2, op1);
7878 __ bne(AT, R0, L);
7879 __ nop();
7880 __ mov_d(dst, src);
7881 __ bind(L);
7882 break;
7883 default:
7884 Unimplemented();
7885 }
7886 %}
7888 ins_pipe( pipe_slow );
7889 %}
7891 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
7892 match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
7893 ins_cost(200);
7894 format %{
7895 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpP_reg_reg\n"
7896 "\tCMOV $dst, $src \t @cmovD_cmpP_reg_reg"
7897 %}
7899 ins_encode %{
7900 Register op1 = $tmp1$$Register;
7901 Register op2 = $tmp2$$Register;
7902 FloatRegister dst = as_FloatRegister($dst$$reg);
7903 FloatRegister src = as_FloatRegister($src$$reg);
7904 int flag = $cop$$cmpcode;
7905 Label L;
7907 switch(flag)
7908 {
7909 case 0x01: //equal
7910 __ bne(op1, op2, L);
7911 __ nop();
7912 __ mov_d(dst, src);
7913 __ bind(L);
7914 break;
7915 case 0x02: //not_equal
7916 __ beq(op1, op2, L);
7917 __ nop();
7918 __ mov_d(dst, src);
7919 __ bind(L);
7920 break;
7921 case 0x03: //great
7922 __ slt(AT, op2, op1);
7923 __ beq(AT, R0, L);
7924 __ nop();
7925 __ mov_d(dst, src);
7926 __ bind(L);
7927 break;
7928 case 0x04: //great_equal
7929 __ slt(AT, op1, op2);
7930 __ bne(AT, R0, L);
7931 __ nop();
7932 __ mov_d(dst, src);
7933 __ bind(L);
7934 break;
7935 case 0x05: //less
7936 __ slt(AT, op1, op2);
7937 __ beq(AT, R0, L);
7938 __ nop();
7939 __ mov_d(dst, src);
7940 __ bind(L);
7941 break;
7942 case 0x06: //less_equal
7943 __ slt(AT, op2, op1);
7944 __ bne(AT, R0, L);
7945 __ nop();
7946 __ mov_d(dst, src);
7947 __ bind(L);
7948 break;
7949 default:
7950 Unimplemented();
7951 }
7952 %}
7954 ins_pipe( pipe_slow );
7955 %}
7957 //FIXME
7958 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
7959 match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
7960 ins_cost(80);
7961 format %{
7962 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpF_reg_reg\n"
7963 "\tCMOV $dst,$src \t @cmovI_cmpF_reg_reg"
7964 %}
7966 ins_encode %{
7967 FloatRegister reg_op1 = $tmp1$$FloatRegister;
7968 FloatRegister reg_op2 = $tmp2$$FloatRegister;
7969 Register dst = $dst$$Register;
7970 Register src = $src$$Register;
7971 int flag = $cop$$cmpcode;
7973 switch(flag)
7974 {
7975 case 0x01: //equal
7976 __ c_eq_s(reg_op1, reg_op2);
7977 __ movt(dst, src);
7978 break;
7979 case 0x02: //not_equal
7980 __ c_eq_s(reg_op1, reg_op2);
7981 __ movf(dst, src);
7982 break;
7983 case 0x03: //greater
7984 __ c_ole_s(reg_op1, reg_op2);
7985 __ movf(dst, src);
7986 break;
7987 case 0x04: //greater_equal
7988 __ c_olt_s(reg_op1, reg_op2);
7989 __ movf(dst, src);
7990 break;
7991 case 0x05: //less
7992 __ c_ult_s(reg_op1, reg_op2);
7993 __ movt(dst, src);
7994 break;
7995 case 0x06: //less_equal
7996 __ c_ule_s(reg_op1, reg_op2);
7997 __ movt(dst, src);
7998 break;
7999 default:
8000 Unimplemented();
8001 }
8002 %}
8003 ins_pipe( pipe_slow );
8004 %}
8006 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
8007 match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
8008 ins_cost(200);
8009 format %{
8010 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpF_reg_reg\n"
8011 "\tCMOV $dst,$src \t @cmovF_cmpF_reg_reg"
8012 %}
8014 ins_encode %{
8015 FloatRegister reg_op1 = $tmp1$$FloatRegister;
8016 FloatRegister reg_op2 = $tmp2$$FloatRegister;
8017 FloatRegister dst = $dst$$FloatRegister;
8018 FloatRegister src = $src$$FloatRegister;
8019 Label L;
8020 int flag = $cop$$cmpcode;
8022 switch(flag)
8023 {
8024 case 0x01: //equal
8025 __ c_eq_s(reg_op1, reg_op2);
8026 __ bc1f(L);
8027 __ nop();
8028 __ mov_s(dst, src);
8029 __ bind(L);
8030 break;
8031 case 0x02: //not_equal
8032 __ c_eq_s(reg_op1, reg_op2);
8033 __ bc1t(L);
8034 __ nop();
8035 __ mov_s(dst, src);
8036 __ bind(L);
8037 break;
8038 case 0x03: //greater
8039 __ c_ole_s(reg_op1, reg_op2);
8040 __ bc1t(L);
8041 __ nop();
8042 __ mov_s(dst, src);
8043 __ bind(L);
8044 break;
8045 case 0x04: //greater_equal
8046 __ c_olt_s(reg_op1, reg_op2);
8047 __ bc1t(L);
8048 __ nop();
8049 __ mov_s(dst, src);
8050 __ bind(L);
8051 break;
8052 case 0x05: //less
8053 __ c_ult_s(reg_op1, reg_op2);
8054 __ bc1f(L);
8055 __ nop();
8056 __ mov_s(dst, src);
8057 __ bind(L);
8058 break;
8059 case 0x06: //less_equal
8060 __ c_ule_s(reg_op1, reg_op2);
8061 __ bc1f(L);
8062 __ nop();
8063 __ mov_s(dst, src);
8064 __ bind(L);
8065 break;
8066 default:
8067 Unimplemented();
8068 }
8069 %}
8070 ins_pipe( pipe_slow );
8071 %}
8073 // Manifest a CmpL result in an integer register. Very painful.
8074 // This is the test to avoid.
8075 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
8076 match(Set dst (CmpL3 src1 src2));
8077 ins_cost(1000);
8078 format %{ "cmpL3 $dst, $src1, $src2 @ cmpL3_reg_reg" %}
8079 ins_encode %{
8080 Register opr1 = as_Register($src1$$reg);
8081 Register opr2 = as_Register($src2$$reg);
8082 Register dst = as_Register($dst$$reg);
8084 Label Done;
8086 __ subu(AT, opr1, opr2);
8087 __ bltz(AT, Done);
8088 __ delayed()->daddiu(dst, R0, -1);
8090 __ move(dst, 1);
8091 __ movz(dst, R0, AT);
8093 __ bind(Done);
8094 %}
8095 ins_pipe( pipe_slow );
8096 %}
8098 //
8099 // less_rsult = -1
8100 // greater_result = 1
8101 // equal_result = 0
8102 // nan_result = -1
8103 //
8104 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
8105 match(Set dst (CmpF3 src1 src2));
8106 ins_cost(1000);
8107 format %{ "cmpF3 $dst, $src1, $src2 @ cmpF3_reg_reg" %}
8108 ins_encode %{
8109 FloatRegister src1 = as_FloatRegister($src1$$reg);
8110 FloatRegister src2 = as_FloatRegister($src2$$reg);
8111 Register dst = as_Register($dst$$reg);
8113 Label Done;
8115 __ c_ult_s(src1, src2);
8116 __ bc1t(Done);
8117 __ delayed()->daddiu(dst, R0, -1);
8119 __ c_eq_s(src1, src2);
8120 __ move(dst, 1);
8121 __ movt(dst, R0);
8123 __ bind(Done);
8124 %}
8125 ins_pipe( pipe_slow );
8126 %}
8128 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
8129 match(Set dst (CmpD3 src1 src2));
8130 ins_cost(1000);
8131 format %{ "cmpD3 $dst, $src1, $src2 @ cmpD3_reg_reg" %}
8132 ins_encode %{
8133 FloatRegister src1 = as_FloatRegister($src1$$reg);
8134 FloatRegister src2 = as_FloatRegister($src2$$reg);
8135 Register dst = as_Register($dst$$reg);
8137 Label Done;
8139 __ c_ult_d(src1, src2);
8140 __ bc1t(Done);
8141 __ delayed()->daddiu(dst, R0, -1);
8143 __ c_eq_d(src1, src2);
8144 __ move(dst, 1);
8145 __ movt(dst, R0);
8147 __ bind(Done);
8148 %}
8149 ins_pipe( pipe_slow );
8150 %}
8152 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
8153 match(Set dummy (ClearArray cnt base));
8154 format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
8155 ins_encode %{
8156 //Assume cnt is the number of bytes in an array to be cleared,
8157 //and base points to the starting address of the array.
8158 Register base = $base$$Register;
8159 Register num = $cnt$$Register;
8160 Label Loop, done;
8162 /* 2012/9/21 Jin: according to X86, $cnt is caculated by doublewords(8 bytes) */
8163 __ move(T9, num); /* T9 = words */
8164 __ beq(T9, R0, done);
8165 __ nop();
8166 __ move(AT, base);
8168 __ bind(Loop);
8169 __ sd(R0, Address(AT, 0));
8170 __ daddi(AT, AT, wordSize);
8171 __ daddi(T9, T9, -1);
8172 __ bne(T9, R0, Loop);
8173 __ delayed()->nop();
8174 __ bind(done);
8175 %}
8176 ins_pipe( pipe_slow );
8177 %}
8179 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2, mA7RegI cnt2, no_Ax_mRegI result) %{
8180 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
8181 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
8183 format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
8184 ins_encode %{
8185 // Get the first character position in both strings
8186 // [8] char array, [12] offset, [16] count
8187 Register str1 = $str1$$Register;
8188 Register str2 = $str2$$Register;
8189 Register cnt1 = $cnt1$$Register;
8190 Register cnt2 = $cnt2$$Register;
8191 Register result = $result$$Register;
8193 Label L, Loop, haveResult, done;
8195 // compute the and difference of lengths (in result)
8196 __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
8198 // compute the shorter length (in cnt1)
8199 __ slt(AT, cnt2, cnt1);
8200 __ movn(cnt1, cnt2, AT);
8202 // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
8203 __ bind(Loop); // Loop begin
8204 __ beq(cnt1, R0, done);
8205 __ delayed()->lhu(AT, str1, 0);;
8207 // compare current character
8208 __ lhu(cnt2, str2, 0);
8209 __ bne(AT, cnt2, haveResult);
8210 __ delayed()->addi(str1, str1, 2);
8211 __ addi(str2, str2, 2);
8212 __ b(Loop);
8213 __ delayed()->addi(cnt1, cnt1, -1); // Loop end
8215 __ bind(haveResult);
8216 __ subu(result, AT, cnt2);
8218 __ bind(done);
8219 %}
8221 ins_pipe( pipe_slow );
8222 %}
8224 // intrinsic optimization
8225 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
8226 match(Set result (StrEquals (Binary str1 str2) cnt));
8227 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
8229 format %{ "String Equal $str1, $str2, len:$cnt tmp:$temp -> $result @ string_equals" %}
8230 ins_encode %{
8231 // Get the first character position in both strings
8232 // [8] char array, [12] offset, [16] count
8233 Register str1 = $str1$$Register;
8234 Register str2 = $str2$$Register;
8235 Register cnt = $cnt$$Register;
8236 Register tmp = $temp$$Register;
8237 Register result = $result$$Register;
8239 Label Loop, done;
8242 __ beq(str1, str2, done); // same char[] ?
8243 __ daddiu(result, R0, 1);
8245 __ bind(Loop); // Loop begin
8246 __ beq(cnt, R0, done);
8247 __ daddiu(result, R0, 1); // count == 0
8249 // compare current character
8250 __ lhu(AT, str1, 0);;
8251 __ lhu(tmp, str2, 0);
8252 __ bne(AT, tmp, done);
8253 __ delayed()->daddi(result, R0, 0);
8254 __ addi(str1, str1, 2);
8255 __ addi(str2, str2, 2);
8256 __ b(Loop);
8257 __ delayed()->addi(cnt, cnt, -1); // Loop end
8259 __ bind(done);
8260 %}
8262 ins_pipe( pipe_slow );
8263 %}
8265 //----------Arithmetic Instructions-------------------------------------------
8266 //----------Addition Instructions---------------------------------------------
8267 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
8268 match(Set dst (AddI src1 src2));
8270 format %{ "add $dst, $src1, $src2 #@addI_Reg_Reg" %}
8271 ins_encode %{
8272 Register dst = $dst$$Register;
8273 Register src1 = $src1$$Register;
8274 Register src2 = $src2$$Register;
8275 __ addu32(dst, src1, src2);
8276 %}
8277 ins_pipe( ialu_regI_regI );
8278 %}
8280 instruct addI_Reg_imm(mRegI dst, mRegI src1, immI src2) %{
8281 match(Set dst (AddI src1 src2));
8283 format %{ "add $dst, $src1, $src2 #@addI_Reg_imm" %}
8284 ins_encode %{
8285 Register dst = $dst$$Register;
8286 Register src1 = $src1$$Register;
8287 int imm = $src2$$constant;
8289 if(Assembler::is_simm16(imm)) {
8290 __ addiu32(dst, src1, imm);
8291 } else {
8292 __ move(AT, imm);
8293 __ addu32(dst, src1, AT);
8294 }
8295 %}
8296 ins_pipe( ialu_regI_regI );
8297 %}
8299 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
8300 match(Set dst (AddP src1 src2));
8302 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg" %}
8304 ins_encode %{
8305 Register dst = $dst$$Register;
8306 Register src1 = $src1$$Register;
8307 Register src2 = $src2$$Register;
8308 __ daddu(dst, src1, src2);
8309 %}
8311 ins_pipe( ialu_regI_regI );
8312 %}
8314 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
8315 match(Set dst (AddP src1 (ConvI2L src2)));
8317 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
8319 ins_encode %{
8320 Register dst = $dst$$Register;
8321 Register src1 = $src1$$Register;
8322 Register src2 = $src2$$Register;
8323 __ daddu(dst, src1, src2);
8324 %}
8326 ins_pipe( ialu_regI_regI );
8327 %}
8329 instruct addP_reg_imm(mRegP dst, mRegP src1, immL src2) %{
8330 match(Set dst (AddP src1 src2));
8332 format %{ "daddi $dst, $src1, $src2 #@addP_reg_imm" %}
8333 ins_encode %{
8334 Register src1 = $src1$$Register;
8335 long src2 = $src2$$constant;
8336 Register dst = $dst$$Register;
8338 if(Assembler::is_simm16(src2)) {
8339 __ daddiu(dst, src1, src2);
8340 } else {
8341 __ set64(AT, src2);
8342 __ daddu(dst, src1, AT);
8343 }
8344 %}
8345 ins_pipe( ialu_regI_imm16 );
8346 %}
8348 // Add Long Register with Register
8349 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
8350 match(Set dst (AddL src1 src2));
8351 ins_cost(200);
8352 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
8354 ins_encode %{
8355 Register dst_reg = as_Register($dst$$reg);
8356 Register src1_reg = as_Register($src1$$reg);
8357 Register src2_reg = as_Register($src2$$reg);
8359 __ daddu(dst_reg, src1_reg, src2_reg);
8360 %}
8362 ins_pipe( ialu_regL_regL );
8363 %}
8365 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
8366 %{
8367 match(Set dst (AddL src1 src2));
8369 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_imm " %}
8370 ins_encode %{
8371 Register dst_reg = as_Register($dst$$reg);
8372 Register src1_reg = as_Register($src1$$reg);
8373 int src2_imm = $src2$$constant;
8375 __ daddiu(dst_reg, src1_reg, src2_imm);
8376 %}
8378 ins_pipe( ialu_regL_regL );
8379 %}
8381 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
8382 %{
8383 match(Set dst (AddL (ConvI2L src1) src2));
8385 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_imm " %}
8386 ins_encode %{
8387 Register dst_reg = as_Register($dst$$reg);
8388 Register src1_reg = as_Register($src1$$reg);
8389 int src2_imm = $src2$$constant;
8391 __ daddiu(dst_reg, src1_reg, src2_imm);
8392 %}
8394 ins_pipe( ialu_regL_regL );
8395 %}
8397 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
8398 match(Set dst (AddL (ConvI2L src1) src2));
8399 ins_cost(200);
8400 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
8402 ins_encode %{
8403 Register dst_reg = as_Register($dst$$reg);
8404 Register src1_reg = as_Register($src1$$reg);
8405 Register src2_reg = as_Register($src2$$reg);
8407 __ daddu(dst_reg, src1_reg, src2_reg);
8408 %}
8410 ins_pipe( ialu_regL_regL );
8411 %}
8413 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
8414 match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
8415 ins_cost(200);
8416 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
8418 ins_encode %{
8419 Register dst_reg = as_Register($dst$$reg);
8420 Register src1_reg = as_Register($src1$$reg);
8421 Register src2_reg = as_Register($src2$$reg);
8423 __ daddu(dst_reg, src1_reg, src2_reg);
8424 %}
8426 ins_pipe( ialu_regL_regL );
8427 %}
8429 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
8430 match(Set dst (AddL src1 (ConvI2L src2)));
8431 ins_cost(200);
8432 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
8434 ins_encode %{
8435 Register dst_reg = as_Register($dst$$reg);
8436 Register src1_reg = as_Register($src1$$reg);
8437 Register src2_reg = as_Register($src2$$reg);
8439 __ daddu(dst_reg, src1_reg, src2_reg);
8440 %}
8442 ins_pipe( ialu_regL_regL );
8443 %}
8445 //----------Subtraction Instructions-------------------------------------------
8446 // Integer Subtraction Instructions
8447 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
8448 match(Set dst (SubI src1 src2));
8449 ins_cost(100);
8451 format %{ "sub $dst, $src1, $src2 #@subI_Reg_Reg" %}
8452 ins_encode %{
8453 Register dst = $dst$$Register;
8454 Register src1 = $src1$$Register;
8455 Register src2 = $src2$$Register;
8456 __ subu32(dst, src1, src2);
8457 %}
8458 ins_pipe( ialu_regI_regI );
8459 %}
8461 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1, immI16_sub src2) %{
8462 match(Set dst (SubI src1 src2));
8463 ins_cost(80);
8465 format %{ "sub $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
8466 ins_encode %{
8467 Register dst = $dst$$Register;
8468 Register src1 = $src1$$Register;
8469 __ addiu32(dst, src1, -1 * $src2$$constant);
8470 %}
8471 ins_pipe( ialu_regI_regI );
8472 %}
8474 instruct negI_Reg(mRegI dst, immI0 zero, mRegI src) %{
8475 match(Set dst (SubI zero src));
8476 ins_cost(80);
8478 format %{ "neg $dst, $src #@negI_Reg" %}
8479 ins_encode %{
8480 Register dst = $dst$$Register;
8481 Register src = $src$$Register;
8482 __ subu32(dst, R0, src);
8483 %}
8484 ins_pipe( ialu_regI_regI );
8485 %}
8487 instruct negL_Reg(mRegL dst, immL0 zero, mRegL src) %{
8488 match(Set dst (SubL zero src));
8489 ins_cost(80);
8491 format %{ "neg $dst, $src #@negL_Reg" %}
8492 ins_encode %{
8493 Register dst = $dst$$Register;
8494 Register src = $src$$Register;
8495 __ subu(dst, R0, src);
8496 %}
8497 ins_pipe( ialu_regI_regI );
8498 %}
8500 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1, immL16_sub src2) %{
8501 match(Set dst (SubL src1 src2));
8502 ins_cost(80);
8504 format %{ "sub $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
8505 ins_encode %{
8506 Register dst = $dst$$Register;
8507 Register src1 = $src1$$Register;
8508 __ daddiu(dst, src1, -1 * $src2$$constant);
8509 %}
8510 ins_pipe( ialu_regI_regI );
8511 %}
8513 // Subtract Long Register with Register.
8514 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
8515 match(Set dst (SubL src1 src2));
8516 ins_cost(100);
8517 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_Reg" %}
8518 ins_encode %{
8519 Register dst = as_Register($dst$$reg);
8520 Register src1 = as_Register($src1$$reg);
8521 Register src2 = as_Register($src2$$reg);
8523 __ subu(dst, src1, src2);
8524 %}
8525 ins_pipe( ialu_regL_regL );
8526 %}
8528 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
8529 match(Set dst (SubL src1 (ConvI2L src2)));
8530 ins_cost(100);
8531 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
8532 ins_encode %{
8533 Register dst = as_Register($dst$$reg);
8534 Register src1 = as_Register($src1$$reg);
8535 Register src2 = as_Register($src2$$reg);
8537 __ subu(dst, src1, src2);
8538 %}
8539 ins_pipe( ialu_regL_regL );
8540 %}
8542 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
8543 match(Set dst (SubL (ConvI2L src1) src2));
8544 ins_cost(200);
8545 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
8546 ins_encode %{
8547 Register dst = as_Register($dst$$reg);
8548 Register src1 = as_Register($src1$$reg);
8549 Register src2 = as_Register($src2$$reg);
8551 __ subu(dst, src1, src2);
8552 %}
8553 ins_pipe( ialu_regL_regL );
8554 %}
8556 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
8557 match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
8558 ins_cost(200);
8559 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
8560 ins_encode %{
8561 Register dst = as_Register($dst$$reg);
8562 Register src1 = as_Register($src1$$reg);
8563 Register src2 = as_Register($src2$$reg);
8565 __ subu(dst, src1, src2);
8566 %}
8567 ins_pipe( ialu_regL_regL );
8568 %}
8570 // Integer MOD with Register
8571 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
8572 match(Set dst (ModI src1 src2));
8573 ins_cost(300);
8574 format %{ "modi $dst, $src1, $src2 @ modI_Reg_Reg" %}
8575 ins_encode %{
8576 Register dst = $dst$$Register;
8577 Register src1 = $src1$$Register;
8578 Register src2 = $src2$$Register;
8580 //if (UseLoongsonISA) {
8581 if (0) {
8582 // 2016.08.10
8583 // Experiments show that gsmod is slower that div+mfhi.
8584 // So I just disable it here.
8585 __ gsmod(dst, src1, src2);
8586 } else {
8587 __ div(src1, src2);
8588 __ mfhi(dst);
8589 }
8590 %}
8592 //ins_pipe( ialu_mod );
8593 ins_pipe( ialu_regI_regI );
8594 %}
8596 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
8597 match(Set dst (ModL src1 src2));
8598 format %{ "modL $dst, $src1, $src2 @modL_reg_reg" %}
8600 ins_encode %{
8601 Register dst = as_Register($dst$$reg);
8602 Register op1 = as_Register($src1$$reg);
8603 Register op2 = as_Register($src2$$reg);
8605 if (UseLoongsonISA) {
8606 __ gsdmod(dst, op1, op2);
8607 } else {
8608 __ ddiv(op1, op2);
8609 __ mfhi(dst);
8610 }
8611 %}
8612 ins_pipe( pipe_slow );
8613 %}
8615 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
8616 match(Set dst (MulI src1 src2));
8618 ins_cost(300);
8619 format %{ "mul $dst, $src1, $src2 @ mulI_Reg_Reg" %}
8620 ins_encode %{
8621 Register src1 = $src1$$Register;
8622 Register src2 = $src2$$Register;
8623 Register dst = $dst$$Register;
8625 __ mul(dst, src1, src2);
8626 %}
8627 ins_pipe( ialu_mult );
8628 %}
8630 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
8631 match(Set dst (AddI (MulI src1 src2) src3));
8633 ins_cost(999);
8634 format %{ "madd $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
8635 ins_encode %{
8636 Register src1 = $src1$$Register;
8637 Register src2 = $src2$$Register;
8638 Register src3 = $src3$$Register;
8639 Register dst = $dst$$Register;
8641 __ mtlo(src3);
8642 __ madd(src1, src2);
8643 __ mflo(dst);
8644 %}
8645 ins_pipe( ialu_mult );
8646 %}
8648 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
8649 match(Set dst (DivI src1 src2));
8651 ins_cost(300);
8652 format %{ "div $dst, $src1, $src2 @ divI_Reg_Reg" %}
8653 ins_encode %{
8654 Register src1 = $src1$$Register;
8655 Register src2 = $src2$$Register;
8656 Register dst = $dst$$Register;
8658 /* 2012/4/21 Jin: In MIPS, div does not cause exception.
8659 We must trap an exception manually. */
8660 __ teq(R0, src2, 0x7);
8662 if (UseLoongsonISA) {
8663 __ gsdiv(dst, src1, src2);
8664 } else {
8665 __ div(src1, src2);
8667 __ nop();
8668 __ nop();
8669 __ mflo(dst);
8670 }
8671 %}
8672 ins_pipe( ialu_mod );
8673 %}
8675 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
8676 match(Set dst (DivF src1 src2));
8678 ins_cost(300);
8679 format %{ "divF $dst, $src1, $src2 @ divF_Reg_Reg" %}
8680 ins_encode %{
8681 FloatRegister src1 = $src1$$FloatRegister;
8682 FloatRegister src2 = $src2$$FloatRegister;
8683 FloatRegister dst = $dst$$FloatRegister;
8685 /* Here do we need to trap an exception manually ? */
8686 __ div_s(dst, src1, src2);
8687 %}
8688 ins_pipe( pipe_slow );
8689 %}
8691 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
8692 match(Set dst (DivD src1 src2));
8694 ins_cost(300);
8695 format %{ "divD $dst, $src1, $src2 @ divD_Reg_Reg" %}
8696 ins_encode %{
8697 FloatRegister src1 = $src1$$FloatRegister;
8698 FloatRegister src2 = $src2$$FloatRegister;
8699 FloatRegister dst = $dst$$FloatRegister;
8701 /* Here do we need to trap an exception manually ? */
8702 __ div_d(dst, src1, src2);
8703 %}
8704 ins_pipe( pipe_slow );
8705 %}
8707 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
8708 match(Set dst (MulL src1 src2));
8709 format %{ "mulL $dst, $src1, $src2 @mulL_reg_reg" %}
8710 ins_encode %{
8711 Register dst = as_Register($dst$$reg);
8712 Register op1 = as_Register($src1$$reg);
8713 Register op2 = as_Register($src2$$reg);
8715 if (UseLoongsonISA) {
8716 __ gsdmult(dst, op1, op2);
8717 } else {
8718 __ dmult(op1, op2);
8719 __ mflo(dst);
8720 }
8721 %}
8722 ins_pipe( pipe_slow );
8723 %}
8725 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
8726 match(Set dst (MulL src1 (ConvI2L src2)));
8727 format %{ "mulL $dst, $src1, $src2 @mulL_reg_regI2L" %}
8728 ins_encode %{
8729 Register dst = as_Register($dst$$reg);
8730 Register op1 = as_Register($src1$$reg);
8731 Register op2 = as_Register($src2$$reg);
8733 if (UseLoongsonISA) {
8734 __ gsdmult(dst, op1, op2);
8735 } else {
8736 __ dmult(op1, op2);
8737 __ mflo(dst);
8738 }
8739 %}
8740 ins_pipe( pipe_slow );
8741 %}
8743 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
8744 match(Set dst (DivL src1 src2));
8745 format %{ "divL $dst, $src1, $src2 @divL_reg_reg" %}
8747 ins_encode %{
8748 Register dst = as_Register($dst$$reg);
8749 Register op1 = as_Register($src1$$reg);
8750 Register op2 = as_Register($src2$$reg);
8752 if (UseLoongsonISA) {
8753 __ gsddiv(dst, op1, op2);
8754 } else {
8755 __ ddiv(op1, op2);
8756 __ mflo(dst);
8757 }
8758 %}
8759 ins_pipe( pipe_slow );
8760 %}
8762 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
8763 match(Set dst (AddF src1 src2));
8764 format %{ "AddF $dst, $src1, $src2 @addF_reg_reg" %}
8765 ins_encode %{
8766 FloatRegister src1 = as_FloatRegister($src1$$reg);
8767 FloatRegister src2 = as_FloatRegister($src2$$reg);
8768 FloatRegister dst = as_FloatRegister($dst$$reg);
8770 __ add_s(dst, src1, src2);
8771 %}
8772 ins_pipe( fpu_regF_regF );
8773 %}
8775 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
8776 match(Set dst (SubF src1 src2));
8777 format %{ "SubF $dst, $src1, $src2 @subF_reg_reg" %}
8778 ins_encode %{
8779 FloatRegister src1 = as_FloatRegister($src1$$reg);
8780 FloatRegister src2 = as_FloatRegister($src2$$reg);
8781 FloatRegister dst = as_FloatRegister($dst$$reg);
8783 __ sub_s(dst, src1, src2);
8784 %}
8785 ins_pipe( fpu_regF_regF );
8786 %}
8787 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
8788 match(Set dst (AddD src1 src2));
8789 format %{ "AddD $dst, $src1, $src2 @addD_reg_reg" %}
8790 ins_encode %{
8791 FloatRegister src1 = as_FloatRegister($src1$$reg);
8792 FloatRegister src2 = as_FloatRegister($src2$$reg);
8793 FloatRegister dst = as_FloatRegister($dst$$reg);
8795 __ add_d(dst, src1, src2);
8796 %}
8797 ins_pipe( fpu_regF_regF );
8798 %}
8800 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
8801 match(Set dst (SubD src1 src2));
8802 format %{ "SubD $dst, $src1, $src2 @subD_reg_reg" %}
8803 ins_encode %{
8804 FloatRegister src1 = as_FloatRegister($src1$$reg);
8805 FloatRegister src2 = as_FloatRegister($src2$$reg);
8806 FloatRegister dst = as_FloatRegister($dst$$reg);
8808 __ sub_d(dst, src1, src2);
8809 %}
8810 ins_pipe( fpu_regF_regF );
8811 %}
8813 instruct negF_reg(regF dst, regF src) %{
8814 match(Set dst (NegF src));
8815 format %{ "negF $dst, $src @negF_reg" %}
8816 ins_encode %{
8817 FloatRegister src = as_FloatRegister($src$$reg);
8818 FloatRegister dst = as_FloatRegister($dst$$reg);
8820 __ neg_s(dst, src);
8821 %}
8822 ins_pipe( fpu_regF_regF );
8823 %}
8825 instruct negD_reg(regD dst, regD src) %{
8826 match(Set dst (NegD src));
8827 format %{ "negD $dst, $src @negD_reg" %}
8828 ins_encode %{
8829 FloatRegister src = as_FloatRegister($src$$reg);
8830 FloatRegister dst = as_FloatRegister($dst$$reg);
8832 __ neg_d(dst, src);
8833 %}
8834 ins_pipe( fpu_regF_regF );
8835 %}
8838 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
8839 match(Set dst (MulF src1 src2));
8840 format %{ "MULF $dst, $src1, $src2 @mulF_reg_reg" %}
8841 ins_encode %{
8842 FloatRegister src1 = $src1$$FloatRegister;
8843 FloatRegister src2 = $src2$$FloatRegister;
8844 FloatRegister dst = $dst$$FloatRegister;
8846 __ mul_s(dst, src1, src2);
8847 %}
8848 ins_pipe( fpu_regF_regF );
8849 %}
8851 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
8852 match(Set dst (AddF (MulF src1 src2) src3));
8853 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
8854 ins_cost(44444);
8855 format %{ "maddF $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
8856 ins_encode %{
8857 FloatRegister src1 = $src1$$FloatRegister;
8858 FloatRegister src2 = $src2$$FloatRegister;
8859 FloatRegister src3 = $src3$$FloatRegister;
8860 FloatRegister dst = $dst$$FloatRegister;
8862 __ madd_s(dst, src1, src2, src3);
8863 %}
8864 ins_pipe( fpu_regF_regF );
8865 %}
8867 // Mul two double precision floating piont number
8868 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
8869 match(Set dst (MulD src1 src2));
8870 format %{ "MULD $dst, $src1, $src2 @mulD_reg_reg" %}
8871 ins_encode %{
8872 FloatRegister src1 = $src1$$FloatRegister;
8873 FloatRegister src2 = $src2$$FloatRegister;
8874 FloatRegister dst = $dst$$FloatRegister;
8876 __ mul_d(dst, src1, src2);
8877 %}
8878 ins_pipe( fpu_regF_regF );
8879 %}
8881 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
8882 match(Set dst (AddD (MulD src1 src2) src3));
8883 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
8884 ins_cost(44444);
8885 format %{ "maddD $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
8886 ins_encode %{
8887 FloatRegister src1 = $src1$$FloatRegister;
8888 FloatRegister src2 = $src2$$FloatRegister;
8889 FloatRegister src3 = $src3$$FloatRegister;
8890 FloatRegister dst = $dst$$FloatRegister;
8892 __ madd_d(dst, src1, src2, src3);
8893 %}
8894 ins_pipe( fpu_regF_regF );
8895 %}
8897 instruct absF_reg(regF dst, regF src) %{
8898 match(Set dst (AbsF src));
8899 ins_cost(100);
8900 format %{ "absF $dst, $src @absF_reg" %}
8901 ins_encode %{
8902 FloatRegister src = as_FloatRegister($src$$reg);
8903 FloatRegister dst = as_FloatRegister($dst$$reg);
8905 __ abs_s(dst, src);
8906 %}
8907 ins_pipe( fpu_regF_regF );
8908 %}
8911 // intrinsics for math_native.
8912 // AbsD SqrtD CosD SinD TanD LogD Log10D
8914 instruct absD_reg(regD dst, regD src) %{
8915 match(Set dst (AbsD src));
8916 ins_cost(100);
8917 format %{ "absD $dst, $src @absD_reg" %}
8918 ins_encode %{
8919 FloatRegister src = as_FloatRegister($src$$reg);
8920 FloatRegister dst = as_FloatRegister($dst$$reg);
8922 __ abs_d(dst, src);
8923 %}
8924 ins_pipe( fpu_regF_regF );
8925 %}
8927 instruct sqrtD_reg(regD dst, regD src) %{
8928 match(Set dst (SqrtD src));
8929 ins_cost(100);
8930 format %{ "SqrtD $dst, $src @sqrtD_reg" %}
8931 ins_encode %{
8932 FloatRegister src = as_FloatRegister($src$$reg);
8933 FloatRegister dst = as_FloatRegister($dst$$reg);
8935 __ sqrt_d(dst, src);
8936 %}
8937 ins_pipe( fpu_regF_regF );
8938 %}
8940 instruct sqrtF_reg(regF dst, regF src) %{
8941 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
8942 ins_cost(100);
8943 format %{ "SqrtF $dst, $src @sqrtF_reg" %}
8944 ins_encode %{
8945 FloatRegister src = as_FloatRegister($src$$reg);
8946 FloatRegister dst = as_FloatRegister($dst$$reg);
8948 __ sqrt_s(dst, src);
8949 %}
8950 ins_pipe( fpu_regF_regF );
8951 %}
8952 //----------------------------------Logical Instructions----------------------
8953 //__________________________________Integer Logical Instructions-------------
8955 //And Instuctions
8956 // And Register with Immediate
8957 instruct andI_Reg_immI(mRegI dst, mRegI src1, immI src2) %{
8958 match(Set dst (AndI src1 src2));
8960 format %{ "and $dst, $src1, $src2 #@andI_Reg_immI" %}
8961 ins_encode %{
8962 Register dst = $dst$$Register;
8963 Register src = $src1$$Register;
8964 int val = $src2$$constant;
8966 __ move(AT, val);
8967 __ andr(dst, src, AT);
8968 %}
8969 ins_pipe( ialu_regI_regI );
8970 %}
8972 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
8973 match(Set dst (AndI src1 src2));
8974 ins_cost(60);
8976 format %{ "and $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
8977 ins_encode %{
8978 Register dst = $dst$$Register;
8979 Register src = $src1$$Register;
8980 int val = $src2$$constant;
8982 __ andi(dst, src, val);
8983 %}
8984 ins_pipe( ialu_regI_regI );
8985 %}
8987 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1, immI_nonneg_mask mask) %{
8988 match(Set dst (AndI src1 mask));
8989 ins_cost(60);
8991 format %{ "and $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
8992 ins_encode %{
8993 Register dst = $dst$$Register;
8994 Register src = $src1$$Register;
8995 int size = Assembler::is_int_mask($mask$$constant);
8997 __ ext(dst, src, 0, size);
8998 %}
8999 ins_pipe( ialu_regI_regI );
9000 %}
9002 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1, immL_nonneg_mask mask) %{
9003 match(Set dst (AndL src1 mask));
9004 ins_cost(60);
9006 format %{ "and $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
9007 ins_encode %{
9008 Register dst = $dst$$Register;
9009 Register src = $src1$$Register;
9010 int size = Assembler::is_jlong_mask($mask$$constant);
9012 __ dext(dst, src, 0, size);
9013 %}
9014 ins_pipe( ialu_regI_regI );
9015 %}
9017 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
9018 match(Set dst (XorI src1 src2));
9019 ins_cost(60);
9021 format %{ "xori $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
9022 ins_encode %{
9023 Register dst = $dst$$Register;
9024 Register src = $src1$$Register;
9025 int val = $src2$$constant;
9027 __ xori(dst, src, val);
9028 %}
9029 ins_pipe( ialu_regI_regI );
9030 %}
9032 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1, immI_M1 M1) %{
9033 match(Set dst (XorI src1 M1));
9034 predicate(UseLoongsonISA && Use3A2000);
9035 ins_cost(60);
9037 format %{ "xor $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
9038 ins_encode %{
9039 Register dst = $dst$$Register;
9040 Register src = $src1$$Register;
9042 __ gsorn(dst, R0, src);
9043 %}
9044 ins_pipe( ialu_regI_regI );
9045 %}
9047 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1, immI_M1 M1) %{
9048 match(Set dst (XorI (ConvL2I src1) M1));
9049 predicate(UseLoongsonISA && Use3A2000);
9050 ins_cost(60);
9052 format %{ "xor $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
9053 ins_encode %{
9054 Register dst = $dst$$Register;
9055 Register src = $src1$$Register;
9057 __ gsorn(dst, R0, src);
9058 %}
9059 ins_pipe( ialu_regI_regI );
9060 %}
9062 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
9063 match(Set dst (XorL src1 src2));
9064 ins_cost(60);
9066 format %{ "xori $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
9067 ins_encode %{
9068 Register dst = $dst$$Register;
9069 Register src = $src1$$Register;
9070 int val = $src2$$constant;
9072 __ xori(dst, src, val);
9073 %}
9074 ins_pipe( ialu_regI_regI );
9075 %}
9077 /*
9078 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1, immL_M1 M1) %{
9079 match(Set dst (XorL src1 M1));
9080 predicate(UseLoongsonISA);
9081 ins_cost(60);
9083 format %{ "xor $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
9084 ins_encode %{
9085 Register dst = $dst$$Register;
9086 Register src = $src1$$Register;
9088 __ gsorn(dst, R0, src);
9089 %}
9090 ins_pipe( ialu_regI_regI );
9091 %}
9092 */
9094 instruct lbu_and_lmask(mRegI dst, umemory mem, immI_255 mask) %{
9095 match(Set dst (AndI mask (LoadB mem)));
9096 ins_cost(60);
9098 format %{ "lbu $dst, $mem #@lbu_and_lmask" %}
9099 ins_encode(load_UB_enc(dst, mem));
9100 ins_pipe( ialu_loadI );
9101 %}
9103 instruct lbu_and_rmask(mRegI dst, umemory mem, immI_255 mask) %{
9104 match(Set dst (AndI (LoadB mem) mask));
9105 ins_cost(60);
9107 format %{ "lbu $dst, $mem #@lbu_and_rmask" %}
9108 ins_encode(load_UB_enc(dst, mem));
9109 ins_pipe( ialu_loadI );
9110 %}
9112 instruct andI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9113 match(Set dst (AndI src1 src2));
9115 format %{ "and $dst, $src1, $src2 #@andI_Reg_Reg" %}
9116 ins_encode %{
9117 Register dst = $dst$$Register;
9118 Register src1 = $src1$$Register;
9119 Register src2 = $src2$$Register;
9120 __ andr(dst, src1, src2);
9121 %}
9122 ins_pipe( ialu_regI_regI );
9123 %}
9125 instruct andnI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
9126 match(Set dst (AndI src1 (XorI src2 M1)));
9127 predicate(UseLoongsonISA && Use3A2000);
9129 format %{ "andn $dst, $src1, $src2 #@andnI_Reg_nReg" %}
9130 ins_encode %{
9131 Register dst = $dst$$Register;
9132 Register src1 = $src1$$Register;
9133 Register src2 = $src2$$Register;
9135 __ gsandn(dst, src1, src2);
9136 %}
9137 ins_pipe( ialu_regI_regI );
9138 %}
9140 instruct ornI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
9141 match(Set dst (OrI src1 (XorI src2 M1)));
9142 predicate(UseLoongsonISA && Use3A2000);
9144 format %{ "orn $dst, $src1, $src2 #@ornI_Reg_nReg" %}
9145 ins_encode %{
9146 Register dst = $dst$$Register;
9147 Register src1 = $src1$$Register;
9148 Register src2 = $src2$$Register;
9150 __ gsorn(dst, src1, src2);
9151 %}
9152 ins_pipe( ialu_regI_regI );
9153 %}
9155 instruct andnI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
9156 match(Set dst (AndI (XorI src1 M1) src2));
9157 predicate(UseLoongsonISA && Use3A2000);
9159 format %{ "andn $dst, $src2, $src1 #@andnI_nReg_Reg" %}
9160 ins_encode %{
9161 Register dst = $dst$$Register;
9162 Register src1 = $src1$$Register;
9163 Register src2 = $src2$$Register;
9165 __ gsandn(dst, src2, src1);
9166 %}
9167 ins_pipe( ialu_regI_regI );
9168 %}
9170 instruct ornI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
9171 match(Set dst (OrI (XorI src1 M1) src2));
9172 predicate(UseLoongsonISA && Use3A2000);
9174 format %{ "orn $dst, $src2, $src1 #@ornI_nReg_Reg" %}
9175 ins_encode %{
9176 Register dst = $dst$$Register;
9177 Register src1 = $src1$$Register;
9178 Register src2 = $src2$$Register;
9180 __ gsorn(dst, src2, src1);
9181 %}
9182 ins_pipe( ialu_regI_regI );
9183 %}
9185 // And Long Register with Register
9186 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
9187 match(Set dst (AndL src1 src2));
9188 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
9189 ins_encode %{
9190 Register dst_reg = as_Register($dst$$reg);
9191 Register src1_reg = as_Register($src1$$reg);
9192 Register src2_reg = as_Register($src2$$reg);
9194 __ andr(dst_reg, src1_reg, src2_reg);
9195 %}
9196 ins_pipe( ialu_regL_regL );
9197 %}
9199 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
9200 match(Set dst (AndL src1 (ConvI2L src2)));
9201 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
9202 ins_encode %{
9203 Register dst_reg = as_Register($dst$$reg);
9204 Register src1_reg = as_Register($src1$$reg);
9205 Register src2_reg = as_Register($src2$$reg);
9207 __ andr(dst_reg, src1_reg, src2_reg);
9208 %}
9209 ins_pipe( ialu_regL_regL );
9210 %}
9212 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
9213 match(Set dst (AndL src1 src2));
9214 ins_cost(60);
9216 format %{ "and $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
9217 ins_encode %{
9218 Register dst = $dst$$Register;
9219 Register src = $src1$$Register;
9220 long val = $src2$$constant;
9222 __ andi(dst, src, val);
9223 %}
9224 ins_pipe( ialu_regI_regI );
9225 %}
9227 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1, immL_0_65535 src2) %{
9228 match(Set dst (ConvL2I (AndL src1 src2)));
9229 ins_cost(60);
9231 format %{ "and $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
9232 ins_encode %{
9233 Register dst = $dst$$Register;
9234 Register src = $src1$$Register;
9235 long val = $src2$$constant;
9237 __ andi(dst, src, val);
9238 %}
9239 ins_pipe( ialu_regI_regI );
9240 %}
9242 /*
9243 instruct andnL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
9244 match(Set dst (AndL src1 (XorL src2 M1)));
9245 predicate(UseLoongsonISA);
9247 format %{ "andn $dst, $src1, $src2 #@andnL_Reg_nReg" %}
9248 ins_encode %{
9249 Register dst = $dst$$Register;
9250 Register src1 = $src1$$Register;
9251 Register src2 = $src2$$Register;
9253 __ gsandn(dst, src1, src2);
9254 %}
9255 ins_pipe( ialu_regI_regI );
9256 %}
9257 */
9259 /*
9260 instruct ornL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
9261 match(Set dst (OrL src1 (XorL src2 M1)));
9262 predicate(UseLoongsonISA);
9264 format %{ "orn $dst, $src1, $src2 #@ornL_Reg_nReg" %}
9265 ins_encode %{
9266 Register dst = $dst$$Register;
9267 Register src1 = $src1$$Register;
9268 Register src2 = $src2$$Register;
9270 __ gsorn(dst, src1, src2);
9271 %}
9272 ins_pipe( ialu_regI_regI );
9273 %}
9274 */
9276 /*
9277 instruct andnL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
9278 match(Set dst (AndL (XorL src1 M1) src2));
9279 predicate(UseLoongsonISA);
9281 format %{ "andn $dst, $src2, $src1 #@andnL_nReg_Reg" %}
9282 ins_encode %{
9283 Register dst = $dst$$Register;
9284 Register src1 = $src1$$Register;
9285 Register src2 = $src2$$Register;
9287 __ gsandn(dst, src2, src1);
9288 %}
9289 ins_pipe( ialu_regI_regI );
9290 %}
9291 */
9293 /*
9294 instruct ornL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
9295 match(Set dst (OrL (XorL src1 M1) src2));
9296 predicate(UseLoongsonISA);
9298 format %{ "orn $dst, $src2, $src1 #@ornL_nReg_Reg" %}
9299 ins_encode %{
9300 Register dst = $dst$$Register;
9301 Register src1 = $src1$$Register;
9302 Register src2 = $src2$$Register;
9304 __ gsorn(dst, src2, src1);
9305 %}
9306 ins_pipe( ialu_regI_regI );
9307 %}
9308 */
9310 instruct andL_Reg_immL_M8(mRegL dst, immL_M8 M8) %{
9311 match(Set dst (AndL dst M8));
9312 ins_cost(60);
9314 format %{ "and $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
9315 ins_encode %{
9316 Register dst = $dst$$Register;
9318 __ dins(dst, R0, 0, 3);
9319 %}
9320 ins_pipe( ialu_regI_regI );
9321 %}
9323 instruct andL_Reg_immL_M5(mRegL dst, immL_M5 M5) %{
9324 match(Set dst (AndL dst M5));
9325 ins_cost(60);
9327 format %{ "and $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
9328 ins_encode %{
9329 Register dst = $dst$$Register;
9331 __ dins(dst, R0, 2, 1);
9332 %}
9333 ins_pipe( ialu_regI_regI );
9334 %}
9336 instruct andL_Reg_immL_M7(mRegL dst, immL_M7 M7) %{
9337 match(Set dst (AndL dst M7));
9338 ins_cost(60);
9340 format %{ "and $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
9341 ins_encode %{
9342 Register dst = $dst$$Register;
9344 __ dins(dst, R0, 1, 2);
9345 %}
9346 ins_pipe( ialu_regI_regI );
9347 %}
9349 instruct andL_Reg_immL_M4(mRegL dst, immL_M4 M4) %{
9350 match(Set dst (AndL dst M4));
9351 ins_cost(60);
9353 format %{ "and $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
9354 ins_encode %{
9355 Register dst = $dst$$Register;
9357 __ dins(dst, R0, 0, 2);
9358 %}
9359 ins_pipe( ialu_regI_regI );
9360 %}
9362 instruct andL_Reg_immL_M121(mRegL dst, immL_M121 M121) %{
9363 match(Set dst (AndL dst M121));
9364 ins_cost(60);
9366 format %{ "and $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
9367 ins_encode %{
9368 Register dst = $dst$$Register;
9370 __ dins(dst, R0, 3, 4);
9371 %}
9372 ins_pipe( ialu_regI_regI );
9373 %}
9375 // Or Long Register with Register
9376 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
9377 match(Set dst (OrL src1 src2));
9378 format %{ "OR $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
9379 ins_encode %{
9380 Register dst_reg = $dst$$Register;
9381 Register src1_reg = $src1$$Register;
9382 Register src2_reg = $src2$$Register;
9384 __ orr(dst_reg, src1_reg, src2_reg);
9385 %}
9386 ins_pipe( ialu_regL_regL );
9387 %}
9389 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
9390 match(Set dst (OrL (CastP2X src1) src2));
9391 format %{ "OR $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
9392 ins_encode %{
9393 Register dst_reg = $dst$$Register;
9394 Register src1_reg = $src1$$Register;
9395 Register src2_reg = $src2$$Register;
9397 __ orr(dst_reg, src1_reg, src2_reg);
9398 %}
9399 ins_pipe( ialu_regL_regL );
9400 %}
9402 // Xor Long Register with Register
9403 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
9404 match(Set dst (XorL src1 src2));
9405 format %{ "XOR $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
9406 ins_encode %{
9407 Register dst_reg = as_Register($dst$$reg);
9408 Register src1_reg = as_Register($src1$$reg);
9409 Register src2_reg = as_Register($src2$$reg);
9411 __ xorr(dst_reg, src1_reg, src2_reg);
9412 %}
9413 ins_pipe( ialu_regL_regL );
9414 %}
9416 // Shift Left by 8-bit immediate
9417 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
9418 match(Set dst (LShiftI src shift));
9420 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm" %}
9421 ins_encode %{
9422 Register src = $src$$Register;
9423 Register dst = $dst$$Register;
9424 int shamt = $shift$$constant;
9426 __ sll(dst, src, shamt);
9427 %}
9428 ins_pipe( ialu_regI_regI );
9429 %}
9431 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
9432 match(Set dst (LShiftI (ConvL2I src) shift));
9434 format %{ "SHL $dst, $src, $shift #@salL2I_Reg_imm" %}
9435 ins_encode %{
9436 Register src = $src$$Register;
9437 Register dst = $dst$$Register;
9438 int shamt = $shift$$constant;
9440 __ sll(dst, src, shamt);
9441 %}
9442 ins_pipe( ialu_regI_regI );
9443 %}
9445 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
9446 match(Set dst (AndI (LShiftI src shift) mask));
9448 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
9449 ins_encode %{
9450 Register src = $src$$Register;
9451 Register dst = $dst$$Register;
9453 __ sll(dst, src, 16);
9454 %}
9455 ins_pipe( ialu_regI_regI );
9456 %}
9458 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
9459 %{
9460 match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
9462 format %{ "andi $dst, $src, 7\t# @land7_2_s" %}
9463 ins_encode %{
9464 Register src = $src$$Register;
9465 Register dst = $dst$$Register;
9467 __ andi(dst, src, 7);
9468 %}
9469 ins_pipe(ialu_regI_regI);
9470 %}
9472 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
9473 %{
9474 match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
9476 format %{ "ori $dst, $src1, $src2\t# @ori2s" %}
9477 ins_encode %{
9478 Register src = $src1$$Register;
9479 int val = $src2$$constant;
9480 Register dst = $dst$$Register;
9482 __ ori(dst, src, val);
9483 %}
9484 ins_pipe(ialu_regI_regI);
9485 %}
9487 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
9488 // This idiom is used by the compiler the i2s bytecode.
9489 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
9490 %{
9491 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
9493 format %{ "i2s $dst, $src\t# @i2s" %}
9494 ins_encode %{
9495 Register src = $src$$Register;
9496 Register dst = $dst$$Register;
9498 __ seh(dst, src);
9499 %}
9500 ins_pipe(ialu_regI_regI);
9501 %}
9503 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
9504 // This idiom is used by the compiler for the i2b bytecode.
9505 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
9506 %{
9507 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
9509 format %{ "i2b $dst, $src\t# @i2b" %}
9510 ins_encode %{
9511 Register src = $src$$Register;
9512 Register dst = $dst$$Register;
9514 __ seb(dst, src);
9515 %}
9516 ins_pipe(ialu_regI_regI);
9517 %}
9520 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
9521 match(Set dst (LShiftI (ConvL2I src) shift));
9523 format %{ "SHL $dst, $src, $shift #@salI_RegL2I_imm" %}
9524 ins_encode %{
9525 Register src = $src$$Register;
9526 Register dst = $dst$$Register;
9527 int shamt = $shift$$constant;
9529 __ sll(dst, src, shamt);
9530 %}
9531 ins_pipe( ialu_regI_regI );
9532 %}
9534 // Shift Left by 8-bit immediate
9535 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
9536 match(Set dst (LShiftI src shift));
9538 format %{ "SHL $dst, $src, $shift #@salI_Reg_Reg" %}
9539 ins_encode %{
9540 Register src = $src$$Register;
9541 Register dst = $dst$$Register;
9542 Register shamt = $shift$$Register;
9543 __ sllv(dst, src, shamt);
9544 %}
9545 ins_pipe( ialu_regI_regI );
9546 %}
9549 // Shift Left Long
9550 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
9551 //predicate(UseNewLongLShift);
9552 match(Set dst (LShiftL src shift));
9553 ins_cost(100);
9554 format %{ "salL $dst, $src, $shift @ salL_Reg_imm" %}
9555 ins_encode %{
9556 Register src_reg = as_Register($src$$reg);
9557 Register dst_reg = as_Register($dst$$reg);
9558 int shamt = $shift$$constant;
9560 if (__ is_simm(shamt, 5))
9561 __ dsll(dst_reg, src_reg, shamt);
9562 else
9563 {
9564 int sa = Assembler::low(shamt, 6);
9565 if (sa < 32) {
9566 __ dsll(dst_reg, src_reg, sa);
9567 } else {
9568 __ dsll32(dst_reg, src_reg, sa - 32);
9569 }
9570 }
9571 %}
9572 ins_pipe( ialu_regL_regL );
9573 %}
9575 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
9576 //predicate(UseNewLongLShift);
9577 match(Set dst (LShiftL (ConvI2L src) shift));
9578 ins_cost(100);
9579 format %{ "salL $dst, $src, $shift @ salL_RegI2L_imm" %}
9580 ins_encode %{
9581 Register src_reg = as_Register($src$$reg);
9582 Register dst_reg = as_Register($dst$$reg);
9583 int shamt = $shift$$constant;
9585 if (__ is_simm(shamt, 5))
9586 __ dsll(dst_reg, src_reg, shamt);
9587 else
9588 {
9589 int sa = Assembler::low(shamt, 6);
9590 if (sa < 32) {
9591 __ dsll(dst_reg, src_reg, sa);
9592 } else {
9593 __ dsll32(dst_reg, src_reg, sa - 32);
9594 }
9595 }
9596 %}
9597 ins_pipe( ialu_regL_regL );
9598 %}
9600 // Shift Left Long
9601 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
9602 //predicate(UseNewLongLShift);
9603 match(Set dst (LShiftL src shift));
9604 ins_cost(100);
9605 format %{ "salL $dst, $src, $shift @ salL_Reg_Reg" %}
9606 ins_encode %{
9607 Register src_reg = as_Register($src$$reg);
9608 Register dst_reg = as_Register($dst$$reg);
9610 __ dsllv(dst_reg, src_reg, $shift$$Register);
9611 %}
9612 ins_pipe( ialu_regL_regL );
9613 %}
9615 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
9616 match(Set dst (LShiftL (ConvI2L src) shift));
9617 ins_cost(100);
9618 format %{ "salL $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
9619 ins_encode %{
9620 Register src_reg = as_Register($src$$reg);
9621 Register dst_reg = as_Register($dst$$reg);
9622 int shamt = $shift$$constant;
9624 if (__ is_simm(shamt, 5)) {
9625 __ dsll(dst_reg, src_reg, shamt);
9626 } else {
9627 int sa = Assembler::low(shamt, 6);
9628 if (sa < 32) {
9629 __ dsll(dst_reg, src_reg, sa);
9630 } else {
9631 __ dsll32(dst_reg, src_reg, sa - 32);
9632 }
9633 }
9634 %}
9635 ins_pipe( ialu_regL_regL );
9636 %}
9638 // Shift Right Long
9639 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
9640 match(Set dst (RShiftL src shift));
9641 ins_cost(100);
9642 format %{ "sarL $dst, $src, $shift @ sarL_Reg_imm" %}
9643 ins_encode %{
9644 Register src_reg = as_Register($src$$reg);
9645 Register dst_reg = as_Register($dst$$reg);
9646 int shamt = ($shift$$constant & 0x3f);
9647 if (__ is_simm(shamt, 5))
9648 __ dsra(dst_reg, src_reg, shamt);
9649 else {
9650 int sa = Assembler::low(shamt, 6);
9651 if (sa < 32) {
9652 __ dsra(dst_reg, src_reg, sa);
9653 } else {
9654 __ dsra32(dst_reg, src_reg, sa - 32);
9655 }
9656 }
9657 %}
9658 ins_pipe( ialu_regL_regL );
9659 %}
9661 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
9662 match(Set dst (ConvL2I (RShiftL src shift)));
9663 ins_cost(100);
9664 format %{ "sarL $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
9665 ins_encode %{
9666 Register src_reg = as_Register($src$$reg);
9667 Register dst_reg = as_Register($dst$$reg);
9668 int shamt = $shift$$constant;
9670 __ dsra32(dst_reg, src_reg, shamt - 32);
9671 %}
9672 ins_pipe( ialu_regL_regL );
9673 %}
9675 // Shift Right Long arithmetically
9676 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
9677 //predicate(UseNewLongLShift);
9678 match(Set dst (RShiftL src shift));
9679 ins_cost(100);
9680 format %{ "sarL $dst, $src, $shift @ sarL_Reg_Reg" %}
9681 ins_encode %{
9682 Register src_reg = as_Register($src$$reg);
9683 Register dst_reg = as_Register($dst$$reg);
9685 __ dsrav(dst_reg, src_reg, $shift$$Register);
9686 %}
9687 ins_pipe( ialu_regL_regL );
9688 %}
9690 // Shift Right Long logically
9691 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
9692 match(Set dst (URShiftL src shift));
9693 ins_cost(100);
9694 format %{ "slrL $dst, $src, $shift @ slrL_Reg_Reg" %}
9695 ins_encode %{
9696 Register src_reg = as_Register($src$$reg);
9697 Register dst_reg = as_Register($dst$$reg);
9699 __ dsrlv(dst_reg, src_reg, $shift$$Register);
9700 %}
9701 ins_pipe( ialu_regL_regL );
9702 %}
9704 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
9705 match(Set dst (URShiftL src shift));
9706 ins_cost(80);
9707 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
9708 ins_encode %{
9709 Register src_reg = as_Register($src$$reg);
9710 Register dst_reg = as_Register($dst$$reg);
9711 int shamt = $shift$$constant;
9713 __ dsrl(dst_reg, src_reg, shamt);
9714 %}
9715 ins_pipe( ialu_regL_regL );
9716 %}
9718 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
9719 match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
9720 ins_cost(80);
9721 format %{ "dext $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
9722 ins_encode %{
9723 Register src_reg = as_Register($src$$reg);
9724 Register dst_reg = as_Register($dst$$reg);
9725 int shamt = $shift$$constant;
9727 __ dext(dst_reg, src_reg, shamt, 31);
9728 %}
9729 ins_pipe( ialu_regL_regL );
9730 %}
9732 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
9733 match(Set dst (URShiftL (CastP2X src) shift));
9734 ins_cost(80);
9735 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
9736 ins_encode %{
9737 Register src_reg = as_Register($src$$reg);
9738 Register dst_reg = as_Register($dst$$reg);
9739 int shamt = $shift$$constant;
9741 __ dsrl(dst_reg, src_reg, shamt);
9742 %}
9743 ins_pipe( ialu_regL_regL );
9744 %}
9746 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
9747 match(Set dst (URShiftL src shift));
9748 ins_cost(80);
9749 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
9750 ins_encode %{
9751 Register src_reg = as_Register($src$$reg);
9752 Register dst_reg = as_Register($dst$$reg);
9753 int shamt = $shift$$constant;
9755 __ dsrl32(dst_reg, src_reg, shamt - 32);
9756 %}
9757 ins_pipe( ialu_regL_regL );
9758 %}
9760 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
9761 match(Set dst (ConvL2I (URShiftL src shift)));
9762 predicate(n->in(1)->in(2)->get_int() > 32);
9763 ins_cost(80);
9764 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
9765 ins_encode %{
9766 Register src_reg = as_Register($src$$reg);
9767 Register dst_reg = as_Register($dst$$reg);
9768 int shamt = $shift$$constant;
9770 __ dsrl32(dst_reg, src_reg, shamt - 32);
9771 %}
9772 ins_pipe( ialu_regL_regL );
9773 %}
9775 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
9776 match(Set dst (URShiftL (CastP2X src) shift));
9777 ins_cost(80);
9778 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
9779 ins_encode %{
9780 Register src_reg = as_Register($src$$reg);
9781 Register dst_reg = as_Register($dst$$reg);
9782 int shamt = $shift$$constant;
9784 __ dsrl32(dst_reg, src_reg, shamt - 32);
9785 %}
9786 ins_pipe( ialu_regL_regL );
9787 %}
9789 // Xor Instructions
9790 // Xor Register with Register
9791 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9792 match(Set dst (XorI src1 src2));
9794 format %{ "XOR $dst, $src1, $src2 #@xorI_Reg_Reg" %}
9796 ins_encode %{
9797 Register dst = $dst$$Register;
9798 Register src1 = $src1$$Register;
9799 Register src2 = $src2$$Register;
9800 __ xorr(dst, src1, src2);
9801 __ sll(dst, dst, 0); /* long -> int */
9802 %}
9804 ins_pipe( ialu_regI_regI );
9805 %}
9807 // Or Instructions
9808 // Or Register with Register
9809 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9810 match(Set dst (OrI src1 src2));
9812 format %{ "OR $dst, $src1, $src2 #@orI_Reg_Reg" %}
9813 ins_encode %{
9814 Register dst = $dst$$Register;
9815 Register src1 = $src1$$Register;
9816 Register src2 = $src2$$Register;
9817 __ orr(dst, src1, src2);
9818 %}
9820 ins_pipe( ialu_regI_regI );
9821 %}
9823 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
9824 match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
9825 predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
9827 format %{ "rotr $dst, $src, 1 ...\n\t"
9828 "srl $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
9829 ins_encode %{
9830 Register dst = $dst$$Register;
9831 Register src = $src$$Register;
9832 int rshift = $rshift$$constant;
9834 __ rotr(dst, src, 1);
9835 if (rshift - 1) {
9836 __ srl(dst, dst, rshift - 1);
9837 }
9838 %}
9840 ins_pipe( ialu_regI_regI );
9841 %}
9843 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
9844 match(Set dst (OrI src1 (CastP2X src2)));
9846 format %{ "OR $dst, $src1, $src2 #@orI_Reg_castP2X" %}
9847 ins_encode %{
9848 Register dst = $dst$$Register;
9849 Register src1 = $src1$$Register;
9850 Register src2 = $src2$$Register;
9851 __ orr(dst, src1, src2);
9852 %}
9854 ins_pipe( ialu_regI_regI );
9855 %}
9857 // Logical Shift Right by 8-bit immediate
9858 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
9859 match(Set dst (URShiftI src shift));
9860 // effect(KILL cr);
9862 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_imm" %}
9863 ins_encode %{
9864 Register src = $src$$Register;
9865 Register dst = $dst$$Register;
9866 int shift = $shift$$constant;
9868 __ srl(dst, src, shift);
9869 %}
9870 ins_pipe( ialu_regI_regI );
9871 %}
9873 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
9874 match(Set dst (AndI (URShiftI src shift) mask));
9876 format %{ "ext $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
9877 ins_encode %{
9878 Register src = $src$$Register;
9879 Register dst = $dst$$Register;
9880 int pos = $shift$$constant;
9881 int size = Assembler::is_int_mask($mask$$constant);
9883 __ ext(dst, src, pos, size);
9884 %}
9885 ins_pipe( ialu_regI_regI );
9886 %}
9888 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
9889 %{
9890 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9891 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
9893 ins_cost(100);
9894 format %{ "rotr $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
9895 ins_encode %{
9896 Register dst = $dst$$Register;
9897 int sa = $rshift$$constant;
9899 __ rotr(dst, dst, sa);
9900 %}
9901 ins_pipe( ialu_regI_regI );
9902 %}
9904 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
9905 %{
9906 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9907 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
9909 ins_cost(100);
9910 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
9911 ins_encode %{
9912 Register dst = $dst$$Register;
9913 int sa = $rshift$$constant;
9915 __ drotr(dst, dst, sa);
9916 %}
9917 ins_pipe( ialu_regI_regI );
9918 %}
9920 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
9921 %{
9922 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9923 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
9925 ins_cost(100);
9926 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
9927 ins_encode %{
9928 Register dst = $dst$$Register;
9929 int sa = $rshift$$constant;
9931 __ drotr32(dst, dst, sa - 32);
9932 %}
9933 ins_pipe( ialu_regI_regI );
9934 %}
9936 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
9937 %{
9938 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
9939 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
9941 ins_cost(100);
9942 format %{ "rotr $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
9943 ins_encode %{
9944 Register dst = $dst$$Register;
9945 int sa = $rshift$$constant;
9947 __ rotr(dst, dst, sa);
9948 %}
9949 ins_pipe( ialu_regI_regI );
9950 %}
9952 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
9953 %{
9954 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9955 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
9957 ins_cost(100);
9958 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
9959 ins_encode %{
9960 Register dst = $dst$$Register;
9961 int sa = $rshift$$constant;
9963 __ drotr(dst, dst, sa);
9964 %}
9965 ins_pipe( ialu_regI_regI );
9966 %}
9968 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
9969 %{
9970 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
9971 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
9973 ins_cost(100);
9974 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
9975 ins_encode %{
9976 Register dst = $dst$$Register;
9977 int sa = $rshift$$constant;
9979 __ drotr32(dst, dst, sa - 32);
9980 %}
9981 ins_pipe( ialu_regI_regI );
9982 %}
9984 // Logical Shift Right
9985 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
9986 match(Set dst (URShiftI src shift));
9988 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_Reg" %}
9989 ins_encode %{
9990 Register src = $src$$Register;
9991 Register dst = $dst$$Register;
9992 Register shift = $shift$$Register;
9993 __ srlv(dst, src, shift);
9994 %}
9995 ins_pipe( ialu_regI_regI );
9996 %}
9999 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
10000 match(Set dst (RShiftI src shift));
10001 // effect(KILL cr);
10003 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_imm" %}
10004 ins_encode %{
10005 Register src = $src$$Register;
10006 Register dst = $dst$$Register;
10007 int shift = $shift$$constant;
10008 __ sra(dst, src, shift);
10009 %}
10010 ins_pipe( ialu_regI_regI );
10011 %}
10013 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
10014 match(Set dst (RShiftI src shift));
10015 // effect(KILL cr);
10017 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_Reg" %}
10018 ins_encode %{
10019 Register src = $src$$Register;
10020 Register dst = $dst$$Register;
10021 Register shift = $shift$$Register;
10022 __ srav(dst, src, shift);
10023 %}
10024 ins_pipe( ialu_regI_regI );
10025 %}
10027 //----------Convert Int to Boolean---------------------------------------------
10029 instruct convI2B(mRegI dst, mRegI src) %{
10030 match(Set dst (Conv2B src));
10032 ins_cost(100);
10033 format %{ "convI2B $dst, $src @ convI2B" %}
10034 ins_encode %{
10035 Register dst = as_Register($dst$$reg);
10036 Register src = as_Register($src$$reg);
10038 if (dst != src) {
10039 __ daddiu(dst, R0, 1);
10040 __ movz(dst, R0, src);
10041 } else {
10042 __ move(AT, src);
10043 __ daddiu(dst, R0, 1);
10044 __ movz(dst, R0, AT);
10045 }
10046 %}
10048 ins_pipe( ialu_regL_regL );
10049 %}
10051 instruct convI2L_reg( mRegL dst, mRegI src) %{
10052 match(Set dst (ConvI2L src));
10054 ins_cost(100);
10055 format %{ "SLL $dst, $src @ convI2L_reg\t" %}
10056 ins_encode %{
10057 Register dst = as_Register($dst$$reg);
10058 Register src = as_Register($src$$reg);
10060 if(dst != src) __ sll(dst, src, 0);
10061 %}
10062 ins_pipe( ialu_regL_regL );
10063 %}
10066 instruct convL2I_reg( mRegI dst, mRegL src ) %{
10067 match(Set dst (ConvL2I src));
10069 format %{ "MOV $dst, $src @ convL2I_reg" %}
10070 ins_encode %{
10071 Register dst = as_Register($dst$$reg);
10072 Register src = as_Register($src$$reg);
10074 __ sll(dst, src, 0);
10075 %}
10077 ins_pipe( ialu_regI_regI );
10078 %}
10080 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
10081 match(Set dst (ConvI2L (ConvL2I src)));
10083 format %{ "sll $dst, $src, 0 @ convL2I2L_reg" %}
10084 ins_encode %{
10085 Register dst = as_Register($dst$$reg);
10086 Register src = as_Register($src$$reg);
10088 __ sll(dst, src, 0);
10089 %}
10091 ins_pipe( ialu_regI_regI );
10092 %}
10094 instruct convL2D_reg( regD dst, mRegL src ) %{
10095 match(Set dst (ConvL2D src));
10096 format %{ "convL2D $dst, $src @ convL2D_reg" %}
10097 ins_encode %{
10098 Register src = as_Register($src$$reg);
10099 FloatRegister dst = as_FloatRegister($dst$$reg);
10101 __ dmtc1(src, dst);
10102 __ cvt_d_l(dst, dst);
10103 %}
10105 ins_pipe( pipe_slow );
10106 %}
10108 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
10109 match(Set dst (ConvD2L src));
10110 ins_cost(150);
10111 format %{ "convD2L $dst, $src @ convD2L_reg_fast" %}
10112 ins_encode %{
10113 Register dst = as_Register($dst$$reg);
10114 FloatRegister src = as_FloatRegister($src$$reg);
10116 Label Done;
10118 __ trunc_l_d(F30, src);
10119 // max_long: 0x7fffffffffffffff
10120 // __ set64(AT, 0x7fffffffffffffff);
10121 __ daddiu(AT, R0, -1);
10122 __ dsrl(AT, AT, 1);
10123 __ dmfc1(dst, F30);
10125 __ bne(dst, AT, Done);
10126 __ delayed()->mtc1(R0, F30);
10128 __ cvt_d_w(F30, F30);
10129 __ c_ult_d(src, F30);
10130 __ bc1f(Done);
10131 __ delayed()->daddiu(T9, R0, -1);
10133 __ c_un_d(src, src); //NaN?
10134 __ subu(dst, T9, AT);
10135 __ movt(dst, R0);
10137 __ bind(Done);
10138 %}
10140 ins_pipe( pipe_slow );
10141 %}
10143 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
10144 match(Set dst (ConvD2L src));
10145 ins_cost(250);
10146 format %{ "convD2L $dst, $src @ convD2L_reg_slow" %}
10147 ins_encode %{
10148 Register dst = as_Register($dst$$reg);
10149 FloatRegister src = as_FloatRegister($src$$reg);
10151 Label L;
10153 __ c_un_d(src, src); //NaN?
10154 __ bc1t(L);
10155 __ delayed();
10156 __ move(dst, R0);
10158 __ trunc_l_d(F30, src);
10159 __ cfc1(AT, 31);
10160 __ li(T9, 0x10000);
10161 __ andr(AT, AT, T9);
10162 __ beq(AT, R0, L);
10163 __ delayed()->dmfc1(dst, F30);
10165 __ mov_d(F12, src);
10166 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
10167 __ move(dst, V0);
10168 __ bind(L);
10169 %}
10171 ins_pipe( pipe_slow );
10172 %}
10174 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
10175 match(Set dst (ConvF2I src));
10176 ins_cost(150);
10177 format %{ "convf2i $dst, $src @ convF2I_reg_fast" %}
10178 ins_encode %{
10179 Register dreg = $dst$$Register;
10180 FloatRegister fval = $src$$FloatRegister;
10182 __ trunc_w_s(F30, fval);
10183 __ mfc1(dreg, F30);
10184 __ c_un_s(fval, fval); //NaN?
10185 __ movt(dreg, R0);
10186 %}
10188 ins_pipe( pipe_slow );
10189 %}
10191 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
10192 match(Set dst (ConvF2I src));
10193 ins_cost(250);
10194 format %{ "convf2i $dst, $src @ convF2I_reg_slow" %}
10195 ins_encode %{
10196 Register dreg = $dst$$Register;
10197 FloatRegister fval = $src$$FloatRegister;
10198 Label L;
10200 __ c_un_s(fval, fval); //NaN?
10201 __ bc1t(L);
10202 __ delayed();
10203 __ move(dreg, R0);
10205 __ trunc_w_s(F30, fval);
10207 /* Call SharedRuntime:f2i() to do valid convention */
10208 __ cfc1(AT, 31);
10209 __ li(T9, 0x10000);
10210 __ andr(AT, AT, T9);
10211 __ beq(AT, R0, L);
10212 __ delayed()->mfc1(dreg, F30);
10214 __ mov_s(F12, fval);
10216 /* 2014/01/08 Fu : This bug was found when running ezDS's control-panel.
10217 * J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
10218 *
10219 * An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
10220 * V0 is corrupted during call_VM_leaf(), and should be preserved.
10221 */
10222 if(dreg != V0) {
10223 __ push(V0);
10224 }
10225 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
10226 if(dreg != V0) {
10227 __ move(dreg, V0);
10228 __ pop(V0);
10229 }
10230 __ bind(L);
10231 %}
10233 ins_pipe( pipe_slow );
10234 %}
10236 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
10237 match(Set dst (ConvF2L src));
10238 ins_cost(150);
10239 format %{ "convf2l $dst, $src @ convF2L_reg_fast" %}
10240 ins_encode %{
10241 Register dreg = $dst$$Register;
10242 FloatRegister fval = $src$$FloatRegister;
10244 __ trunc_l_s(F30, fval);
10245 __ dmfc1(dreg, F30);
10246 __ c_un_s(fval, fval); //NaN?
10247 __ movt(dreg, R0);
10248 %}
10250 ins_pipe( pipe_slow );
10251 %}
10253 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
10254 match(Set dst (ConvF2L src));
10255 ins_cost(250);
10256 format %{ "convf2l $dst, $src @ convF2L_reg_slow" %}
10257 ins_encode %{
10258 Register dst = as_Register($dst$$reg);
10259 FloatRegister fval = $src$$FloatRegister;
10260 Label L;
10262 __ c_un_s(fval, fval); //NaN?
10263 __ bc1t(L);
10264 __ delayed();
10265 __ move(dst, R0);
10267 __ trunc_l_s(F30, fval);
10268 __ cfc1(AT, 31);
10269 __ li(T9, 0x10000);
10270 __ andr(AT, AT, T9);
10271 __ beq(AT, R0, L);
10272 __ delayed()->dmfc1(dst, F30);
10274 __ mov_s(F12, fval);
10275 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
10276 __ move(dst, V0);
10277 __ bind(L);
10278 %}
10280 ins_pipe( pipe_slow );
10281 %}
10283 instruct convL2F_reg( regF dst, mRegL src ) %{
10284 match(Set dst (ConvL2F src));
10285 format %{ "convl2f $dst, $src @ convL2F_reg" %}
10286 ins_encode %{
10287 FloatRegister dst = $dst$$FloatRegister;
10288 Register src = as_Register($src$$reg);
10289 Label L;
10291 __ dmtc1(src, dst);
10292 __ cvt_s_l(dst, dst);
10293 %}
10295 ins_pipe( pipe_slow );
10296 %}
10298 instruct convI2F_reg( regF dst, mRegI src ) %{
10299 match(Set dst (ConvI2F src));
10300 format %{ "convi2f $dst, $src @ convI2F_reg" %}
10301 ins_encode %{
10302 Register src = $src$$Register;
10303 FloatRegister dst = $dst$$FloatRegister;
10305 __ mtc1(src, dst);
10306 __ cvt_s_w(dst, dst);
10307 %}
10309 ins_pipe( fpu_regF_regF );
10310 %}
10312 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
10313 match(Set dst (CmpLTMask p zero));
10314 ins_cost(100);
10316 format %{ "sra $dst, $p, 31 @ cmpLTMask_immI0" %}
10317 ins_encode %{
10318 Register src = $p$$Register;
10319 Register dst = $dst$$Register;
10321 __ sra(dst, src, 31);
10322 %}
10323 ins_pipe( pipe_slow );
10324 %}
10327 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
10328 match(Set dst (CmpLTMask p q));
10329 ins_cost(400);
10331 format %{ "cmpLTMask $dst, $p, $q @ cmpLTMask" %}
10332 ins_encode %{
10333 Register p = $p$$Register;
10334 Register q = $q$$Register;
10335 Register dst = $dst$$Register;
10337 __ slt(dst, p, q);
10338 __ subu(dst, R0, dst);
10339 %}
10340 ins_pipe( pipe_slow );
10341 %}
10343 instruct convP2B(mRegI dst, mRegP src) %{
10344 match(Set dst (Conv2B src));
10346 ins_cost(100);
10347 format %{ "convP2B $dst, $src @ convP2B" %}
10348 ins_encode %{
10349 Register dst = as_Register($dst$$reg);
10350 Register src = as_Register($src$$reg);
10352 if (dst != src) {
10353 __ daddiu(dst, R0, 1);
10354 __ movz(dst, R0, src);
10355 } else {
10356 __ move(AT, src);
10357 __ daddiu(dst, R0, 1);
10358 __ movz(dst, R0, AT);
10359 }
10360 %}
10362 ins_pipe( ialu_regL_regL );
10363 %}
10366 instruct convI2D_reg_reg(regD dst, mRegI src) %{
10367 match(Set dst (ConvI2D src));
10368 format %{ "conI2D $dst, $src @convI2D_reg" %}
10369 ins_encode %{
10370 Register src = $src$$Register;
10371 FloatRegister dst = $dst$$FloatRegister;
10372 __ mtc1(src, dst);
10373 __ cvt_d_w(dst, dst);
10374 %}
10375 ins_pipe( fpu_regF_regF );
10376 %}
10378 instruct convF2D_reg_reg(regD dst, regF src) %{
10379 match(Set dst (ConvF2D src));
10380 format %{ "convF2D $dst, $src\t# @convF2D_reg_reg" %}
10381 ins_encode %{
10382 FloatRegister dst = $dst$$FloatRegister;
10383 FloatRegister src = $src$$FloatRegister;
10385 __ cvt_d_s(dst, src);
10386 %}
10387 ins_pipe( fpu_regF_regF );
10388 %}
10390 instruct convD2F_reg_reg(regF dst, regD src) %{
10391 match(Set dst (ConvD2F src));
10392 format %{ "convD2F $dst, $src\t# @convD2F_reg_reg" %}
10393 ins_encode %{
10394 FloatRegister dst = $dst$$FloatRegister;
10395 FloatRegister src = $src$$FloatRegister;
10397 __ cvt_s_d(dst, src);
10398 %}
10399 ins_pipe( fpu_regF_regF );
10400 %}
10402 // Convert a double to an int. If the double is a NAN, stuff a zero in instead.
10403 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
10404 match(Set dst (ConvD2I src));
10406 ins_cost(150);
10407 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
10409 ins_encode %{
10410 FloatRegister src = $src$$FloatRegister;
10411 Register dst = $dst$$Register;
10413 Label Done;
10415 __ trunc_w_d(F30, src);
10416 // max_int: 2147483647
10417 __ move(AT, 0x7fffffff);
10418 __ mfc1(dst, F30);
10420 __ bne(dst, AT, Done);
10421 __ delayed()->mtc1(R0, F30);
10423 __ cvt_d_w(F30, F30);
10424 __ c_ult_d(src, F30);
10425 __ bc1f(Done);
10426 __ delayed()->addiu(T9, R0, -1);
10428 __ c_un_d(src, src); //NaN?
10429 __ subu32(dst, T9, AT);
10430 __ movt(dst, R0);
10432 __ bind(Done);
10433 %}
10434 ins_pipe( pipe_slow );
10435 %}
10437 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
10438 match(Set dst (ConvD2I src));
10440 ins_cost(250);
10441 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
10443 ins_encode %{
10444 FloatRegister src = $src$$FloatRegister;
10445 Register dst = $dst$$Register;
10446 Label L;
10448 __ trunc_w_d(F30, src);
10449 __ cfc1(AT, 31);
10450 __ li(T9, 0x10000);
10451 __ andr(AT, AT, T9);
10452 __ beq(AT, R0, L);
10453 __ delayed()->mfc1(dst, F30);
10455 __ mov_d(F12, src);
10456 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
10457 __ move(dst, V0);
10458 __ bind(L);
10460 %}
10461 ins_pipe( pipe_slow );
10462 %}
10464 // Convert oop pointer into compressed form
10465 instruct encodeHeapOop(mRegN dst, mRegP src) %{
10466 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
10467 match(Set dst (EncodeP src));
10468 format %{ "encode_heap_oop $dst,$src" %}
10469 ins_encode %{
10470 Register src = $src$$Register;
10471 Register dst = $dst$$Register;
10472 if (src != dst) {
10473 __ move(dst, src);
10474 }
10475 __ encode_heap_oop(dst);
10476 %}
10477 ins_pipe( ialu_regL_regL );
10478 %}
10480 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
10481 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
10482 match(Set dst (EncodeP src));
10483 format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
10484 ins_encode %{
10485 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
10486 %}
10487 ins_pipe( ialu_regL_regL );
10488 %}
10490 instruct decodeHeapOop(mRegP dst, mRegN src) %{
10491 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
10492 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
10493 match(Set dst (DecodeN src));
10494 format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
10495 ins_encode %{
10496 Register s = $src$$Register;
10497 Register d = $dst$$Register;
10498 if (s != d) {
10499 __ move(d, s);
10500 }
10501 __ decode_heap_oop(d);
10502 %}
10503 ins_pipe( ialu_regL_regL );
10504 %}
10506 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
10507 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
10508 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
10509 match(Set dst (DecodeN src));
10510 format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
10511 ins_encode %{
10512 Register s = $src$$Register;
10513 Register d = $dst$$Register;
10514 if (s != d) {
10515 __ decode_heap_oop_not_null(d, s);
10516 } else {
10517 __ decode_heap_oop_not_null(d);
10518 }
10519 %}
10520 ins_pipe( ialu_regL_regL );
10521 %}
10523 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
10524 match(Set dst (EncodePKlass src));
10525 format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
10526 ins_encode %{
10527 __ encode_klass_not_null($dst$$Register, $src$$Register);
10528 %}
10529 ins_pipe( ialu_regL_regL );
10530 %}
10532 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
10533 match(Set dst (DecodeNKlass src));
10534 format %{ "decode_heap_klass_not_null $dst,$src" %}
10535 ins_encode %{
10536 Register s = $src$$Register;
10537 Register d = $dst$$Register;
10538 if (s != d) {
10539 __ decode_klass_not_null(d, s);
10540 } else {
10541 __ decode_klass_not_null(d);
10542 }
10543 %}
10544 ins_pipe( ialu_regL_regL );
10545 %}
10547 //FIXME
10548 instruct tlsLoadP(mRegP dst) %{
10549 match(Set dst (ThreadLocal));
10551 ins_cost(0);
10552 format %{ " get_thread in $dst #@tlsLoadP" %}
10553 ins_encode %{
10554 Register dst = $dst$$Register;
10555 #ifdef OPT_THREAD
10556 __ move(dst, TREG);
10557 #else
10558 __ get_thread(dst);
10559 #endif
10560 %}
10562 ins_pipe( ialu_loadI );
10563 %}
10566 instruct checkCastPP( mRegP dst ) %{
10567 match(Set dst (CheckCastPP dst));
10569 format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
10570 ins_encode( /*empty encoding*/ );
10571 ins_pipe( empty );
10572 %}
10574 instruct castPP(mRegP dst)
10575 %{
10576 match(Set dst (CastPP dst));
10578 size(0);
10579 format %{ "# castPP of $dst" %}
10580 ins_encode(/* empty encoding */);
10581 ins_pipe(empty);
10582 %}
10584 instruct castII( mRegI dst ) %{
10585 match(Set dst (CastII dst));
10586 format %{ "#castII of $dst empty encoding" %}
10587 ins_encode( /*empty encoding*/ );
10588 ins_cost(0);
10589 ins_pipe( empty );
10590 %}
10592 // Return Instruction
10593 // Remove the return address & jump to it.
10594 instruct Ret() %{
10595 match(Return);
10596 format %{ "RET #@Ret" %}
10598 ins_encode %{
10599 __ jr(RA);
10600 __ nop();
10601 %}
10603 ins_pipe( pipe_jump );
10604 %}
10606 /*
10607 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
10608 instruct jumpXtnd(mRegL switch_val) %{
10609 match(Jump switch_val);
10611 ins_cost(350);
10613 format %{ "load T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
10614 "jr T9\n\t"
10615 "nop" %}
10616 ins_encode %{
10617 Register table_base = $constanttablebase;
10618 int con_offset = $constantoffset;
10619 Register switch_reg = $switch_val$$Register;
10621 if (UseLoongsonISA) {
10622 if (Assembler::is_simm(con_offset, 8)) {
10623 __ gsldx(T9, table_base, switch_reg, con_offset);
10624 } else if (Assembler::is_simm16(con_offset)) {
10625 __ daddu(T9, table_base, switch_reg);
10626 __ ld(T9, T9, con_offset);
10627 } else {
10628 __ move(T9, con_offset);
10629 __ daddu(AT, table_base, switch_reg);
10630 __ gsldx(T9, AT, T9, 0);
10631 }
10632 } else {
10633 if (Assembler::is_simm16(con_offset)) {
10634 __ daddu(T9, table_base, switch_reg);
10635 __ ld(T9, T9, con_offset);
10636 } else {
10637 __ move(T9, con_offset);
10638 __ daddu(AT, table_base, switch_reg);
10639 __ daddu(AT, T9, AT);
10640 __ ld(T9, AT, 0);
10641 }
10642 }
10644 __ jr(T9);
10645 __ nop();
10647 %}
10648 ins_pipe(pipe_jump);
10649 %}
10650 */
10652 // Jump Direct - Label defines a relative address from JMP
10653 instruct jmpDir(label labl) %{
10654 match(Goto);
10655 effect(USE labl);
10657 ins_cost(300);
10658 format %{ "JMP $labl #@jmpDir" %}
10660 ins_encode %{
10661 Label &L = *($labl$$label);
10662 if(&L)
10663 __ b(L);
10664 else
10665 __ b(int(0));
10666 __ nop();
10667 %}
10669 ins_pipe( pipe_jump );
10670 ins_pc_relative(1);
10671 %}
10675 // Tail Jump; remove the return address; jump to target.
10676 // TailCall above leaves the return address around.
10677 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
10678 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
10679 // "restore" before this instruction (in Epilogue), we need to materialize it
10680 // in %i0.
10681 //FIXME
10682 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
10683 match( TailJump jump_target ex_oop );
10684 ins_cost(200);
10685 format %{ "Jmp $jump_target ; ex_oop = $ex_oop #@tailjmpInd" %}
10686 ins_encode %{
10687 Register target = $jump_target$$Register;
10689 /* 2012/9/14 Jin: V0, V1 are indicated in:
10690 * [stubGenerator_mips.cpp] generate_forward_exception()
10691 * [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
10692 */
10693 Register oop = $ex_oop$$Register;
10694 Register exception_oop = V0;
10695 Register exception_pc = V1;
10697 __ move(exception_pc, RA);
10698 __ move(exception_oop, oop);
10700 __ jr(target);
10701 __ nop();
10702 %}
10703 ins_pipe( pipe_jump );
10704 %}
10706 // ============================================================================
10707 // Procedure Call/Return Instructions
10708 // Call Java Static Instruction
10709 // Note: If this code changes, the corresponding ret_addr_offset() and
10710 // compute_padding() functions will have to be adjusted.
10711 instruct CallStaticJavaDirect(method meth) %{
10712 match(CallStaticJava);
10713 effect(USE meth);
10715 ins_cost(300);
10716 format %{ "CALL,static #@CallStaticJavaDirect " %}
10717 ins_encode( Java_Static_Call( meth ) );
10718 ins_pipe( pipe_slow );
10719 ins_pc_relative(1);
10720 %}
10722 // Call Java Dynamic Instruction
10723 // Note: If this code changes, the corresponding ret_addr_offset() and
10724 // compute_padding() functions will have to be adjusted.
10725 instruct CallDynamicJavaDirect(method meth) %{
10726 match(CallDynamicJava);
10727 effect(USE meth);
10729 ins_cost(300);
10730 format %{"MOV IC_Klass, (oop)-1\n\t"
10731 "CallDynamic @ CallDynamicJavaDirect" %}
10732 ins_encode( Java_Dynamic_Call( meth ) );
10733 ins_pipe( pipe_slow );
10734 ins_pc_relative(1);
10735 %}
10737 instruct CallLeafNoFPDirect(method meth) %{
10738 match(CallLeafNoFP);
10739 effect(USE meth);
10741 ins_cost(300);
10742 format %{ "CALL_LEAF_NOFP,runtime " %}
10743 ins_encode(Java_To_Runtime(meth));
10744 ins_pipe( pipe_slow );
10745 ins_pc_relative(1);
10746 ins_alignment(16);
10747 %}
10749 // Prefetch instructions.
10751 instruct prefetchrNTA( umemory mem ) %{
10752 match(PrefetchRead mem);
10753 ins_cost(125);
10755 format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
10756 ins_encode %{
10757 int base = $mem$$base;
10758 int index = $mem$$index;
10759 int scale = $mem$$scale;
10760 int disp = $mem$$disp;
10762 assert(index == 0, "no index");
10763 __ daddiu(AT, as_Register(base), disp);
10764 __ pref(0, AT, 0); //hint: 0:load
10765 %}
10766 ins_pipe(pipe_slow);
10767 %}
10769 instruct prefetchwNTA( umemory mem ) %{
10770 match(PrefetchWrite mem);
10771 ins_cost(125);
10772 format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
10773 ins_encode %{
10774 int base = $mem$$base;
10775 int index = $mem$$index;
10776 int scale = $mem$$scale;
10777 int disp = $mem$$disp;
10779 assert(index == 0, "no index");
10780 __ daddiu(AT, as_Register(base), disp);
10781 __ pref(1, AT, 0); //hint: 1:store
10782 %}
10783 ins_pipe(pipe_slow);
10784 %}
10786 // Prefetch instructions for allocation.
10788 instruct prefetchAllocNTA( memory mem ) %{
10789 match(PrefetchAllocation mem);
10790 ins_cost(125);
10791 format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
10792 ins_encode %{
10793 int base = $mem$$base;
10794 int index = $mem$$index;
10795 int scale = $mem$$scale;
10796 int disp = $mem$$disp;
10798 Register dst = R0;
10800 if( index != 0 ) {
10801 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
10802 __ gslbx(dst, as_Register(base), as_Register(index), disp);
10803 } else {
10804 __ lb(dst, as_Register(base), disp);
10805 }
10806 %}
10807 ins_pipe(pipe_slow);
10808 %}
10811 // Call runtime without safepoint
10812 instruct CallLeafDirect(method meth) %{
10813 match(CallLeaf);
10814 effect(USE meth);
10816 ins_cost(300);
10817 format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
10818 ins_encode(Java_To_Runtime(meth));
10819 ins_pipe( pipe_slow );
10820 ins_pc_relative(1);
10821 ins_alignment(16);
10822 %}
10824 // Load Char (16bit unsigned)
10825 instruct loadUS(mRegI dst, umemory mem) %{
10826 match(Set dst (LoadUS mem));
10828 ins_cost(125);
10829 format %{ "loadUS $dst,$mem @ loadC" %}
10830 ins_encode(load_C_enc(dst, mem));
10831 ins_pipe( ialu_loadI );
10832 %}
10834 instruct loadUS_convI2L(mRegL dst, umemory mem) %{
10835 match(Set dst (ConvI2L (LoadUS mem)));
10837 ins_cost(125);
10838 format %{ "loadUS $dst,$mem @ loadUS_convI2L" %}
10839 ins_encode(load_C_enc(dst, mem));
10840 ins_pipe( ialu_loadI );
10841 %}
10843 // Store Char (16bit unsigned)
10844 instruct storeC(memory mem, mRegI src) %{
10845 match(Set mem (StoreC mem src));
10847 ins_cost(125);
10848 format %{ "storeC $src, $mem @ storeC" %}
10849 ins_encode(store_C_reg_enc(mem, src));
10850 ins_pipe( ialu_loadI );
10851 %}
10853 instruct storeC0(memory mem, immI0 zero) %{
10854 match(Set mem (StoreC mem zero));
10856 ins_cost(125);
10857 format %{ "storeC $zero, $mem @ storeC0" %}
10858 ins_encode(store_C0_enc(mem));
10859 ins_pipe( ialu_loadI );
10860 %}
10863 instruct loadConF0(regF dst, immF0 zero) %{
10864 match(Set dst zero);
10865 ins_cost(100);
10867 format %{ "mov $dst, zero @ loadConF0\n"%}
10868 ins_encode %{
10869 FloatRegister dst = $dst$$FloatRegister;
10871 __ mtc1(R0, dst);
10872 %}
10873 ins_pipe( fpu_loadF );
10874 %}
10877 instruct loadConF(regF dst, immF src) %{
10878 match(Set dst src);
10879 ins_cost(125);
10881 format %{ "lwc1 $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
10882 ins_encode %{
10883 int con_offset = $constantoffset($src);
10885 if (Assembler::is_simm16(con_offset)) {
10886 __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
10887 } else {
10888 __ set64(AT, con_offset);
10889 if (UseLoongsonISA) {
10890 __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
10891 } else {
10892 __ daddu(AT, $constanttablebase, AT);
10893 __ lwc1($dst$$FloatRegister, AT, 0);
10894 }
10895 }
10896 %}
10897 ins_pipe( fpu_loadF );
10898 %}
10901 instruct loadConD0(regD dst, immD0 zero) %{
10902 match(Set dst zero);
10903 ins_cost(100);
10905 format %{ "mov $dst, zero @ loadConD0"%}
10906 ins_encode %{
10907 FloatRegister dst = as_FloatRegister($dst$$reg);
10909 __ dmtc1(R0, dst);
10910 %}
10911 ins_pipe( fpu_loadF );
10912 %}
10914 instruct loadConD(regD dst, immD src) %{
10915 match(Set dst src);
10916 ins_cost(125);
10918 format %{ "ldc1 $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
10919 ins_encode %{
10920 int con_offset = $constantoffset($src);
10922 if (Assembler::is_simm16(con_offset)) {
10923 __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
10924 } else {
10925 __ set64(AT, con_offset);
10926 if (UseLoongsonISA) {
10927 __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
10928 } else {
10929 __ daddu(AT, $constanttablebase, AT);
10930 __ ldc1($dst$$FloatRegister, AT, 0);
10931 }
10932 }
10933 %}
10934 ins_pipe( fpu_loadF );
10935 %}
10937 // Store register Float value (it is faster than store from FPU register)
10938 instruct storeF_reg( memory mem, regF src) %{
10939 match(Set mem (StoreF mem src));
10941 ins_cost(50);
10942 format %{ "store $mem, $src\t# store float @ storeF_reg" %}
10943 ins_encode(store_F_reg_enc(mem, src));
10944 ins_pipe( fpu_storeF );
10945 %}
10947 instruct storeF_imm0( memory mem, immF0 zero) %{
10948 match(Set mem (StoreF mem zero));
10950 ins_cost(40);
10951 format %{ "store $mem, zero\t# store float @ storeF_imm0" %}
10952 ins_encode %{
10953 int base = $mem$$base;
10954 int index = $mem$$index;
10955 int scale = $mem$$scale;
10956 int disp = $mem$$disp;
10958 if( index != 0 ) {
10959 assert(UseLoongsonISA, "Only supported for Loongson CPUs");
10960 __ gsswx(R0, as_Register(base), as_Register(index), disp);
10961 } else {
10962 __ sw(R0, as_Register(base), disp);
10963 }
10964 %}
10965 ins_pipe( ialu_storeI );
10966 %}
10968 // Load Double
10969 instruct loadD(regD dst, memory mem) %{
10970 match(Set dst (LoadD mem));
10972 ins_cost(150);
10973 format %{ "loadD $dst, $mem #@loadD" %}
10974 ins_encode(load_D_enc(dst, mem));
10975 ins_pipe( ialu_loadI );
10976 %}
10978 // Load Double - UNaligned
10979 instruct loadD_unaligned(regD dst, memory mem ) %{
10980 match(Set dst (LoadD_unaligned mem));
10981 ins_cost(250);
10982 // FIXME: Jin: Need more effective ldl/ldr
10983 format %{ "loadD_unaligned $dst, $mem #@loadD_unaligned" %}
10984 ins_encode(load_D_enc(dst, mem));
10985 ins_pipe( ialu_loadI );
10986 %}
10988 instruct storeD_reg( memory mem, regD src) %{
10989 match(Set mem (StoreD mem src));
10991 ins_cost(50);
10992 format %{ "store $mem, $src\t# store float @ storeD_reg" %}
10993 ins_encode(store_D_reg_enc(mem, src));
10994 ins_pipe( fpu_storeF );
10995 %}
10997 instruct loadSSI(mRegI dst, stackSlotI src)
10998 %{
10999 match(Set dst src);
11001 ins_cost(125);
11002 format %{ "lw $dst, $src\t# int stk @ loadSSI" %}
11003 ins_encode %{
11004 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
11005 __ lw($dst$$Register, SP, $src$$disp);
11006 %}
11007 ins_pipe(ialu_loadI);
11008 %}
11010 instruct storeSSI(stackSlotI dst, mRegI src)
11011 %{
11012 match(Set dst src);
11014 ins_cost(100);
11015 format %{ "sw $dst, $src\t# int stk @ storeSSI" %}
11016 ins_encode %{
11017 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
11018 __ sw($src$$Register, SP, $dst$$disp);
11019 %}
11020 ins_pipe(ialu_storeI);
11021 %}
11023 instruct loadSSL(mRegL dst, stackSlotL src)
11024 %{
11025 match(Set dst src);
11027 ins_cost(125);
11028 format %{ "ld $dst, $src\t# long stk @ loadSSL" %}
11029 ins_encode %{
11030 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
11031 __ ld($dst$$Register, SP, $src$$disp);
11032 %}
11033 ins_pipe(ialu_loadI);
11034 %}
11036 instruct storeSSL(stackSlotL dst, mRegL src)
11037 %{
11038 match(Set dst src);
11040 ins_cost(100);
11041 format %{ "sd $dst, $src\t# long stk @ storeSSL" %}
11042 ins_encode %{
11043 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
11044 __ sd($src$$Register, SP, $dst$$disp);
11045 %}
11046 ins_pipe(ialu_storeI);
11047 %}
11049 instruct loadSSP(mRegP dst, stackSlotP src)
11050 %{
11051 match(Set dst src);
11053 ins_cost(125);
11054 format %{ "ld $dst, $src\t# ptr stk @ loadSSP" %}
11055 ins_encode %{
11056 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
11057 __ ld($dst$$Register, SP, $src$$disp);
11058 %}
11059 ins_pipe(ialu_loadI);
11060 %}
11062 instruct storeSSP(stackSlotP dst, mRegP src)
11063 %{
11064 match(Set dst src);
11066 ins_cost(100);
11067 format %{ "sd $dst, $src\t# ptr stk @ storeSSP" %}
11068 ins_encode %{
11069 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
11070 __ sd($src$$Register, SP, $dst$$disp);
11071 %}
11072 ins_pipe(ialu_storeI);
11073 %}
11075 instruct loadSSF(regF dst, stackSlotF src)
11076 %{
11077 match(Set dst src);
11079 ins_cost(125);
11080 format %{ "lwc1 $dst, $src\t# float stk @ loadSSF" %}
11081 ins_encode %{
11082 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
11083 __ lwc1($dst$$FloatRegister, SP, $src$$disp);
11084 %}
11085 ins_pipe(ialu_loadI);
11086 %}
11088 instruct storeSSF(stackSlotF dst, regF src)
11089 %{
11090 match(Set dst src);
11092 ins_cost(100);
11093 format %{ "swc1 $dst, $src\t# float stk @ storeSSF" %}
11094 ins_encode %{
11095 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
11096 __ swc1($src$$FloatRegister, SP, $dst$$disp);
11097 %}
11098 ins_pipe(fpu_storeF);
11099 %}
11101 // Use the same format since predicate() can not be used here.
11102 instruct loadSSD(regD dst, stackSlotD src)
11103 %{
11104 match(Set dst src);
11106 ins_cost(125);
11107 format %{ "ldc1 $dst, $src\t# double stk @ loadSSD" %}
11108 ins_encode %{
11109 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
11110 __ ldc1($dst$$FloatRegister, SP, $src$$disp);
11111 %}
11112 ins_pipe(ialu_loadI);
11113 %}
11115 instruct storeSSD(stackSlotD dst, regD src)
11116 %{
11117 match(Set dst src);
11119 ins_cost(100);
11120 format %{ "sdc1 $dst, $src\t# double stk @ storeSSD" %}
11121 ins_encode %{
11122 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
11123 __ sdc1($src$$FloatRegister, SP, $dst$$disp);
11124 %}
11125 ins_pipe(fpu_storeF);
11126 %}
11128 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
11129 match( Set cr (FastLock object box) );
11130 effect( TEMP tmp, TEMP scr, USE_KILL box );
11131 ins_cost(300);
11132 format %{ "FASTLOCK $cr $object, $box, $tmp #@ cmpFastLock" %}
11133 ins_encode %{
11134 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
11135 %}
11137 ins_pipe( pipe_slow );
11138 ins_pc_relative(1);
11139 %}
11141 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
11142 match( Set cr (FastUnlock object box) );
11143 effect( TEMP tmp, USE_KILL box );
11144 ins_cost(300);
11145 format %{ "FASTUNLOCK $object, $box, $tmp #@cmpFastUnlock" %}
11146 ins_encode %{
11147 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
11148 %}
11150 ins_pipe( pipe_slow );
11151 ins_pc_relative(1);
11152 %}
11154 // Store CMS card-mark Immediate
11155 instruct storeImmCM(memory mem, mRegI src) %{
11156 match(Set mem (StoreCM mem src));
11158 ins_cost(500);
11159 format %{ "sb $src, $mem (CMS card-mark) @ storeImmCM" %}
11160 ins_encode(store_B_reg_sync_enc(mem, src));
11161 ins_pipe( ialu_storeI );
11162 %}
11164 instruct storeI0CM(memory mem, immI0 zero) %{
11165 match(Set mem (StoreCM mem zero));
11167 ins_cost(450);
11168 format %{ "sb $zero, $mem (CMS card-mark) @ storeI0CM" %}
11169 ins_encode(store_B0_sync_enc(mem));
11170 ins_pipe( ialu_storeI );
11171 %}
11173 // Die now
11174 instruct ShouldNotReachHere( )
11175 %{
11176 match(Halt);
11177 ins_cost(300);
11179 // Use the following format syntax
11180 format %{ "ILLTRAP ;#@ShouldNotReachHere" %}
11181 ins_encode %{
11182 // Here we should emit illtrap !
11184 __ stop("in ShoudNotReachHere");
11186 %}
11187 ins_pipe( pipe_jump );
11188 %}
11190 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11191 instruct jmpLoopEnd(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
11192 match(CountedLoopEnd cop (CmpI src1 src2));
11193 effect(USE labl);
11195 ins_cost(300);
11196 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd" %}
11197 ins_encode %{
11198 Register op1 = $src1$$Register;
11199 Register op2 = $src2$$Register;
11200 Label &L = *($labl$$label);
11201 int flag = $cop$$cmpcode;
11203 switch(flag)
11204 {
11205 case 0x01: //equal
11206 if (&L)
11207 __ beq(op1, op2, L);
11208 else
11209 __ beq(op1, op2, (int)0);
11210 break;
11211 case 0x02: //not_equal
11212 if (&L)
11213 __ bne(op1, op2, L);
11214 else
11215 __ bne(op1, op2, (int)0);
11216 break;
11217 case 0x03: //above
11218 __ slt(AT, op2, op1);
11219 if(&L)
11220 __ bne(AT, R0, L);
11221 else
11222 __ bne(AT, R0, (int)0);
11223 break;
11224 case 0x04: //above_equal
11225 __ slt(AT, op1, op2);
11226 if(&L)
11227 __ beq(AT, R0, L);
11228 else
11229 __ beq(AT, R0, (int)0);
11230 break;
11231 case 0x05: //below
11232 __ slt(AT, op1, op2);
11233 if(&L)
11234 __ bne(AT, R0, L);
11235 else
11236 __ bne(AT, R0, (int)0);
11237 break;
11238 case 0x06: //below_equal
11239 __ slt(AT, op2, op1);
11240 if(&L)
11241 __ beq(AT, R0, L);
11242 else
11243 __ beq(AT, R0, (int)0);
11244 break;
11245 default:
11246 Unimplemented();
11247 }
11248 __ nop();
11249 %}
11250 ins_pipe( pipe_jump );
11251 ins_pc_relative(1);
11252 %}
11255 instruct jmpLoopEnd_reg_imm16_sub(cmpOp cop, mRegI src1, immI16_sub src2, label labl) %{
11256 match(CountedLoopEnd cop (CmpI src1 src2));
11257 effect(USE labl);
11259 ins_cost(250);
11260 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_imm16_sub" %}
11261 ins_encode %{
11262 Register op1 = $src1$$Register;
11263 int op2 = $src2$$constant;
11264 Label &L = *($labl$$label);
11265 int flag = $cop$$cmpcode;
11267 __ addiu32(AT, op1, -1 * op2);
11269 switch(flag)
11270 {
11271 case 0x01: //equal
11272 if (&L)
11273 __ beq(AT, R0, L);
11274 else
11275 __ beq(AT, R0, (int)0);
11276 break;
11277 case 0x02: //not_equal
11278 if (&L)
11279 __ bne(AT, R0, L);
11280 else
11281 __ bne(AT, R0, (int)0);
11282 break;
11283 case 0x03: //above
11284 if(&L)
11285 __ bgtz(AT, L);
11286 else
11287 __ bgtz(AT, (int)0);
11288 break;
11289 case 0x04: //above_equal
11290 if(&L)
11291 __ bgez(AT, L);
11292 else
11293 __ bgez(AT,(int)0);
11294 break;
11295 case 0x05: //below
11296 if(&L)
11297 __ bltz(AT, L);
11298 else
11299 __ bltz(AT, (int)0);
11300 break;
11301 case 0x06: //below_equal
11302 if(&L)
11303 __ blez(AT, L);
11304 else
11305 __ blez(AT, (int)0);
11306 break;
11307 default:
11308 Unimplemented();
11309 }
11310 __ nop();
11311 %}
11312 ins_pipe( pipe_jump );
11313 ins_pc_relative(1);
11314 %}
11317 /*
11318 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11319 instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
11320 match(CountedLoopEnd cop cmp);
11321 effect(USE labl);
11323 ins_cost(300);
11324 format %{ "J$cop,u $labl\t# Loop end" %}
11325 size(6);
11326 opcode(0x0F, 0x80);
11327 ins_encode( Jcc( cop, labl) );
11328 ins_pipe( pipe_jump );
11329 ins_pc_relative(1);
11330 %}
11332 instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
11333 match(CountedLoopEnd cop cmp);
11334 effect(USE labl);
11336 ins_cost(200);
11337 format %{ "J$cop,u $labl\t# Loop end" %}
11338 opcode(0x0F, 0x80);
11339 ins_encode( Jcc( cop, labl) );
11340 ins_pipe( pipe_jump );
11341 ins_pc_relative(1);
11342 %}
11343 */
11345 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
11346 instruct jmpCon_flags(cmpOp cop, FlagsReg cr, label labl) %{
11347 match(If cop cr);
11348 effect(USE labl);
11350 ins_cost(300);
11351 format %{ "J$cop $labl #mips uses AT as eflag @jmpCon_flags" %}
11353 ins_encode %{
11354 Label &L = *($labl$$label);
11355 switch($cop$$cmpcode)
11356 {
11357 case 0x01: //equal
11358 if (&L)
11359 __ bne(AT, R0, L);
11360 else
11361 __ bne(AT, R0, (int)0);
11362 break;
11363 case 0x02: //not equal
11364 if (&L)
11365 __ beq(AT, R0, L);
11366 else
11367 __ beq(AT, R0, (int)0);
11368 break;
11369 default:
11370 Unimplemented();
11371 }
11372 __ nop();
11373 %}
11375 ins_pipe( pipe_jump );
11376 ins_pc_relative(1);
11377 %}
11380 // ============================================================================
11381 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
11382 // array for an instance of the superklass. Set a hidden internal cache on a
11383 // hit (cache is checked with exposed code in gen_subtype_check()). Return
11384 // NZ for a miss or zero for a hit. The encoding ALSO sets flags.
11385 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
11386 match(Set result (PartialSubtypeCheck sub super));
11387 effect(KILL tmp);
11388 ins_cost(1100); // slightly larger than the next version
11389 format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
11391 ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
11392 ins_pipe( pipe_slow );
11393 %}
11396 // Conditional-store of an int value.
11397 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
11398 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
11399 match(Set cr (StoreIConditional mem (Binary oldval newval)));
11400 // effect(KILL oldval);
11401 format %{ "CMPXCHG $newval, $mem, $oldval \t# @storeIConditional" %}
11403 ins_encode %{
11404 Register oldval = $oldval$$Register;
11405 Register newval = $newval$$Register;
11406 Address addr(as_Register($mem$$base), $mem$$disp);
11407 Label again, failure;
11409 // int base = $mem$$base;
11410 int index = $mem$$index;
11411 int scale = $mem$$scale;
11412 int disp = $mem$$disp;
11414 guarantee(Assembler::is_simm16(disp), "");
11416 if( index != 0 ) {
11417 __ stop("in storeIConditional: index != 0");
11418 } else {
11419 __ bind(again);
11420 if(UseSyncLevel <= 1000) __ sync();
11421 __ ll(AT, addr);
11422 __ bne(AT, oldval, failure);
11423 __ delayed()->addu(AT, R0, R0);
11425 __ addu(AT, newval, R0);
11426 __ sc(AT, addr);
11427 __ beq(AT, R0, again);
11428 __ delayed()->addiu(AT, R0, 0xFF);
11429 __ bind(failure);
11430 __ sync();
11431 }
11432 %}
11434 ins_pipe( long_memory_op );
11435 %}
11437 // Conditional-store of a long value.
11438 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
11439 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
11440 %{
11441 match(Set cr (StoreLConditional mem (Binary oldval newval)));
11442 effect(KILL oldval);
11444 format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
11445 ins_encode%{
11446 Register oldval = $oldval$$Register;
11447 Register newval = $newval$$Register;
11448 Address addr((Register)$mem$$base, $mem$$disp);
11450 int index = $mem$$index;
11451 int scale = $mem$$scale;
11452 int disp = $mem$$disp;
11454 guarantee(Assembler::is_simm16(disp), "");
11456 if( index != 0 ) {
11457 __ stop("in storeIConditional: index != 0");
11458 } else {
11459 __ cmpxchg(newval, addr, oldval);
11460 }
11461 %}
11462 ins_pipe( long_memory_op );
11463 %}
11466 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
11467 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
11468 effect(KILL oldval);
11469 // match(CompareAndSwapI mem_ptr (Binary oldval newval));
11470 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
11471 "MOV $res, 1 @ compareAndSwapI\n\t"
11472 "BNE AT, R0 @ compareAndSwapI\n\t"
11473 "MOV $res, 0 @ compareAndSwapI\n"
11474 "L:" %}
11475 ins_encode %{
11476 Register newval = $newval$$Register;
11477 Register oldval = $oldval$$Register;
11478 Register res = $res$$Register;
11479 Address addr($mem_ptr$$Register, 0);
11480 Label L;
11482 __ cmpxchg32(newval, addr, oldval);
11483 __ move(res, AT);
11484 %}
11485 ins_pipe( long_memory_op );
11486 %}
11488 //FIXME:
11489 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
11490 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
11491 effect(KILL oldval);
11492 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
11493 "MOV $res, AT @ compareAndSwapP\n\t"
11494 "L:" %}
11495 ins_encode %{
11496 Register newval = $newval$$Register;
11497 Register oldval = $oldval$$Register;
11498 Register res = $res$$Register;
11499 Address addr($mem_ptr$$Register, 0);
11500 Label L;
11502 __ cmpxchg(newval, addr, oldval);
11503 __ move(res, AT);
11504 %}
11505 ins_pipe( long_memory_op );
11506 %}
11508 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
11509 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
11510 effect(KILL oldval);
11511 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
11512 "MOV $res, AT @ compareAndSwapN\n\t"
11513 "L:" %}
11514 ins_encode %{
11515 Register newval = $newval$$Register;
11516 Register oldval = $oldval$$Register;
11517 Register res = $res$$Register;
11518 Address addr($mem_ptr$$Register, 0);
11519 Label L;
11521 /* 2013/7/19 Jin: cmpxchg32 is implemented with ll/sc, which will do sign extension.
11522 * Thus, we should extend oldval's sign for correct comparision.
11523 */
11524 __ sll(oldval, oldval, 0);
11526 __ cmpxchg32(newval, addr, oldval);
11527 __ move(res, AT);
11528 %}
11529 ins_pipe( long_memory_op );
11530 %}
11532 //----------Max and Min--------------------------------------------------------
11533 // Min Instructions
11534 ////
11535 // *** Min and Max using the conditional move are slower than the
11536 // *** branch version on a Pentium III.
11537 // // Conditional move for min
11538 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
11539 // effect( USE_DEF op2, USE op1, USE cr );
11540 // format %{ "CMOVlt $op2,$op1\t! min" %}
11541 // opcode(0x4C,0x0F);
11542 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
11543 // ins_pipe( pipe_cmov_reg );
11544 //%}
11545 //
11546 //// Min Register with Register (P6 version)
11547 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
11548 // predicate(VM_Version::supports_cmov() );
11549 // match(Set op2 (MinI op1 op2));
11550 // ins_cost(200);
11551 // expand %{
11552 // eFlagsReg cr;
11553 // compI_eReg(cr,op1,op2);
11554 // cmovI_reg_lt(op2,op1,cr);
11555 // %}
11556 //%}
11558 // Min Register with Register (generic version)
11559 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
11560 match(Set dst (MinI dst src));
11561 //effect(KILL flags);
11562 ins_cost(80);
11564 format %{ "MIN $dst, $src @minI_Reg_Reg" %}
11565 ins_encode %{
11566 Register dst = $dst$$Register;
11567 Register src = $src$$Register;
11569 __ slt(AT, src, dst);
11570 __ movn(dst, src, AT);
11572 %}
11574 ins_pipe( pipe_slow );
11575 %}
11577 // Max Register with Register
11578 // *** Min and Max using the conditional move are slower than the
11579 // *** branch version on a Pentium III.
11580 // // Conditional move for max
11581 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
11582 // effect( USE_DEF op2, USE op1, USE cr );
11583 // format %{ "CMOVgt $op2,$op1\t! max" %}
11584 // opcode(0x4F,0x0F);
11585 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
11586 // ins_pipe( pipe_cmov_reg );
11587 //%}
11588 //
11589 // // Max Register with Register (P6 version)
11590 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
11591 // predicate(VM_Version::supports_cmov() );
11592 // match(Set op2 (MaxI op1 op2));
11593 // ins_cost(200);
11594 // expand %{
11595 // eFlagsReg cr;
11596 // compI_eReg(cr,op1,op2);
11597 // cmovI_reg_gt(op2,op1,cr);
11598 // %}
11599 //%}
11601 // Max Register with Register (generic version)
11602 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
11603 match(Set dst (MaxI dst src));
11604 ins_cost(80);
11606 format %{ "MAX $dst, $src @maxI_Reg_Reg" %}
11608 ins_encode %{
11609 Register dst = $dst$$Register;
11610 Register src = $src$$Register;
11612 __ slt(AT, dst, src);
11613 __ movn(dst, src, AT);
11615 %}
11617 ins_pipe( pipe_slow );
11618 %}
11620 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
11621 match(Set dst (MaxI dst zero));
11622 ins_cost(50);
11624 format %{ "MAX $dst, 0 @maxI_Reg_zero" %}
11626 ins_encode %{
11627 Register dst = $dst$$Register;
11629 __ slt(AT, dst, R0);
11630 __ movn(dst, R0, AT);
11632 %}
11634 ins_pipe( pipe_slow );
11635 %}
11637 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
11638 %{
11639 match(Set dst (AndL src mask));
11641 format %{ "movl $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
11642 ins_encode %{
11643 Register dst = $dst$$Register;
11644 Register src = $src$$Register;
11646 __ dext(dst, src, 0, 32);
11647 %}
11648 ins_pipe(ialu_regI_regI);
11649 %}
11651 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
11652 %{
11653 match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
11655 format %{ "combine_i2l $dst, $src2(H), $src1(L) @ combine_i2l" %}
11656 ins_encode %{
11657 Register dst = $dst$$Register;
11658 Register src1 = $src1$$Register;
11659 Register src2 = $src2$$Register;
11661 if (src1 == dst) {
11662 __ dinsu(dst, src2, 32, 32);
11663 } else if (src2 == dst) {
11664 __ dsll32(dst, dst, 0);
11665 __ dins(dst, src1, 0, 32);
11666 } else {
11667 __ dext(dst, src1, 0, 32);
11668 __ dinsu(dst, src2, 32, 32);
11669 }
11670 %}
11671 ins_pipe(ialu_regI_regI);
11672 %}
11674 // Zero-extend convert int to long
11675 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
11676 %{
11677 match(Set dst (AndL (ConvI2L src) mask));
11679 format %{ "movl $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
11680 ins_encode %{
11681 Register dst = $dst$$Register;
11682 Register src = $src$$Register;
11684 __ dext(dst, src, 0, 32);
11685 %}
11686 ins_pipe(ialu_regI_regI);
11687 %}
11689 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
11690 %{
11691 match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
11693 format %{ "movl $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
11694 ins_encode %{
11695 Register dst = $dst$$Register;
11696 Register src = $src$$Register;
11698 __ dext(dst, src, 0, 32);
11699 %}
11700 ins_pipe(ialu_regI_regI);
11701 %}
11703 // Match loading integer and casting it to unsigned int in long register.
11704 // LoadI + ConvI2L + AndL 0xffffffff.
11705 instruct loadUI2L_rmask(mRegL dst, umemory mem, immL_32bits mask) %{
11706 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
11708 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
11709 ins_encode (load_N_enc(dst, mem));
11710 ins_pipe(ialu_loadI);
11711 %}
11713 instruct loadUI2L_lmask(mRegL dst, umemory mem, immL_32bits mask) %{
11714 match(Set dst (AndL mask (ConvI2L (LoadI mem))));
11716 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
11717 ins_encode (load_N_enc(dst, mem));
11718 ins_pipe(ialu_loadI);
11719 %}
11722 // ============================================================================
11723 // Safepoint Instruction
11724 instruct safePoint_poll_reg(mRegP poll) %{
11725 match(SafePoint poll);
11726 predicate(false);
11727 effect(USE poll);
11729 ins_cost(125);
11730 format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
11732 ins_encode %{
11733 Register poll_reg = $poll$$Register;
11735 __ block_comment("Safepoint:");
11736 __ relocate(relocInfo::poll_type);
11737 __ lw(AT, poll_reg, 0);
11738 %}
11740 ins_pipe( ialu_storeI );
11741 %}
11743 instruct safePoint_poll() %{
11744 match(SafePoint);
11746 ins_cost(105);
11747 format %{ "poll for GC @ safePoint_poll" %}
11749 ins_encode %{
11750 __ block_comment("Safepoint:");
11751 __ set64(T9, (long)os::get_polling_page());
11752 __ relocate(relocInfo::poll_type);
11753 __ lw(AT, T9, 0);
11754 %}
11756 ins_pipe( ialu_storeI );
11757 %}
11759 //----------Arithmetic Conversion Instructions---------------------------------
11761 instruct roundFloat_nop(regF dst)
11762 %{
11763 match(Set dst (RoundFloat dst));
11765 ins_cost(0);
11766 ins_encode();
11767 ins_pipe(empty);
11768 %}
11770 instruct roundDouble_nop(regD dst)
11771 %{
11772 match(Set dst (RoundDouble dst));
11774 ins_cost(0);
11775 ins_encode();
11776 ins_pipe(empty);
11777 %}
11779 //---------- Zeros Count Instructions ------------------------------------------
11780 // CountLeadingZerosINode CountTrailingZerosINode
11781 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
11782 predicate(UseCountLeadingZerosInstruction);
11783 match(Set dst (CountLeadingZerosI src));
11785 format %{ "clz $dst, $src\t# count leading zeros (int)" %}
11786 ins_encode %{
11787 __ clz($dst$$Register, $src$$Register);
11788 %}
11789 ins_pipe( ialu_regL_regL );
11790 %}
11792 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
11793 predicate(UseCountLeadingZerosInstruction);
11794 match(Set dst (CountLeadingZerosL src));
11796 format %{ "dclz $dst, $src\t# count leading zeros (long)" %}
11797 ins_encode %{
11798 __ dclz($dst$$Register, $src$$Register);
11799 %}
11800 ins_pipe( ialu_regL_regL );
11801 %}
11803 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
11804 predicate(UseCountTrailingZerosInstruction);
11805 match(Set dst (CountTrailingZerosI src));
11807 format %{ "ctz $dst, $src\t# count trailing zeros (int)" %}
11808 ins_encode %{
11809 // ctz and dctz is gs instructions.
11810 __ ctz($dst$$Register, $src$$Register);
11811 %}
11812 ins_pipe( ialu_regL_regL );
11813 %}
11815 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
11816 predicate(UseCountTrailingZerosInstruction);
11817 match(Set dst (CountTrailingZerosL src));
11819 format %{ "dcto $dst, $src\t# count trailing zeros (long)" %}
11820 ins_encode %{
11821 __ dctz($dst$$Register, $src$$Register);
11822 %}
11823 ins_pipe( ialu_regL_regL );
11824 %}
11826 // ====================VECTOR INSTRUCTIONS=====================================
11828 // Load vectors (8 bytes long)
11829 instruct loadV8(vecD dst, memory mem) %{
11830 predicate(n->as_LoadVector()->memory_size() == 8);
11831 match(Set dst (LoadVector mem));
11832 ins_cost(125);
11833 format %{ "load $dst, $mem\t! load vector (8 bytes)" %}
11834 ins_encode(load_D_enc(dst, mem));
11835 ins_pipe( fpu_loadF );
11836 %}
11838 // Store vectors (8 bytes long)
11839 instruct storeV8(memory mem, vecD src) %{
11840 predicate(n->as_StoreVector()->memory_size() == 8);
11841 match(Set mem (StoreVector mem src));
11842 ins_cost(145);
11843 format %{ "store $mem, $src\t! store vector (8 bytes)" %}
11844 ins_encode(store_D_reg_enc(mem, src));
11845 ins_pipe( fpu_storeF );
11846 %}
11848 instruct Repl8B_DSP(vecD dst, mRegI src) %{
11849 predicate(n->as_Vector()->length() == 8 && Use3A2000);
11850 match(Set dst (ReplicateB src));
11851 ins_cost(100);
11852 format %{ "replv_ob AT, $src\n\t"
11853 "dmtc1 AT, $dst\t! replicate8B" %}
11854 ins_encode %{
11855 __ replv_ob(AT, $src$$Register);
11856 __ dmtc1(AT, $dst$$FloatRegister);
11857 %}
11858 ins_pipe( pipe_mtc1 );
11859 %}
11861 instruct Repl8B(vecD dst, mRegI src) %{
11862 predicate(n->as_Vector()->length() == 8);
11863 match(Set dst (ReplicateB src));
11864 ins_cost(140);
11865 format %{ "move AT, $src\n\t"
11866 "dins AT, AT, 8, 8\n\t"
11867 "dins AT, AT, 16, 16\n\t"
11868 "dinsu AT, AT, 32, 32\n\t"
11869 "dmtc1 AT, $dst\t! replicate8B" %}
11870 ins_encode %{
11871 __ move(AT, $src$$Register);
11872 __ dins(AT, AT, 8, 8);
11873 __ dins(AT, AT, 16, 16);
11874 __ dinsu(AT, AT, 32, 32);
11875 __ dmtc1(AT, $dst$$FloatRegister);
11876 %}
11877 ins_pipe( pipe_mtc1 );
11878 %}
11880 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
11881 predicate(n->as_Vector()->length() == 8 && Use3A2000);
11882 match(Set dst (ReplicateB con));
11883 ins_cost(110);
11884 format %{ "repl_ob AT, [$con]\n\t"
11885 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
11886 ins_encode %{
11887 int val = $con$$constant;
11888 __ repl_ob(AT, val);
11889 __ dmtc1(AT, $dst$$FloatRegister);
11890 %}
11891 ins_pipe( pipe_mtc1 );
11892 %}
11894 instruct Repl8B_imm(vecD dst, immI con) %{
11895 predicate(n->as_Vector()->length() == 8);
11896 match(Set dst (ReplicateB con));
11897 ins_cost(150);
11898 format %{ "move AT, [$con]\n\t"
11899 "dins AT, AT, 8, 8\n\t"
11900 "dins AT, AT, 16, 16\n\t"
11901 "dinsu AT, AT, 32, 32\n\t"
11902 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
11903 ins_encode %{
11904 __ move(AT, $con$$constant);
11905 __ dins(AT, AT, 8, 8);
11906 __ dins(AT, AT, 16, 16);
11907 __ dinsu(AT, AT, 32, 32);
11908 __ dmtc1(AT, $dst$$FloatRegister);
11909 %}
11910 ins_pipe( pipe_mtc1 );
11911 %}
11913 instruct Repl8B_zero(vecD dst, immI0 zero) %{
11914 predicate(n->as_Vector()->length() == 8);
11915 match(Set dst (ReplicateB zero));
11916 ins_cost(90);
11917 format %{ "dmtc1 R0, $dst\t! replicate8B zero" %}
11918 ins_encode %{
11919 __ dmtc1(R0, $dst$$FloatRegister);
11920 %}
11921 ins_pipe( pipe_mtc1 );
11922 %}
11924 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
11925 predicate(n->as_Vector()->length() == 8);
11926 match(Set dst (ReplicateB M1));
11927 ins_cost(80);
11928 format %{ "dmtc1 -1, $dst\t! replicate8B -1" %}
11929 ins_encode %{
11930 __ nor(AT, R0, R0);
11931 __ dmtc1(AT, $dst$$FloatRegister);
11932 %}
11933 ins_pipe( pipe_mtc1 );
11934 %}
11936 instruct Repl4S_DSP(vecD dst, mRegI src) %{
11937 predicate(n->as_Vector()->length() == 4 && Use3A2000);
11938 match(Set dst (ReplicateS src));
11939 ins_cost(100);
11940 format %{ "replv_qh AT, $src\n\t"
11941 "dmtc1 AT, $dst\t! replicate4S" %}
11942 ins_encode %{
11943 __ replv_qh(AT, $src$$Register);
11944 __ dmtc1(AT, $dst$$FloatRegister);
11945 %}
11946 ins_pipe( pipe_mtc1 );
11947 %}
11949 instruct Repl4S(vecD dst, mRegI src) %{
11950 predicate(n->as_Vector()->length() == 4);
11951 match(Set dst (ReplicateS src));
11952 ins_cost(120);
11953 format %{ "move AT, $src \n\t"
11954 "dins AT, AT, 16, 16\n\t"
11955 "dinsu AT, AT, 32, 32\n\t"
11956 "dmtc1 AT, $dst\t! replicate4S" %}
11957 ins_encode %{
11958 __ move(AT, $src$$Register);
11959 __ dins(AT, AT, 16, 16);
11960 __ dinsu(AT, AT, 32, 32);
11961 __ dmtc1(AT, $dst$$FloatRegister);
11962 %}
11963 ins_pipe( pipe_mtc1 );
11964 %}
11966 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
11967 predicate(n->as_Vector()->length() == 4 && Use3A2000);
11968 match(Set dst (ReplicateS con));
11969 ins_cost(100);
11970 format %{ "replv_qh AT, [$con]\n\t"
11971 "dmtc1 AT, $dst\t! replicate4S($con)" %}
11972 ins_encode %{
11973 int val = $con$$constant;
11974 if ( Assembler::is_simm(val, 10)) {
11975 //repl_qh supports 10 bits immediate
11976 __ repl_qh(AT, val);
11977 } else {
11978 __ li32(AT, val);
11979 __ replv_qh(AT, AT);
11980 }
11981 __ dmtc1(AT, $dst$$FloatRegister);
11982 %}
11983 ins_pipe( pipe_mtc1 );
11984 %}
11986 instruct Repl4S_imm(vecD dst, immI con) %{
11987 predicate(n->as_Vector()->length() == 4);
11988 match(Set dst (ReplicateS con));
11989 ins_cost(110);
11990 format %{ "move AT, [$con]\n\t"
11991 "dins AT, AT, 16, 16\n\t"
11992 "dinsu AT, AT, 32, 32\n\t"
11993 "dmtc1 AT, $dst\t! replicate4S($con)" %}
11994 ins_encode %{
11995 __ move(AT, $con$$constant);
11996 __ dins(AT, AT, 16, 16);
11997 __ dinsu(AT, AT, 32, 32);
11998 __ dmtc1(AT, $dst$$FloatRegister);
11999 %}
12000 ins_pipe( pipe_mtc1 );
12001 %}
12003 instruct Repl4S_zero(vecD dst, immI0 zero) %{
12004 predicate(n->as_Vector()->length() == 4);
12005 match(Set dst (ReplicateS zero));
12006 format %{ "dmtc1 R0, $dst\t! replicate4S zero" %}
12007 ins_encode %{
12008 __ dmtc1(R0, $dst$$FloatRegister);
12009 %}
12010 ins_pipe( pipe_mtc1 );
12011 %}
12013 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
12014 predicate(n->as_Vector()->length() == 4);
12015 match(Set dst (ReplicateS M1));
12016 format %{ "dmtc1 -1, $dst\t! replicate4S -1" %}
12017 ins_encode %{
12018 __ nor(AT, R0, R0);
12019 __ dmtc1(AT, $dst$$FloatRegister);
12020 %}
12021 ins_pipe( pipe_mtc1 );
12022 %}
12024 // Replicate integer (4 byte) scalar to be vector
12025 instruct Repl2I(vecD dst, mRegI src) %{
12026 predicate(n->as_Vector()->length() == 2);
12027 match(Set dst (ReplicateI src));
12028 format %{ "dins AT, $src, 0, 32\n\t"
12029 "dinsu AT, $src, 32, 32\n\t"
12030 "dmtc1 AT, $dst\t! replicate2I" %}
12031 ins_encode %{
12032 __ dins(AT, $src$$Register, 0, 32);
12033 __ dinsu(AT, $src$$Register, 32, 32);
12034 __ dmtc1(AT, $dst$$FloatRegister);
12035 %}
12036 ins_pipe( pipe_mtc1 );
12037 %}
12039 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
12040 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
12041 predicate(n->as_Vector()->length() == 2);
12042 match(Set dst (ReplicateI con));
12043 effect(KILL tmp);
12044 format %{ "li32 AT, [$con], 32\n\t"
12045 "dinsu AT, AT\n\t"
12046 "dmtc1 AT, $dst\t! replicate2I($con)" %}
12047 ins_encode %{
12048 int val = $con$$constant;
12049 __ li32(AT, val);
12050 __ dinsu(AT, AT, 32, 32);
12051 __ dmtc1(AT, $dst$$FloatRegister);
12052 %}
12053 ins_pipe( pipe_mtc1 );
12054 %}
12056 // Replicate integer (4 byte) scalar zero to be vector
12057 instruct Repl2I_zero(vecD dst, immI0 zero) %{
12058 predicate(n->as_Vector()->length() == 2);
12059 match(Set dst (ReplicateI zero));
12060 format %{ "dmtc1 R0, $dst\t! replicate2I zero" %}
12061 ins_encode %{
12062 __ dmtc1(R0, $dst$$FloatRegister);
12063 %}
12064 ins_pipe( pipe_mtc1 );
12065 %}
12067 // Replicate integer (4 byte) scalar -1 to be vector
12068 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
12069 predicate(n->as_Vector()->length() == 2);
12070 match(Set dst (ReplicateI M1));
12071 format %{ "dmtc1 -1, $dst\t! replicate2I -1, use AT" %}
12072 ins_encode %{
12073 __ nor(AT, R0, R0);
12074 __ dmtc1(AT, $dst$$FloatRegister);
12075 %}
12076 ins_pipe( pipe_mtc1 );
12077 %}
12079 // Replicate float (4 byte) scalar to be vector
12080 instruct Repl2F(vecD dst, regF src) %{
12081 predicate(n->as_Vector()->length() == 2);
12082 match(Set dst (ReplicateF src));
12083 format %{ "cvt.ps $dst, $src, $src\t! replicate2F" %}
12084 ins_encode %{
12085 __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
12086 %}
12087 ins_pipe( pipe_slow );
12088 %}
12090 // Replicate float (4 byte) scalar zero to be vector
12091 instruct Repl2F_zero(vecD dst, immF0 zero) %{
12092 predicate(n->as_Vector()->length() == 2);
12093 match(Set dst (ReplicateF zero));
12094 format %{ "dmtc1 R0, $dst\t! replicate2F zero" %}
12095 ins_encode %{
12096 __ dmtc1(R0, $dst$$FloatRegister);
12097 %}
12098 ins_pipe( pipe_mtc1 );
12099 %}
12102 // ====================VECTOR ARITHMETIC=======================================
12104 // --------------------------------- ADD --------------------------------------
12106 // Floats vector add
12107 instruct vadd2F(vecD dst, vecD src) %{
12108 predicate(n->as_Vector()->length() == 2);
12109 match(Set dst (AddVF dst src));
12110 format %{ "add.ps $dst,$src\t! add packed2F" %}
12111 ins_encode %{
12112 __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
12113 %}
12114 ins_pipe( pipe_slow );
12115 %}
12117 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
12118 predicate(n->as_Vector()->length() == 2);
12119 match(Set dst (AddVF src1 src2));
12120 format %{ "add.ps $dst,$src1,$src2\t! add packed2F" %}
12121 ins_encode %{
12122 __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
12123 %}
12124 ins_pipe( fpu_regF_regF );
12125 %}
12127 // --------------------------------- SUB --------------------------------------
12129 // Floats vector sub
12130 instruct vsub2F(vecD dst, vecD src) %{
12131 predicate(n->as_Vector()->length() == 2);
12132 match(Set dst (SubVF dst src));
12133 format %{ "sub.ps $dst,$src\t! sub packed2F" %}
12134 ins_encode %{
12135 __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
12136 %}
12137 ins_pipe( fpu_regF_regF );
12138 %}
12140 // --------------------------------- MUL --------------------------------------
12142 // Floats vector mul
12143 instruct vmul2F(vecD dst, vecD src) %{
12144 predicate(n->as_Vector()->length() == 2);
12145 match(Set dst (MulVF dst src));
12146 format %{ "mul.ps $dst, $src\t! mul packed2F" %}
12147 ins_encode %{
12148 __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
12149 %}
12150 ins_pipe( fpu_regF_regF );
12151 %}
12153 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
12154 predicate(n->as_Vector()->length() == 2);
12155 match(Set dst (MulVF src1 src2));
12156 format %{ "mul.ps $dst, $src1, $src2\t! mul packed2F" %}
12157 ins_encode %{
12158 __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
12159 %}
12160 ins_pipe( fpu_regF_regF );
12161 %}
12163 // --------------------------------- DIV --------------------------------------
12164 // MIPS do not have div.ps
12167 //----------PEEPHOLE RULES-----------------------------------------------------
12168 // These must follow all instruction definitions as they use the names
12169 // defined in the instructions definitions.
12170 //
12171 // peepmatch ( root_instr_name [preceeding_instruction]* );
12172 //
12173 // peepconstraint %{
12174 // (instruction_number.operand_name relational_op instruction_number.operand_name
12175 // [, ...] );
12176 // // instruction numbers are zero-based using left to right order in peepmatch
12177 //
12178 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
12179 // // provide an instruction_number.operand_name for each operand that appears
12180 // // in the replacement instruction's match rule
12181 //
12182 // ---------VM FLAGS---------------------------------------------------------
12183 //
12184 // All peephole optimizations can be turned off using -XX:-OptoPeephole
12185 //
12186 // Each peephole rule is given an identifying number starting with zero and
12187 // increasing by one in the order seen by the parser. An individual peephole
12188 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
12189 // on the command-line.
12190 //
12191 // ---------CURRENT LIMITATIONS----------------------------------------------
12192 //
12193 // Only match adjacent instructions in same basic block
12194 // Only equality constraints
12195 // Only constraints between operands, not (0.dest_reg == EAX_enc)
12196 // Only one replacement instruction
12197 //
12198 // ---------EXAMPLE----------------------------------------------------------
12199 //
12200 // // pertinent parts of existing instructions in architecture description
12201 // instruct movI(eRegI dst, eRegI src) %{
12202 // match(Set dst (CopyI src));
12203 // %}
12204 //
12205 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
12206 // match(Set dst (AddI dst src));
12207 // effect(KILL cr);
12208 // %}
12209 //
12210 // // Change (inc mov) to lea
12211 // peephole %{
12212 // // increment preceeded by register-register move
12213 // peepmatch ( incI_eReg movI );
12214 // // require that the destination register of the increment
12215 // // match the destination register of the move
12216 // peepconstraint ( 0.dst == 1.dst );
12217 // // construct a replacement instruction that sets
12218 // // the destination to ( move's source register + one )
12219 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
12220 // %}
12221 //
12222 // Implementation no longer uses movX instructions since
12223 // machine-independent system no longer uses CopyX nodes.
12224 //
12225 // peephole %{
12226 // peepmatch ( incI_eReg movI );
12227 // peepconstraint ( 0.dst == 1.dst );
12228 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
12229 // %}
12230 //
12231 // peephole %{
12232 // peepmatch ( decI_eReg movI );
12233 // peepconstraint ( 0.dst == 1.dst );
12234 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
12235 // %}
12236 //
12237 // peephole %{
12238 // peepmatch ( addI_eReg_imm movI );
12239 // peepconstraint ( 0.dst == 1.dst );
12240 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
12241 // %}
12242 //
12243 // peephole %{
12244 // peepmatch ( addP_eReg_imm movP );
12245 // peepconstraint ( 0.dst == 1.dst );
12246 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
12247 // %}
12249 // // Change load of spilled value to only a spill
12250 // instruct storeI(memory mem, eRegI src) %{
12251 // match(Set mem (StoreI mem src));
12252 // %}
12253 //
12254 // instruct loadI(eRegI dst, memory mem) %{
12255 // match(Set dst (LoadI mem));
12256 // %}
12257 //
12258 //peephole %{
12259 // peepmatch ( loadI storeI );
12260 // peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
12261 // peepreplace ( storeI( 1.mem 1.mem 1.src ) );
12262 //%}
12264 //----------SMARTSPILL RULES---------------------------------------------------
12265 // These must follow all instruction definitions as they use the names
12266 // defined in the instructions definitions.