Wed, 15 Feb 2017 09:29:03 -0500
[C2] Add instruct andI_Reg_immI_nonneg_mask in mips_64.ad
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 __ li48(T9, (long)OptoRuntime::exception_blob()->entry_point());
574 __ jr(T9);
575 __ delayed()->nop();
576 __ align(16);
577 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
578 __ end_a_stub();
579 return offset;
580 }
582 // Emit deopt handler code.
583 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
584 /*
585 // Note that the code buffer's insts_mark is always relative to insts.
586 // That's why we must use the macroassembler to generate a handler.
587 MacroAssembler _masm(&cbuf);
588 address base = __ start_a_stub(size_deopt_handler());
589 if (base == NULL) return 0; // CodeBuffer::expand failed
590 int offset = __ offset();
592 #ifdef _LP64
593 address the_pc = (address) __ pc();
594 Label next;
595 // push a "the_pc" on the stack without destroying any registers
596 // as they all may be live.
598 // push address of "next"
599 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
600 __ bind(next);
601 // adjust it so it matches "the_pc"
602 __ subptr(Address(rsp, 0), __ offset() - offset);
603 #else
604 InternalAddress here(__ pc());
605 __ pushptr(here.addr());
606 #endif
608 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
609 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
610 __ end_a_stub();
611 return offset;
612 */
613 // Note that the code buffer's insts_mark is always relative to insts.
614 // That's why we must use the macroassembler to generate a handler.
615 MacroAssembler _masm(&cbuf);
616 address base =
617 __ start_a_stub(size_deopt_handler());
619 // FIXME
620 if (base == NULL) return 0; // CodeBuffer::expand failed
621 int offset = __ offset();
623 __ block_comment("; emit_deopt_handler");
625 cbuf.set_insts_mark();
626 __ relocate(relocInfo::runtime_call_type);
628 __ li48(T9, (long)SharedRuntime::deopt_blob()->unpack());
629 __ jalr(T9);
630 __ delayed()->nop();
631 __ align(16);
632 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
633 __ end_a_stub();
634 return offset;
635 }
638 const bool Matcher::match_rule_supported(int opcode) {
639 if (!has_match_rule(opcode))
640 return false;
642 switch (opcode) {
643 //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
644 case Op_CountLeadingZerosI:
645 case Op_CountLeadingZerosL:
646 if (!UseCountLeadingZerosInstruction)
647 return false;
648 break;
649 case Op_CountTrailingZerosI:
650 case Op_CountTrailingZerosL:
651 if (!UseCountTrailingZerosInstruction)
652 return false;
653 break;
654 }
656 return true; // Per default match rules are supported.
657 }
659 //FIXME
660 // emit call stub, compiled java to interpreter
661 void emit_java_to_interp(CodeBuffer &cbuf ) {
662 // Stub is fixed up when the corresponding call is converted from calling
663 // compiled code to calling interpreted code.
664 // mov rbx,0
665 // jmp -1
667 address mark = cbuf.insts_mark(); // get mark within main instrs section
669 // Note that the code buffer's insts_mark is always relative to insts.
670 // That's why we must use the macroassembler to generate a stub.
671 MacroAssembler _masm(&cbuf);
673 address base =
674 __ start_a_stub(Compile::MAX_stubs_size);
675 if (base == NULL) return; // CodeBuffer::expand failed
676 // static stub relocation stores the instruction address of the call
678 __ relocate(static_stub_Relocation::spec(mark), 0);
680 /* 2012/10/29 Jin: Rmethod contains methodOop, it should be relocated for GC */
681 /*
682 int oop_index = __ oop_recorder()->allocate_index(NULL);
683 RelocationHolder rspec = oop_Relocation::spec(oop_index);
684 __ relocate(rspec);
685 */
687 // static stub relocation also tags the methodOop in the code-stream.
688 __ li48(S3, (long)0);
689 // This is recognized as unresolved by relocs/nativeInst/ic code
691 __ relocate(relocInfo::runtime_call_type);
693 cbuf.set_insts_mark();
694 address call_pc = (address)-1;
695 __ li48(AT, (long)call_pc);
696 __ jr(AT);
697 __ nop();
698 __ align(16);
699 __ end_a_stub();
700 // Update current stubs pointer and restore code_end.
701 }
703 // size of call stub, compiled java to interpretor
704 uint size_java_to_interp() {
705 int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
706 return round_to(size, 16);
707 }
709 // relocation entries for call stub, compiled java to interpreter
710 uint reloc_java_to_interp() {
711 return 16; // in emit_java_to_interp + in Java_Static_Call
712 }
714 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
715 if( Assembler::is_simm16(offset) ) return true;
716 else
717 {
718 assert(false, "Not implemented yet !" );
719 Unimplemented();
720 }
721 }
724 // No additional cost for CMOVL.
725 const int Matcher::long_cmove_cost() { return 0; }
727 // No CMOVF/CMOVD with SSE2
728 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
730 // Does the CPU require late expand (see block.cpp for description of late expand)?
731 const bool Matcher::require_postalloc_expand = false;
733 // Should the Matcher clone shifts on addressing modes, expecting them
734 // to be subsumed into complex addressing expressions or compute them
735 // into registers? True for Intel but false for most RISCs
736 const bool Matcher::clone_shift_expressions = false;
738 // Do we need to mask the count passed to shift instructions or does
739 // the cpu only look at the lower 5/6 bits anyway?
740 const bool Matcher::need_masked_shift_count = false;
742 bool Matcher::narrow_oop_use_complex_address() {
743 NOT_LP64(ShouldNotCallThis());
744 assert(UseCompressedOops, "only for compressed oops code");
745 return false;
746 }
748 bool Matcher::narrow_klass_use_complex_address() {
749 NOT_LP64(ShouldNotCallThis());
750 assert(UseCompressedClassPointers, "only for compressed klass code");
751 return false;
752 }
754 // This is UltraSparc specific, true just means we have fast l2f conversion
755 const bool Matcher::convL2FSupported(void) {
756 return true;
757 }
759 // Max vector size in bytes. 0 if not supported.
760 const int Matcher::vector_width_in_bytes(BasicType bt) {
761 assert(MaxVectorSize == 8, "");
762 return 8;
763 }
765 // Vector ideal reg
766 const int Matcher::vector_ideal_reg(int size) {
767 assert(MaxVectorSize == 8, "");
768 switch(size) {
769 case 8: return Op_VecD;
770 }
771 ShouldNotReachHere();
772 return 0;
773 }
775 // Only lowest bits of xmm reg are used for vector shift count.
776 const int Matcher::vector_shift_count_ideal_reg(int size) {
777 fatal("vector shift is not supported");
778 return Node::NotAMachineReg;
779 }
781 // Limits on vector size (number of elements) loaded into vector.
782 const int Matcher::max_vector_size(const BasicType bt) {
783 assert(is_java_primitive(bt), "only primitive type vectors");
784 return vector_width_in_bytes(bt)/type2aelembytes(bt);
785 }
787 const int Matcher::min_vector_size(const BasicType bt) {
788 return max_vector_size(bt); // Same as max.
789 }
791 // MIPS supports misaligned vectors store/load? FIXME
792 const bool Matcher::misaligned_vectors_ok() {
793 return false;
794 //return !AlignVector; // can be changed by flag
795 }
797 // Register for DIVI projection of divmodI
798 RegMask Matcher::divI_proj_mask() {
799 ShouldNotReachHere();
800 return RegMask();
801 }
803 // Register for MODI projection of divmodI
804 RegMask Matcher::modI_proj_mask() {
805 ShouldNotReachHere();
806 return RegMask();
807 }
809 // Register for DIVL projection of divmodL
810 RegMask Matcher::divL_proj_mask() {
811 ShouldNotReachHere();
812 return RegMask();
813 }
815 int Matcher::regnum_to_fpu_offset(int regnum) {
816 return regnum - 32; // The FP registers are in the second chunk
817 }
820 const bool Matcher::isSimpleConstant64(jlong value) {
821 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
822 return true;
823 }
826 // Return whether or not this register is ever used as an argument. This
827 // function is used on startup to build the trampoline stubs in generateOptoStub.
828 // Registers not mentioned will be killed by the VM call in the trampoline, and
829 // arguments in those registers not be available to the callee.
830 bool Matcher::can_be_java_arg( int reg ) {
831 /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
832 if ( reg == T0_num || reg == T0_H_num
833 || reg == A0_num || reg == A0_H_num
834 || reg == A1_num || reg == A1_H_num
835 || reg == A2_num || reg == A2_H_num
836 || reg == A3_num || reg == A3_H_num
837 || reg == A4_num || reg == A4_H_num
838 || reg == A5_num || reg == A5_H_num
839 || reg == A6_num || reg == A6_H_num
840 || reg == A7_num || reg == A7_H_num )
841 return true;
843 if ( reg == F12_num || reg == F12_H_num
844 || reg == F13_num || reg == F13_H_num
845 || reg == F14_num || reg == F14_H_num
846 || reg == F15_num || reg == F15_H_num
847 || reg == F16_num || reg == F16_H_num
848 || reg == F17_num || reg == F17_H_num
849 || reg == F18_num || reg == F18_H_num
850 || reg == F19_num || reg == F19_H_num )
851 return true;
853 return false;
854 }
856 bool Matcher::is_spillable_arg( int reg ) {
857 return can_be_java_arg(reg);
858 }
860 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
861 return false;
862 }
864 // Register for MODL projection of divmodL
865 RegMask Matcher::modL_proj_mask() {
866 ShouldNotReachHere();
867 return RegMask();
868 }
870 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
871 return FP_REG_mask();
872 }
874 // MIPS doesn't support AES intrinsics
875 const bool Matcher::pass_original_key_for_aes() {
876 return false;
877 }
879 // The address of the call instruction needs to be 16-byte aligned to
880 // ensure that it does not span a cache line so that it can be patched.
882 int CallStaticJavaDirectNode::compute_padding(int current_offset) const {
883 //lui
884 //ori
885 //dsll
886 //ori
888 //jalr
889 //nop
891 return round_to(current_offset, alignment_required()) - current_offset;
892 }
894 // The address of the call instruction needs to be 16-byte aligned to
895 // ensure that it does not span a cache line so that it can be patched.
896 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const {
897 //li64 <--- skip
899 //lui
900 //ori
901 //dsll
902 //ori
904 //jalr
905 //nop
907 current_offset += 4 * 6; // skip li64
908 return round_to(current_offset, alignment_required()) - current_offset;
909 }
911 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
912 //lui
913 //ori
914 //dsll
915 //ori
917 //jalr
918 //nop
920 return round_to(current_offset, alignment_required()) - current_offset;
921 }
923 int CallLeafDirectNode::compute_padding(int current_offset) const {
924 //lui
925 //ori
926 //dsll
927 //ori
929 //jalr
930 //nop
932 return round_to(current_offset, alignment_required()) - current_offset;
933 }
935 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
936 //lui
937 //ori
938 //dsll
939 //ori
941 //jalr
942 //nop
944 return round_to(current_offset, alignment_required()) - current_offset;
945 }
947 // If CPU can load and store mis-aligned doubles directly then no fixup is
948 // needed. Else we split the double into 2 integer pieces and move it
949 // piece-by-piece. Only happens when passing doubles into C code as the
950 // Java calling convention forces doubles to be aligned.
951 const bool Matcher::misaligned_doubles_ok = false;
952 // Do floats take an entire double register or just half?
953 //const bool Matcher::float_in_double = true;
954 bool Matcher::float_in_double() { return false; }
955 // Threshold size for cleararray.
956 const int Matcher::init_array_short_size = 8 * BytesPerLong;
957 // Do ints take an entire long register or just half?
958 const bool Matcher::int_in_long = true;
959 // Is it better to copy float constants, or load them directly from memory?
960 // Intel can load a float constant from a direct address, requiring no
961 // extra registers. Most RISCs will have to materialize an address into a
962 // register first, so they would do better to copy the constant from stack.
963 const bool Matcher::rematerialize_float_constants = false;
964 // Advertise here if the CPU requires explicit rounding operations
965 // to implement the UseStrictFP mode.
966 const bool Matcher::strict_fp_requires_explicit_rounding = false;
967 // The ecx parameter to rep stos for the ClearArray node is in dwords.
968 const bool Matcher::init_array_count_is_in_bytes = false;
971 // Indicate if the safepoint node needs the polling page as an input.
972 // Since MIPS doesn't have absolute addressing, it needs.
973 bool SafePointNode::needs_polling_address_input() {
974 return true;
975 }
977 // !!!!! Special hack to get all type of calls to specify the byte offset
978 // from the start of the call to the point where the return address
979 // will point.
980 int MachCallStaticJavaNode::ret_addr_offset() {
981 assert(NativeCall::instruction_size == 24, "in MachCallStaticJavaNode::ret_addr_offset");
982 //The value ought to be 16 bytes.
983 //lui
984 //ori
985 //dsll
986 //ori
987 //jalr
988 //nop
989 return NativeCall::instruction_size;
990 }
992 int MachCallDynamicJavaNode::ret_addr_offset() {
993 /* 2012/9/10 Jin: must be kept in sync with Java_Dynamic_Call */
995 // return NativeCall::instruction_size;
996 assert(NativeCall::instruction_size == 24, "in MachCallDynamicJavaNode::ret_addr_offset");
997 //The value ought to be 4 + 16 bytes.
998 //lui IC_Klass,
999 //ori IC_Klass,
1000 //dsll IC_Klass
1001 //ori IC_Klass
1002 //lui T9
1003 //ori T9
1004 //dsll T9
1005 //ori T9
1006 //jalr T9
1007 //nop
1008 return 6 * 4 + NativeCall::instruction_size;
1010 }
1012 /*
1013 // EMIT_OPCODE()
1014 void emit_opcode(CodeBuffer &cbuf, int code) {
1015 *(cbuf.code_end()) = (unsigned char)code;
1016 cbuf.set_code_end(cbuf.code_end() + 1);
1017 }
1018 */
1020 void emit_d32_reloc(CodeBuffer &cbuf, int d32, relocInfo::relocType reloc,
1021 int format) {
1022 cbuf.relocate(cbuf.insts_mark(), reloc, format);
1023 cbuf.insts()->emit_int32(d32);
1024 }
1026 //=============================================================================
1028 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
1029 enum RC { rc_bad, rc_int, rc_float, rc_stack };
1030 static enum RC rc_class( OptoReg::Name reg ) {
1031 if( !OptoReg::is_valid(reg) ) return rc_bad;
1032 if (OptoReg::is_stack(reg)) return rc_stack;
1033 VMReg r = OptoReg::as_VMReg(reg);
1034 if (r->is_Register()) return rc_int;
1035 assert(r->is_FloatRegister(), "must be");
1036 return rc_float;
1037 }
1039 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
1040 // Get registers to move
1041 OptoReg::Name src_second = ra_->get_reg_second(in(1));
1042 OptoReg::Name src_first = ra_->get_reg_first(in(1));
1043 OptoReg::Name dst_second = ra_->get_reg_second(this );
1044 OptoReg::Name dst_first = ra_->get_reg_first(this );
1046 enum RC src_second_rc = rc_class(src_second);
1047 enum RC src_first_rc = rc_class(src_first);
1048 enum RC dst_second_rc = rc_class(dst_second);
1049 enum RC dst_first_rc = rc_class(dst_first);
1051 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
1053 // Generate spill code!
1054 int size = 0;
1056 if( src_first == dst_first && src_second == dst_second )
1057 return 0; // Self copy, no move
1059 if (src_first_rc == rc_stack) {
1060 // mem ->
1061 if (dst_first_rc == rc_stack) {
1062 // mem -> mem
1063 assert(src_second != dst_first, "overlap");
1064 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1065 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1066 // 64-bit
1067 int src_offset = ra_->reg2offset(src_first);
1068 int dst_offset = ra_->reg2offset(dst_first);
1069 if (cbuf) {
1070 MacroAssembler _masm(cbuf);
1071 __ ld(AT, Address(SP, src_offset));
1072 __ sd(AT, Address(SP, dst_offset));
1073 #ifndef PRODUCT
1074 } else {
1075 if(!do_size){
1076 if (size != 0) st->print("\n\t");
1077 st->print("ld AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
1078 "sd AT, [SP + #%d]",
1079 src_offset, dst_offset);
1080 }
1081 #endif
1082 }
1083 size += 8;
1084 } else {
1085 // 32-bit
1086 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1087 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1088 // No pushl/popl, so:
1089 int src_offset = ra_->reg2offset(src_first);
1090 int dst_offset = ra_->reg2offset(dst_first);
1091 if (cbuf) {
1092 MacroAssembler _masm(cbuf);
1093 __ lw(AT, Address(SP, src_offset));
1094 __ sw(AT, Address(SP, dst_offset));
1095 #ifndef PRODUCT
1096 } else {
1097 if(!do_size){
1098 if (size != 0) st->print("\n\t");
1099 st->print("lw AT, [SP + #%d] spill 2\n\t"
1100 "sw AT, [SP + #%d]\n\t",
1101 src_offset, dst_offset);
1102 }
1103 #endif
1104 }
1105 size += 8;
1106 }
1107 return size;
1108 } else if (dst_first_rc == rc_int) {
1109 // mem -> gpr
1110 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1111 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1112 // 64-bit
1113 int offset = ra_->reg2offset(src_first);
1114 if (cbuf) {
1115 MacroAssembler _masm(cbuf);
1116 __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1117 #ifndef PRODUCT
1118 } else {
1119 if(!do_size){
1120 if (size != 0) st->print("\n\t");
1121 st->print("ld %s, [SP + #%d]\t# spill 3",
1122 Matcher::regName[dst_first],
1123 offset);
1124 }
1125 #endif
1126 }
1127 size += 4;
1128 } else {
1129 // 32-bit
1130 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1131 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1132 int offset = ra_->reg2offset(src_first);
1133 if (cbuf) {
1134 MacroAssembler _masm(cbuf);
1135 if (this->ideal_reg() == Op_RegI)
1136 __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1137 else
1138 __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1139 #ifndef PRODUCT
1140 } else {
1141 if(!do_size){
1142 if (size != 0) st->print("\n\t");
1143 if (this->ideal_reg() == Op_RegI)
1144 st->print("lw %s, [SP + #%d]\t# spill 4",
1145 Matcher::regName[dst_first],
1146 offset);
1147 else
1148 st->print("lwu %s, [SP + #%d]\t# spill 5",
1149 Matcher::regName[dst_first],
1150 offset);
1151 }
1152 #endif
1153 }
1154 size += 4;
1155 }
1156 return size;
1157 } else if (dst_first_rc == rc_float) {
1158 // mem-> xmm
1159 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1160 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1161 // 64-bit
1162 int offset = ra_->reg2offset(src_first);
1163 if (cbuf) {
1164 MacroAssembler _masm(cbuf);
1165 __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1166 #ifndef PRODUCT
1167 } else {
1168 if(!do_size){
1169 if (size != 0) st->print("\n\t");
1170 st->print("ldc1 %s, [SP + #%d]\t# spill 6",
1171 Matcher::regName[dst_first],
1172 offset);
1173 }
1174 #endif
1175 }
1176 size += 4;
1177 } else {
1178 // 32-bit
1179 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1180 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1181 int offset = ra_->reg2offset(src_first);
1182 if (cbuf) {
1183 MacroAssembler _masm(cbuf);
1184 __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1185 #ifndef PRODUCT
1186 } else {
1187 if(!do_size){
1188 if (size != 0) st->print("\n\t");
1189 st->print("lwc1 %s, [SP + #%d]\t# spill 7",
1190 Matcher::regName[dst_first],
1191 offset);
1192 }
1193 #endif
1194 }
1195 size += 4;
1196 }
1197 return size;
1198 }
1199 } else if (src_first_rc == rc_int) {
1200 // gpr ->
1201 if (dst_first_rc == rc_stack) {
1202 // gpr -> mem
1203 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1204 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1205 // 64-bit
1206 int offset = ra_->reg2offset(dst_first);
1207 if (cbuf) {
1208 MacroAssembler _masm(cbuf);
1209 __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1210 #ifndef PRODUCT
1211 } else {
1212 if(!do_size){
1213 if (size != 0) st->print("\n\t");
1214 st->print("sd %s, [SP + #%d] # spill 8",
1215 Matcher::regName[src_first],
1216 offset);
1217 }
1218 #endif
1219 }
1220 size += 4;
1221 } else {
1222 // 32-bit
1223 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1224 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1225 int offset = ra_->reg2offset(dst_first);
1226 if (cbuf) {
1227 MacroAssembler _masm(cbuf);
1228 __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1229 #ifndef PRODUCT
1230 } else {
1231 if(!do_size){
1232 if (size != 0) st->print("\n\t");
1233 st->print("sw %s, [SP + #%d]\t# spill 9",
1234 Matcher::regName[src_first], offset);
1235 }
1236 #endif
1237 }
1238 size += 4;
1239 }
1240 return size;
1241 } else if (dst_first_rc == rc_int) {
1242 // gpr -> gpr
1243 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1244 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1245 // 64-bit
1246 if (cbuf) {
1247 MacroAssembler _masm(cbuf);
1248 __ move(as_Register(Matcher::_regEncode[dst_first]),
1249 as_Register(Matcher::_regEncode[src_first]));
1250 #ifndef PRODUCT
1251 } else {
1252 if(!do_size){
1253 if (size != 0) st->print("\n\t");
1254 st->print("move(64bit) %s <-- %s\t# spill 10",
1255 Matcher::regName[dst_first],
1256 Matcher::regName[src_first]);
1257 }
1258 #endif
1259 }
1260 size += 4;
1261 return size;
1262 } else {
1263 // 32-bit
1264 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1265 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1266 if (cbuf) {
1267 MacroAssembler _masm(cbuf);
1268 if (this->ideal_reg() == Op_RegI)
1269 __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1270 else
1271 __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
1273 #ifndef PRODUCT
1274 } else {
1275 if(!do_size){
1276 if (size != 0) st->print("\n\t");
1277 st->print("move(32-bit) %s <-- %s\t# spill 11",
1278 Matcher::regName[dst_first],
1279 Matcher::regName[src_first]);
1280 }
1281 #endif
1282 }
1283 size += 4;
1284 return size;
1285 }
1286 } else if (dst_first_rc == rc_float) {
1287 // gpr -> xmm
1288 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1289 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1290 // 64-bit
1291 if (cbuf) {
1292 MacroAssembler _masm(cbuf);
1293 __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
1294 #ifndef PRODUCT
1295 } else {
1296 if(!do_size){
1297 if (size != 0) st->print("\n\t");
1298 st->print("dmtc1 %s, %s\t# spill 12",
1299 Matcher::regName[dst_first],
1300 Matcher::regName[src_first]);
1301 }
1302 #endif
1303 }
1304 size += 4;
1305 } else {
1306 // 32-bit
1307 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1308 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1309 if (cbuf) {
1310 MacroAssembler _masm(cbuf);
1311 __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
1312 #ifndef PRODUCT
1313 } else {
1314 if(!do_size){
1315 if (size != 0) st->print("\n\t");
1316 st->print("mtc1 %s, %s\t# spill 13",
1317 Matcher::regName[dst_first],
1318 Matcher::regName[src_first]);
1319 }
1320 #endif
1321 }
1322 size += 4;
1323 }
1324 return size;
1325 }
1326 } else if (src_first_rc == rc_float) {
1327 // xmm ->
1328 if (dst_first_rc == rc_stack) {
1329 // xmm -> mem
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 int offset = ra_->reg2offset(dst_first);
1334 if (cbuf) {
1335 MacroAssembler _masm(cbuf);
1336 __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
1337 #ifndef PRODUCT
1338 } else {
1339 if(!do_size){
1340 if (size != 0) st->print("\n\t");
1341 st->print("sdc1 %s, [SP + #%d]\t# spill 14",
1342 Matcher::regName[src_first],
1343 offset);
1344 }
1345 #endif
1346 }
1347 size += 4;
1348 } else {
1349 // 32-bit
1350 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1351 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1352 int offset = ra_->reg2offset(dst_first);
1353 if (cbuf) {
1354 MacroAssembler _masm(cbuf);
1355 __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
1356 #ifndef PRODUCT
1357 } else {
1358 if(!do_size){
1359 if (size != 0) st->print("\n\t");
1360 st->print("swc1 %s, [SP + #%d]\t# spill 15",
1361 Matcher::regName[src_first],
1362 offset);
1363 }
1364 #endif
1365 }
1366 size += 4;
1367 }
1368 return size;
1369 } else if (dst_first_rc == rc_int) {
1370 // xmm -> gpr
1371 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1372 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1373 // 64-bit
1374 if (cbuf) {
1375 MacroAssembler _masm(cbuf);
1376 __ dmfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1377 #ifndef PRODUCT
1378 } else {
1379 if(!do_size){
1380 if (size != 0) st->print("\n\t");
1381 st->print("dmfc1 %s, %s\t# spill 16",
1382 Matcher::regName[dst_first],
1383 Matcher::regName[src_first]);
1384 }
1385 #endif
1386 }
1387 size += 4;
1388 } else {
1389 // 32-bit
1390 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1391 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1392 if (cbuf) {
1393 MacroAssembler _masm(cbuf);
1394 __ mfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1395 #ifndef PRODUCT
1396 } else {
1397 if(!do_size){
1398 if (size != 0) st->print("\n\t");
1399 st->print("mfc1 %s, %s\t# spill 17",
1400 Matcher::regName[dst_first],
1401 Matcher::regName[src_first]);
1402 }
1403 #endif
1404 }
1405 size += 4;
1406 }
1407 return size;
1408 } else if (dst_first_rc == rc_float) {
1409 // xmm -> xmm
1410 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1411 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1412 // 64-bit
1413 if (cbuf) {
1414 MacroAssembler _masm(cbuf);
1415 __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1416 #ifndef PRODUCT
1417 } else {
1418 if(!do_size){
1419 if (size != 0) st->print("\n\t");
1420 st->print("mov_d %s <-- %s\t# spill 18",
1421 Matcher::regName[dst_first],
1422 Matcher::regName[src_first]);
1423 }
1424 #endif
1425 }
1426 size += 4;
1427 } else {
1428 // 32-bit
1429 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1430 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1431 if (cbuf) {
1432 MacroAssembler _masm(cbuf);
1433 __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1434 #ifndef PRODUCT
1435 } else {
1436 if(!do_size){
1437 if (size != 0) st->print("\n\t");
1438 st->print("mov_s %s <-- %s\t# spill 19",
1439 Matcher::regName[dst_first],
1440 Matcher::regName[src_first]);
1441 }
1442 #endif
1443 }
1444 size += 4;
1445 }
1446 return size;
1447 }
1448 }
1450 assert(0," foo ");
1451 Unimplemented();
1452 return size;
1454 }
1456 #ifndef PRODUCT
1457 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1458 implementation( NULL, ra_, false, st );
1459 }
1460 #endif
1462 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1463 implementation( &cbuf, ra_, false, NULL );
1464 }
1466 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1467 return implementation( NULL, ra_, true, NULL );
1468 }
1470 //=============================================================================
1471 #
1473 #ifndef PRODUCT
1474 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
1475 st->print("INT3");
1476 }
1477 #endif
1479 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
1480 MacroAssembler _masm(&cbuf);
1481 __ int3();
1482 }
1484 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
1485 return MachNode::size(ra_);
1486 }
1489 //=============================================================================
1490 #ifndef PRODUCT
1491 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1492 Compile *C = ra_->C;
1493 int framesize = C->frame_size_in_bytes();
1495 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1497 st->print("daddiu SP, SP, %d # Rlease stack @ MachEpilogNode",framesize);
1498 st->cr(); st->print("\t");
1499 if (UseLoongsonISA) {
1500 st->print("gslq RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
1501 } else {
1502 st->print("ld RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
1503 st->cr(); st->print("\t");
1504 st->print("ld FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
1505 }
1507 if( do_polling() && C->is_method_compilation() ) {
1508 st->print("Poll Safepoint # MachEpilogNode");
1509 }
1510 }
1511 #endif
1513 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1514 Compile *C = ra_->C;
1515 MacroAssembler _masm(&cbuf);
1516 int framesize = C->frame_size_in_bytes();
1518 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1520 __ daddiu(SP, SP, framesize);
1522 if (UseLoongsonISA) {
1523 __ gslq(RA, FP, SP, -wordSize*2);
1524 } else {
1525 __ ld(RA, SP, -wordSize );
1526 __ ld(FP, SP, -wordSize*2 );
1527 }
1529 /* 2012/11/19 Jin: The epilog in a RuntimeStub should not contain a safepoint */
1530 if( do_polling() && C->is_method_compilation() ) {
1531 #ifndef OPT_SAFEPOINT
1532 __ set64(AT, (long)os::get_polling_page());
1533 __ relocate(relocInfo::poll_return_type);
1534 __ lw(AT, AT, 0);
1535 #else
1536 __ lui(AT, Assembler::split_high((intptr_t)os::get_polling_page()));
1537 __ relocate(relocInfo::poll_return_type);
1538 __ lw(AT, AT, Assembler::split_low((intptr_t)os::get_polling_page()));
1539 #endif
1540 }
1541 }
1543 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1544 return MachNode::size(ra_); // too many variables; just compute it the hard way fujie debug
1545 }
1547 int MachEpilogNode::reloc() const {
1548 return 0; // a large enough number
1549 }
1551 const Pipeline * MachEpilogNode::pipeline() const {
1552 return MachNode::pipeline_class();
1553 }
1555 int MachEpilogNode::safepoint_offset() const { return 0; }
1557 //=============================================================================
1559 #ifndef PRODUCT
1560 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1561 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1562 int reg = ra_->get_reg_first(this);
1563 st->print("ADDI %s, SP, %d @BoxLockNode",Matcher::regName[reg],offset);
1564 }
1565 #endif
1568 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1569 return 4;
1570 }
1572 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1573 MacroAssembler _masm(&cbuf);
1574 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1575 int reg = ra_->get_encode(this);
1577 __ addi(as_Register(reg), SP, offset);
1578 /*
1579 if( offset >= 128 ) {
1580 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1581 emit_rm(cbuf, 0x2, reg, 0x04);
1582 emit_rm(cbuf, 0x0, 0x04, SP_enc);
1583 emit_d32(cbuf, offset);
1584 }
1585 else {
1586 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1587 emit_rm(cbuf, 0x1, reg, 0x04);
1588 emit_rm(cbuf, 0x0, 0x04, SP_enc);
1589 emit_d8(cbuf, offset);
1590 }
1591 */
1592 }
1595 //static int sizeof_FFree_Float_Stack_All = -1;
1597 int MachCallRuntimeNode::ret_addr_offset() {
1598 //lui
1599 //ori
1600 //dsll
1601 //ori
1602 //jalr
1603 //nop
1604 assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
1605 return NativeCall::instruction_size;
1606 // return 16;
1607 }
1613 //=============================================================================
1614 #ifndef PRODUCT
1615 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
1616 st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
1617 }
1618 #endif
1620 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
1621 MacroAssembler _masm(&cbuf);
1622 int i = 0;
1623 for(i = 0; i < _count; i++)
1624 __ nop();
1625 }
1627 uint MachNopNode::size(PhaseRegAlloc *) const {
1628 return 4 * _count;
1629 }
1630 const Pipeline* MachNopNode::pipeline() const {
1631 return MachNode::pipeline_class();
1632 }
1634 //=============================================================================
1636 //=============================================================================
1637 #ifndef PRODUCT
1638 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1639 st->print_cr("load_klass(AT, T0)");
1640 st->print_cr("\tbeq(AT, iCache, L)");
1641 st->print_cr("\tnop");
1642 st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
1643 st->print_cr("\tnop");
1644 st->print_cr("\tnop");
1645 st->print_cr(" L:");
1646 }
1647 #endif
1650 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1651 MacroAssembler _masm(&cbuf);
1652 #ifdef ASSERT
1653 //uint code_size = cbuf.code_size();
1654 #endif
1655 int ic_reg = Matcher::inline_cache_reg_encode();
1656 Label L;
1657 Register receiver = T0;
1658 Register iCache = as_Register(ic_reg);
1659 __ load_klass(AT, receiver);
1660 __ beq(AT, iCache, L);
1661 __ nop();
1663 __ relocate(relocInfo::runtime_call_type);
1664 __ li48(T9, (long)SharedRuntime::get_ic_miss_stub());
1665 __ jr(T9);
1666 __ nop();
1668 /* WARNING these NOPs are critical so that verified entry point is properly
1669 * 8 bytes aligned for patching by NativeJump::patch_verified_entry() */
1670 __ align(CodeEntryAlignment);
1671 __ bind(L);
1672 }
1674 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1675 return MachNode::size(ra_);
1676 }
1680 //=============================================================================
1682 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
1684 int Compile::ConstantTable::calculate_table_base_offset() const {
1685 return 0; // absolute addressing, no offset
1686 }
1688 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1689 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1690 ShouldNotReachHere();
1691 }
1693 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1694 Compile* C = ra_->C;
1695 Compile::ConstantTable& constant_table = C->constant_table();
1696 MacroAssembler _masm(&cbuf);
1698 Register Rtoc = as_Register(ra_->get_encode(this));
1699 CodeSection* consts_section = __ code()->consts();
1700 int consts_size = consts_section->align_at_start(consts_section->size());
1701 assert(constant_table.size() == consts_size, "must be equal");
1703 if (consts_section->size()) {
1704 // Materialize the constant table base.
1705 address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
1706 // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
1707 __ relocate(relocInfo::internal_pc_type);
1708 __ li48(Rtoc, (long)baseaddr);
1709 }
1710 }
1712 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1713 // li48 (4 insts)
1714 return 4 * 4;
1715 }
1717 #ifndef PRODUCT
1718 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1719 Register r = as_Register(ra_->get_encode(this));
1720 st->print("li48 %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
1721 }
1722 #endif
1725 //=============================================================================
1726 #ifndef PRODUCT
1727 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1728 Compile* C = ra_->C;
1730 int framesize = C->frame_size_in_bytes();
1731 int bangsize = C->bang_size_in_bytes();
1732 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1734 // Calls to C2R adapters often do not accept exceptional returns.
1735 // We require that their callers must bang for them. But be careful, because
1736 // some VM calls (such as call site linkage) can use several kilobytes of
1737 // stack. But the stack safety zone should account for that.
1738 // See bugs 4446381, 4468289, 4497237.
1739 if (C->need_stack_bang(bangsize)) {
1740 st->print_cr("# stack bang"); st->print("\t");
1741 }
1742 if (UseLoongsonISA) {
1743 st->print("gssq RA, FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1744 } else {
1745 st->print("sd RA, %d(SP) @ MachPrologNode\n\t", -wordSize);
1746 st->print("sd FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1747 }
1748 st->print("daddiu FP, SP, -%d \n\t", wordSize*2);
1749 st->print("daddiu SP, SP, -%d \t",framesize);
1750 }
1751 #endif
1754 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1755 Compile* C = ra_->C;
1756 MacroAssembler _masm(&cbuf);
1758 int framesize = C->frame_size_in_bytes();
1759 int bangsize = C->bang_size_in_bytes();
1761 // __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false);
1763 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1765 if (C->need_stack_bang(framesize)) {
1766 __ generate_stack_overflow_check(framesize);
1767 }
1769 if (UseLoongsonISA) {
1770 __ gssq(RA, FP, SP, -wordSize*2);
1771 } else {
1772 __ sd(RA, SP, -wordSize);
1773 __ sd(FP, SP, -wordSize*2);
1774 }
1775 __ daddiu(FP, SP, -wordSize*2);
1776 __ daddiu(SP, SP, -framesize);
1777 __ nop(); /* 2013.10.22 Jin: Make enough room for patch_verified_entry() */
1778 __ nop();
1780 C->set_frame_complete(cbuf.insts_size());
1781 if (C->has_mach_constant_base_node()) {
1782 // NOTE: We set the table base offset here because users might be
1783 // emitted before MachConstantBaseNode.
1784 Compile::ConstantTable& constant_table = C->constant_table();
1785 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1786 }
1788 }
1791 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1792 //fprintf(stderr, "\nPrologNode::size(ra_)= %d \n", MachNode::size(ra_));//fujie debug
1793 return MachNode::size(ra_); // too many variables; just compute it the hard way
1794 }
1796 int MachPrologNode::reloc() const {
1797 return 0; // a large enough number
1798 }
1800 %}
1802 //----------ENCODING BLOCK-----------------------------------------------------
1803 // This block specifies the encoding classes used by the compiler to output
1804 // byte streams. Encoding classes generate functions which are called by
1805 // Machine Instruction Nodes in order to generate the bit encoding of the
1806 // instruction. Operands specify their base encoding interface with the
1807 // interface keyword. There are currently supported four interfaces,
1808 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
1809 // operand to generate a function which returns its register number when
1810 // queried. CONST_INTER causes an operand to generate a function which
1811 // returns the value of the constant when queried. MEMORY_INTER causes an
1812 // operand to generate four functions which return the Base Register, the
1813 // Index Register, the Scale Value, and the Offset Value of the operand when
1814 // queried. COND_INTER causes an operand to generate six functions which
1815 // return the encoding code (ie - encoding bits for the instruction)
1816 // associated with each basic boolean condition for a conditional instruction.
1817 // Instructions specify two basic values for encoding. They use the
1818 // ins_encode keyword to specify their encoding class (which must be one of
1819 // the class names specified in the encoding block), and they use the
1820 // opcode keyword to specify, in order, their primary, secondary, and
1821 // tertiary opcode. Only the opcode sections which a particular instruction
1822 // needs for encoding need to be specified.
1823 encode %{
1824 /*
1825 Alias:
1826 1044 b java.io.ObjectInputStream::readHandle (130 bytes)
1827 118 B14: # B19 B15 <- B13 Freq: 0.899955
1828 118 add S1, S2, V0 #@addP_reg_reg
1829 11c lb S0, [S1 + #-8257524] #@loadB
1830 120 BReq S0, #3, B19 #@branchConI_reg_imm P=0.100000 C=-1.000000
1831 */
1832 //Load byte signed
1833 enc_class load_B_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 if( Assembler::is_simm16(disp) ) {
1843 if( UseLoongsonISA ) {
1844 if (scale == 0) {
1845 __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
1846 } else {
1847 __ dsll(AT, as_Register(index), scale);
1848 __ gslbx(as_Register(dst), as_Register(base), AT, disp);
1849 }
1850 } else {
1851 if (scale == 0) {
1852 __ addu(AT, as_Register(base), as_Register(index));
1853 } else {
1854 __ dsll(AT, as_Register(index), scale);
1855 __ addu(AT, as_Register(base), AT);
1856 }
1857 __ lb(as_Register(dst), AT, disp);
1858 }
1859 } else {
1860 if (scale == 0) {
1861 __ addu(AT, as_Register(base), as_Register(index));
1862 } else {
1863 __ dsll(AT, as_Register(index), scale);
1864 __ addu(AT, as_Register(base), AT);
1865 }
1866 __ move(T9, disp);
1867 if( UseLoongsonISA ) {
1868 __ gslbx(as_Register(dst), AT, T9, 0);
1869 } else {
1870 __ addu(AT, AT, T9);
1871 __ lb(as_Register(dst), AT, 0);
1872 }
1873 }
1874 } else {
1875 if( Assembler::is_simm16(disp) ) {
1876 __ lb(as_Register(dst), as_Register(base), disp);
1877 } else {
1878 __ move(T9, disp);
1879 if( UseLoongsonISA ) {
1880 __ gslbx(as_Register(dst), as_Register(base), T9, 0);
1881 } else {
1882 __ addu(AT, as_Register(base), T9);
1883 __ lb(as_Register(dst), AT, 0);
1884 }
1885 }
1886 }
1887 %}
1889 //Load byte unsigned
1890 enc_class load_UB_enc (mRegI dst, memory mem) %{
1891 MacroAssembler _masm(&cbuf);
1892 int dst = $dst$$reg;
1893 int base = $mem$$base;
1894 int index = $mem$$index;
1895 int scale = $mem$$scale;
1896 int disp = $mem$$disp;
1898 if( index != 0 ) {
1899 if (scale == 0) {
1900 __ daddu(AT, as_Register(base), as_Register(index));
1901 } else {
1902 __ dsll(AT, as_Register(index), scale);
1903 __ daddu(AT, as_Register(base), AT);
1904 }
1905 if( Assembler::is_simm16(disp) ) {
1906 __ lbu(as_Register(dst), AT, disp);
1907 } else {
1908 __ move(T9, disp);
1909 __ daddu(AT, AT, T9);
1910 __ lbu(as_Register(dst), AT, 0);
1911 }
1912 } else {
1913 if( Assembler::is_simm16(disp) ) {
1914 __ lbu(as_Register(dst), as_Register(base), disp);
1915 } else {
1916 __ move(T9, disp);
1917 __ daddu(AT, as_Register(base), T9);
1918 __ lbu(as_Register(dst), AT, 0);
1919 }
1920 }
1921 %}
1923 enc_class store_B_reg_enc (memory mem, mRegI src) %{
1924 MacroAssembler _masm(&cbuf);
1925 int src = $src$$reg;
1926 int base = $mem$$base;
1927 int index = $mem$$index;
1928 int scale = $mem$$scale;
1929 int disp = $mem$$disp;
1931 if( index != 0 ) {
1932 if (scale == 0) {
1933 if( Assembler::is_simm(disp, 8) ) {
1934 if (UseLoongsonISA) {
1935 __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
1936 } else {
1937 __ addu(AT, as_Register(base), as_Register(index));
1938 __ sb(as_Register(src), AT, disp);
1939 }
1940 } else if( Assembler::is_simm16(disp) ) {
1941 __ addu(AT, as_Register(base), as_Register(index));
1942 __ sb(as_Register(src), AT, disp);
1943 } else {
1944 __ addu(AT, as_Register(base), as_Register(index));
1945 __ move(T9, disp);
1946 if (UseLoongsonISA) {
1947 __ gssbx(as_Register(src), AT, T9, 0);
1948 } else {
1949 __ addu(AT, AT, T9);
1950 __ sb(as_Register(src), AT, 0);
1951 }
1952 }
1953 } else {
1954 __ dsll(AT, as_Register(index), scale);
1955 if( Assembler::is_simm(disp, 8) ) {
1956 if (UseLoongsonISA) {
1957 __ gssbx(as_Register(src), AT, as_Register(base), disp);
1958 } else {
1959 __ addu(AT, as_Register(base), AT);
1960 __ sb(as_Register(src), AT, disp);
1961 }
1962 } else if( Assembler::is_simm16(disp) ) {
1963 __ addu(AT, as_Register(base), AT);
1964 __ sb(as_Register(src), AT, disp);
1965 } else {
1966 __ addu(AT, as_Register(base), AT);
1967 __ move(T9, disp);
1968 if (UseLoongsonISA) {
1969 __ gssbx(as_Register(src), AT, T9, 0);
1970 } else {
1971 __ addu(AT, AT, T9);
1972 __ sb(as_Register(src), AT, 0);
1973 }
1974 }
1975 }
1976 } else {
1977 if( Assembler::is_simm16(disp) ) {
1978 __ sb(as_Register(src), as_Register(base), disp);
1979 } else {
1980 __ move(T9, disp);
1981 if (UseLoongsonISA) {
1982 __ gssbx(as_Register(src), as_Register(base), T9, 0);
1983 } else {
1984 __ addu(AT, as_Register(base), T9);
1985 __ sb(as_Register(src), AT, 0);
1986 }
1987 }
1988 }
1989 %}
1991 enc_class store_B_immI_enc (memory mem, immI8 src) %{
1992 MacroAssembler _masm(&cbuf);
1993 int base = $mem$$base;
1994 int index = $mem$$index;
1995 int scale = $mem$$scale;
1996 int disp = $mem$$disp;
1997 int value = $src$$constant;
1999 if( index != 0 ) {
2000 if (!UseLoongsonISA) {
2001 if (scale == 0) {
2002 __ daddu(AT, as_Register(base), as_Register(index));
2003 } else {
2004 __ dsll(AT, as_Register(index), scale);
2005 __ daddu(AT, as_Register(base), AT);
2006 }
2007 if( Assembler::is_simm16(disp) ) {
2008 if (value == 0) {
2009 __ sb(R0, AT, disp);
2010 } else {
2011 __ move(T9, value);
2012 __ sb(T9, AT, disp);
2013 }
2014 } else {
2015 if (value == 0) {
2016 __ move(T9, disp);
2017 __ daddu(AT, AT, T9);
2018 __ sb(R0, AT, 0);
2019 } else {
2020 __ move(T9, disp);
2021 __ daddu(AT, AT, T9);
2022 __ move(T9, value);
2023 __ sb(T9, AT, 0);
2024 }
2025 }
2026 } else {
2028 if (scale == 0) {
2029 if( Assembler::is_simm(disp, 8) ) {
2030 if (value == 0) {
2031 __ gssbx(R0, as_Register(base), as_Register(index), disp);
2032 } else {
2033 __ move(T9, value);
2034 __ gssbx(T9, as_Register(base), as_Register(index), disp);
2035 }
2036 } else if( Assembler::is_simm16(disp) ) {
2037 __ daddu(AT, as_Register(base), as_Register(index));
2038 if (value == 0) {
2039 __ sb(R0, AT, disp);
2040 } else {
2041 __ move(T9, value);
2042 __ sb(T9, AT, disp);
2043 }
2044 } else {
2045 if (value == 0) {
2046 __ daddu(AT, as_Register(base), as_Register(index));
2047 __ move(T9, disp);
2048 __ gssbx(R0, AT, T9, 0);
2049 } else {
2050 __ move(AT, disp);
2051 __ move(T9, value);
2052 __ daddu(AT, as_Register(base), AT);
2053 __ gssbx(T9, AT, as_Register(index), 0);
2054 }
2055 }
2057 } else {
2059 if( Assembler::is_simm(disp, 8) ) {
2060 __ dsll(AT, as_Register(index), scale);
2061 if (value == 0) {
2062 __ gssbx(R0, as_Register(base), AT, disp);
2063 } else {
2064 __ move(T9, value);
2065 __ gssbx(T9, as_Register(base), AT, disp);
2066 }
2067 } else if( Assembler::is_simm16(disp) ) {
2068 __ dsll(AT, as_Register(index), scale);
2069 __ daddu(AT, as_Register(base), AT);
2070 if (value == 0) {
2071 __ sb(R0, AT, disp);
2072 } else {
2073 __ move(T9, value);
2074 __ sb(T9, AT, disp);
2075 }
2076 } else {
2077 __ dsll(AT, as_Register(index), scale);
2078 if (value == 0) {
2079 __ daddu(AT, as_Register(base), AT);
2080 __ move(T9, disp);
2081 __ gssbx(R0, AT, T9, 0);
2082 } else {
2083 __ move(T9, disp);
2084 __ daddu(AT, AT, T9);
2085 __ move(T9, value);
2086 __ gssbx(T9, as_Register(base), AT, 0);
2087 }
2088 }
2089 }
2090 }
2091 } else {
2092 if( Assembler::is_simm16(disp) ) {
2093 if (value == 0) {
2094 __ sb(R0, as_Register(base), disp);
2095 } else {
2096 __ move(AT, value);
2097 __ sb(AT, as_Register(base), disp);
2098 }
2099 } else {
2100 if (value == 0) {
2101 __ move(T9, disp);
2102 if (UseLoongsonISA) {
2103 __ gssbx(R0, as_Register(base), T9, 0);
2104 } else {
2105 __ daddu(AT, as_Register(base), T9);
2106 __ sb(R0, AT, 0);
2107 }
2108 } else {
2109 __ move(T9, disp);
2110 if (UseLoongsonISA) {
2111 __ move(AT, value);
2112 __ gssbx(AT, as_Register(base), T9, 0);
2113 } else {
2114 __ daddu(AT, as_Register(base), T9);
2115 __ move(T9, value);
2116 __ sb(T9, AT, 0);
2117 }
2118 }
2119 }
2120 }
2121 %}
2124 enc_class store_B_immI_enc_sync (memory mem, immI8 src) %{
2125 MacroAssembler _masm(&cbuf);
2126 int base = $mem$$base;
2127 int index = $mem$$index;
2128 int scale = $mem$$scale;
2129 int disp = $mem$$disp;
2130 int value = $src$$constant;
2132 if( index != 0 ) {
2133 if (scale == 0) {
2134 __ daddu(AT, as_Register(base), as_Register(index));
2135 } else {
2136 __ dsll(AT, as_Register(index), scale);
2137 __ daddu(AT, as_Register(base), AT);
2138 }
2139 if( Assembler::is_simm16(disp) ) {
2140 if (value == 0) {
2141 __ sb(R0, AT, disp);
2142 } else {
2143 __ move(T9, value);
2144 __ sb(T9, AT, disp);
2145 }
2146 } else {
2147 if (value == 0) {
2148 __ move(T9, disp);
2149 __ daddu(AT, AT, T9);
2150 __ sb(R0, AT, 0);
2151 } else {
2152 __ move(T9, disp);
2153 __ daddu(AT, AT, T9);
2154 __ move(T9, value);
2155 __ sb(T9, AT, 0);
2156 }
2157 }
2158 } else {
2159 if( Assembler::is_simm16(disp) ) {
2160 if (value == 0) {
2161 __ sb(R0, as_Register(base), disp);
2162 } else {
2163 __ move(AT, value);
2164 __ sb(AT, as_Register(base), disp);
2165 }
2166 } else {
2167 if (value == 0) {
2168 __ move(T9, disp);
2169 __ daddu(AT, as_Register(base), T9);
2170 __ sb(R0, AT, 0);
2171 } else {
2172 __ move(T9, disp);
2173 __ daddu(AT, as_Register(base), T9);
2174 __ move(T9, value);
2175 __ sb(T9, AT, 0);
2176 }
2177 }
2178 }
2180 __ sync();
2181 %}
2183 // Load Short (16bit signed)
2184 enc_class load_S_enc (mRegI dst, memory mem) %{
2185 MacroAssembler _masm(&cbuf);
2186 int dst = $dst$$reg;
2187 int base = $mem$$base;
2188 int index = $mem$$index;
2189 int scale = $mem$$scale;
2190 int disp = $mem$$disp;
2192 if( index != 0 ) {
2193 if (scale == 0) {
2194 __ daddu(AT, as_Register(base), as_Register(index));
2195 } else {
2196 __ dsll(AT, as_Register(index), scale);
2197 __ daddu(AT, as_Register(base), AT);
2198 }
2199 if( Assembler::is_simm16(disp) ) {
2200 __ lh(as_Register(dst), AT, disp);
2201 } else {
2202 __ move(T9, disp);
2203 __ addu(AT, AT, T9);
2204 __ lh(as_Register(dst), AT, 0);
2205 }
2206 } else {
2207 if( Assembler::is_simm16(disp) ) {
2208 __ lh(as_Register(dst), as_Register(base), disp);
2209 } else {
2210 __ move(T9, disp);
2211 __ addu(AT, as_Register(base), T9);
2212 __ lh(as_Register(dst), AT, 0);
2213 }
2214 }
2215 %}
2217 // Load Char (16bit unsigned)
2218 enc_class load_C_enc (mRegI dst, memory mem) %{
2219 MacroAssembler _masm(&cbuf);
2220 int dst = $dst$$reg;
2221 int base = $mem$$base;
2222 int index = $mem$$index;
2223 int scale = $mem$$scale;
2224 int disp = $mem$$disp;
2226 if( index != 0 ) {
2227 if (scale == 0) {
2228 __ daddu(AT, as_Register(base), as_Register(index));
2229 } else {
2230 __ dsll(AT, as_Register(index), scale);
2231 __ daddu(AT, as_Register(base), AT);
2232 }
2233 if( Assembler::is_simm16(disp) ) {
2234 __ lhu(as_Register(dst), AT, disp);
2235 } else {
2236 __ move(T9, disp);
2237 __ addu(AT, AT, T9);
2238 __ lhu(as_Register(dst), AT, 0);
2239 }
2240 } else {
2241 if( Assembler::is_simm16(disp) ) {
2242 __ lhu(as_Register(dst), as_Register(base), disp);
2243 } else {
2244 __ move(T9, disp);
2245 __ daddu(AT, as_Register(base), T9);
2246 __ lhu(as_Register(dst), AT, 0);
2247 }
2248 }
2249 %}
2251 // Store Char (16bit unsigned)
2252 enc_class store_C_reg_enc (memory mem, mRegI src) %{
2253 MacroAssembler _masm(&cbuf);
2254 int src = $src$$reg;
2255 int base = $mem$$base;
2256 int index = $mem$$index;
2257 int scale = $mem$$scale;
2258 int disp = $mem$$disp;
2260 if( index != 0 ) {
2261 if( Assembler::is_simm16(disp) ) {
2262 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2263 if (scale == 0) {
2264 __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
2265 } else {
2266 __ dsll(AT, as_Register(index), scale);
2267 __ gsshx(as_Register(src), as_Register(base), AT, disp);
2268 }
2269 } else {
2270 if (scale == 0) {
2271 __ addu(AT, as_Register(base), as_Register(index));
2272 } else {
2273 __ dsll(AT, as_Register(index), scale);
2274 __ addu(AT, as_Register(base), AT);
2275 }
2276 __ sh(as_Register(src), AT, disp);
2277 }
2278 } else {
2279 if (scale == 0) {
2280 __ addu(AT, as_Register(base), as_Register(index));
2281 } else {
2282 __ dsll(AT, as_Register(index), scale);
2283 __ addu(AT, as_Register(base), AT);
2284 }
2285 __ move(T9, disp);
2286 if( UseLoongsonISA ) {
2287 __ gsshx(as_Register(src), AT, T9, 0);
2288 } else {
2289 __ addu(AT, AT, T9);
2290 __ sh(as_Register(src), AT, 0);
2291 }
2292 }
2293 } else {
2294 if( Assembler::is_simm16(disp) ) {
2295 __ sh(as_Register(src), as_Register(base), disp);
2296 } else {
2297 __ move(T9, disp);
2298 if( UseLoongsonISA ) {
2299 __ gsshx(as_Register(src), as_Register(base), T9, 0);
2300 } else {
2301 __ addu(AT, as_Register(base), T9);
2302 __ sh(as_Register(src), AT, 0);
2303 }
2304 }
2305 }
2306 %}
2308 enc_class load_I_enc (mRegI dst, memory mem) %{
2309 MacroAssembler _masm(&cbuf);
2310 int dst = $dst$$reg;
2311 int base = $mem$$base;
2312 int index = $mem$$index;
2313 int scale = $mem$$scale;
2314 int disp = $mem$$disp;
2316 if( index != 0 ) {
2317 if( Assembler::is_simm16(disp) ) {
2318 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2319 if (scale == 0) {
2320 __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
2321 } else {
2322 __ dsll(AT, as_Register(index), scale);
2323 __ gslwx(as_Register(dst), as_Register(base), AT, disp);
2324 }
2325 } else {
2326 if (scale == 0) {
2327 __ addu(AT, as_Register(base), as_Register(index));
2328 } else {
2329 __ dsll(AT, as_Register(index), scale);
2330 __ addu(AT, as_Register(base), AT);
2331 }
2332 __ lw(as_Register(dst), AT, disp);
2333 }
2334 } else {
2335 if (scale == 0) {
2336 __ addu(AT, as_Register(base), as_Register(index));
2337 } else {
2338 __ dsll(AT, as_Register(index), scale);
2339 __ addu(AT, as_Register(base), AT);
2340 }
2341 __ move(T9, disp);
2342 if( UseLoongsonISA ) {
2343 __ gslwx(as_Register(dst), AT, T9, 0);
2344 } else {
2345 __ addu(AT, AT, T9);
2346 __ lw(as_Register(dst), AT, 0);
2347 }
2348 }
2349 } else {
2350 if( Assembler::is_simm16(disp) ) {
2351 __ lw(as_Register(dst), as_Register(base), disp);
2352 } else {
2353 __ move(T9, disp);
2354 if( UseLoongsonISA ) {
2355 __ gslwx(as_Register(dst), as_Register(base), T9, 0);
2356 } else {
2357 __ addu(AT, as_Register(base), T9);
2358 __ lw(as_Register(dst), AT, 0);
2359 }
2360 }
2361 }
2362 %}
2364 enc_class store_I_reg_enc (memory mem, mRegI src) %{
2365 MacroAssembler _masm(&cbuf);
2366 int src = $src$$reg;
2367 int base = $mem$$base;
2368 int index = $mem$$index;
2369 int scale = $mem$$scale;
2370 int disp = $mem$$disp;
2372 if( index != 0 ) {
2373 if( Assembler::is_simm16(disp) ) {
2374 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2375 if (scale == 0) {
2376 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
2377 } else {
2378 __ dsll(AT, as_Register(index), scale);
2379 __ gsswx(as_Register(src), as_Register(base), AT, disp);
2380 }
2381 } else {
2382 if (scale == 0) {
2383 __ addu(AT, as_Register(base), as_Register(index));
2384 } else {
2385 __ dsll(AT, as_Register(index), scale);
2386 __ addu(AT, as_Register(base), AT);
2387 }
2388 __ sw(as_Register(src), AT, disp);
2389 }
2390 } else {
2391 if (scale == 0) {
2392 __ addu(AT, as_Register(base), as_Register(index));
2393 } else {
2394 __ dsll(AT, as_Register(index), scale);
2395 __ addu(AT, as_Register(base), AT);
2396 }
2397 __ move(T9, disp);
2398 if( UseLoongsonISA ) {
2399 __ gsswx(as_Register(src), AT, T9, 0);
2400 } else {
2401 __ addu(AT, AT, T9);
2402 __ sw(as_Register(src), AT, 0);
2403 }
2404 }
2405 } else {
2406 if( Assembler::is_simm16(disp) ) {
2407 __ sw(as_Register(src), as_Register(base), disp);
2408 } else {
2409 __ move(T9, disp);
2410 if( UseLoongsonISA ) {
2411 __ gsswx(as_Register(src), as_Register(base), T9, 0);
2412 } else {
2413 __ addu(AT, as_Register(base), T9);
2414 __ sw(as_Register(src), AT, 0);
2415 }
2416 }
2417 }
2418 %}
2420 enc_class store_I_immI_enc (memory mem, immI src) %{
2421 MacroAssembler _masm(&cbuf);
2422 int base = $mem$$base;
2423 int index = $mem$$index;
2424 int scale = $mem$$scale;
2425 int disp = $mem$$disp;
2426 int value = $src$$constant;
2428 if( index != 0 ) {
2429 if (scale == 0) {
2430 __ daddu(AT, as_Register(base), as_Register(index));
2431 } else {
2432 __ dsll(AT, as_Register(index), scale);
2433 __ daddu(AT, as_Register(base), AT);
2434 }
2435 if( Assembler::is_simm16(disp) ) {
2436 if (value == 0) {
2437 __ sw(R0, AT, disp);
2438 } else {
2439 __ move(T9, value);
2440 __ sw(T9, AT, disp);
2441 }
2442 } else {
2443 if (value == 0) {
2444 __ move(T9, disp);
2445 __ addu(AT, AT, T9);
2446 __ sw(R0, AT, 0);
2447 } else {
2448 __ move(T9, disp);
2449 __ addu(AT, AT, T9);
2450 __ move(T9, value);
2451 __ sw(T9, AT, 0);
2452 }
2453 }
2454 } else {
2455 if( Assembler::is_simm16(disp) ) {
2456 if (value == 0) {
2457 __ sw(R0, as_Register(base), disp);
2458 } else {
2459 __ move(AT, value);
2460 __ sw(AT, as_Register(base), disp);
2461 }
2462 } else {
2463 if (value == 0) {
2464 __ move(T9, disp);
2465 __ addu(AT, as_Register(base), T9);
2466 __ sw(R0, AT, 0);
2467 } else {
2468 __ move(T9, disp);
2469 __ addu(AT, as_Register(base), T9);
2470 __ move(T9, value);
2471 __ sw(T9, AT, 0);
2472 }
2473 }
2474 }
2475 %}
2477 enc_class load_N_enc (mRegN dst, memory mem) %{
2478 MacroAssembler _masm(&cbuf);
2479 int dst = $dst$$reg;
2480 int base = $mem$$base;
2481 int index = $mem$$index;
2482 int scale = $mem$$scale;
2483 int disp = $mem$$disp;
2484 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2485 assert(disp_reloc == relocInfo::none, "cannot have disp");
2487 if( index != 0 ) {
2488 if (scale == 0) {
2489 __ daddu(AT, as_Register(base), as_Register(index));
2490 } else {
2491 __ dsll(AT, as_Register(index), scale);
2492 __ daddu(AT, as_Register(base), AT);
2493 }
2494 if( Assembler::is_simm16(disp) ) {
2495 __ lwu(as_Register(dst), AT, disp);
2496 } else {
2497 __ li(T9, disp);
2498 __ daddu(AT, AT, T9);
2499 __ lwu(as_Register(dst), AT, 0);
2500 }
2501 } else {
2502 if( Assembler::is_simm16(disp) ) {
2503 __ lwu(as_Register(dst), as_Register(base), disp);
2504 } else {
2505 __ li(T9, disp);
2506 __ daddu(AT, as_Register(base), T9);
2507 __ lwu(as_Register(dst), AT, 0);
2508 }
2509 }
2511 %}
2514 enc_class load_P_enc (mRegP dst, memory mem) %{
2515 MacroAssembler _masm(&cbuf);
2516 int dst = $dst$$reg;
2517 int base = $mem$$base;
2518 int index = $mem$$index;
2519 int scale = $mem$$scale;
2520 int disp = $mem$$disp;
2521 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2522 assert(disp_reloc == relocInfo::none, "cannot have disp");
2524 if( index != 0 ) {
2525 if (scale == 0) {
2526 __ daddu(AT, as_Register(base), as_Register(index));
2527 } else {
2528 __ dsll(AT, as_Register(index), scale);
2529 __ daddu(AT, as_Register(base), AT);
2530 }
2531 if( Assembler::is_simm16(disp) ) {
2532 __ ld(as_Register(dst), AT, disp);
2533 } else {
2534 __ li(T9, disp);
2535 __ daddu(AT, AT, T9);
2536 __ ld(as_Register(dst), AT, 0);
2537 }
2538 } else {
2539 if( Assembler::is_simm16(disp) ) {
2540 __ ld(as_Register(dst), as_Register(base), disp);
2541 } else {
2542 __ li(T9, disp);
2543 __ daddu(AT, as_Register(base), T9);
2544 __ ld(as_Register(dst), AT, 0);
2545 }
2546 }
2547 // if( disp_reloc != relocInfo::none) __ ld(as_Register(dst), as_Register(dst), 0);
2548 %}
2550 enc_class store_P_reg_enc (memory mem, mRegP src) %{
2551 MacroAssembler _masm(&cbuf);
2552 int src = $src$$reg;
2553 int base = $mem$$base;
2554 int index = $mem$$index;
2555 int scale = $mem$$scale;
2556 int disp = $mem$$disp;
2558 if( index != 0 ) {
2559 if (scale == 0) {
2560 __ daddu(AT, as_Register(base), as_Register(index));
2561 } else {
2562 __ dsll(AT, as_Register(index), scale);
2563 __ daddu(AT, as_Register(base), AT);
2564 }
2565 if( Assembler::is_simm16(disp) ) {
2566 __ sd(as_Register(src), AT, disp);
2567 } else {
2568 __ move(T9, disp);
2569 __ daddu(AT, AT, T9);
2570 __ sd(as_Register(src), AT, 0);
2571 }
2572 } else {
2573 if( Assembler::is_simm16(disp) ) {
2574 __ sd(as_Register(src), as_Register(base), disp);
2575 } else {
2576 __ move(T9, disp);
2577 __ daddu(AT, as_Register(base), T9);
2578 __ sd(as_Register(src), AT, 0);
2579 }
2580 }
2581 %}
2583 enc_class store_N_reg_enc (memory mem, mRegN src) %{
2584 MacroAssembler _masm(&cbuf);
2585 int src = $src$$reg;
2586 int base = $mem$$base;
2587 int index = $mem$$index;
2588 int scale = $mem$$scale;
2589 int disp = $mem$$disp;
2591 if( index != 0 ) {
2592 if (scale == 0) {
2593 __ daddu(AT, as_Register(base), as_Register(index));
2594 } else {
2595 __ dsll(AT, as_Register(index), scale);
2596 __ daddu(AT, as_Register(base), AT);
2597 }
2598 if( Assembler::is_simm16(disp) ) {
2599 __ sw(as_Register(src), AT, disp);
2600 } else {
2601 __ move(T9, disp);
2602 __ addu(AT, AT, T9);
2603 __ sw(as_Register(src), AT, 0);
2604 }
2605 } else {
2606 if( Assembler::is_simm16(disp) ) {
2607 __ sw(as_Register(src), as_Register(base), disp);
2608 } else {
2609 __ move(T9, disp);
2610 __ addu(AT, as_Register(base), T9);
2611 __ sw(as_Register(src), AT, 0);
2612 }
2613 }
2614 %}
2616 enc_class store_P_immP_enc (memory mem, immP31 src) %{
2617 MacroAssembler _masm(&cbuf);
2618 int base = $mem$$base;
2619 int index = $mem$$index;
2620 int scale = $mem$$scale;
2621 int disp = $mem$$disp;
2622 long value = $src$$constant;
2624 if( index != 0 ) {
2625 if (scale == 0) {
2626 __ daddu(AT, as_Register(base), as_Register(index));
2627 } else {
2628 __ dsll(AT, as_Register(index), scale);
2629 __ daddu(AT, as_Register(base), AT);
2630 }
2631 if( Assembler::is_simm16(disp) ) {
2632 if (value == 0) {
2633 __ sd(R0, AT, disp);
2634 } else {
2635 __ move(T9, value);
2636 __ sd(T9, AT, disp);
2637 }
2638 } else {
2639 if (value == 0) {
2640 __ move(T9, disp);
2641 __ daddu(AT, AT, T9);
2642 __ sd(R0, AT, 0);
2643 } else {
2644 __ move(T9, disp);
2645 __ daddu(AT, AT, T9);
2646 __ move(T9, value);
2647 __ sd(T9, AT, 0);
2648 }
2649 }
2650 } else {
2651 if( Assembler::is_simm16(disp) ) {
2652 if (value == 0) {
2653 __ sd(R0, as_Register(base), disp);
2654 } else {
2655 __ move(AT, value);
2656 __ sd(AT, as_Register(base), disp);
2657 }
2658 } else {
2659 if (value == 0) {
2660 __ move(T9, disp);
2661 __ daddu(AT, as_Register(base), T9);
2662 __ sd(R0, AT, 0);
2663 } else {
2664 __ move(T9, disp);
2665 __ daddu(AT, as_Register(base), T9);
2666 __ move(T9, value);
2667 __ sd(T9, AT, 0);
2668 }
2669 }
2670 }
2671 %}
2673 /*
2674 * 1d4 storeImmN [S0 + #16 (8-bit)], narrowoop: spec/benchmarks/_213_javac/Identifier:exact *
2675 * # compressed ptr ! Field: spec/benchmarks/_213_javac/Identifier.value
2676 * 0x00000055648065d4: daddu at, s0, zero
2677 * 0x00000055648065d8: lui t9, 0x0 ; {oop(a 'spec/benchmarks/_213_javac/Identifier')}
2678 * 0x00000055648065dc: ori t9, t9, 0xfffff610
2679 * 0x00000055648065e0: dsll t9, t9, 16
2680 * 0x00000055648065e4: ori t9, t9, 0xffffc628
2681 * 0x00000055648065e8: sw t9, 0x10(at)
2682 */
2683 enc_class storeImmN_enc (memory mem, immN src) %{
2684 MacroAssembler _masm(&cbuf);
2685 int base = $mem$$base;
2686 int index = $mem$$index;
2687 int scale = $mem$$scale;
2688 int disp = $mem$$disp;
2689 long * value = (long *)$src$$constant;
2691 if (value == NULL) {
2692 guarantee(Assembler::is_simm16(disp), "FIXME: disp is not simm16!");
2693 if (index == 0) {
2694 __ sw(R0, as_Register(base), disp);
2695 } else {
2696 if (scale == 0) {
2697 __ daddu(AT, as_Register(base), as_Register(index));
2698 } else {
2699 __ dsll(AT, as_Register(index), scale);
2700 __ daddu(AT, as_Register(base), AT);
2701 }
2702 __ sw(R0, AT, disp);
2703 }
2705 return;
2706 }
2708 int oop_index = __ oop_recorder()->find_index((jobject)value);
2709 RelocationHolder rspec = oop_Relocation::spec(oop_index);
2711 guarantee(scale == 0, "FIXME: scale is not zero !");
2712 guarantee(value != 0, "FIXME: value is zero !");
2714 if (index != 0) {
2715 if (scale == 0) {
2716 __ daddu(AT, as_Register(base), as_Register(index));
2717 } else {
2718 __ dsll(AT, as_Register(index), scale);
2719 __ daddu(AT, as_Register(base), AT);
2720 }
2721 if( Assembler::is_simm16(disp) ) {
2722 if(rspec.type() != relocInfo::none) {
2723 __ relocate(rspec, Assembler::narrow_oop_operand);
2724 __ li48(T9, oop_index);
2725 } else {
2726 __ set64(T9, oop_index);
2727 }
2728 __ sw(T9, AT, disp);
2729 } else {
2730 __ move(T9, disp);
2731 __ addu(AT, AT, T9);
2733 if(rspec.type() != relocInfo::none) {
2734 __ relocate(rspec, Assembler::narrow_oop_operand);
2735 __ li48(T9, oop_index);
2736 } else {
2737 __ set64(T9, oop_index);
2738 }
2739 __ sw(T9, AT, 0);
2740 }
2741 }
2742 else {
2743 if( Assembler::is_simm16(disp) ) {
2744 if($src->constant_reloc() != relocInfo::none) {
2745 __ relocate(rspec, Assembler::narrow_oop_operand);
2746 __ li48(T9, oop_index);
2747 } else {
2748 __ set64(T9, oop_index);
2749 }
2750 __ sw(T9, as_Register(base), disp);
2751 } else {
2752 __ move(T9, disp);
2753 __ daddu(AT, as_Register(base), T9);
2755 if($src->constant_reloc() != relocInfo::none){
2756 __ relocate(rspec, Assembler::narrow_oop_operand);
2757 __ li48(T9, oop_index);
2758 } else {
2759 __ set64(T9, oop_index);
2760 }
2761 __ sw(T9, AT, 0);
2762 }
2763 }
2764 %}
2766 enc_class storeImmNKlass_enc (memory mem, immNKlass src) %{
2767 MacroAssembler _masm(&cbuf);
2769 assert (UseCompressedOops, "should only be used for compressed headers");
2770 assert (__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
2772 int base = $mem$$base;
2773 int index = $mem$$index;
2774 int scale = $mem$$scale;
2775 int disp = $mem$$disp;
2776 long value = $src$$constant;
2778 int klass_index = __ oop_recorder()->find_index((Klass*)value);
2779 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
2780 long narrowp = Klass::encode_klass((Klass*)value);
2782 if(index!=0){
2783 if (scale == 0) {
2784 __ daddu(AT, as_Register(base), as_Register(index));
2785 } else {
2786 __ dsll(AT, as_Register(index), scale);
2787 __ daddu(AT, as_Register(base), AT);
2788 }
2790 if( Assembler::is_simm16(disp) ) {
2791 if(rspec.type() != relocInfo::none){
2792 __ relocate(rspec, Assembler::narrow_oop_operand);
2793 __ li48(T9, narrowp);
2794 } else {
2795 __ set64(T9, narrowp);
2796 }
2797 __ sw(T9, AT, disp);
2798 } else {
2799 __ move(T9, disp);
2800 __ daddu(AT, AT, T9);
2802 if(rspec.type() != relocInfo::none){
2803 __ relocate(rspec, Assembler::narrow_oop_operand);
2804 __ li48(T9, narrowp);
2805 } else {
2806 __ set64(T9, narrowp);
2807 }
2809 __ sw(T9, AT, 0);
2810 }
2811 } else {
2812 if( Assembler::is_simm16(disp) ) {
2813 if(rspec.type() != relocInfo::none){
2814 __ relocate(rspec, Assembler::narrow_oop_operand);
2815 __ li48(T9, narrowp);
2816 }
2817 else {
2818 __ set64(T9, narrowp);
2819 }
2820 __ sw(T9, as_Register(base), disp);
2821 } else {
2822 __ move(T9, disp);
2823 __ daddu(AT, as_Register(base), T9);
2825 if(rspec.type() != relocInfo::none){
2826 __ relocate(rspec, Assembler::narrow_oop_operand);
2827 __ li48(T9, narrowp);
2828 } else {
2829 __ set64(T9, narrowp);
2830 }
2831 __ sw(T9, AT, 0);
2832 }
2833 }
2834 %}
2836 enc_class storeImmN0_enc(memory mem, ImmN0 src) %{
2837 MacroAssembler _masm(&cbuf);
2838 int base = $mem$$base;
2839 int index = $mem$$index;
2840 int scale = $mem$$scale;
2841 int disp = $mem$$disp;
2843 if(index!=0){
2844 if (scale == 0) {
2845 __ daddu(AT, as_Register(base), as_Register(index));
2846 } else {
2847 __ dsll(AT, as_Register(index), scale);
2848 __ daddu(AT, as_Register(base), AT);
2849 }
2851 if( Assembler::is_simm16(disp) ) {
2852 __ sw(R0, AT, disp);
2853 } else {
2854 __ move(T9, disp);
2855 __ daddu(AT, AT, T9);
2856 __ sw(R0, AT, 0);
2857 }
2858 }
2859 else {
2860 if( Assembler::is_simm16(disp) ) {
2861 __ sw(R0, as_Register(base), disp);
2862 } else {
2863 __ move(T9, disp);
2864 __ daddu(AT, as_Register(base), T9);
2865 __ sw(R0, AT, 0);
2866 }
2867 }
2868 %}
2870 enc_class load_L_enc (mRegL dst, memory mem) %{
2871 MacroAssembler _masm(&cbuf);
2872 int base = $mem$$base;
2873 int index = $mem$$index;
2874 int scale = $mem$$scale;
2875 int disp = $mem$$disp;
2876 Register dst_reg = as_Register($dst$$reg);
2878 /*********************2013/03/27**************************
2879 * Jin: $base may contain a null object.
2880 * Server JIT force the exception_offset to be the pos of
2881 * the first instruction.
2882 * I insert such a 'null_check' at the beginning.
2883 *******************************************************/
2885 __ lw(AT, as_Register(base), 0);
2887 /*********************2012/10/04**************************
2888 * Error case found in SortTest
2889 * 337 b java.util.Arrays::sort1 (401 bytes)
2890 * B73:
2891 * d34 lw T4.lo, [T4 + #16] #@loadL-lo
2892 * lw T4.hi, [T4 + #16]+4 #@loadL-hi
2893 *
2894 * The original instructions generated here are :
2895 * __ lw(dst_lo, as_Register(base), disp);
2896 * __ lw(dst_hi, as_Register(base), disp + 4);
2897 *******************************************************/
2899 if( index != 0 ) {
2900 if (scale == 0) {
2901 __ daddu(AT, as_Register(base), as_Register(index));
2902 } else {
2903 __ dsll(AT, as_Register(index), scale);
2904 __ daddu(AT, as_Register(base), AT);
2905 }
2906 if( Assembler::is_simm16(disp) ) {
2907 __ ld(dst_reg, AT, disp);
2908 } else {
2909 __ move(T9, disp);
2910 __ daddu(AT, AT, T9);
2911 __ ld(dst_reg, AT, 0);
2912 }
2913 } else {
2914 if( Assembler::is_simm16(disp) ) {
2915 __ move(AT, as_Register(base));
2916 __ ld(dst_reg, AT, disp);
2917 } else {
2918 __ move(T9, disp);
2919 __ daddu(AT, as_Register(base), T9);
2920 __ ld(dst_reg, AT, 0);
2921 }
2922 }
2923 %}
2925 enc_class store_L_reg_enc (memory mem, mRegL src) %{
2926 MacroAssembler _masm(&cbuf);
2927 int base = $mem$$base;
2928 int index = $mem$$index;
2929 int scale = $mem$$scale;
2930 int disp = $mem$$disp;
2931 Register src_reg = as_Register($src$$reg);
2933 if( index != 0 ) {
2934 if (scale == 0) {
2935 __ daddu(AT, as_Register(base), as_Register(index));
2936 } else {
2937 __ dsll(AT, as_Register(index), scale);
2938 __ daddu(AT, as_Register(base), AT);
2939 }
2940 if( Assembler::is_simm16(disp) ) {
2941 __ sd(src_reg, AT, disp);
2942 } else {
2943 __ move(T9, disp);
2944 __ daddu(AT, AT, T9);
2945 __ sd(src_reg, AT, 0);
2946 }
2947 } else {
2948 if( Assembler::is_simm16(disp) ) {
2949 __ move(AT, as_Register(base));
2950 __ sd(src_reg, AT, disp);
2951 } else {
2952 __ move(T9, disp);
2953 __ daddu(AT, as_Register(base), T9);
2954 __ sd(src_reg, AT, 0);
2955 }
2956 }
2957 %}
2959 enc_class store_L_immL0_enc (memory mem, immL0 src) %{
2960 MacroAssembler _masm(&cbuf);
2961 int base = $mem$$base;
2962 int index = $mem$$index;
2963 int scale = $mem$$scale;
2964 int disp = $mem$$disp;
2966 if( index != 0 ) {
2967 if (scale == 0) {
2968 __ daddu(AT, as_Register(base), as_Register(index));
2969 } else {
2970 __ dsll(AT, as_Register(index), scale);
2971 __ daddu(AT, as_Register(base), AT);
2972 }
2973 if( Assembler::is_simm16(disp) ) {
2974 __ sd(R0, AT, disp);
2975 } else {
2976 __ move(T9, disp);
2977 __ addu(AT, AT, T9);
2978 __ sd(R0, AT, 0);
2979 }
2980 } else {
2981 if( Assembler::is_simm16(disp) ) {
2982 __ move(AT, as_Register(base));
2983 __ sd(R0, AT, disp);
2984 } else {
2985 __ move(T9, disp);
2986 __ addu(AT, as_Register(base), T9);
2987 __ sd(R0, AT, 0);
2988 }
2989 }
2990 %}
2992 enc_class store_L_immL_enc (memory mem, immL src) %{
2993 MacroAssembler _masm(&cbuf);
2994 int base = $mem$$base;
2995 int index = $mem$$index;
2996 int scale = $mem$$scale;
2997 int disp = $mem$$disp;
2998 long imm = $src$$constant;
3000 if( index != 0 ) {
3001 if (scale == 0) {
3002 __ daddu(AT, as_Register(base), as_Register(index));
3003 } else {
3004 __ dsll(AT, as_Register(index), scale);
3005 __ daddu(AT, as_Register(base), AT);
3006 }
3007 if( Assembler::is_simm16(disp) ) {
3008 __ li(T9, imm);
3009 __ sd(T9, AT, disp);
3010 } else {
3011 __ move(T9, disp);
3012 __ addu(AT, AT, T9);
3013 __ li(T9, imm);
3014 __ sd(T9, AT, 0);
3015 }
3016 } else {
3017 if( Assembler::is_simm16(disp) ) {
3018 __ move(AT, as_Register(base));
3019 __ li(T9, imm);
3020 __ sd(T9, AT, disp);
3021 } else {
3022 __ move(T9, disp);
3023 __ addu(AT, as_Register(base), T9);
3024 __ li(T9, imm);
3025 __ sd(T9, AT, 0);
3026 }
3027 }
3028 %}
3030 enc_class load_F_enc (regF dst, memory mem) %{
3031 MacroAssembler _masm(&cbuf);
3032 int base = $mem$$base;
3033 int index = $mem$$index;
3034 int scale = $mem$$scale;
3035 int disp = $mem$$disp;
3036 FloatRegister dst = $dst$$FloatRegister;
3038 if( index != 0 ) {
3039 if( Assembler::is_simm16(disp) ) {
3040 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3041 if (scale == 0) {
3042 __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
3043 } else {
3044 __ dsll(AT, as_Register(index), scale);
3045 __ gslwxc1(dst, as_Register(base), AT, disp);
3046 }
3047 } else {
3048 if (scale == 0) {
3049 __ daddu(AT, as_Register(base), as_Register(index));
3050 } else {
3051 __ dsll(AT, as_Register(index), scale);
3052 __ daddu(AT, as_Register(base), AT);
3053 }
3054 __ lwc1(dst, AT, disp);
3055 }
3056 } else {
3057 if (scale == 0) {
3058 __ daddu(AT, as_Register(base), as_Register(index));
3059 } else {
3060 __ dsll(AT, as_Register(index), scale);
3061 __ daddu(AT, as_Register(base), AT);
3062 }
3063 __ move(T9, disp);
3064 if( UseLoongsonISA ) {
3065 __ gslwxc1(dst, AT, T9, 0);
3066 } else {
3067 __ daddu(AT, AT, T9);
3068 __ lwc1(dst, AT, 0);
3069 }
3070 }
3071 } else {
3072 if( Assembler::is_simm16(disp) ) {
3073 __ lwc1(dst, as_Register(base), disp);
3074 } else {
3075 __ move(T9, disp);
3076 if( UseLoongsonISA ) {
3077 __ gslwxc1(dst, as_Register(base), T9, 0);
3078 } else {
3079 __ daddu(AT, as_Register(base), T9);
3080 __ lwc1(dst, AT, 0);
3081 }
3082 }
3083 }
3084 %}
3086 enc_class store_F_reg_enc (memory mem, regF src) %{
3087 MacroAssembler _masm(&cbuf);
3088 int base = $mem$$base;
3089 int index = $mem$$index;
3090 int scale = $mem$$scale;
3091 int disp = $mem$$disp;
3092 FloatRegister src = $src$$FloatRegister;
3094 if( index != 0 ) {
3095 if( Assembler::is_simm16(disp) ) {
3096 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3097 if (scale == 0) {
3098 __ gsswxc1(src, as_Register(base), as_Register(index), disp);
3099 } else {
3100 __ dsll(AT, as_Register(index), scale);
3101 __ gsswxc1(src, as_Register(base), AT, disp);
3102 }
3103 } else {
3104 if (scale == 0) {
3105 __ daddu(AT, as_Register(base), as_Register(index));
3106 } else {
3107 __ dsll(AT, as_Register(index), scale);
3108 __ daddu(AT, as_Register(base), AT);
3109 }
3110 __ swc1(src, AT, disp);
3111 }
3112 } else {
3113 if (scale == 0) {
3114 __ daddu(AT, as_Register(base), as_Register(index));
3115 } else {
3116 __ dsll(AT, as_Register(index), scale);
3117 __ daddu(AT, as_Register(base), AT);
3118 }
3119 __ move(T9, disp);
3120 if( UseLoongsonISA ) {
3121 __ gsswxc1(src, AT, T9, 0);
3122 } else {
3123 __ daddu(AT, AT, T9);
3124 __ swc1(src, AT, 0);
3125 }
3126 }
3127 } else {
3128 if( Assembler::is_simm16(disp) ) {
3129 __ swc1(src, as_Register(base), disp);
3130 } else {
3131 __ move(T9, disp);
3132 if( UseLoongsonISA ) {
3133 __ gslwxc1(src, as_Register(base), T9, 0);
3134 } else {
3135 __ daddu(AT, as_Register(base), T9);
3136 __ swc1(src, AT, 0);
3137 }
3138 }
3139 }
3140 %}
3142 enc_class load_D_enc (regD dst, memory mem) %{
3143 MacroAssembler _masm(&cbuf);
3144 int base = $mem$$base;
3145 int index = $mem$$index;
3146 int scale = $mem$$scale;
3147 int disp = $mem$$disp;
3148 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3150 if( index != 0 ) {
3151 if( Assembler::is_simm16(disp) ) {
3152 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3153 if (scale == 0) {
3154 __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
3155 } else {
3156 __ dsll(AT, as_Register(index), scale);
3157 __ gsldxc1(dst_reg, as_Register(base), AT, disp);
3158 }
3159 } else {
3160 if (scale == 0) {
3161 __ daddu(AT, as_Register(base), as_Register(index));
3162 } else {
3163 __ dsll(AT, as_Register(index), scale);
3164 __ daddu(AT, as_Register(base), AT);
3165 }
3166 __ ldc1(dst_reg, AT, disp);
3167 }
3168 } else {
3169 if (scale == 0) {
3170 __ daddu(AT, as_Register(base), as_Register(index));
3171 } else {
3172 __ dsll(AT, as_Register(index), scale);
3173 __ daddu(AT, as_Register(base), AT);
3174 }
3175 __ move(T9, disp);
3176 if( UseLoongsonISA ) {
3177 __ gsldxc1(dst_reg, AT, T9, 0);
3178 } else {
3179 __ addu(AT, AT, T9);
3180 __ ldc1(dst_reg, AT, 0);
3181 }
3182 }
3183 } else {
3184 if( Assembler::is_simm16(disp) ) {
3185 __ ldc1(dst_reg, as_Register(base), disp);
3186 } else {
3187 __ move(T9, disp);
3188 if( UseLoongsonISA ) {
3189 __ gsldxc1(dst_reg, as_Register(base), T9, 0);
3190 } else {
3191 __ addu(AT, as_Register(base), T9);
3192 __ ldc1(dst_reg, AT, 0);
3193 }
3194 }
3195 }
3196 %}
3198 enc_class store_D_reg_enc (memory mem, regD src) %{
3199 MacroAssembler _masm(&cbuf);
3200 int base = $mem$$base;
3201 int index = $mem$$index;
3202 int scale = $mem$$scale;
3203 int disp = $mem$$disp;
3204 FloatRegister src_reg = as_FloatRegister($src$$reg);
3206 if( index != 0 ) {
3207 if( Assembler::is_simm16(disp) ) {
3208 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3209 if (scale == 0) {
3210 __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
3211 } else {
3212 __ dsll(AT, as_Register(index), scale);
3213 __ gssdxc1(src_reg, as_Register(base), AT, disp);
3214 }
3215 } else {
3216 if (scale == 0) {
3217 __ daddu(AT, as_Register(base), as_Register(index));
3218 } else {
3219 __ dsll(AT, as_Register(index), scale);
3220 __ daddu(AT, as_Register(base), AT);
3221 }
3222 __ sdc1(src_reg, AT, disp);
3223 }
3224 } else {
3225 if (scale == 0) {
3226 __ daddu(AT, as_Register(base), as_Register(index));
3227 } else {
3228 __ dsll(AT, as_Register(index), scale);
3229 __ daddu(AT, as_Register(base), AT);
3230 }
3231 __ move(T9, disp);
3232 if( UseLoongsonISA ) {
3233 __ gssdxc1(src_reg, AT, T9, 0);
3234 } else {
3235 __ addu(AT, AT, T9);
3236 __ sdc1(src_reg, AT, 0);
3237 }
3238 }
3239 } else {
3240 if( Assembler::is_simm16(disp) ) {
3241 __ sdc1(src_reg, as_Register(base), disp);
3242 } else {
3243 __ move(T9, disp);
3244 if( UseLoongsonISA ) {
3245 __ gssdxc1(src_reg, as_Register(base), T9, 0);
3246 } else {
3247 __ addu(AT, as_Register(base), T9);
3248 __ sdc1(src_reg, AT, 0);
3249 }
3250 }
3251 }
3252 %}
3254 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf
3255 MacroAssembler _masm(&cbuf);
3256 // This is the instruction starting address for relocation info.
3257 __ block_comment("Java_To_Runtime");
3258 cbuf.set_insts_mark();
3259 __ relocate(relocInfo::runtime_call_type);
3261 __ li48(T9, (long)$meth$$method);
3262 __ jalr(T9);
3263 __ nop();
3264 %}
3266 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
3267 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
3268 // who we intended to call.
3269 MacroAssembler _masm(&cbuf);
3270 cbuf.set_insts_mark();
3272 if ( !_method ) {
3273 __ relocate(relocInfo::runtime_call_type);
3274 //emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.code_end()) - 4),
3275 // runtime_call_Relocation::spec(), RELOC_IMM32 );
3276 } else if(_optimized_virtual) {
3277 __ relocate(relocInfo::opt_virtual_call_type);
3278 //emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.code_end()) - 4),
3279 // opt_virtual_call_Relocation::spec(), RELOC_IMM32 );
3280 } else {
3281 __ relocate(relocInfo::static_call_type);
3282 //emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.code_end()) - 4),
3283 // static_call_Relocation::spec(), RELOC_IMM32 );
3284 }
3286 __ li(T9, $meth$$method);
3287 __ jalr(T9);
3288 __ nop();
3289 if( _method ) { // Emit stub for static call
3290 emit_java_to_interp(cbuf);
3291 }
3292 %}
3295 /*
3296 * [Ref: LIR_Assembler::ic_call() ]
3297 */
3298 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL
3299 MacroAssembler _masm(&cbuf);
3300 __ block_comment("Java_Dynamic_Call");
3301 __ ic_call((address)$meth$$method);
3302 %}
3305 enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
3306 Register flags = $cr$$Register;
3307 Label L;
3309 MacroAssembler _masm(&cbuf);
3311 __ addu(flags, R0, R0);
3312 __ beq(AT, R0, L);
3313 __ delayed()->nop();
3314 __ move(flags, 0xFFFFFFFF);
3315 __ bind(L);
3316 %}
3318 enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
3319 Register result = $result$$Register;
3320 Register sub = $sub$$Register;
3321 Register super = $super$$Register;
3322 Register length = $tmp$$Register;
3323 Register tmp = T9;
3324 Label miss;
3326 /* 2012/9/28 Jin: result may be the same as sub
3327 * 47c B40: # B21 B41 <- B20 Freq: 0.155379
3328 * 47c partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
3329 * 4bc mov S2, NULL #@loadConP
3330 * 4c0 beq S1, S2, B21 #@branchConP P=0.999999 C=-1.000000
3331 */
3332 MacroAssembler _masm(&cbuf);
3333 Label done;
3334 __ check_klass_subtype_slow_path(sub, super, length, tmp,
3335 NULL, &miss,
3336 /*set_cond_codes:*/ true);
3337 /* 2013/7/22 Jin: Refer to X86_64's RDI */
3338 __ move(result, 0);
3339 __ b(done);
3340 __ nop();
3342 __ bind(miss);
3343 __ move(result, 1);
3344 __ bind(done);
3345 %}
3347 %}
3350 //---------MIPS FRAME--------------------------------------------------------------
3351 // Definition of frame structure and management information.
3352 //
3353 // S T A C K L A Y O U T Allocators stack-slot number
3354 // | (to get allocators register number
3355 // G Owned by | | v add SharedInfo::stack0)
3356 // r CALLER | |
3357 // o | +--------+ pad to even-align allocators stack-slot
3358 // w V | pad0 | numbers; owned by CALLER
3359 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
3360 // h ^ | in | 5
3361 // | | args | 4 Holes in incoming args owned by SELF
3362 // | | old | | 3
3363 // | | SP-+--------+----> Matcher::_old_SP, even aligned
3364 // v | | ret | 3 return address
3365 // Owned by +--------+
3366 // Self | pad2 | 2 pad to align old SP
3367 // | +--------+ 1
3368 // | | locks | 0
3369 // | +--------+----> SharedInfo::stack0, even aligned
3370 // | | pad1 | 11 pad to align new SP
3371 // | +--------+
3372 // | | | 10
3373 // | | spills | 9 spills
3374 // V | | 8 (pad0 slot for callee)
3375 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
3376 // ^ | out | 7
3377 // | | args | 6 Holes in outgoing args owned by CALLEE
3378 // Owned by new | |
3379 // Callee SP-+--------+----> Matcher::_new_SP, even aligned
3380 // | |
3381 //
3382 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
3383 // known from SELF's arguments and the Java calling convention.
3384 // Region 6-7 is determined per call site.
3385 // Note 2: If the calling convention leaves holes in the incoming argument
3386 // area, those holes are owned by SELF. Holes in the outgoing area
3387 // are owned by the CALLEE. Holes should not be nessecary in the
3388 // incoming area, as the Java calling convention is completely under
3389 // the control of the AD file. Doubles can be sorted and packed to
3390 // avoid holes. Holes in the outgoing arguments may be nessecary for
3391 // varargs C calling conventions.
3392 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
3393 // even aligned with pad0 as needed.
3394 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
3395 // region 6-11 is even aligned; it may be padded out more so that
3396 // the region from SP to FP meets the minimum stack alignment.
3397 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3398 // alignment. Region 11, pad1, may be dynamically extended so that
3399 // SP meets the minimum alignment.
3402 frame %{
3404 stack_direction(TOWARDS_LOW);
3406 // These two registers define part of the calling convention
3407 // between compiled code and the interpreter.
3408 // SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention
3409 // for more information. by yjl 3/16/2006
3411 inline_cache_reg(T1); // Inline Cache Register
3412 interpreter_method_oop_reg(S3); // Method Oop Register when calling interpreter
3413 /*
3414 inline_cache_reg(T1); // Inline Cache Register or methodOop for I2C
3415 interpreter_arg_ptr_reg(A0); // Argument pointer for I2C adapters
3416 */
3418 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
3419 cisc_spilling_operand_name(indOffset32);
3421 // Number of stack slots consumed by locking an object
3422 // generate Compile::sync_stack_slots
3423 #ifdef _LP64
3424 sync_stack_slots(2);
3425 #else
3426 sync_stack_slots(1);
3427 #endif
3429 frame_pointer(SP);
3431 // Interpreter stores its frame pointer in a register which is
3432 // stored to the stack by I2CAdaptors.
3433 // I2CAdaptors convert from interpreted java to compiled java.
3435 interpreter_frame_pointer(FP);
3437 // generate Matcher::stack_alignment
3438 stack_alignment(StackAlignmentInBytes); //wordSize = sizeof(char*);
3440 // Number of stack slots between incoming argument block and the start of
3441 // a new frame. The PROLOG must add this many slots to the stack. The
3442 // EPILOG must remove this many slots. Intel needs one slot for
3443 // return address.
3444 // generate Matcher::in_preserve_stack_slots
3445 //in_preserve_stack_slots(VerifyStackAtCalls + 2); //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
3446 in_preserve_stack_slots(4); //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
3448 // Number of outgoing stack slots killed above the out_preserve_stack_slots
3449 // for calls to C. Supports the var-args backing area for register parms.
3450 varargs_C_out_slots_killed(0);
3452 // The after-PROLOG location of the return address. Location of
3453 // return address specifies a type (REG or STACK) and a number
3454 // representing the register number (i.e. - use a register name) or
3455 // stack slot.
3456 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3457 // Otherwise, it is above the locks and verification slot and alignment word
3458 //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
3459 return_addr(REG RA);
3461 // Body of function which returns an integer array locating
3462 // arguments either in registers or in stack slots. Passed an array
3463 // of ideal registers called "sig" and a "length" count. Stack-slot
3464 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3465 // arguments for a CALLEE. Incoming stack arguments are
3466 // automatically biased by the preserve_stack_slots field above.
3469 // will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
3470 // StartNode::calling_convention call this. by yjl 3/16/2006
3471 calling_convention %{
3472 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3473 %}
3478 // Body of function which returns an integer array locating
3479 // arguments either in registers or in stack slots. Passed an array
3480 // of ideal registers called "sig" and a "length" count. Stack-slot
3481 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3482 // arguments for a CALLEE. Incoming stack arguments are
3483 // automatically biased by the preserve_stack_slots field above.
3486 // SEE CallRuntimeNode::calling_convention for more information. by yjl 3/16/2006
3487 c_calling_convention %{
3488 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
3489 %}
3492 // Location of C & interpreter return values
3493 // register(s) contain(s) return value for Op_StartI2C and Op_StartOSR.
3494 // SEE Matcher::match. by yjl 3/16/2006
3495 c_return_value %{
3496 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3497 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
3498 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
3499 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num };
3500 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3501 %}
3503 // Location of return values
3504 // register(s) contain(s) return value for Op_StartC2I and Op_Start.
3505 // SEE Matcher::match. by yjl 3/16/2006
3507 return_value %{
3508 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3509 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
3510 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
3511 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num};
3512 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3513 %}
3515 %}
3517 //----------ATTRIBUTES---------------------------------------------------------
3518 //----------Operand Attributes-------------------------------------------------
3519 op_attrib op_cost(0); // Required cost attribute
3521 //----------Instruction Attributes---------------------------------------------
3522 ins_attrib ins_cost(100); // Required cost attribute
3523 ins_attrib ins_size(32); // Required size attribute (in bits)
3524 ins_attrib ins_pc_relative(0); // Required PC Relative flag
3525 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
3526 // non-matching short branch variant of some
3527 // long branch?
3528 ins_attrib ins_alignment(4); // Required alignment attribute (must be a power of 2)
3529 // specifies the alignment that some part of the instruction (not
3530 // necessarily the start) requires. If > 1, a compute_padding()
3531 // function must be provided for the instruction
3533 //----------OPERANDS-----------------------------------------------------------
3534 // Operand definitions must precede instruction definitions for correct parsing
3535 // in the ADLC because operands constitute user defined types which are used in
3536 // instruction definitions.
3538 // Vectors
3539 operand vecD() %{
3540 constraint(ALLOC_IN_RC(dbl_reg));
3541 match(VecD);
3543 format %{ %}
3544 interface(REG_INTER);
3545 %}
3547 // Flags register, used as output of compare instructions
3548 operand FlagsReg() %{
3549 constraint(ALLOC_IN_RC(mips_flags));
3550 match(RegFlags);
3552 format %{ "EFLAGS" %}
3553 interface(REG_INTER);
3554 %}
3556 //----------Simple Operands----------------------------------------------------
3557 //TODO: Should we need to define some more special immediate number ?
3558 // Immediate Operands
3559 // Integer Immediate
3560 operand immI() %{
3561 match(ConI);
3562 //TODO: should not match immI8 here LEE
3563 match(immI8);
3565 op_cost(20);
3566 format %{ %}
3567 interface(CONST_INTER);
3568 %}
3570 // Long Immediate 8-bit
3571 operand immL8()
3572 %{
3573 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3574 match(ConL);
3576 op_cost(5);
3577 format %{ %}
3578 interface(CONST_INTER);
3579 %}
3581 // Constant for test vs zero
3582 operand immI0() %{
3583 predicate(n->get_int() == 0);
3584 match(ConI);
3586 op_cost(0);
3587 format %{ %}
3588 interface(CONST_INTER);
3589 %}
3591 // Constant for increment
3592 operand immI1() %{
3593 predicate(n->get_int() == 1);
3594 match(ConI);
3596 op_cost(0);
3597 format %{ %}
3598 interface(CONST_INTER);
3599 %}
3601 // Constant for decrement
3602 operand immI_M1() %{
3603 predicate(n->get_int() == -1);
3604 match(ConI);
3606 op_cost(0);
3607 format %{ %}
3608 interface(CONST_INTER);
3609 %}
3611 // Valid scale values for addressing modes
3612 operand immI2() %{
3613 predicate(0 <= n->get_int() && (n->get_int() <= 3));
3614 match(ConI);
3616 format %{ %}
3617 interface(CONST_INTER);
3618 %}
3620 operand immI8() %{
3621 predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
3622 match(ConI);
3624 op_cost(5);
3625 format %{ %}
3626 interface(CONST_INTER);
3627 %}
3629 operand immI16() %{
3630 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
3631 match(ConI);
3633 op_cost(10);
3634 format %{ %}
3635 interface(CONST_INTER);
3636 %}
3638 // Constant for long shifts
3639 operand immI_32() %{
3640 predicate( n->get_int() == 32 );
3641 match(ConI);
3643 op_cost(0);
3644 format %{ %}
3645 interface(CONST_INTER);
3646 %}
3648 operand immI_63() %{
3649 predicate( n->get_int() == 63 );
3650 match(ConI);
3652 op_cost(0);
3653 format %{ %}
3654 interface(CONST_INTER);
3655 %}
3657 operand immI_0_31() %{
3658 predicate( n->get_int() >= 0 && n->get_int() <= 31 );
3659 match(ConI);
3661 op_cost(0);
3662 format %{ %}
3663 interface(CONST_INTER);
3664 %}
3666 // Operand for non-negtive integer mask
3667 operand immI_nonneg_mask() %{
3668 predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
3669 match(ConI);
3671 op_cost(0);
3672 format %{ %}
3673 interface(CONST_INTER);
3674 %}
3676 operand immI_32_63() %{
3677 predicate( n->get_int() >= 32 && n->get_int() <= 63 );
3678 match(ConI);
3679 op_cost(0);
3681 format %{ %}
3682 interface(CONST_INTER);
3683 %}
3685 operand immI16_sub() %{
3686 predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
3687 match(ConI);
3689 op_cost(10);
3690 format %{ %}
3691 interface(CONST_INTER);
3692 %}
3694 operand immI_0_32767() %{
3695 predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
3696 match(ConI);
3697 op_cost(0);
3699 format %{ %}
3700 interface(CONST_INTER);
3701 %}
3703 operand immI_0_65535() %{
3704 predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
3705 match(ConI);
3706 op_cost(0);
3708 format %{ %}
3709 interface(CONST_INTER);
3710 %}
3712 operand immI_1() %{
3713 predicate( n->get_int() == 1 );
3714 match(ConI);
3716 op_cost(0);
3717 format %{ %}
3718 interface(CONST_INTER);
3719 %}
3721 operand immI_2() %{
3722 predicate( n->get_int() == 2 );
3723 match(ConI);
3725 op_cost(0);
3726 format %{ %}
3727 interface(CONST_INTER);
3728 %}
3730 operand immI_3() %{
3731 predicate( n->get_int() == 3 );
3732 match(ConI);
3734 op_cost(0);
3735 format %{ %}
3736 interface(CONST_INTER);
3737 %}
3739 operand immI_7() %{
3740 predicate( n->get_int() == 7 );
3741 match(ConI);
3743 format %{ %}
3744 interface(CONST_INTER);
3745 %}
3747 // Immediates for special shifts (sign extend)
3749 // Constants for increment
3750 operand immI_16() %{
3751 predicate( n->get_int() == 16 );
3752 match(ConI);
3754 format %{ %}
3755 interface(CONST_INTER);
3756 %}
3758 operand immI_24() %{
3759 predicate( n->get_int() == 24 );
3760 match(ConI);
3762 format %{ %}
3763 interface(CONST_INTER);
3764 %}
3766 // Constant for byte-wide masking
3767 operand immI_255() %{
3768 predicate( n->get_int() == 255 );
3769 match(ConI);
3771 op_cost(0);
3772 format %{ %}
3773 interface(CONST_INTER);
3774 %}
3776 operand immI_65535() %{
3777 predicate( n->get_int() == 65535 );
3778 match(ConI);
3780 op_cost(5);
3781 format %{ %}
3782 interface(CONST_INTER);
3783 %}
3785 operand immI_65536() %{
3786 predicate( n->get_int() == 65536 );
3787 match(ConI);
3789 op_cost(5);
3790 format %{ %}
3791 interface(CONST_INTER);
3792 %}
3794 // Pointer Immediate
3795 operand immP() %{
3796 match(ConP);
3798 op_cost(10);
3799 format %{ %}
3800 interface(CONST_INTER);
3801 %}
3803 operand immP31()
3804 %{
3805 predicate(n->as_Type()->type()->reloc() == relocInfo::none
3806 && (n->get_ptr() >> 31) == 0);
3807 match(ConP);
3809 op_cost(5);
3810 format %{ %}
3811 interface(CONST_INTER);
3812 %}
3814 // NULL Pointer Immediate
3815 operand immP0() %{
3816 predicate( n->get_ptr() == 0 );
3817 match(ConP);
3818 op_cost(0);
3820 format %{ %}
3821 interface(CONST_INTER);
3822 %}
3824 // Pointer Immediate: 64-bit
3825 operand immP_set() %{
3826 match(ConP);
3828 op_cost(5);
3829 // formats are generated automatically for constants and base registers
3830 format %{ %}
3831 interface(CONST_INTER);
3832 %}
3834 // Pointer Immediate: 64-bit
3835 operand immP_load() %{
3836 predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
3837 match(ConP);
3839 op_cost(5);
3840 // formats are generated automatically for constants and base registers
3841 format %{ %}
3842 interface(CONST_INTER);
3843 %}
3845 // Pointer Immediate: 64-bit
3846 operand immP_no_oop_cheap() %{
3847 predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
3848 match(ConP);
3850 op_cost(5);
3851 // formats are generated automatically for constants and base registers
3852 format %{ %}
3853 interface(CONST_INTER);
3854 %}
3856 // Pointer for polling page
3857 operand immP_poll() %{
3858 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
3859 match(ConP);
3860 op_cost(5);
3862 format %{ %}
3863 interface(CONST_INTER);
3864 %}
3866 // Pointer Immediate
3867 operand immN() %{
3868 match(ConN);
3870 op_cost(10);
3871 format %{ %}
3872 interface(CONST_INTER);
3873 %}
3875 operand immNKlass() %{
3876 match(ConNKlass);
3878 op_cost(10);
3879 format %{ %}
3880 interface(CONST_INTER);
3881 %}
3883 // NULL Pointer Immediate
3884 operand immN0() %{
3885 predicate(n->get_narrowcon() == 0);
3886 match(ConN);
3888 op_cost(5);
3889 format %{ %}
3890 interface(CONST_INTER);
3891 %}
3893 // Long Immediate
3894 operand immL() %{
3895 match(ConL);
3897 op_cost(20);
3898 format %{ %}
3899 interface(CONST_INTER);
3900 %}
3902 // Long Immediate zero
3903 operand immL0() %{
3904 predicate( n->get_long() == 0L );
3905 match(ConL);
3906 op_cost(0);
3908 format %{ %}
3909 interface(CONST_INTER);
3910 %}
3912 operand immL7() %{
3913 predicate( n->get_long() == 7L );
3914 match(ConL);
3915 op_cost(0);
3917 format %{ %}
3918 interface(CONST_INTER);
3919 %}
3921 operand immL_M1() %{
3922 predicate( n->get_long() == -1L );
3923 match(ConL);
3924 op_cost(0);
3926 format %{ %}
3927 interface(CONST_INTER);
3928 %}
3930 // bit 0..2 zero
3931 operand immL_M8() %{
3932 predicate( n->get_long() == -8L );
3933 match(ConL);
3934 op_cost(0);
3936 format %{ %}
3937 interface(CONST_INTER);
3938 %}
3940 // bit 2 zero
3941 operand immL_M5() %{
3942 predicate( n->get_long() == -5L );
3943 match(ConL);
3944 op_cost(0);
3946 format %{ %}
3947 interface(CONST_INTER);
3948 %}
3950 // bit 1..2 zero
3951 operand immL_M7() %{
3952 predicate( n->get_long() == -7L );
3953 match(ConL);
3954 op_cost(0);
3956 format %{ %}
3957 interface(CONST_INTER);
3958 %}
3960 // bit 0..1 zero
3961 operand immL_M4() %{
3962 predicate( n->get_long() == -4L );
3963 match(ConL);
3964 op_cost(0);
3966 format %{ %}
3967 interface(CONST_INTER);
3968 %}
3970 // bit 3..6 zero
3971 operand immL_M121() %{
3972 predicate( n->get_long() == -121L );
3973 match(ConL);
3974 op_cost(0);
3976 format %{ %}
3977 interface(CONST_INTER);
3978 %}
3980 // Long immediate from 0 to 127.
3981 // Used for a shorter form of long mul by 10.
3982 operand immL_127() %{
3983 predicate((0 <= n->get_long()) && (n->get_long() <= 127));
3984 match(ConL);
3985 op_cost(0);
3987 format %{ %}
3988 interface(CONST_INTER);
3989 %}
3991 operand immL_0_65535() %{
3992 predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
3993 match(ConL);
3994 op_cost(0);
3996 format %{ %}
3997 interface(CONST_INTER);
3998 %}
4000 // Long Immediate: cheap (materialize in <= 3 instructions)
4001 operand immL_cheap() %{
4002 predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
4003 match(ConL);
4004 op_cost(0);
4006 format %{ %}
4007 interface(CONST_INTER);
4008 %}
4010 // Long Immediate: expensive (materialize in > 3 instructions)
4011 operand immL_expensive() %{
4012 predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
4013 match(ConL);
4014 op_cost(0);
4016 format %{ %}
4017 interface(CONST_INTER);
4018 %}
4020 operand immL16() %{
4021 predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
4022 match(ConL);
4024 op_cost(10);
4025 format %{ %}
4026 interface(CONST_INTER);
4027 %}
4029 operand immL16_sub() %{
4030 predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
4031 match(ConL);
4033 op_cost(10);
4034 format %{ %}
4035 interface(CONST_INTER);
4036 %}
4038 // Long Immediate: low 32-bit mask
4039 operand immL_32bits() %{
4040 predicate(n->get_long() == 0xFFFFFFFFL);
4041 match(ConL);
4042 op_cost(20);
4044 format %{ %}
4045 interface(CONST_INTER);
4046 %}
4048 // Long Immediate 32-bit signed
4049 operand immL32()
4050 %{
4051 predicate(n->get_long() == (int) (n->get_long()));
4052 match(ConL);
4054 op_cost(15);
4055 format %{ %}
4056 interface(CONST_INTER);
4057 %}
4060 //single-precision floating-point zero
4061 operand immF0() %{
4062 predicate(jint_cast(n->getf()) == 0);
4063 match(ConF);
4065 op_cost(5);
4066 format %{ %}
4067 interface(CONST_INTER);
4068 %}
4070 //single-precision floating-point immediate
4071 operand immF() %{
4072 match(ConF);
4074 op_cost(20);
4075 format %{ %}
4076 interface(CONST_INTER);
4077 %}
4079 //double-precision floating-point zero
4080 operand immD0() %{
4081 predicate(jlong_cast(n->getd()) == 0);
4082 match(ConD);
4084 op_cost(5);
4085 format %{ %}
4086 interface(CONST_INTER);
4087 %}
4089 //double-precision floating-point immediate
4090 operand immD() %{
4091 match(ConD);
4093 op_cost(20);
4094 format %{ %}
4095 interface(CONST_INTER);
4096 %}
4098 // Register Operands
4099 // Integer Register
4100 operand mRegI() %{
4101 constraint(ALLOC_IN_RC(int_reg));
4102 match(RegI);
4104 format %{ %}
4105 interface(REG_INTER);
4106 %}
4108 operand no_Ax_mRegI() %{
4109 constraint(ALLOC_IN_RC(no_Ax_int_reg));
4110 match(RegI);
4111 match(mRegI);
4113 format %{ %}
4114 interface(REG_INTER);
4115 %}
4117 operand mS0RegI() %{
4118 constraint(ALLOC_IN_RC(s0_reg));
4119 match(RegI);
4120 match(mRegI);
4122 format %{ "S0" %}
4123 interface(REG_INTER);
4124 %}
4126 operand mS1RegI() %{
4127 constraint(ALLOC_IN_RC(s1_reg));
4128 match(RegI);
4129 match(mRegI);
4131 format %{ "S1" %}
4132 interface(REG_INTER);
4133 %}
4135 operand mS2RegI() %{
4136 constraint(ALLOC_IN_RC(s2_reg));
4137 match(RegI);
4138 match(mRegI);
4140 format %{ "S2" %}
4141 interface(REG_INTER);
4142 %}
4144 operand mS3RegI() %{
4145 constraint(ALLOC_IN_RC(s3_reg));
4146 match(RegI);
4147 match(mRegI);
4149 format %{ "S3" %}
4150 interface(REG_INTER);
4151 %}
4153 operand mS4RegI() %{
4154 constraint(ALLOC_IN_RC(s4_reg));
4155 match(RegI);
4156 match(mRegI);
4158 format %{ "S4" %}
4159 interface(REG_INTER);
4160 %}
4162 operand mS5RegI() %{
4163 constraint(ALLOC_IN_RC(s5_reg));
4164 match(RegI);
4165 match(mRegI);
4167 format %{ "S5" %}
4168 interface(REG_INTER);
4169 %}
4171 operand mS6RegI() %{
4172 constraint(ALLOC_IN_RC(s6_reg));
4173 match(RegI);
4174 match(mRegI);
4176 format %{ "S6" %}
4177 interface(REG_INTER);
4178 %}
4180 operand mS7RegI() %{
4181 constraint(ALLOC_IN_RC(s7_reg));
4182 match(RegI);
4183 match(mRegI);
4185 format %{ "S7" %}
4186 interface(REG_INTER);
4187 %}
4190 operand mT0RegI() %{
4191 constraint(ALLOC_IN_RC(t0_reg));
4192 match(RegI);
4193 match(mRegI);
4195 format %{ "T0" %}
4196 interface(REG_INTER);
4197 %}
4199 operand mT1RegI() %{
4200 constraint(ALLOC_IN_RC(t1_reg));
4201 match(RegI);
4202 match(mRegI);
4204 format %{ "T1" %}
4205 interface(REG_INTER);
4206 %}
4208 operand mT2RegI() %{
4209 constraint(ALLOC_IN_RC(t2_reg));
4210 match(RegI);
4211 match(mRegI);
4213 format %{ "T2" %}
4214 interface(REG_INTER);
4215 %}
4217 operand mT3RegI() %{
4218 constraint(ALLOC_IN_RC(t3_reg));
4219 match(RegI);
4220 match(mRegI);
4222 format %{ "T3" %}
4223 interface(REG_INTER);
4224 %}
4226 operand mT8RegI() %{
4227 constraint(ALLOC_IN_RC(t8_reg));
4228 match(RegI);
4229 match(mRegI);
4231 format %{ "T8" %}
4232 interface(REG_INTER);
4233 %}
4235 operand mT9RegI() %{
4236 constraint(ALLOC_IN_RC(t9_reg));
4237 match(RegI);
4238 match(mRegI);
4240 format %{ "T9" %}
4241 interface(REG_INTER);
4242 %}
4244 operand mA0RegI() %{
4245 constraint(ALLOC_IN_RC(a0_reg));
4246 match(RegI);
4247 match(mRegI);
4249 format %{ "A0" %}
4250 interface(REG_INTER);
4251 %}
4253 operand mA1RegI() %{
4254 constraint(ALLOC_IN_RC(a1_reg));
4255 match(RegI);
4256 match(mRegI);
4258 format %{ "A1" %}
4259 interface(REG_INTER);
4260 %}
4262 operand mA2RegI() %{
4263 constraint(ALLOC_IN_RC(a2_reg));
4264 match(RegI);
4265 match(mRegI);
4267 format %{ "A2" %}
4268 interface(REG_INTER);
4269 %}
4271 operand mA3RegI() %{
4272 constraint(ALLOC_IN_RC(a3_reg));
4273 match(RegI);
4274 match(mRegI);
4276 format %{ "A3" %}
4277 interface(REG_INTER);
4278 %}
4280 operand mA4RegI() %{
4281 constraint(ALLOC_IN_RC(a4_reg));
4282 match(RegI);
4283 match(mRegI);
4285 format %{ "A4" %}
4286 interface(REG_INTER);
4287 %}
4289 operand mA5RegI() %{
4290 constraint(ALLOC_IN_RC(a5_reg));
4291 match(RegI);
4292 match(mRegI);
4294 format %{ "A5" %}
4295 interface(REG_INTER);
4296 %}
4298 operand mA6RegI() %{
4299 constraint(ALLOC_IN_RC(a6_reg));
4300 match(RegI);
4301 match(mRegI);
4303 format %{ "A6" %}
4304 interface(REG_INTER);
4305 %}
4307 operand mA7RegI() %{
4308 constraint(ALLOC_IN_RC(a7_reg));
4309 match(RegI);
4310 match(mRegI);
4312 format %{ "A7" %}
4313 interface(REG_INTER);
4314 %}
4316 operand mV0RegI() %{
4317 constraint(ALLOC_IN_RC(v0_reg));
4318 match(RegI);
4319 match(mRegI);
4321 format %{ "V0" %}
4322 interface(REG_INTER);
4323 %}
4325 operand mV1RegI() %{
4326 constraint(ALLOC_IN_RC(v1_reg));
4327 match(RegI);
4328 match(mRegI);
4330 format %{ "V1" %}
4331 interface(REG_INTER);
4332 %}
4334 operand mRegN() %{
4335 constraint(ALLOC_IN_RC(int_reg));
4336 match(RegN);
4338 format %{ %}
4339 interface(REG_INTER);
4340 %}
4342 operand t0_RegN() %{
4343 constraint(ALLOC_IN_RC(t0_reg));
4344 match(RegN);
4345 match(mRegN);
4347 format %{ %}
4348 interface(REG_INTER);
4349 %}
4351 operand t1_RegN() %{
4352 constraint(ALLOC_IN_RC(t1_reg));
4353 match(RegN);
4354 match(mRegN);
4356 format %{ %}
4357 interface(REG_INTER);
4358 %}
4360 operand t2_RegN() %{
4361 constraint(ALLOC_IN_RC(t2_reg));
4362 match(RegN);
4363 match(mRegN);
4365 format %{ %}
4366 interface(REG_INTER);
4367 %}
4369 operand t3_RegN() %{
4370 constraint(ALLOC_IN_RC(t3_reg));
4371 match(RegN);
4372 match(mRegN);
4374 format %{ %}
4375 interface(REG_INTER);
4376 %}
4378 operand t8_RegN() %{
4379 constraint(ALLOC_IN_RC(t8_reg));
4380 match(RegN);
4381 match(mRegN);
4383 format %{ %}
4384 interface(REG_INTER);
4385 %}
4387 operand t9_RegN() %{
4388 constraint(ALLOC_IN_RC(t9_reg));
4389 match(RegN);
4390 match(mRegN);
4392 format %{ %}
4393 interface(REG_INTER);
4394 %}
4396 operand a0_RegN() %{
4397 constraint(ALLOC_IN_RC(a0_reg));
4398 match(RegN);
4399 match(mRegN);
4401 format %{ %}
4402 interface(REG_INTER);
4403 %}
4405 operand a1_RegN() %{
4406 constraint(ALLOC_IN_RC(a1_reg));
4407 match(RegN);
4408 match(mRegN);
4410 format %{ %}
4411 interface(REG_INTER);
4412 %}
4414 operand a2_RegN() %{
4415 constraint(ALLOC_IN_RC(a2_reg));
4416 match(RegN);
4417 match(mRegN);
4419 format %{ %}
4420 interface(REG_INTER);
4421 %}
4423 operand a3_RegN() %{
4424 constraint(ALLOC_IN_RC(a3_reg));
4425 match(RegN);
4426 match(mRegN);
4428 format %{ %}
4429 interface(REG_INTER);
4430 %}
4432 operand a4_RegN() %{
4433 constraint(ALLOC_IN_RC(a4_reg));
4434 match(RegN);
4435 match(mRegN);
4437 format %{ %}
4438 interface(REG_INTER);
4439 %}
4441 operand a5_RegN() %{
4442 constraint(ALLOC_IN_RC(a5_reg));
4443 match(RegN);
4444 match(mRegN);
4446 format %{ %}
4447 interface(REG_INTER);
4448 %}
4450 operand a6_RegN() %{
4451 constraint(ALLOC_IN_RC(a6_reg));
4452 match(RegN);
4453 match(mRegN);
4455 format %{ %}
4456 interface(REG_INTER);
4457 %}
4459 operand a7_RegN() %{
4460 constraint(ALLOC_IN_RC(a7_reg));
4461 match(RegN);
4462 match(mRegN);
4464 format %{ %}
4465 interface(REG_INTER);
4466 %}
4468 operand s0_RegN() %{
4469 constraint(ALLOC_IN_RC(s0_reg));
4470 match(RegN);
4471 match(mRegN);
4473 format %{ %}
4474 interface(REG_INTER);
4475 %}
4477 operand s1_RegN() %{
4478 constraint(ALLOC_IN_RC(s1_reg));
4479 match(RegN);
4480 match(mRegN);
4482 format %{ %}
4483 interface(REG_INTER);
4484 %}
4486 operand s2_RegN() %{
4487 constraint(ALLOC_IN_RC(s2_reg));
4488 match(RegN);
4489 match(mRegN);
4491 format %{ %}
4492 interface(REG_INTER);
4493 %}
4495 operand s3_RegN() %{
4496 constraint(ALLOC_IN_RC(s3_reg));
4497 match(RegN);
4498 match(mRegN);
4500 format %{ %}
4501 interface(REG_INTER);
4502 %}
4504 operand s4_RegN() %{
4505 constraint(ALLOC_IN_RC(s4_reg));
4506 match(RegN);
4507 match(mRegN);
4509 format %{ %}
4510 interface(REG_INTER);
4511 %}
4513 operand s5_RegN() %{
4514 constraint(ALLOC_IN_RC(s5_reg));
4515 match(RegN);
4516 match(mRegN);
4518 format %{ %}
4519 interface(REG_INTER);
4520 %}
4522 operand s6_RegN() %{
4523 constraint(ALLOC_IN_RC(s6_reg));
4524 match(RegN);
4525 match(mRegN);
4527 format %{ %}
4528 interface(REG_INTER);
4529 %}
4531 operand s7_RegN() %{
4532 constraint(ALLOC_IN_RC(s7_reg));
4533 match(RegN);
4534 match(mRegN);
4536 format %{ %}
4537 interface(REG_INTER);
4538 %}
4540 operand v0_RegN() %{
4541 constraint(ALLOC_IN_RC(v0_reg));
4542 match(RegN);
4543 match(mRegN);
4545 format %{ %}
4546 interface(REG_INTER);
4547 %}
4549 operand v1_RegN() %{
4550 constraint(ALLOC_IN_RC(v1_reg));
4551 match(RegN);
4552 match(mRegN);
4554 format %{ %}
4555 interface(REG_INTER);
4556 %}
4558 // Pointer Register
4559 operand mRegP() %{
4560 constraint(ALLOC_IN_RC(p_reg));
4561 match(RegP);
4563 format %{ %}
4564 interface(REG_INTER);
4565 %}
4567 operand no_T8_mRegP() %{
4568 constraint(ALLOC_IN_RC(no_T8_p_reg));
4569 match(RegP);
4570 match(mRegP);
4572 format %{ %}
4573 interface(REG_INTER);
4574 %}
4576 operand s0_RegP()
4577 %{
4578 constraint(ALLOC_IN_RC(s0_long_reg));
4579 match(RegP);
4580 match(mRegP);
4581 match(no_T8_mRegP);
4583 format %{ %}
4584 interface(REG_INTER);
4585 %}
4587 operand s1_RegP()
4588 %{
4589 constraint(ALLOC_IN_RC(s1_long_reg));
4590 match(RegP);
4591 match(mRegP);
4592 match(no_T8_mRegP);
4594 format %{ %}
4595 interface(REG_INTER);
4596 %}
4598 operand s2_RegP()
4599 %{
4600 constraint(ALLOC_IN_RC(s2_long_reg));
4601 match(RegP);
4602 match(mRegP);
4603 match(no_T8_mRegP);
4605 format %{ %}
4606 interface(REG_INTER);
4607 %}
4609 operand s3_RegP()
4610 %{
4611 constraint(ALLOC_IN_RC(s3_long_reg));
4612 match(RegP);
4613 match(mRegP);
4614 match(no_T8_mRegP);
4616 format %{ %}
4617 interface(REG_INTER);
4618 %}
4620 operand s4_RegP()
4621 %{
4622 constraint(ALLOC_IN_RC(s4_long_reg));
4623 match(RegP);
4624 match(mRegP);
4625 match(no_T8_mRegP);
4627 format %{ %}
4628 interface(REG_INTER);
4629 %}
4631 operand s5_RegP()
4632 %{
4633 constraint(ALLOC_IN_RC(s5_long_reg));
4634 match(RegP);
4635 match(mRegP);
4636 match(no_T8_mRegP);
4638 format %{ %}
4639 interface(REG_INTER);
4640 %}
4642 operand s6_RegP()
4643 %{
4644 constraint(ALLOC_IN_RC(s6_long_reg));
4645 match(RegP);
4646 match(mRegP);
4647 match(no_T8_mRegP);
4649 format %{ %}
4650 interface(REG_INTER);
4651 %}
4653 operand s7_RegP()
4654 %{
4655 constraint(ALLOC_IN_RC(s7_long_reg));
4656 match(RegP);
4657 match(mRegP);
4658 match(no_T8_mRegP);
4660 format %{ %}
4661 interface(REG_INTER);
4662 %}
4664 operand t0_RegP()
4665 %{
4666 constraint(ALLOC_IN_RC(t0_long_reg));
4667 match(RegP);
4668 match(mRegP);
4669 match(no_T8_mRegP);
4671 format %{ %}
4672 interface(REG_INTER);
4673 %}
4675 operand t1_RegP()
4676 %{
4677 constraint(ALLOC_IN_RC(t1_long_reg));
4678 match(RegP);
4679 match(mRegP);
4680 match(no_T8_mRegP);
4682 format %{ %}
4683 interface(REG_INTER);
4684 %}
4686 operand t2_RegP()
4687 %{
4688 constraint(ALLOC_IN_RC(t2_long_reg));
4689 match(RegP);
4690 match(mRegP);
4691 match(no_T8_mRegP);
4693 format %{ %}
4694 interface(REG_INTER);
4695 %}
4697 operand t3_RegP()
4698 %{
4699 constraint(ALLOC_IN_RC(t3_long_reg));
4700 match(RegP);
4701 match(mRegP);
4702 match(no_T8_mRegP);
4704 format %{ %}
4705 interface(REG_INTER);
4706 %}
4708 operand t8_RegP()
4709 %{
4710 constraint(ALLOC_IN_RC(t8_long_reg));
4711 match(RegP);
4712 match(mRegP);
4714 format %{ %}
4715 interface(REG_INTER);
4716 %}
4718 operand t9_RegP()
4719 %{
4720 constraint(ALLOC_IN_RC(t9_long_reg));
4721 match(RegP);
4722 match(mRegP);
4723 match(no_T8_mRegP);
4725 format %{ %}
4726 interface(REG_INTER);
4727 %}
4729 operand a0_RegP()
4730 %{
4731 constraint(ALLOC_IN_RC(a0_long_reg));
4732 match(RegP);
4733 match(mRegP);
4734 match(no_T8_mRegP);
4736 format %{ %}
4737 interface(REG_INTER);
4738 %}
4740 operand a1_RegP()
4741 %{
4742 constraint(ALLOC_IN_RC(a1_long_reg));
4743 match(RegP);
4744 match(mRegP);
4745 match(no_T8_mRegP);
4747 format %{ %}
4748 interface(REG_INTER);
4749 %}
4751 operand a2_RegP()
4752 %{
4753 constraint(ALLOC_IN_RC(a2_long_reg));
4754 match(RegP);
4755 match(mRegP);
4756 match(no_T8_mRegP);
4758 format %{ %}
4759 interface(REG_INTER);
4760 %}
4762 operand a3_RegP()
4763 %{
4764 constraint(ALLOC_IN_RC(a3_long_reg));
4765 match(RegP);
4766 match(mRegP);
4767 match(no_T8_mRegP);
4769 format %{ %}
4770 interface(REG_INTER);
4771 %}
4773 operand a4_RegP()
4774 %{
4775 constraint(ALLOC_IN_RC(a4_long_reg));
4776 match(RegP);
4777 match(mRegP);
4778 match(no_T8_mRegP);
4780 format %{ %}
4781 interface(REG_INTER);
4782 %}
4785 operand a5_RegP()
4786 %{
4787 constraint(ALLOC_IN_RC(a5_long_reg));
4788 match(RegP);
4789 match(mRegP);
4790 match(no_T8_mRegP);
4792 format %{ %}
4793 interface(REG_INTER);
4794 %}
4796 operand a6_RegP()
4797 %{
4798 constraint(ALLOC_IN_RC(a6_long_reg));
4799 match(RegP);
4800 match(mRegP);
4801 match(no_T8_mRegP);
4803 format %{ %}
4804 interface(REG_INTER);
4805 %}
4807 operand a7_RegP()
4808 %{
4809 constraint(ALLOC_IN_RC(a7_long_reg));
4810 match(RegP);
4811 match(mRegP);
4812 match(no_T8_mRegP);
4814 format %{ %}
4815 interface(REG_INTER);
4816 %}
4818 operand v0_RegP()
4819 %{
4820 constraint(ALLOC_IN_RC(v0_long_reg));
4821 match(RegP);
4822 match(mRegP);
4823 match(no_T8_mRegP);
4825 format %{ %}
4826 interface(REG_INTER);
4827 %}
4829 operand v1_RegP()
4830 %{
4831 constraint(ALLOC_IN_RC(v1_long_reg));
4832 match(RegP);
4833 match(mRegP);
4834 match(no_T8_mRegP);
4836 format %{ %}
4837 interface(REG_INTER);
4838 %}
4840 /*
4841 operand mSPRegP(mRegP reg) %{
4842 constraint(ALLOC_IN_RC(sp_reg));
4843 match(reg);
4845 format %{ "SP" %}
4846 interface(REG_INTER);
4847 %}
4849 operand mFPRegP(mRegP reg) %{
4850 constraint(ALLOC_IN_RC(fp_reg));
4851 match(reg);
4853 format %{ "FP" %}
4854 interface(REG_INTER);
4855 %}
4856 */
4858 operand mRegL() %{
4859 constraint(ALLOC_IN_RC(long_reg));
4860 match(RegL);
4862 format %{ %}
4863 interface(REG_INTER);
4864 %}
4866 operand v0RegL() %{
4867 constraint(ALLOC_IN_RC(v0_long_reg));
4868 match(RegL);
4869 match(mRegL);
4871 format %{ %}
4872 interface(REG_INTER);
4873 %}
4875 operand v1RegL() %{
4876 constraint(ALLOC_IN_RC(v1_long_reg));
4877 match(RegL);
4878 match(mRegL);
4880 format %{ %}
4881 interface(REG_INTER);
4882 %}
4884 operand a0RegL() %{
4885 constraint(ALLOC_IN_RC(a0_long_reg));
4886 match(RegL);
4887 match(mRegL);
4889 format %{ "A0" %}
4890 interface(REG_INTER);
4891 %}
4893 operand a1RegL() %{
4894 constraint(ALLOC_IN_RC(a1_long_reg));
4895 match(RegL);
4896 match(mRegL);
4898 format %{ %}
4899 interface(REG_INTER);
4900 %}
4902 operand a2RegL() %{
4903 constraint(ALLOC_IN_RC(a2_long_reg));
4904 match(RegL);
4905 match(mRegL);
4907 format %{ %}
4908 interface(REG_INTER);
4909 %}
4911 operand a3RegL() %{
4912 constraint(ALLOC_IN_RC(a3_long_reg));
4913 match(RegL);
4914 match(mRegL);
4916 format %{ %}
4917 interface(REG_INTER);
4918 %}
4920 operand t0RegL() %{
4921 constraint(ALLOC_IN_RC(t0_long_reg));
4922 match(RegL);
4923 match(mRegL);
4925 format %{ %}
4926 interface(REG_INTER);
4927 %}
4929 operand t1RegL() %{
4930 constraint(ALLOC_IN_RC(t1_long_reg));
4931 match(RegL);
4932 match(mRegL);
4934 format %{ %}
4935 interface(REG_INTER);
4936 %}
4938 operand t2RegL() %{
4939 constraint(ALLOC_IN_RC(t2_long_reg));
4940 match(RegL);
4941 match(mRegL);
4943 format %{ %}
4944 interface(REG_INTER);
4945 %}
4947 operand t3RegL() %{
4948 constraint(ALLOC_IN_RC(t3_long_reg));
4949 match(RegL);
4950 match(mRegL);
4952 format %{ %}
4953 interface(REG_INTER);
4954 %}
4956 operand t8RegL() %{
4957 constraint(ALLOC_IN_RC(t8_long_reg));
4958 match(RegL);
4959 match(mRegL);
4961 format %{ %}
4962 interface(REG_INTER);
4963 %}
4965 operand a4RegL() %{
4966 constraint(ALLOC_IN_RC(a4_long_reg));
4967 match(RegL);
4968 match(mRegL);
4970 format %{ %}
4971 interface(REG_INTER);
4972 %}
4974 operand a5RegL() %{
4975 constraint(ALLOC_IN_RC(a5_long_reg));
4976 match(RegL);
4977 match(mRegL);
4979 format %{ %}
4980 interface(REG_INTER);
4981 %}
4983 operand a6RegL() %{
4984 constraint(ALLOC_IN_RC(a6_long_reg));
4985 match(RegL);
4986 match(mRegL);
4988 format %{ %}
4989 interface(REG_INTER);
4990 %}
4992 operand a7RegL() %{
4993 constraint(ALLOC_IN_RC(a7_long_reg));
4994 match(RegL);
4995 match(mRegL);
4997 format %{ %}
4998 interface(REG_INTER);
4999 %}
5001 operand s0RegL() %{
5002 constraint(ALLOC_IN_RC(s0_long_reg));
5003 match(RegL);
5004 match(mRegL);
5006 format %{ %}
5007 interface(REG_INTER);
5008 %}
5010 operand s1RegL() %{
5011 constraint(ALLOC_IN_RC(s1_long_reg));
5012 match(RegL);
5013 match(mRegL);
5015 format %{ %}
5016 interface(REG_INTER);
5017 %}
5019 operand s2RegL() %{
5020 constraint(ALLOC_IN_RC(s2_long_reg));
5021 match(RegL);
5022 match(mRegL);
5024 format %{ %}
5025 interface(REG_INTER);
5026 %}
5028 operand s3RegL() %{
5029 constraint(ALLOC_IN_RC(s3_long_reg));
5030 match(RegL);
5031 match(mRegL);
5033 format %{ %}
5034 interface(REG_INTER);
5035 %}
5037 operand s4RegL() %{
5038 constraint(ALLOC_IN_RC(s4_long_reg));
5039 match(RegL);
5040 match(mRegL);
5042 format %{ %}
5043 interface(REG_INTER);
5044 %}
5046 operand s7RegL() %{
5047 constraint(ALLOC_IN_RC(s7_long_reg));
5048 match(RegL);
5049 match(mRegL);
5051 format %{ %}
5052 interface(REG_INTER);
5053 %}
5055 // Floating register operands
5056 operand regF() %{
5057 constraint(ALLOC_IN_RC(flt_reg));
5058 match(RegF);
5060 format %{ %}
5061 interface(REG_INTER);
5062 %}
5064 //Double Precision Floating register operands
5065 operand regD() %{
5066 constraint(ALLOC_IN_RC(dbl_reg));
5067 match(RegD);
5069 format %{ %}
5070 interface(REG_INTER);
5071 %}
5073 //----------Memory Operands----------------------------------------------------
5074 // Indirect Memory Operand
5075 operand indirect(mRegP reg) %{
5076 constraint(ALLOC_IN_RC(p_reg));
5077 match(reg);
5079 format %{ "[$reg] @ indirect" %}
5080 interface(MEMORY_INTER) %{
5081 base($reg);
5082 index(0x0); /* NO_INDEX */
5083 scale(0x0);
5084 disp(0x0);
5085 %}
5086 %}
5088 // Indirect Memory Plus Short Offset Operand
5089 operand indOffset8(mRegP reg, immL8 off)
5090 %{
5091 constraint(ALLOC_IN_RC(p_reg));
5092 match(AddP reg off);
5094 format %{ "[$reg + $off (8-bit)] @ indOffset8" %}
5095 interface(MEMORY_INTER) %{
5096 base($reg);
5097 index(0x0); /* NO_INDEX */
5098 scale(0x0);
5099 disp($off);
5100 %}
5101 %}
5103 // Indirect Memory Times Scale Plus Index Register
5104 operand indIndexScale(mRegP reg, mRegL lreg, immI2 scale)
5105 %{
5106 constraint(ALLOC_IN_RC(p_reg));
5107 match(AddP reg (LShiftL lreg scale));
5109 op_cost(10);
5110 format %{"[$reg + $lreg << $scale] @ indIndexScale" %}
5111 interface(MEMORY_INTER) %{
5112 base($reg);
5113 index($lreg);
5114 scale($scale);
5115 disp(0x0);
5116 %}
5117 %}
5120 // [base + index + offset]
5121 operand baseIndexOffset8(mRegP base, mRegL index, immL8 off)
5122 %{
5123 constraint(ALLOC_IN_RC(p_reg));
5124 op_cost(5);
5125 match(AddP (AddP base index) off);
5127 format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8" %}
5128 interface(MEMORY_INTER) %{
5129 base($base);
5130 index($index);
5131 scale(0x0);
5132 disp($off);
5133 %}
5134 %}
5136 // [base + index + offset]
5137 operand baseIndexOffset8_convI2L(mRegP base, mRegI index, immL8 off)
5138 %{
5139 constraint(ALLOC_IN_RC(p_reg));
5140 op_cost(5);
5141 match(AddP (AddP base (ConvI2L index)) off);
5143 format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8_convI2L" %}
5144 interface(MEMORY_INTER) %{
5145 base($base);
5146 index($index);
5147 scale(0x0);
5148 disp($off);
5149 %}
5150 %}
5152 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5153 operand indIndexScaleOffset8(mRegP reg, immL8 off, mRegL lreg, immI2 scale)
5154 %{
5155 constraint(ALLOC_IN_RC(p_reg));
5156 match(AddP (AddP reg (LShiftL lreg scale)) off);
5158 op_cost(10);
5159 format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffset8" %}
5160 interface(MEMORY_INTER) %{
5161 base($reg);
5162 index($lreg);
5163 scale($scale);
5164 disp($off);
5165 %}
5166 %}
5168 operand indIndexScaleOffset8_convI2L(mRegP reg, immL8 off, mRegI ireg, immI2 scale)
5169 %{
5170 constraint(ALLOC_IN_RC(p_reg));
5171 match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
5173 op_cost(10);
5174 format %{"[$reg + $off + $ireg << $scale] @ indIndexScaleOffset8_convI2L" %}
5175 interface(MEMORY_INTER) %{
5176 base($reg);
5177 index($ireg);
5178 scale($scale);
5179 disp($off);
5180 %}
5181 %}
5183 // [base + index<<scale + offset]
5184 operand basePosIndexScaleOffset8(mRegP base, mRegI index, immL8 off, immI_0_31 scale)
5185 %{
5186 constraint(ALLOC_IN_RC(p_reg));
5187 //predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5188 op_cost(10);
5189 match(AddP (AddP base (LShiftL (ConvI2L index) scale)) off);
5191 format %{ "[$base + $index << $scale + $off (8-bit)] @ basePosIndexScaleOffset8" %}
5192 interface(MEMORY_INTER) %{
5193 base($base);
5194 index($index);
5195 scale($scale);
5196 disp($off);
5197 %}
5198 %}
5200 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5201 operand indIndexScaleOffsetNarrow(mRegN reg, immL8 off, mRegL lreg, immI2 scale)
5202 %{
5203 predicate(Universe::narrow_oop_shift() == 0);
5204 constraint(ALLOC_IN_RC(p_reg));
5205 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
5207 op_cost(10);
5208 format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffsetNarrow" %}
5209 interface(MEMORY_INTER) %{
5210 base($reg);
5211 index($lreg);
5212 scale($scale);
5213 disp($off);
5214 %}
5215 %}
5217 // [base + index<<scale + offset] for compressd Oops
5218 operand indPosIndexI2LScaleOffset8Narrow(mRegN base, mRegI index, immL8 off, immI_0_31 scale)
5219 %{
5220 constraint(ALLOC_IN_RC(p_reg));
5221 //predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5222 predicate(Universe::narrow_oop_shift() == 0);
5223 op_cost(10);
5224 match(AddP (AddP (DecodeN base) (LShiftL (ConvI2L index) scale)) off);
5226 format %{ "[$base + $index << $scale + $off (8-bit)] @ indPosIndexI2LScaleOffset8Narrow" %}
5227 interface(MEMORY_INTER) %{
5228 base($base);
5229 index($index);
5230 scale($scale);
5231 disp($off);
5232 %}
5233 %}
5235 //FIXME: I think it's better to limit the immI to be 16-bit at most!
5236 // Indirect Memory Plus Long Offset Operand
5237 operand indOffset32(mRegP reg, immL32 off) %{
5238 constraint(ALLOC_IN_RC(p_reg));
5239 op_cost(20);
5240 match(AddP reg off);
5242 format %{ "[$reg + $off (32-bit)] @ indOffset32" %}
5243 interface(MEMORY_INTER) %{
5244 base($reg);
5245 index(0x0); /* NO_INDEX */
5246 scale(0x0);
5247 disp($off);
5248 %}
5249 %}
5251 // Indirect Memory Plus Index Register
5252 operand indIndex(mRegP addr, mRegL index) %{
5253 constraint(ALLOC_IN_RC(p_reg));
5254 match(AddP addr index);
5256 op_cost(20);
5257 format %{"[$addr + $index] @ indIndex" %}
5258 interface(MEMORY_INTER) %{
5259 base($addr);
5260 index($index);
5261 scale(0x0);
5262 disp(0x0);
5263 %}
5264 %}
5266 operand indirectNarrowKlass(mRegN reg)
5267 %{
5268 predicate(Universe::narrow_klass_shift() == 0);
5269 constraint(ALLOC_IN_RC(p_reg));
5270 op_cost(10);
5271 match(DecodeNKlass reg);
5273 format %{ "[$reg] @ indirectNarrowKlass" %}
5274 interface(MEMORY_INTER) %{
5275 base($reg);
5276 index(0x0);
5277 scale(0x0);
5278 disp(0x0);
5279 %}
5280 %}
5282 operand indOffset8NarrowKlass(mRegN reg, immL8 off)
5283 %{
5284 predicate(Universe::narrow_klass_shift() == 0);
5285 constraint(ALLOC_IN_RC(p_reg));
5286 op_cost(10);
5287 match(AddP (DecodeNKlass reg) off);
5289 format %{ "[$reg + $off (8-bit)] @ indOffset8NarrowKlass" %}
5290 interface(MEMORY_INTER) %{
5291 base($reg);
5292 index(0x0);
5293 scale(0x0);
5294 disp($off);
5295 %}
5296 %}
5298 operand indOffset32NarrowKlass(mRegN reg, immL32 off)
5299 %{
5300 predicate(Universe::narrow_klass_shift() == 0);
5301 constraint(ALLOC_IN_RC(p_reg));
5302 op_cost(10);
5303 match(AddP (DecodeNKlass reg) off);
5305 format %{ "[$reg + $off (32-bit)] @ indOffset32NarrowKlass" %}
5306 interface(MEMORY_INTER) %{
5307 base($reg);
5308 index(0x0);
5309 scale(0x0);
5310 disp($off);
5311 %}
5312 %}
5314 operand indIndexOffsetNarrowKlass(mRegN reg, mRegL lreg, immL32 off)
5315 %{
5316 predicate(Universe::narrow_klass_shift() == 0);
5317 constraint(ALLOC_IN_RC(p_reg));
5318 match(AddP (AddP (DecodeNKlass reg) lreg) off);
5320 op_cost(10);
5321 format %{"[$reg + $off + $lreg] @ indIndexOffsetNarrowKlass" %}
5322 interface(MEMORY_INTER) %{
5323 base($reg);
5324 index($lreg);
5325 scale(0x0);
5326 disp($off);
5327 %}
5328 %}
5330 operand indIndexNarrowKlass(mRegN reg, mRegL lreg)
5331 %{
5332 predicate(Universe::narrow_klass_shift() == 0);
5333 constraint(ALLOC_IN_RC(p_reg));
5334 match(AddP (DecodeNKlass reg) lreg);
5336 op_cost(10);
5337 format %{"[$reg + $lreg] @ indIndexNarrowKlass" %}
5338 interface(MEMORY_INTER) %{
5339 base($reg);
5340 index($lreg);
5341 scale(0x0);
5342 disp(0x0);
5343 %}
5344 %}
5346 // Indirect Memory Operand
5347 operand indirectNarrow(mRegN reg)
5348 %{
5349 predicate(Universe::narrow_oop_shift() == 0);
5350 constraint(ALLOC_IN_RC(p_reg));
5351 op_cost(10);
5352 match(DecodeN reg);
5354 format %{ "[$reg] @ indirectNarrow" %}
5355 interface(MEMORY_INTER) %{
5356 base($reg);
5357 index(0x0);
5358 scale(0x0);
5359 disp(0x0);
5360 %}
5361 %}
5363 // Indirect Memory Plus Short Offset Operand
5364 operand indOffset8Narrow(mRegN reg, immL8 off)
5365 %{
5366 predicate(Universe::narrow_oop_shift() == 0);
5367 constraint(ALLOC_IN_RC(p_reg));
5368 op_cost(10);
5369 match(AddP (DecodeN reg) off);
5371 format %{ "[$reg + $off (8-bit)] @ indOffset8Narrow" %}
5372 interface(MEMORY_INTER) %{
5373 base($reg);
5374 index(0x0);
5375 scale(0x0);
5376 disp($off);
5377 %}
5378 %}
5380 // Indirect Memory Plus Index Register Plus Offset Operand
5381 operand indIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
5382 %{
5383 predicate(Universe::narrow_oop_shift() == 0);
5384 constraint(ALLOC_IN_RC(p_reg));
5385 match(AddP (AddP (DecodeN reg) lreg) off);
5387 op_cost(10);
5388 format %{"[$reg + $off + $lreg] @ indIndexOffset8Narrow" %}
5389 interface(MEMORY_INTER) %{
5390 base($reg);
5391 index($lreg);
5392 scale(0x0);
5393 disp($off);
5394 %}
5395 %}
5397 //----------Load Long Memory Operands------------------------------------------
5398 // The load-long idiom will use it's address expression again after loading
5399 // the first word of the long. If the load-long destination overlaps with
5400 // registers used in the addressing expression, the 2nd half will be loaded
5401 // from a clobbered address. Fix this by requiring that load-long use
5402 // address registers that do not overlap with the load-long target.
5404 // load-long support
5405 operand load_long_RegP() %{
5406 constraint(ALLOC_IN_RC(p_reg));
5407 match(RegP);
5408 match(mRegP);
5409 op_cost(100);
5410 format %{ %}
5411 interface(REG_INTER);
5412 %}
5414 // Indirect Memory Operand Long
5415 operand load_long_indirect(load_long_RegP reg) %{
5416 constraint(ALLOC_IN_RC(p_reg));
5417 match(reg);
5419 format %{ "[$reg]" %}
5420 interface(MEMORY_INTER) %{
5421 base($reg);
5422 index(0x0);
5423 scale(0x0);
5424 disp(0x0);
5425 %}
5426 %}
5428 // Indirect Memory Plus Long Offset Operand
5429 operand load_long_indOffset32(load_long_RegP reg, immL32 off) %{
5430 match(AddP reg off);
5432 format %{ "[$reg + $off]" %}
5433 interface(MEMORY_INTER) %{
5434 base($reg);
5435 index(0x0);
5436 scale(0x0);
5437 disp($off);
5438 %}
5439 %}
5441 //----------Conditional Branch Operands----------------------------------------
5442 // Comparison Op - This is the operation of the comparison, and is limited to
5443 // the following set of codes:
5444 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5445 //
5446 // Other attributes of the comparison, such as unsignedness, are specified
5447 // by the comparison instruction that sets a condition code flags register.
5448 // That result is represented by a flags operand whose subtype is appropriate
5449 // to the unsignedness (etc.) of the comparison.
5450 //
5451 // Later, the instruction which matches both the Comparison Op (a Bool) and
5452 // the flags (produced by the Cmp) specifies the coding of the comparison op
5453 // by matching a specific subtype of Bool operand below, such as cmpOpU.
5455 // Comparision Code
5456 operand cmpOp() %{
5457 match(Bool);
5459 format %{ "" %}
5460 interface(COND_INTER) %{
5461 equal(0x01);
5462 not_equal(0x02);
5463 greater(0x03);
5464 greater_equal(0x04);
5465 less(0x05);
5466 less_equal(0x06);
5467 overflow(0x7);
5468 no_overflow(0x8);
5469 %}
5470 %}
5473 // Comparision Code
5474 // Comparison Code, unsigned compare. Used by FP also, with
5475 // C2 (unordered) turned into GT or LT already. The other bits
5476 // C0 and C3 are turned into Carry & Zero flags.
5477 operand cmpOpU() %{
5478 match(Bool);
5480 format %{ "" %}
5481 interface(COND_INTER) %{
5482 equal(0x01);
5483 not_equal(0x02);
5484 greater(0x03);
5485 greater_equal(0x04);
5486 less(0x05);
5487 less_equal(0x06);
5488 overflow(0x7);
5489 no_overflow(0x8);
5490 %}
5491 %}
5493 /*
5494 // Comparison Code, unsigned compare. Used by FP also, with
5495 // C2 (unordered) turned into GT or LT already. The other bits
5496 // C0 and C3 are turned into Carry & Zero flags.
5497 operand cmpOpU() %{
5498 match(Bool);
5500 format %{ "" %}
5501 interface(COND_INTER) %{
5502 equal(0x4);
5503 not_equal(0x5);
5504 less(0x2);
5505 greater_equal(0x3);
5506 less_equal(0x6);
5507 greater(0x7);
5508 %}
5509 %}
5510 */
5511 /*
5512 // Comparison Code for FP conditional move
5513 operand cmpOp_fcmov() %{
5514 match(Bool);
5516 format %{ "" %}
5517 interface(COND_INTER) %{
5518 equal (0x01);
5519 not_equal (0x02);
5520 greater (0x03);
5521 greater_equal(0x04);
5522 less (0x05);
5523 less_equal (0x06);
5524 %}
5525 %}
5527 // Comparision Code used in long compares
5528 operand cmpOp_commute() %{
5529 match(Bool);
5531 format %{ "" %}
5532 interface(COND_INTER) %{
5533 equal(0x4);
5534 not_equal(0x5);
5535 less(0xF);
5536 greater_equal(0xE);
5537 less_equal(0xD);
5538 greater(0xC);
5539 %}
5540 %}
5541 */
5543 //----------Special Memory Operands--------------------------------------------
5544 // Stack Slot Operand - This operand is used for loading and storing temporary
5545 // values on the stack where a match requires a value to
5546 // flow through memory.
5547 operand stackSlotP(sRegP reg) %{
5548 constraint(ALLOC_IN_RC(stack_slots));
5549 // No match rule because this operand is only generated in matching
5550 op_cost(50);
5551 format %{ "[$reg]" %}
5552 interface(MEMORY_INTER) %{
5553 base(0x1d); // SP
5554 index(0x0); // No Index
5555 scale(0x0); // No Scale
5556 disp($reg); // Stack Offset
5557 %}
5558 %}
5560 operand stackSlotI(sRegI reg) %{
5561 constraint(ALLOC_IN_RC(stack_slots));
5562 // No match rule because this operand is only generated in matching
5563 op_cost(50);
5564 format %{ "[$reg]" %}
5565 interface(MEMORY_INTER) %{
5566 base(0x1d); // SP
5567 index(0x0); // No Index
5568 scale(0x0); // No Scale
5569 disp($reg); // Stack Offset
5570 %}
5571 %}
5573 operand stackSlotF(sRegF reg) %{
5574 constraint(ALLOC_IN_RC(stack_slots));
5575 // No match rule because this operand is only generated in matching
5576 op_cost(50);
5577 format %{ "[$reg]" %}
5578 interface(MEMORY_INTER) %{
5579 base(0x1d); // SP
5580 index(0x0); // No Index
5581 scale(0x0); // No Scale
5582 disp($reg); // Stack Offset
5583 %}
5584 %}
5586 operand stackSlotD(sRegD reg) %{
5587 constraint(ALLOC_IN_RC(stack_slots));
5588 // No match rule because this operand is only generated in matching
5589 op_cost(50);
5590 format %{ "[$reg]" %}
5591 interface(MEMORY_INTER) %{
5592 base(0x1d); // SP
5593 index(0x0); // No Index
5594 scale(0x0); // No Scale
5595 disp($reg); // Stack Offset
5596 %}
5597 %}
5599 operand stackSlotL(sRegL reg) %{
5600 constraint(ALLOC_IN_RC(stack_slots));
5601 // No match rule because this operand is only generated in matching
5602 op_cost(50);
5603 format %{ "[$reg]" %}
5604 interface(MEMORY_INTER) %{
5605 base(0x1d); // SP
5606 index(0x0); // No Index
5607 scale(0x0); // No Scale
5608 disp($reg); // Stack Offset
5609 %}
5610 %}
5613 //------------------------OPERAND CLASSES--------------------------------------
5614 //opclass memory( direct, indirect, indOffset16, indOffset32, indOffset32X, indIndexOffset );
5615 opclass memory( indirect, indirectNarrow, indOffset8, indOffset32, indIndex, indIndexScale, load_long_indirect, load_long_indOffset32, baseIndexOffset8, baseIndexOffset8_convI2L, indIndexScaleOffset8, indIndexScaleOffset8_convI2L, basePosIndexScaleOffset8, indIndexScaleOffsetNarrow, indPosIndexI2LScaleOffset8Narrow, indOffset8Narrow, indIndexOffset8Narrow);
5618 //----------PIPELINE-----------------------------------------------------------
5619 // Rules which define the behavior of the target architectures pipeline.
5621 pipeline %{
5623 //----------ATTRIBUTES---------------------------------------------------------
5624 attributes %{
5625 fixed_size_instructions; // Fixed size instructions
5626 branch_has_delay_slot; // branch have delay slot in gs2
5627 max_instructions_per_bundle = 1; // 1 instruction per bundle
5628 max_bundles_per_cycle = 4; // Up to 4 bundles per cycle
5629 bundle_unit_size=4;
5630 instruction_unit_size = 4; // An instruction is 4 bytes long
5631 instruction_fetch_unit_size = 16; // The processor fetches one line
5632 instruction_fetch_units = 1; // of 16 bytes
5634 // List of nop instructions
5635 nops( MachNop );
5636 %}
5638 //----------RESOURCES----------------------------------------------------------
5639 // Resources are the functional units available to the machine
5641 resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4, ALU1, ALU2, ALU = ALU1 | ALU2, FPU1, FPU2, FPU = FPU1 | FPU2, MEM, BR);
5643 //----------PIPELINE DESCRIPTION-----------------------------------------------
5644 // Pipeline Description specifies the stages in the machine's pipeline
5646 // IF: fetch
5647 // ID: decode
5648 // RD: read
5649 // CA: caculate
5650 // WB: write back
5651 // CM: commit
5653 pipe_desc(IF, ID, RD, CA, WB, CM);
5656 //----------PIPELINE CLASSES---------------------------------------------------
5657 // Pipeline Classes describe the stages in which input and output are
5658 // referenced by the hardware pipeline.
5660 //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
5661 pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
5662 single_instruction;
5663 src1 : RD(read);
5664 src2 : RD(read);
5665 dst : WB(write)+1;
5666 DECODE : ID;
5667 ALU : CA;
5668 %}
5670 //No.19 Integer mult operation : dst <-- reg1 mult reg2
5671 pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
5672 src1 : RD(read);
5673 src2 : RD(read);
5674 dst : WB(write)+5;
5675 DECODE : ID;
5676 ALU2 : CA;
5677 %}
5679 pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
5680 src1 : RD(read);
5681 src2 : RD(read);
5682 dst : WB(write)+10;
5683 DECODE : ID;
5684 ALU2 : CA;
5685 %}
5687 //No.19 Integer div operation : dst <-- reg1 div reg2
5688 pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
5689 src1 : RD(read);
5690 src2 : RD(read);
5691 dst : WB(write)+10;
5692 DECODE : ID;
5693 ALU2 : CA;
5694 %}
5696 //No.19 Integer mod operation : dst <-- reg1 mod reg2
5697 pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
5698 instruction_count(2);
5699 src1 : RD(read);
5700 src2 : RD(read);
5701 dst : WB(write)+10;
5702 DECODE : ID;
5703 ALU2 : CA;
5704 %}
5706 //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
5707 pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
5708 instruction_count(2);
5709 src1 : RD(read);
5710 src2 : RD(read);
5711 dst : WB(write);
5712 DECODE : ID;
5713 ALU : CA;
5714 %}
5716 //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
5717 pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
5718 instruction_count(2);
5719 src : RD(read);
5720 dst : WB(write);
5721 DECODE : ID;
5722 ALU : CA;
5723 %}
5725 //no.16 load Long from memory :
5726 pipe_class ialu_loadL(mRegL dst, memory mem) %{
5727 instruction_count(2);
5728 mem : RD(read);
5729 dst : WB(write)+5;
5730 DECODE : ID;
5731 MEM : RD;
5732 %}
5734 //No.17 Store Long to Memory :
5735 pipe_class ialu_storeL(mRegL src, memory mem) %{
5736 instruction_count(2);
5737 mem : RD(read);
5738 src : RD(read);
5739 DECODE : ID;
5740 MEM : RD;
5741 %}
5743 //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
5744 pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
5745 single_instruction;
5746 src : RD(read);
5747 dst : WB(write);
5748 DECODE : ID;
5749 ALU : CA;
5750 %}
5752 //No.3 Integer move operation : dst <-- reg
5753 pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
5754 src : RD(read);
5755 dst : WB(write);
5756 DECODE : ID;
5757 ALU : CA;
5758 %}
5760 //No.4 No instructions : do nothing
5761 pipe_class empty( ) %{
5762 instruction_count(0);
5763 %}
5765 //No.5 UnConditional branch :
5766 pipe_class pipe_jump( label labl ) %{
5767 multiple_bundles;
5768 DECODE : ID;
5769 BR : RD;
5770 %}
5772 //No.6 ALU Conditional branch :
5773 pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
5774 multiple_bundles;
5775 src1 : RD(read);
5776 src2 : RD(read);
5777 DECODE : ID;
5778 BR : RD;
5779 %}
5781 //no.7 load integer from memory :
5782 pipe_class ialu_loadI(mRegI dst, memory mem) %{
5783 mem : RD(read);
5784 dst : WB(write)+3;
5785 DECODE : ID;
5786 MEM : RD;
5787 %}
5789 //No.8 Store Integer to Memory :
5790 pipe_class ialu_storeI(mRegI src, memory mem) %{
5791 mem : RD(read);
5792 src : RD(read);
5793 DECODE : ID;
5794 MEM : RD;
5795 %}
5798 //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
5799 pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
5800 src1 : RD(read);
5801 src2 : RD(read);
5802 dst : WB(write);
5803 DECODE : ID;
5804 FPU : CA;
5805 %}
5807 //No.22 Floating div operation : dst <-- reg1 div reg2
5808 pipe_class fpu_div(regF dst, regF src1, regF src2) %{
5809 src1 : RD(read);
5810 src2 : RD(read);
5811 dst : WB(write);
5812 DECODE : ID;
5813 FPU2 : CA;
5814 %}
5816 pipe_class fcvt_I2D(regD dst, mRegI src) %{
5817 src : RD(read);
5818 dst : WB(write);
5819 DECODE : ID;
5820 FPU1 : CA;
5821 %}
5823 pipe_class fcvt_D2I(mRegI dst, regD src) %{
5824 src : RD(read);
5825 dst : WB(write);
5826 DECODE : ID;
5827 FPU1 : CA;
5828 %}
5830 pipe_class pipe_mfc1(mRegI dst, regD src) %{
5831 src : RD(read);
5832 dst : WB(write);
5833 DECODE : ID;
5834 MEM : RD;
5835 %}
5837 pipe_class pipe_mtc1(regD dst, mRegI src) %{
5838 src : RD(read);
5839 dst : WB(write);
5840 DECODE : ID;
5841 MEM : RD(5);
5842 %}
5844 //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
5845 pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
5846 multiple_bundles;
5847 src1 : RD(read);
5848 src2 : RD(read);
5849 dst : WB(write);
5850 DECODE : ID;
5851 FPU2 : CA;
5852 %}
5854 //No.11 Load Floating from Memory :
5855 pipe_class fpu_loadF(regF dst, memory mem) %{
5856 instruction_count(1);
5857 mem : RD(read);
5858 dst : WB(write)+3;
5859 DECODE : ID;
5860 MEM : RD;
5861 %}
5863 //No.12 Store Floating to Memory :
5864 pipe_class fpu_storeF(regF src, memory mem) %{
5865 instruction_count(1);
5866 mem : RD(read);
5867 src : RD(read);
5868 DECODE : ID;
5869 MEM : RD;
5870 %}
5872 //No.13 FPU Conditional branch :
5873 pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
5874 multiple_bundles;
5875 src1 : RD(read);
5876 src2 : RD(read);
5877 DECODE : ID;
5878 BR : RD;
5879 %}
5881 //No.14 Floating FPU reg operation : dst <-- op reg
5882 pipe_class fpu1_regF(regF dst, regF src) %{
5883 src : RD(read);
5884 dst : WB(write);
5885 DECODE : ID;
5886 FPU : CA;
5887 %}
5889 pipe_class long_memory_op() %{
5890 instruction_count(10); multiple_bundles; force_serialization;
5891 fixed_latency(30);
5892 %}
5894 pipe_class simple_call() %{
5895 instruction_count(10); multiple_bundles; force_serialization;
5896 fixed_latency(200);
5897 BR : RD;
5898 %}
5900 pipe_class call() %{
5901 instruction_count(10); multiple_bundles; force_serialization;
5902 fixed_latency(200);
5903 %}
5905 //FIXME:
5906 //No.9 Piple slow : for multi-instructions
5907 pipe_class pipe_slow( ) %{
5908 instruction_count(20);
5909 force_serialization;
5910 multiple_bundles;
5911 fixed_latency(50);
5912 %}
5914 %}
5918 //----------INSTRUCTIONS-------------------------------------------------------
5919 //
5920 // match -- States which machine-independent subtree may be replaced
5921 // by this instruction.
5922 // ins_cost -- The estimated cost of this instruction is used by instruction
5923 // selection to identify a minimum cost tree of machine
5924 // instructions that matches a tree of machine-independent
5925 // instructions.
5926 // format -- A string providing the disassembly for this instruction.
5927 // The value of an instruction's operand may be inserted
5928 // by referring to it with a '$' prefix.
5929 // opcode -- Three instruction opcodes may be provided. These are referred
5930 // to within an encode class as $primary, $secondary, and $tertiary
5931 // respectively. The primary opcode is commonly used to
5932 // indicate the type of machine instruction, while secondary
5933 // and tertiary are often used for prefix options or addressing
5934 // modes.
5935 // ins_encode -- A list of encode classes with parameters. The encode class
5936 // name must have been defined in an 'enc_class' specification
5937 // in the encode section of the architecture description.
5940 // Load Integer
5941 instruct loadI(mRegI dst, memory mem) %{
5942 match(Set dst (LoadI mem));
5944 ins_cost(125);
5945 format %{ "lw $dst, $mem #@loadI" %}
5946 ins_encode (load_I_enc(dst, mem));
5947 ins_pipe( ialu_loadI );
5948 %}
5950 instruct loadI_convI2L(mRegL dst, memory mem) %{
5951 match(Set dst (ConvI2L (LoadI mem)));
5953 ins_cost(125);
5954 format %{ "lw $dst, $mem #@loadI_convI2L" %}
5955 ins_encode (load_I_enc(dst, mem));
5956 ins_pipe( ialu_loadI );
5957 %}
5959 // Load Integer (32 bit signed) to Byte (8 bit signed)
5960 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
5961 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
5963 ins_cost(125);
5964 format %{ "lb $dst, $mem\t# int -> byte #@loadI2B" %}
5965 ins_encode(load_B_enc(dst, mem));
5966 ins_pipe(ialu_loadI);
5967 %}
5969 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
5970 instruct loadI2UB(mRegI dst, memory mem, immI_255 mask) %{
5971 match(Set dst (AndI (LoadI mem) mask));
5973 ins_cost(125);
5974 format %{ "lbu $dst, $mem\t# int -> ubyte #@loadI2UB" %}
5975 ins_encode(load_UB_enc(dst, mem));
5976 ins_pipe(ialu_loadI);
5977 %}
5979 // Load Integer (32 bit signed) to Short (16 bit signed)
5980 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
5981 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
5983 ins_cost(125);
5984 format %{ "lh $dst, $mem\t# int -> short #@loadI2S" %}
5985 ins_encode(load_S_enc(dst, mem));
5986 ins_pipe(ialu_loadI);
5987 %}
5989 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
5990 instruct loadI2US(mRegI dst, memory mem, immI_65535 mask) %{
5991 match(Set dst (AndI (LoadI mem) mask));
5993 ins_cost(125);
5994 format %{ "lhu $dst, $mem\t# int -> ushort/char #@loadI2US" %}
5995 ins_encode(load_C_enc(dst, mem));
5996 ins_pipe(ialu_loadI);
5997 %}
5999 // Load Long.
6000 instruct loadL(mRegL dst, memory mem) %{
6001 // predicate(!((LoadLNode*)n)->require_atomic_access());
6002 match(Set dst (LoadL mem));
6004 ins_cost(250);
6005 format %{ "ld $dst, $mem #@loadL" %}
6006 ins_encode(load_L_enc(dst, mem));
6007 ins_pipe( ialu_loadL );
6008 %}
6010 // Load Long - UNaligned
6011 instruct loadL_unaligned(mRegL dst, memory mem) %{
6012 match(Set dst (LoadL_unaligned mem));
6014 // FIXME: Jin: Need more effective ldl/ldr
6015 ins_cost(450);
6016 format %{ "ld $dst, $mem #@loadL_unaligned\n\t" %}
6017 ins_encode(load_L_enc(dst, mem));
6018 ins_pipe( ialu_loadL );
6019 %}
6021 // Store Long
6022 instruct storeL_reg(memory mem, mRegL src) %{
6023 predicate(!((StoreLNode*)n)->require_atomic_access());
6024 match(Set mem (StoreL mem src));
6026 ins_cost(200);
6027 format %{ "sd $mem, $src #@storeL_reg\n" %}
6028 ins_encode(store_L_reg_enc(mem, src));
6029 ins_pipe( ialu_storeL );
6030 %}
6032 //FIXME:volatile! atomic!
6033 // Volatile Store Long. Must be atomic, so move it into
6034 // the FP TOS and then do a 64-bit FIST. Has to probe the
6035 // target address before the store (for null-ptr checks)
6036 // so the memory operand is used twice in the encoding.
6037 instruct storeL_reg_atomic(memory mem, mRegL src) %{
6038 predicate(((StoreLNode*)n)->require_atomic_access());
6039 match(Set mem (StoreL mem src));
6041 ins_cost(200);
6042 format %{ "sw $mem, $src #@storeL_reg_atomic\n" %}
6043 ins_encode %{
6044 Register src = as_Register($src$$reg);
6046 int base = $mem$$base;
6047 int index = $mem$$index;
6048 int scale = $mem$$scale;
6049 int disp = $mem$$disp;
6051 if( index != 0 ) {
6052 if( Assembler::is_simm16(disp) ) {
6053 if (scale == 0) {
6054 __ addu(AT, as_Register(base), as_Register(index));
6055 } else {
6056 __ dsll(AT, as_Register(index), scale);
6057 __ addu(AT, as_Register(base), AT);
6058 }
6059 __ sd(src, AT, disp);
6060 } else {
6061 if (scale == 0) {
6062 __ addu(AT, as_Register(base), as_Register(index));
6063 } else {
6064 __ dsll(AT, as_Register(index), scale);
6065 __ addu(AT, as_Register(base), AT);
6066 }
6067 __ move(T9, disp);
6068 __ addu(AT, AT, T9);
6069 __ sd(src, AT, 0);
6070 }
6071 } else {
6072 if( Assembler::is_simm16(disp) ) {
6073 __ move(AT, as_Register(base));
6074 __ sd(src, AT, disp);
6075 } else {
6076 __ move(AT, as_Register(base));
6077 __ move(T9, disp);
6078 __ addu(AT, AT, T9);
6079 __ sd(src, AT, 0);
6080 }
6081 }
6083 %}
6084 ins_pipe( ialu_storeL );
6085 %}
6087 instruct storeL_immL0(memory mem, immL0 zero) %{
6088 match(Set mem (StoreL mem zero));
6090 ins_cost(180);
6091 format %{ "sd $mem, zero #@storeL_immL0" %}
6092 ins_encode(store_L_immL0_enc(mem, zero));
6093 ins_pipe( ialu_storeL );
6094 %}
6096 instruct storeL_imm(memory mem, immL src) %{
6097 match(Set mem (StoreL mem src));
6099 ins_cost(200);
6100 format %{ "sw $mem, $src #@storeL_imm" %}
6101 ins_encode(store_L_immL_enc(mem, src));
6102 ins_pipe( ialu_storeL );
6103 %}
6105 // Load Compressed Pointer
6106 instruct loadN(mRegN dst, memory mem)
6107 %{
6108 match(Set dst (LoadN mem));
6110 ins_cost(125); // XXX
6111 format %{ "lwu $dst, $mem\t# compressed ptr @ loadN" %}
6112 //TODO: Address should be implemented
6113 /*
6114 ins_encode %{
6115 __ lwu($dst$$Register, $mem$$Address);
6116 %}
6117 */
6118 ins_encode (load_N_enc(dst, mem));
6119 ins_pipe( ialu_loadI ); // XXX
6120 %}
6122 // Load Pointer
6123 instruct loadP(mRegP dst, memory mem) %{
6124 match(Set dst (LoadP mem));
6126 ins_cost(125);
6127 format %{ "ld $dst, $mem #@loadP" %}
6128 ins_encode (load_P_enc(dst, mem));
6129 ins_pipe( ialu_loadI );
6130 %}
6132 // Load Klass Pointer
6133 instruct loadKlass(mRegP dst, memory mem) %{
6134 match(Set dst (LoadKlass mem));
6136 ins_cost(125);
6137 format %{ "MOV $dst,$mem @ loadKlass" %}
6138 ins_encode (load_P_enc(dst, mem));
6139 ins_pipe( ialu_loadI );
6140 %}
6142 // Load narrow Klass Pointer
6143 instruct loadNKlass(mRegN dst, memory mem)
6144 %{
6145 match(Set dst (LoadNKlass mem));
6147 ins_cost(125); // XXX
6148 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
6149 ins_encode (load_N_enc(dst, mem));
6150 /*
6151 ins_encode %{
6152 __ lwu($dst$$Register, $mem$$Address);
6153 %}
6154 */
6155 ins_pipe( ialu_loadI ); // XXX
6156 %}
6158 // Load Constant
6159 instruct loadConI(mRegI dst, immI src) %{
6160 match(Set dst src);
6162 ins_cost(150);
6163 format %{ "mov $dst, $src #@loadConI" %}
6164 ins_encode %{
6165 Register dst = $dst$$Register;
6166 int value = $src$$constant;
6167 __ move(dst, value);
6168 %}
6169 ins_pipe( ialu_regI_regI );
6170 %}
6172 // Load Constant 65536
6173 instruct loadConI_65536(mRegI dst, immI_65536 src) %{
6174 match(Set dst src);
6176 ins_cost(100);
6177 format %{ "mov $dst, 65536 #@loadConI_65536" %}
6178 ins_encode %{
6179 Register dst = $dst$$Register;
6181 __ lui(dst, 1);
6182 %}
6183 ins_pipe( ialu_regI_regI );
6184 %}
6186 instruct loadConL_set64(mRegL dst, immL src) %{
6187 match(Set dst src);
6188 ins_cost(120);
6189 format %{ "li $dst, $src @ loadConL_set64" %}
6190 ins_encode %{
6191 __ set64($dst$$Register, $src$$constant);
6192 %}
6193 ins_pipe(ialu_regL_regL);
6194 %}
6196 /*
6197 // Load long value from constant table (predicated by immL_expensive).
6198 instruct loadConL_load(mRegL dst, immL_expensive src) %{
6199 match(Set dst src);
6200 ins_cost(150);
6201 format %{ "ld $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
6202 ins_encode %{
6203 int con_offset = $constantoffset($src);
6205 if (Assembler::is_simm16(con_offset)) {
6206 __ ld($dst$$Register, $constanttablebase, con_offset);
6207 } else {
6208 __ set64(AT, con_offset);
6209 if (UseLoongsonISA) {
6210 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
6211 } else {
6212 __ daddu(AT, $constanttablebase, AT);
6213 __ ld($dst$$Register, AT, 0);
6214 }
6215 }
6216 %}
6217 ins_pipe(ialu_loadI);
6218 %}
6219 */
6221 instruct loadConL16(mRegL dst, immL16 src) %{
6222 match(Set dst src);
6223 ins_cost(105);
6224 format %{ "mov $dst, $src #@loadConL16" %}
6225 ins_encode %{
6226 Register dst_reg = as_Register($dst$$reg);
6227 int value = $src$$constant;
6228 __ daddiu(dst_reg, R0, value);
6229 %}
6230 ins_pipe( ialu_regL_regL );
6231 %}
6234 instruct loadConL0(mRegL dst, immL0 src) %{
6235 match(Set dst src);
6236 ins_cost(100);
6237 format %{ "mov $dst, zero #@loadConL0" %}
6238 ins_encode %{
6239 Register dst_reg = as_Register($dst$$reg);
6240 __ daddu(dst_reg, R0, R0);
6241 %}
6242 ins_pipe( ialu_regL_regL );
6243 %}
6245 // Load Range
6246 instruct loadRange(mRegI dst, memory mem) %{
6247 match(Set dst (LoadRange mem));
6249 ins_cost(125);
6250 format %{ "MOV $dst,$mem @ loadRange" %}
6251 ins_encode(load_I_enc(dst, mem));
6252 ins_pipe( ialu_loadI );
6253 %}
6256 instruct storeP(memory mem, mRegP src ) %{
6257 match(Set mem (StoreP mem src));
6259 ins_cost(125);
6260 format %{ "sd $src, $mem #@storeP" %}
6261 ins_encode(store_P_reg_enc(mem, src));
6262 ins_pipe( ialu_storeI );
6263 %}
6265 /*
6266 [Ref: loadConP]
6268 Error:
6269 0x2d4b6d40: lui t9, 0x4f <--- handle
6270 0x2d4b6d44: addiu t9, t9, 0xffff808c
6271 0x2d4b6d48: sw t9, 0x4(s2)
6273 OK:
6274 0x2cc5ed40: lui t9, 0x336a <--- klass
6275 0x2cc5ed44: addiu t9, t9, 0x5a10
6276 0x2cc5ed48: sw t9, 0x4(s2)
6277 */
6278 // Store Pointer Immediate; null pointers or constant oops that do not
6279 // need card-mark barriers.
6281 // Store NULL Pointer, mark word, or other simple pointer constant.
6282 instruct storeImmP(memory mem, immP31 src) %{
6283 match(Set mem (StoreP mem src));
6285 ins_cost(150);
6286 format %{ "mov $mem, $src #@storeImmP" %}
6287 ins_encode(store_P_immP_enc(mem, src));
6288 ins_pipe( ialu_storeI );
6289 %}
6291 // Store Byte Immediate
6292 instruct storeImmB(memory mem, immI8 src) %{
6293 match(Set mem (StoreB mem src));
6295 ins_cost(150);
6296 format %{ "movb $mem, $src #@storeImmB" %}
6297 ins_encode(store_B_immI_enc(mem, src));
6298 ins_pipe( ialu_storeI );
6299 %}
6301 // Store Compressed Pointer
6302 instruct storeN(memory mem, mRegN src)
6303 %{
6304 match(Set mem (StoreN mem src));
6306 ins_cost(125); // XXX
6307 format %{ "sw $mem, $src\t# compressed ptr @ storeN" %}
6308 ins_encode(store_N_reg_enc(mem, src));
6309 ins_pipe( ialu_storeI );
6310 %}
6312 instruct storeNKlass(memory mem, mRegN src)
6313 %{
6314 match(Set mem (StoreNKlass mem src));
6316 ins_cost(125); // XXX
6317 format %{ "sw $mem, $src\t# compressed klass ptr @ storeNKlass" %}
6318 ins_encode(store_N_reg_enc(mem, src));
6319 ins_pipe( ialu_storeI );
6320 %}
6322 instruct storeImmN0(memory mem, immN0 zero)
6323 %{
6324 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL);
6325 match(Set mem (StoreN mem zero));
6327 ins_cost(125); // XXX
6328 format %{ "storeN0 $mem, R12\t# compressed ptr" %}
6329 ins_encode(storeImmN0_enc(mem, zero));
6330 ins_pipe( ialu_storeI );
6331 %}
6333 instruct storeImmN(memory mem, immN src)
6334 %{
6335 match(Set mem (StoreN mem src));
6337 ins_cost(150); // XXX
6338 format %{ "storeImmN $mem, $src\t# compressed ptr @ storeImmN" %}
6339 ins_encode(storeImmN_enc(mem, src));
6340 ins_pipe( ialu_storeI );
6341 %}
6343 instruct storeImmNKlass(memory mem, immNKlass src)
6344 %{
6345 match(Set mem (StoreNKlass mem src));
6347 ins_cost(150); // XXX
6348 format %{ "sw $mem, $src\t# compressed klass ptr @ storeImmNKlass" %}
6349 ins_encode(storeImmNKlass_enc(mem, src));
6350 ins_pipe( ialu_storeI );
6351 %}
6353 // Store Byte
6354 instruct storeB(memory mem, mRegI src) %{
6355 match(Set mem (StoreB mem src));
6357 ins_cost(125);
6358 format %{ "sb $src, $mem #@storeB" %}
6359 ins_encode(store_B_reg_enc(mem, src));
6360 ins_pipe( ialu_storeI );
6361 %}
6363 // Load Byte (8bit signed)
6364 instruct loadB(mRegI dst, memory mem) %{
6365 match(Set dst (LoadB mem));
6367 ins_cost(125);
6368 format %{ "lb $dst, $mem #@loadB" %}
6369 ins_encode(load_B_enc(dst, mem));
6370 ins_pipe( ialu_loadI );
6371 %}
6373 instruct loadB_convI2L(mRegL dst, memory mem) %{
6374 match(Set dst (ConvI2L (LoadB mem)));
6376 ins_cost(125);
6377 format %{ "lb $dst, $mem #@loadB_convI2L" %}
6378 ins_encode(load_B_enc(dst, mem));
6379 ins_pipe( ialu_loadI );
6380 %}
6382 // Load Byte (8bit UNsigned)
6383 instruct loadUB(mRegI dst, memory mem) %{
6384 match(Set dst (LoadUB mem));
6386 ins_cost(125);
6387 format %{ "lbu $dst, $mem #@loadUB" %}
6388 ins_encode(load_UB_enc(dst, mem));
6389 ins_pipe( ialu_loadI );
6390 %}
6392 instruct loadUB_convI2L(mRegL dst, memory mem) %{
6393 match(Set dst (ConvI2L (LoadUB mem)));
6395 ins_cost(125);
6396 format %{ "lbu $dst, $mem #@loadUB_convI2L" %}
6397 ins_encode(load_UB_enc(dst, mem));
6398 ins_pipe( ialu_loadI );
6399 %}
6401 // Load Short (16bit signed)
6402 instruct loadS(mRegI dst, memory mem) %{
6403 match(Set dst (LoadS mem));
6405 ins_cost(125);
6406 format %{ "lh $dst, $mem #@loadS" %}
6407 ins_encode(load_S_enc(dst, mem));
6408 ins_pipe( ialu_loadI );
6409 %}
6411 // Load Short (16 bit signed) to Byte (8 bit signed)
6412 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
6413 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
6415 ins_cost(125);
6416 format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
6417 ins_encode(load_B_enc(dst, mem));
6418 ins_pipe(ialu_loadI);
6419 %}
6421 instruct loadS_convI2L(mRegL dst, memory mem) %{
6422 match(Set dst (ConvI2L (LoadS mem)));
6424 ins_cost(125);
6425 format %{ "lh $dst, $mem #@loadS_convI2L" %}
6426 ins_encode(load_S_enc(dst, mem));
6427 ins_pipe( ialu_loadI );
6428 %}
6430 // Store Integer Immediate
6431 instruct storeImmI(memory mem, immI src) %{
6432 match(Set mem (StoreI mem src));
6434 ins_cost(150);
6435 format %{ "mov $mem, $src #@storeImmI" %}
6436 ins_encode(store_I_immI_enc(mem, src));
6437 ins_pipe( ialu_storeI );
6438 %}
6440 // Store Integer
6441 instruct storeI(memory mem, mRegI src) %{
6442 match(Set mem (StoreI mem src));
6444 ins_cost(125);
6445 format %{ "sw $mem, $src #@storeI" %}
6446 ins_encode(store_I_reg_enc(mem, src));
6447 ins_pipe( ialu_storeI );
6448 %}
6450 instruct storeI_convL2I(memory mem, mRegL src) %{
6451 match(Set mem (StoreI mem (ConvL2I src)));
6453 ins_cost(125);
6454 format %{ "sw $mem, $src #@storeI_convL2I" %}
6455 ins_encode(store_I_reg_enc(mem, src));
6456 ins_pipe( ialu_storeI );
6457 %}
6459 // Load Float
6460 instruct loadF(regF dst, memory mem) %{
6461 match(Set dst (LoadF mem));
6463 ins_cost(150);
6464 format %{ "loadF $dst, $mem #@loadF" %}
6465 ins_encode(load_F_enc(dst, mem));
6466 ins_pipe( ialu_loadI );
6467 %}
6469 instruct loadConP_general(mRegP dst, immP src) %{
6470 match(Set dst src);
6472 ins_cost(120);
6473 format %{ "li $dst, $src #@loadConP_general" %}
6475 ins_encode %{
6476 Register dst = $dst$$Register;
6477 long* value = (long*)$src$$constant;
6478 bool is_need_reloc = $src->constant_reloc() != relocInfo::none;
6480 /* During GC, klassOop may be moved to new position in the heap.
6481 * It must be relocated.
6482 * Refer: [c1_LIRAssembler_mips.cpp] jobject2reg()
6483 */
6484 if (is_need_reloc) {
6485 if($src->constant_reloc() == relocInfo::metadata_type){
6486 int klass_index = __ oop_recorder()->find_index((Klass*)value);
6487 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
6489 __ relocate(rspec);
6490 __ li48(dst, (long)value);
6491 }
6493 if($src->constant_reloc() == relocInfo::oop_type){
6494 int oop_index = __ oop_recorder()->find_index((jobject)value);
6495 RelocationHolder rspec = oop_Relocation::spec(oop_index);
6497 __ relocate(rspec);
6498 __ li48(dst, (long)value);
6499 }
6500 } else {
6501 __ set64(dst, (long)value);
6502 }
6503 %}
6505 ins_pipe( ialu_regI_regI );
6506 %}
6508 /*
6509 instruct loadConP_load(mRegP dst, immP_load src) %{
6510 match(Set dst src);
6512 ins_cost(100);
6513 format %{ "ld $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
6515 ins_encode %{
6517 int con_offset = $constantoffset($src);
6519 if (Assembler::is_simm16(con_offset)) {
6520 __ ld($dst$$Register, $constanttablebase, con_offset);
6521 } else {
6522 __ set64(AT, con_offset);
6523 if (UseLoongsonISA) {
6524 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
6525 } else {
6526 __ daddu(AT, $constanttablebase, AT);
6527 __ ld($dst$$Register, AT, 0);
6528 }
6529 }
6530 %}
6532 ins_pipe(ialu_loadI);
6533 %}
6534 */
6536 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
6537 match(Set dst src);
6539 ins_cost(80);
6540 format %{ "li $dst, $src @ loadConP_no_oop_cheap" %}
6542 ins_encode %{
6543 __ set64($dst$$Register, $src$$constant);
6544 %}
6546 ins_pipe(ialu_regI_regI);
6547 %}
6550 instruct loadConP_poll(mRegP dst, immP_poll src) %{
6551 match(Set dst src);
6553 ins_cost(50);
6554 format %{ "li $dst, $src #@loadConP_poll" %}
6556 ins_encode %{
6557 Register dst = $dst$$Register;
6558 intptr_t value = (intptr_t)$src$$constant;
6560 __ set64(dst, (jlong)value);
6561 %}
6563 ins_pipe( ialu_regI_regI );
6564 %}
6566 instruct loadConP0(mRegP dst, immP0 src)
6567 %{
6568 match(Set dst src);
6570 ins_cost(50);
6571 format %{ "mov $dst, R0\t# ptr" %}
6572 ins_encode %{
6573 Register dst_reg = $dst$$Register;
6574 __ daddu(dst_reg, R0, R0);
6575 %}
6576 ins_pipe( ialu_regI_regI );
6577 %}
6579 instruct loadConN0(mRegN dst, immN0 src) %{
6580 match(Set dst src);
6581 format %{ "move $dst, R0\t# compressed NULL ptr" %}
6582 ins_encode %{
6583 __ move($dst$$Register, R0);
6584 %}
6585 ins_pipe( ialu_regI_regI );
6586 %}
6588 instruct loadConN(mRegN dst, immN src) %{
6589 match(Set dst src);
6591 ins_cost(125);
6592 format %{ "li $dst, $src\t# compressed ptr @ loadConN" %}
6593 ins_encode %{
6594 address con = (address)$src$$constant;
6595 if (con == NULL) {
6596 ShouldNotReachHere();
6597 } else {
6598 assert (UseCompressedOops, "should only be used for compressed headers");
6599 assert (Universe::heap() != NULL, "java heap should be initialized");
6600 assert (__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
6602 Register dst = $dst$$Register;
6603 long* value = (long*)$src$$constant;
6604 int oop_index = __ oop_recorder()->find_index((jobject)value);
6605 RelocationHolder rspec = oop_Relocation::spec(oop_index);
6606 if(rspec.type()!=relocInfo::none){
6607 __ relocate(rspec, Assembler::narrow_oop_operand);
6608 __ li48(dst, oop_index);
6609 } else {
6610 __ set64(dst, oop_index);
6611 }
6612 }
6613 %}
6614 ins_pipe( ialu_regI_regI ); // XXX
6615 %}
6617 instruct loadConNKlass(mRegN dst, immNKlass src) %{
6618 match(Set dst src);
6620 ins_cost(125);
6621 format %{ "li $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
6622 ins_encode %{
6623 address con = (address)$src$$constant;
6624 if (con == NULL) {
6625 ShouldNotReachHere();
6626 } else {
6627 Register dst = $dst$$Register;
6628 long* value = (long*)$src$$constant;
6630 int klass_index = __ oop_recorder()->find_index((Klass*)value);
6631 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
6632 long narrowp = (long)Klass::encode_klass((Klass*)value);
6634 if(rspec.type()!=relocInfo::none){
6635 __ relocate(rspec, Assembler::narrow_oop_operand);
6636 __ li48(dst, narrowp);
6637 } else {
6638 __ set64(dst, narrowp);
6639 }
6640 }
6641 %}
6642 ins_pipe( ialu_regI_regI ); // XXX
6643 %}
6645 //FIXME
6646 // Tail Call; Jump from runtime stub to Java code.
6647 // Also known as an 'interprocedural jump'.
6648 // Target of jump will eventually return to caller.
6649 // TailJump below removes the return address.
6650 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
6651 match(TailCall jump_target method_oop );
6652 ins_cost(300);
6653 format %{ "JMP $jump_target \t# @TailCalljmpInd" %}
6655 ins_encode %{
6656 Register target = $jump_target$$Register;
6657 Register oop = $method_oop$$Register;
6659 /* 2012/10/12 Jin: RA will be used in generate_forward_exception() */
6660 __ push(RA);
6662 __ move(S3, oop);
6663 __ jr(target);
6664 __ nop();
6665 %}
6667 ins_pipe( pipe_jump );
6668 %}
6670 // Create exception oop: created by stack-crawling runtime code.
6671 // Created exception is now available to this handler, and is setup
6672 // just prior to jumping to this handler. No code emitted.
6673 instruct CreateException( a0_RegP ex_oop )
6674 %{
6675 match(Set ex_oop (CreateEx));
6677 // use the following format syntax
6678 format %{ "# exception oop is in A0; no code emitted @CreateException" %}
6679 ins_encode %{
6680 /* Jin: X86 leaves this function empty */
6681 __ block_comment("CreateException is empty in X86/MIPS");
6682 %}
6683 ins_pipe( empty );
6684 // ins_pipe( pipe_jump );
6685 %}
6688 /* 2012/9/14 Jin: The mechanism of exception handling is clear now.
6690 - Common try/catch:
6691 2012/9/14 Jin: [stubGenerator_mips.cpp] generate_forward_exception()
6692 |- V0, V1 are created
6693 |- T9 <= SharedRuntime::exception_handler_for_return_address
6694 `- jr T9
6695 `- the caller's exception_handler
6696 `- jr OptoRuntime::exception_blob
6697 `- here
6698 - Rethrow(e.g. 'unwind'):
6699 * The callee:
6700 |- an exception is triggered during execution
6701 `- exits the callee method through RethrowException node
6702 |- The callee pushes exception_oop(T0) and exception_pc(RA)
6703 `- The callee jumps to OptoRuntime::rethrow_stub()
6704 * In OptoRuntime::rethrow_stub:
6705 |- The VM calls _rethrow_Java to determine the return address in the caller method
6706 `- exits the stub with tailjmpInd
6707 |- pops exception_oop(V0) and exception_pc(V1)
6708 `- jumps to the return address(usually an exception_handler)
6709 * The caller:
6710 `- continues processing the exception_blob with V0/V1
6711 */
6713 /*
6714 Disassembling OptoRuntime::rethrow_stub()
6716 ; locals
6717 0x2d3bf320: addiu sp, sp, 0xfffffff8
6718 0x2d3bf324: sw ra, 0x4(sp)
6719 0x2d3bf328: sw fp, 0x0(sp)
6720 0x2d3bf32c: addu fp, sp, zero
6721 0x2d3bf330: addiu sp, sp, 0xfffffff0
6722 0x2d3bf334: sw ra, 0x8(sp)
6723 0x2d3bf338: sw t0, 0x4(sp)
6724 0x2d3bf33c: sw sp, 0x0(sp)
6726 ; get_thread(S2)
6727 0x2d3bf340: addu s2, sp, zero
6728 0x2d3bf344: srl s2, s2, 12
6729 0x2d3bf348: sll s2, s2, 2
6730 0x2d3bf34c: lui at, 0x2c85
6731 0x2d3bf350: addu at, at, s2
6732 0x2d3bf354: lw s2, 0xffffcc80(at)
6734 0x2d3bf358: lw s0, 0x0(sp)
6735 0x2d3bf35c: sw s0, 0x118(s2) // last_sp -> threa
6736 0x2d3bf360: sw s2, 0xc(sp)
6738 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
6739 0x2d3bf364: lw a0, 0x4(sp)
6740 0x2d3bf368: lw a1, 0xc(sp)
6741 0x2d3bf36c: lw a2, 0x8(sp)
6742 ;; Java_To_Runtime
6743 0x2d3bf370: lui t9, 0x2c34
6744 0x2d3bf374: addiu t9, t9, 0xffff8a48
6745 0x2d3bf378: jalr t9
6746 0x2d3bf37c: nop
6748 0x2d3bf380: addu s3, v0, zero ; S3: SharedRuntime::raw_exception_handler_for_return_address()
6750 0x2d3bf384: lw s0, 0xc(sp)
6751 0x2d3bf388: sw zero, 0x118(s0)
6752 0x2d3bf38c: sw zero, 0x11c(s0)
6753 0x2d3bf390: lw s1, 0x144(s0) ; ex_oop: S1
6754 0x2d3bf394: addu s2, s0, zero
6755 0x2d3bf398: sw zero, 0x144(s2)
6756 0x2d3bf39c: lw s0, 0x4(s2)
6757 0x2d3bf3a0: addiu s4, zero, 0x0
6758 0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
6759 0x2d3bf3a8: nop
6760 0x2d3bf3ac: addiu sp, sp, 0x10
6761 0x2d3bf3b0: addiu sp, sp, 0x8
6762 0x2d3bf3b4: lw ra, 0xfffffffc(sp)
6763 0x2d3bf3b8: lw fp, 0xfffffff8(sp)
6764 0x2d3bf3bc: lui at, 0x2b48
6765 0x2d3bf3c0: lw at, 0x100(at)
6767 ; tailjmpInd: Restores exception_oop & exception_pc
6768 0x2d3bf3c4: addu v1, ra, zero
6769 0x2d3bf3c8: addu v0, s1, zero
6770 0x2d3bf3cc: jr s3
6771 0x2d3bf3d0: nop
6772 ; Exception:
6773 0x2d3bf3d4: lui s1, 0x2cc8 ; generate_forward_exception()
6774 0x2d3bf3d8: addiu s1, s1, 0x40
6775 0x2d3bf3dc: addiu s2, zero, 0x0
6776 0x2d3bf3e0: addiu sp, sp, 0x10
6777 0x2d3bf3e4: addiu sp, sp, 0x8
6778 0x2d3bf3e8: lw ra, 0xfffffffc(sp)
6779 0x2d3bf3ec: lw fp, 0xfffffff8(sp)
6780 0x2d3bf3f0: lui at, 0x2b48
6781 0x2d3bf3f4: lw at, 0x100(at)
6782 ; TailCalljmpInd
6783 __ push(RA); ; to be used in generate_forward_exception()
6784 0x2d3bf3f8: addu t7, s2, zero
6785 0x2d3bf3fc: jr s1
6786 0x2d3bf400: nop
6787 */
6788 // Rethrow exception:
6789 // The exception oop will come in the first argument position.
6790 // Then JUMP (not call) to the rethrow stub code.
6791 instruct RethrowException()
6792 %{
6793 match(Rethrow);
6795 // use the following format syntax
6796 format %{ "JMP rethrow_stub #@RethrowException" %}
6797 ins_encode %{
6798 __ block_comment("@ RethrowException");
6800 cbuf.set_insts_mark();
6801 cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
6803 // call OptoRuntime::rethrow_stub to get the exception handler in parent method
6804 __ li(T9, OptoRuntime::rethrow_stub());
6805 __ jr(T9);
6806 __ nop();
6807 %}
6808 ins_pipe( pipe_jump );
6809 %}
6811 instruct branchConP_zero(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
6812 match(If cmp (CmpP op1 zero));
6813 effect(USE labl);
6815 ins_cost(180);
6816 format %{ "b$cmp $op1, R0, $labl #@branchConP_zero" %}
6818 ins_encode %{
6819 Register op1 = $op1$$Register;
6820 Register op2 = R0;
6821 Label &L = *($labl$$label);
6822 int flag = $cmp$$cmpcode;
6824 switch(flag)
6825 {
6826 case 0x01: //equal
6827 if (&L)
6828 __ beq(op1, op2, L);
6829 else
6830 __ beq(op1, op2, (int)0);
6831 break;
6832 case 0x02: //not_equal
6833 if (&L)
6834 __ bne(op1, op2, L);
6835 else
6836 __ bne(op1, op2, (int)0);
6837 break;
6838 /*
6839 case 0x03: //above
6840 __ sltu(AT, op2, op1);
6841 if(&L)
6842 __ bne(R0, AT, L);
6843 else
6844 __ bne(R0, AT, (int)0);
6845 break;
6846 case 0x04: //above_equal
6847 __ sltu(AT, op1, op2);
6848 if(&L)
6849 __ beq(AT, R0, L);
6850 else
6851 __ beq(AT, R0, (int)0);
6852 break;
6853 case 0x05: //below
6854 __ sltu(AT, op1, op2);
6855 if(&L)
6856 __ bne(R0, AT, L);
6857 else
6858 __ bne(R0, AT, (int)0);
6859 break;
6860 case 0x06: //below_equal
6861 __ sltu(AT, op2, op1);
6862 if(&L)
6863 __ beq(AT, R0, L);
6864 else
6865 __ beq(AT, R0, (int)0);
6866 break;
6867 */
6868 default:
6869 Unimplemented();
6870 }
6871 __ nop();
6872 %}
6874 ins_pc_relative(1);
6875 ins_pipe( pipe_alu_branch );
6876 %}
6879 instruct branchConP(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
6880 match(If cmp (CmpP op1 op2));
6881 // predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
6882 effect(USE labl);
6884 ins_cost(200);
6885 format %{ "b$cmp $op1, $op2, $labl #@branchConP" %}
6887 ins_encode %{
6888 Register op1 = $op1$$Register;
6889 Register op2 = $op2$$Register;
6890 Label &L = *($labl$$label);
6891 int flag = $cmp$$cmpcode;
6893 switch(flag)
6894 {
6895 case 0x01: //equal
6896 if (&L)
6897 __ beq(op1, op2, L);
6898 else
6899 __ beq(op1, op2, (int)0);
6900 break;
6901 case 0x02: //not_equal
6902 if (&L)
6903 __ bne(op1, op2, L);
6904 else
6905 __ bne(op1, op2, (int)0);
6906 break;
6907 case 0x03: //above
6908 __ sltu(AT, op2, op1);
6909 if(&L)
6910 __ bne(R0, AT, L);
6911 else
6912 __ bne(R0, AT, (int)0);
6913 break;
6914 case 0x04: //above_equal
6915 __ sltu(AT, op1, op2);
6916 if(&L)
6917 __ beq(AT, R0, L);
6918 else
6919 __ beq(AT, R0, (int)0);
6920 break;
6921 case 0x05: //below
6922 __ sltu(AT, op1, op2);
6923 if(&L)
6924 __ bne(R0, AT, L);
6925 else
6926 __ bne(R0, AT, (int)0);
6927 break;
6928 case 0x06: //below_equal
6929 __ sltu(AT, op2, op1);
6930 if(&L)
6931 __ beq(AT, R0, L);
6932 else
6933 __ beq(AT, R0, (int)0);
6934 break;
6935 default:
6936 Unimplemented();
6937 }
6938 __ nop();
6939 %}
6941 ins_pc_relative(1);
6942 ins_pipe( pipe_alu_branch );
6943 %}
6945 instruct cmpN_null_branch(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
6946 match(If cmp (CmpN op1 null));
6947 effect(USE labl);
6949 ins_cost(180);
6950 format %{ "CMP $op1,0\t! compressed ptr\n\t"
6951 "BP$cmp $labl @ cmpN_null_branch" %}
6952 ins_encode %{
6953 Register op1 = $op1$$Register;
6954 Register op2 = R0;
6955 Label &L = *($labl$$label);
6956 int flag = $cmp$$cmpcode;
6958 switch(flag)
6959 {
6960 case 0x01: //equal
6961 if (&L)
6962 __ beq(op1, op2, L);
6963 else
6964 __ beq(op1, op2, (int)0);
6965 break;
6966 case 0x02: //not_equal
6967 if (&L)
6968 __ bne(op1, op2, L);
6969 else
6970 __ bne(op1, op2, (int)0);
6971 break;
6972 default:
6973 Unimplemented();
6974 }
6975 __ nop();
6976 %}
6977 //TODO: pipe_branchP or create pipe_branchN LEE
6978 ins_pc_relative(1);
6979 ins_pipe( pipe_alu_branch );
6980 %}
6982 instruct cmpN_reg_branch(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
6983 match(If cmp (CmpN op1 op2));
6984 effect(USE labl);
6986 ins_cost(180);
6987 format %{ "CMP $op1,$op2\t! compressed ptr\n\t"
6988 "BP$cmp $labl" %}
6989 ins_encode %{
6990 Register op1_reg = $op1$$Register;
6991 Register op2_reg = $op2$$Register;
6992 Label &L = *($labl$$label);
6993 int flag = $cmp$$cmpcode;
6995 switch(flag)
6996 {
6997 case 0x01: //equal
6998 if (&L)
6999 __ beq(op1_reg, op2_reg, L);
7000 else
7001 __ beq(op1_reg, op2_reg, (int)0);
7002 break;
7003 case 0x02: //not_equal
7004 if (&L)
7005 __ bne(op1_reg, op2_reg, L);
7006 else
7007 __ bne(op1_reg, op2_reg, (int)0);
7008 break;
7009 case 0x03: //above
7010 __ sltu(AT, op2_reg, op1_reg);
7011 if(&L)
7012 __ bne(R0, AT, L);
7013 else
7014 __ bne(R0, AT, (int)0);
7015 break;
7016 case 0x04: //above_equal
7017 __ sltu(AT, op1_reg, op2_reg);
7018 if(&L)
7019 __ beq(AT, R0, L);
7020 else
7021 __ beq(AT, R0, (int)0);
7022 break;
7023 case 0x05: //below
7024 __ sltu(AT, op1_reg, op2_reg);
7025 if(&L)
7026 __ bne(R0, AT, L);
7027 else
7028 __ bne(R0, AT, (int)0);
7029 break;
7030 case 0x06: //below_equal
7031 __ sltu(AT, op2_reg, op1_reg);
7032 if(&L)
7033 __ beq(AT, R0, L);
7034 else
7035 __ beq(AT, R0, (int)0);
7036 break;
7037 default:
7038 Unimplemented();
7039 }
7040 __ nop();
7041 %}
7042 ins_pc_relative(1);
7043 ins_pipe( pipe_alu_branch );
7044 %}
7046 instruct branchConIU_reg_reg(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
7047 match( If cmp (CmpU src1 src2) );
7048 effect(USE labl);
7049 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_reg" %}
7051 ins_encode %{
7052 Register op1 = $src1$$Register;
7053 Register op2 = $src2$$Register;
7054 Label &L = *($labl$$label);
7055 int flag = $cmp$$cmpcode;
7057 switch(flag)
7058 {
7059 case 0x01: //equal
7060 if (&L)
7061 __ beq(op1, op2, L);
7062 else
7063 __ beq(op1, op2, (int)0);
7064 break;
7065 case 0x02: //not_equal
7066 if (&L)
7067 __ bne(op1, op2, L);
7068 else
7069 __ bne(op1, op2, (int)0);
7070 break;
7071 case 0x03: //above
7072 __ sltu(AT, op2, op1);
7073 if(&L)
7074 __ bne(AT, R0, L);
7075 else
7076 __ bne(AT, R0, (int)0);
7077 break;
7078 case 0x04: //above_equal
7079 __ sltu(AT, op1, op2);
7080 if(&L)
7081 __ beq(AT, R0, L);
7082 else
7083 __ beq(AT, R0, (int)0);
7084 break;
7085 case 0x05: //below
7086 __ sltu(AT, op1, op2);
7087 if(&L)
7088 __ bne(AT, R0, L);
7089 else
7090 __ bne(AT, R0, (int)0);
7091 break;
7092 case 0x06: //below_equal
7093 __ sltu(AT, op2, op1);
7094 if(&L)
7095 __ beq(AT, R0, L);
7096 else
7097 __ beq(AT, R0, (int)0);
7098 break;
7099 default:
7100 Unimplemented();
7101 }
7102 __ nop();
7103 %}
7105 ins_pc_relative(1);
7106 ins_pipe( pipe_alu_branch );
7107 %}
7110 instruct branchConIU_reg_imm(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
7111 match( If cmp (CmpU src1 src2) );
7112 effect(USE labl);
7113 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_imm" %}
7115 ins_encode %{
7116 Register op1 = $src1$$Register;
7117 int val = $src2$$constant;
7118 Label &L = *($labl$$label);
7119 int flag = $cmp$$cmpcode;
7121 __ move(AT, val);
7122 switch(flag)
7123 {
7124 case 0x01: //equal
7125 if (&L)
7126 __ beq(op1, AT, L);
7127 else
7128 __ beq(op1, AT, (int)0);
7129 break;
7130 case 0x02: //not_equal
7131 if (&L)
7132 __ bne(op1, AT, L);
7133 else
7134 __ bne(op1, AT, (int)0);
7135 break;
7136 case 0x03: //above
7137 __ sltu(AT, AT, op1);
7138 if(&L)
7139 __ bne(R0, AT, L);
7140 else
7141 __ bne(R0, AT, (int)0);
7142 break;
7143 case 0x04: //above_equal
7144 __ sltu(AT, op1, AT);
7145 if(&L)
7146 __ beq(AT, R0, L);
7147 else
7148 __ beq(AT, R0, (int)0);
7149 break;
7150 case 0x05: //below
7151 __ sltu(AT, op1, AT);
7152 if(&L)
7153 __ bne(R0, AT, L);
7154 else
7155 __ bne(R0, AT, (int)0);
7156 break;
7157 case 0x06: //below_equal
7158 __ sltu(AT, AT, op1);
7159 if(&L)
7160 __ beq(AT, R0, L);
7161 else
7162 __ beq(AT, R0, (int)0);
7163 break;
7164 default:
7165 Unimplemented();
7166 }
7167 __ nop();
7168 %}
7170 ins_pc_relative(1);
7171 ins_pipe( pipe_alu_branch );
7172 %}
7174 instruct branchConI_reg_reg(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
7175 match( If cmp (CmpI src1 src2) );
7176 effect(USE labl);
7177 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_reg" %}
7179 ins_encode %{
7180 Register op1 = $src1$$Register;
7181 Register op2 = $src2$$Register;
7182 Label &L = *($labl$$label);
7183 int flag = $cmp$$cmpcode;
7185 switch(flag)
7186 {
7187 case 0x01: //equal
7188 if (&L)
7189 __ beq(op1, op2, L);
7190 else
7191 __ beq(op1, op2, (int)0);
7192 break;
7193 case 0x02: //not_equal
7194 if (&L)
7195 __ bne(op1, op2, L);
7196 else
7197 __ bne(op1, op2, (int)0);
7198 break;
7199 case 0x03: //above
7200 __ slt(AT, op2, op1);
7201 if(&L)
7202 __ bne(R0, AT, L);
7203 else
7204 __ bne(R0, AT, (int)0);
7205 break;
7206 case 0x04: //above_equal
7207 __ slt(AT, op1, op2);
7208 if(&L)
7209 __ beq(AT, R0, L);
7210 else
7211 __ beq(AT, R0, (int)0);
7212 break;
7213 case 0x05: //below
7214 __ slt(AT, op1, op2);
7215 if(&L)
7216 __ bne(R0, AT, L);
7217 else
7218 __ bne(R0, AT, (int)0);
7219 break;
7220 case 0x06: //below_equal
7221 __ slt(AT, op2, op1);
7222 if(&L)
7223 __ beq(AT, R0, L);
7224 else
7225 __ beq(AT, R0, (int)0);
7226 break;
7227 default:
7228 Unimplemented();
7229 }
7230 __ nop();
7231 %}
7233 ins_pc_relative(1);
7234 ins_pipe( pipe_alu_branch );
7235 %}
7237 instruct branchConI_reg_imm0(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
7238 match( If cmp (CmpI src1 src2) );
7239 effect(USE labl);
7240 ins_cost(170);
7241 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm0" %}
7243 ins_encode %{
7244 Register op1 = $src1$$Register;
7245 // int val = $src2$$constant;
7246 Label &L = *($labl$$label);
7247 int flag = $cmp$$cmpcode;
7249 //__ move(AT, val);
7250 switch(flag)
7251 {
7252 case 0x01: //equal
7253 if (&L)
7254 __ beq(op1, R0, L);
7255 else
7256 __ beq(op1, R0, (int)0);
7257 break;
7258 case 0x02: //not_equal
7259 if (&L)
7260 __ bne(op1, R0, L);
7261 else
7262 __ bne(op1, R0, (int)0);
7263 break;
7264 case 0x03: //greater
7265 if(&L)
7266 __ bgtz(op1, L);
7267 else
7268 __ bgtz(op1, (int)0);
7269 break;
7270 case 0x04: //greater_equal
7271 if(&L)
7272 __ bgez(op1, L);
7273 else
7274 __ bgez(op1, (int)0);
7275 break;
7276 case 0x05: //less
7277 if(&L)
7278 __ bltz(op1, L);
7279 else
7280 __ bltz(op1, (int)0);
7281 break;
7282 case 0x06: //less_equal
7283 if(&L)
7284 __ blez(op1, L);
7285 else
7286 __ blez(op1, (int)0);
7287 break;
7288 default:
7289 Unimplemented();
7290 }
7291 __ nop();
7292 %}
7294 ins_pc_relative(1);
7295 ins_pipe( pipe_alu_branch );
7296 %}
7299 instruct branchConI_reg_imm(cmpOp cmp, mRegI src1, immI src2, label labl) %{
7300 match( If cmp (CmpI src1 src2) );
7301 effect(USE labl);
7302 ins_cost(200);
7303 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm" %}
7305 ins_encode %{
7306 Register op1 = $src1$$Register;
7307 int val = $src2$$constant;
7308 Label &L = *($labl$$label);
7309 int flag = $cmp$$cmpcode;
7311 __ move(AT, val);
7312 switch(flag)
7313 {
7314 case 0x01: //equal
7315 if (&L)
7316 __ beq(op1, AT, L);
7317 else
7318 __ beq(op1, AT, (int)0);
7319 break;
7320 case 0x02: //not_equal
7321 if (&L)
7322 __ bne(op1, AT, L);
7323 else
7324 __ bne(op1, AT, (int)0);
7325 break;
7326 case 0x03: //greater
7327 __ slt(AT, AT, op1);
7328 if(&L)
7329 __ bne(R0, AT, L);
7330 else
7331 __ bne(R0, AT, (int)0);
7332 break;
7333 case 0x04: //greater_equal
7334 __ slt(AT, op1, AT);
7335 if(&L)
7336 __ beq(AT, R0, L);
7337 else
7338 __ beq(AT, R0, (int)0);
7339 break;
7340 case 0x05: //less
7341 __ slt(AT, op1, AT);
7342 if(&L)
7343 __ bne(R0, AT, L);
7344 else
7345 __ bne(R0, AT, (int)0);
7346 break;
7347 case 0x06: //less_equal
7348 __ slt(AT, AT, op1);
7349 if(&L)
7350 __ beq(AT, R0, L);
7351 else
7352 __ beq(AT, R0, (int)0);
7353 break;
7354 default:
7355 Unimplemented();
7356 }
7357 __ nop();
7358 %}
7360 ins_pc_relative(1);
7361 ins_pipe( pipe_alu_branch );
7362 %}
7364 instruct branchConIU_reg_imm0(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
7365 match( If cmp (CmpU src1 zero) );
7366 effect(USE labl);
7367 format %{ "BR$cmp $src1, zero, $labl #@branchConIU_reg_imm0" %}
7369 ins_encode %{
7370 Register op1 = $src1$$Register;
7371 Label &L = *($labl$$label);
7372 int flag = $cmp$$cmpcode;
7374 switch(flag)
7375 {
7376 case 0x01: //equal
7377 if (&L)
7378 __ beq(op1, R0, L);
7379 else
7380 __ beq(op1, R0, (int)0);
7381 break;
7382 case 0x02: //not_equal
7383 if (&L)
7384 __ bne(op1, R0, L);
7385 else
7386 __ bne(op1, R0, (int)0);
7387 break;
7388 case 0x03: //above
7389 if(&L)
7390 __ bne(R0, op1, L);
7391 else
7392 __ bne(R0, op1, (int)0);
7393 break;
7394 case 0x04: //above_equal
7395 if(&L)
7396 __ beq(R0, R0, L);
7397 else
7398 __ beq(R0, R0, (int)0);
7399 break;
7400 case 0x05: //below
7401 return;
7402 break;
7403 case 0x06: //below_equal
7404 if(&L)
7405 __ beq(op1, R0, L);
7406 else
7407 __ beq(op1, R0, (int)0);
7408 break;
7409 default:
7410 Unimplemented();
7411 }
7412 __ nop();
7413 %}
7415 ins_pc_relative(1);
7416 ins_pipe( pipe_alu_branch );
7417 %}
7420 instruct branchConIU_reg_immI16(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
7421 match( If cmp (CmpU src1 src2) );
7422 effect(USE labl);
7423 ins_cost(180);
7424 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_immI16" %}
7426 ins_encode %{
7427 Register op1 = $src1$$Register;
7428 int val = $src2$$constant;
7429 Label &L = *($labl$$label);
7430 int flag = $cmp$$cmpcode;
7432 switch(flag)
7433 {
7434 case 0x01: //equal
7435 __ move(AT, val);
7436 if (&L)
7437 __ beq(op1, AT, L);
7438 else
7439 __ beq(op1, AT, (int)0);
7440 break;
7441 case 0x02: //not_equal
7442 __ move(AT, val);
7443 if (&L)
7444 __ bne(op1, AT, L);
7445 else
7446 __ bne(op1, AT, (int)0);
7447 break;
7448 case 0x03: //above
7449 __ move(AT, val);
7450 __ sltu(AT, AT, op1);
7451 if(&L)
7452 __ bne(R0, AT, L);
7453 else
7454 __ bne(R0, AT, (int)0);
7455 break;
7456 case 0x04: //above_equal
7457 __ sltiu(AT, op1, val);
7458 if(&L)
7459 __ beq(AT, R0, L);
7460 else
7461 __ beq(AT, R0, (int)0);
7462 break;
7463 case 0x05: //below
7464 __ sltiu(AT, op1, val);
7465 if(&L)
7466 __ bne(R0, AT, L);
7467 else
7468 __ bne(R0, AT, (int)0);
7469 break;
7470 case 0x06: //below_equal
7471 __ move(AT, val);
7472 __ sltu(AT, AT, op1);
7473 if(&L)
7474 __ beq(AT, R0, L);
7475 else
7476 __ beq(AT, R0, (int)0);
7477 break;
7478 default:
7479 Unimplemented();
7480 }
7481 __ nop();
7482 %}
7484 ins_pc_relative(1);
7485 ins_pipe( pipe_alu_branch );
7486 %}
7489 instruct branchConL_regL_regL(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
7490 match( If cmp (CmpL src1 src2) );
7491 effect(USE labl);
7492 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_regL" %}
7493 ins_cost(250);
7495 ins_encode %{
7496 Register opr1_reg = as_Register($src1$$reg);
7497 Register opr2_reg = as_Register($src2$$reg);
7499 Label &target = *($labl$$label);
7500 int flag = $cmp$$cmpcode;
7502 switch(flag)
7503 {
7504 case 0x01: //equal
7505 if (&target)
7506 __ beq(opr1_reg, opr2_reg, target);
7507 else
7508 __ beq(opr1_reg, opr2_reg, (int)0);
7509 __ delayed()->nop();
7510 break;
7512 case 0x02: //not_equal
7513 if(&target)
7514 __ bne(opr1_reg, opr2_reg, target);
7515 else
7516 __ bne(opr1_reg, opr2_reg, (int)0);
7517 __ delayed()->nop();
7518 break;
7520 case 0x03: //greater
7521 __ slt(AT, opr2_reg, opr1_reg);
7522 if(&target)
7523 __ bne(AT, R0, target);
7524 else
7525 __ bne(AT, R0, (int)0);
7526 __ delayed()->nop();
7527 break;
7529 case 0x04: //greater_equal
7530 __ slt(AT, opr1_reg, opr2_reg);
7531 if(&target)
7532 __ beq(AT, R0, target);
7533 else
7534 __ beq(AT, R0, (int)0);
7535 __ delayed()->nop();
7537 break;
7539 case 0x05: //less
7540 __ slt(AT, opr1_reg, opr2_reg);
7541 if(&target)
7542 __ bne(AT, R0, target);
7543 else
7544 __ bne(AT, R0, (int)0);
7545 __ delayed()->nop();
7547 break;
7549 case 0x06: //less_equal
7550 __ slt(AT, opr2_reg, opr1_reg);
7552 if(&target)
7553 __ beq(AT, R0, target);
7554 else
7555 __ beq(AT, R0, (int)0);
7556 __ delayed()->nop();
7558 break;
7560 default:
7561 Unimplemented();
7562 }
7563 %}
7566 ins_pc_relative(1);
7567 ins_pipe( pipe_alu_branch );
7568 %}
7570 instruct branchConL_reg_immL16_sub(cmpOp cmp, mRegL src1, immL16_sub src2, label labl) %{
7571 match( If cmp (CmpL src1 src2) );
7572 effect(USE labl);
7573 ins_cost(180);
7574 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_reg_immL16_sub" %}
7576 ins_encode %{
7577 Register op1 = $src1$$Register;
7578 int val = $src2$$constant;
7579 Label &L = *($labl$$label);
7580 int flag = $cmp$$cmpcode;
7582 __ daddiu(AT, op1, -1 * val);
7583 switch(flag)
7584 {
7585 case 0x01: //equal
7586 if (&L)
7587 __ beq(R0, AT, L);
7588 else
7589 __ beq(R0, AT, (int)0);
7590 break;
7591 case 0x02: //not_equal
7592 if (&L)
7593 __ bne(R0, AT, L);
7594 else
7595 __ bne(R0, AT, (int)0);
7596 break;
7597 case 0x03: //greater
7598 if(&L)
7599 __ bgtz(AT, L);
7600 else
7601 __ bgtz(AT, (int)0);
7602 break;
7603 case 0x04: //greater_equal
7604 if(&L)
7605 __ bgez(AT, L);
7606 else
7607 __ bgez(AT, (int)0);
7608 break;
7609 case 0x05: //less
7610 if(&L)
7611 __ bltz(AT, L);
7612 else
7613 __ bltz(AT, (int)0);
7614 break;
7615 case 0x06: //less_equal
7616 if(&L)
7617 __ blez(AT, L);
7618 else
7619 __ blez(AT, (int)0);
7620 break;
7621 default:
7622 Unimplemented();
7623 }
7624 __ nop();
7625 %}
7627 ins_pc_relative(1);
7628 ins_pipe( pipe_alu_branch );
7629 %}
7632 instruct branchConI_reg_imm16_sub(cmpOp cmp, mRegI src1, immI16_sub src2, label labl) %{
7633 match( If cmp (CmpI src1 src2) );
7634 effect(USE labl);
7635 ins_cost(180);
7636 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm16_sub" %}
7638 ins_encode %{
7639 Register op1 = $src1$$Register;
7640 int val = $src2$$constant;
7641 Label &L = *($labl$$label);
7642 int flag = $cmp$$cmpcode;
7644 __ addiu32(AT, op1, -1 * val);
7645 switch(flag)
7646 {
7647 case 0x01: //equal
7648 if (&L)
7649 __ beq(R0, AT, L);
7650 else
7651 __ beq(R0, AT, (int)0);
7652 break;
7653 case 0x02: //not_equal
7654 if (&L)
7655 __ bne(R0, AT, L);
7656 else
7657 __ bne(R0, AT, (int)0);
7658 break;
7659 case 0x03: //greater
7660 if(&L)
7661 __ bgtz(AT, L);
7662 else
7663 __ bgtz(AT, (int)0);
7664 break;
7665 case 0x04: //greater_equal
7666 if(&L)
7667 __ bgez(AT, L);
7668 else
7669 __ bgez(AT, (int)0);
7670 break;
7671 case 0x05: //less
7672 if(&L)
7673 __ bltz(AT, L);
7674 else
7675 __ bltz(AT, (int)0);
7676 break;
7677 case 0x06: //less_equal
7678 if(&L)
7679 __ blez(AT, L);
7680 else
7681 __ blez(AT, (int)0);
7682 break;
7683 default:
7684 Unimplemented();
7685 }
7686 __ nop();
7687 %}
7689 ins_pc_relative(1);
7690 ins_pipe( pipe_alu_branch );
7691 %}
7693 instruct branchConL_regL_immL0(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
7694 match( If cmp (CmpL src1 zero) );
7695 effect(USE labl);
7696 format %{ "BR$cmp $src1, zero, $labl #@branchConL_regL_immL0" %}
7697 ins_cost(150);
7699 ins_encode %{
7700 Register opr1_reg = as_Register($src1$$reg);
7701 Label &target = *($labl$$label);
7702 int flag = $cmp$$cmpcode;
7704 switch(flag)
7705 {
7706 case 0x01: //equal
7707 if (&target)
7708 __ beq(opr1_reg, R0, target);
7709 else
7710 __ beq(opr1_reg, R0, int(0));
7711 break;
7713 case 0x02: //not_equal
7714 if(&target)
7715 __ bne(opr1_reg, R0, target);
7716 else
7717 __ bne(opr1_reg, R0, (int)0);
7718 break;
7720 case 0x03: //greater
7721 if(&target)
7722 __ bgtz(opr1_reg, target);
7723 else
7724 __ bgtz(opr1_reg, (int)0);
7725 break;
7727 case 0x04: //greater_equal
7728 if(&target)
7729 __ bgez(opr1_reg, target);
7730 else
7731 __ bgez(opr1_reg, (int)0);
7732 break;
7734 case 0x05: //less
7735 __ slt(AT, opr1_reg, R0);
7736 if(&target)
7737 __ bne(AT, R0, target);
7738 else
7739 __ bne(AT, R0, (int)0);
7740 break;
7742 case 0x06: //less_equal
7743 if (&target)
7744 __ blez(opr1_reg, target);
7745 else
7746 __ blez(opr1_reg, int(0));
7747 break;
7749 default:
7750 Unimplemented();
7751 }
7752 __ delayed()->nop();
7753 %}
7756 ins_pc_relative(1);
7757 ins_pipe( pipe_alu_branch );
7758 %}
7760 /*
7761 // Conditional Direct Branch
7762 instruct branchCon(cmpOp cmp, flagsReg icc, label labl) %{
7763 match(If cmp icc);
7764 effect(USE labl);
7766 size(8);
7767 ins_cost(BRANCH_COST);
7768 format %{ "BP$cmp $icc,$labl" %}
7769 // Prim = bits 24-22, Secnd = bits 31-30
7770 ins_encode( enc_bp( labl, cmp, icc ) );
7771 ins_pc_relative(1);
7772 ins_pipe(br_cc);
7773 %}
7774 */
7776 //FIXME
7777 instruct branchConF_reg_reg(cmpOp cmp, regF src1, regF src2, label labl) %{
7778 match( If cmp (CmpF src1 src2) );
7779 effect(USE labl);
7780 format %{ "BR$cmp $src1, $src2, $labl #@branchConF_reg_reg" %}
7782 ins_encode %{
7783 FloatRegister reg_op1 = $src1$$FloatRegister;
7784 FloatRegister reg_op2 = $src2$$FloatRegister;
7785 Label &L = *($labl$$label);
7786 int flag = $cmp$$cmpcode;
7788 switch(flag)
7789 {
7790 case 0x01: //equal
7791 __ c_eq_s(reg_op1, reg_op2);
7792 if (&L)
7793 __ bc1t(L);
7794 else
7795 __ bc1t((int)0);
7796 break;
7797 case 0x02: //not_equal
7798 __ c_eq_s(reg_op1, reg_op2);
7799 if (&L)
7800 __ bc1f(L);
7801 else
7802 __ bc1f((int)0);
7803 break;
7804 case 0x03: //greater
7805 __ c_ule_s(reg_op1, reg_op2);
7806 if(&L)
7807 __ bc1f(L);
7808 else
7809 __ bc1f((int)0);
7810 break;
7811 case 0x04: //greater_equal
7812 __ c_ult_s(reg_op1, reg_op2);
7813 if(&L)
7814 __ bc1f(L);
7815 else
7816 __ bc1f((int)0);
7817 break;
7818 case 0x05: //less
7819 __ c_ult_s(reg_op1, reg_op2);
7820 if(&L)
7821 __ bc1t(L);
7822 else
7823 __ bc1t((int)0);
7824 break;
7825 case 0x06: //less_equal
7826 __ c_ule_s(reg_op1, reg_op2);
7827 if(&L)
7828 __ bc1t(L);
7829 else
7830 __ bc1t((int)0);
7831 break;
7832 default:
7833 Unimplemented();
7834 }
7835 __ nop();
7836 %}
7838 ins_pc_relative(1);
7839 ins_pipe(pipe_slow);
7840 %}
7842 instruct branchConD_reg_reg(cmpOp cmp, regD src1, regD src2, label labl) %{
7843 match( If cmp (CmpD src1 src2) );
7844 effect(USE labl);
7845 format %{ "BR$cmp $src1, $src2, $labl #@branchConD_reg_reg" %}
7847 ins_encode %{
7848 FloatRegister reg_op1 = $src1$$FloatRegister;
7849 FloatRegister reg_op2 = $src2$$FloatRegister;
7850 Label &L = *($labl$$label);
7851 int flag = $cmp$$cmpcode;
7853 switch(flag)
7854 {
7855 case 0x01: //equal
7856 __ c_eq_d(reg_op1, reg_op2);
7857 if (&L)
7858 __ bc1t(L);
7859 else
7860 __ bc1t((int)0);
7861 break;
7862 case 0x02: //not_equal
7863 //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.
7864 __ c_eq_d(reg_op1, reg_op2);
7865 if (&L)
7866 __ bc1f(L);
7867 else
7868 __ bc1f((int)0);
7869 break;
7870 case 0x03: //greater
7871 __ c_ule_d(reg_op1, reg_op2);
7872 if(&L)
7873 __ bc1f(L);
7874 else
7875 __ bc1f((int)0);
7876 break;
7877 case 0x04: //greater_equal
7878 __ c_ult_d(reg_op1, reg_op2);
7879 if(&L)
7880 __ bc1f(L);
7881 else
7882 __ bc1f((int)0);
7883 break;
7884 case 0x05: //less
7885 __ c_ult_d(reg_op1, reg_op2);
7886 if(&L)
7887 __ bc1t(L);
7888 else
7889 __ bc1t((int)0);
7890 break;
7891 case 0x06: //less_equal
7892 __ c_ule_d(reg_op1, reg_op2);
7893 if(&L)
7894 __ bc1t(L);
7895 else
7896 __ bc1t((int)0);
7897 break;
7898 default:
7899 Unimplemented();
7900 }
7901 __ nop();
7902 %}
7904 ins_pc_relative(1);
7905 ins_pipe(pipe_slow);
7906 %}
7909 // Call Runtime Instruction
7910 instruct CallRuntimeDirect(method meth) %{
7911 match(CallRuntime );
7912 effect(USE meth);
7914 ins_cost(300);
7915 format %{ "CALL,runtime #@CallRuntimeDirect" %}
7916 ins_encode( Java_To_Runtime( meth ) );
7917 ins_pipe( pipe_slow );
7918 ins_alignment(16);
7919 %}
7923 //------------------------MemBar Instructions-------------------------------
7924 //Memory barrier flavors
7926 instruct membar_acquire() %{
7927 match(MemBarAcquire);
7928 ins_cost(0);
7930 size(0);
7931 format %{ "MEMBAR-acquire (empty) @ membar_acquire" %}
7932 ins_encode();
7933 ins_pipe(empty);
7934 %}
7936 instruct load_fence() %{
7937 match(LoadFence);
7938 ins_cost(400);
7940 format %{ "MEMBAR @ load_fence" %}
7941 ins_encode %{
7942 __ sync();
7943 %}
7944 ins_pipe(pipe_slow);
7945 %}
7947 instruct membar_acquire_lock()
7948 %{
7949 match(MemBarAcquireLock);
7950 ins_cost(0);
7952 size(0);
7953 format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
7954 ins_encode();
7955 ins_pipe(empty);
7956 %}
7958 instruct membar_release() %{
7959 match(MemBarRelease);
7960 ins_cost(0);
7962 size(0);
7963 format %{ "MEMBAR-release (empty) @ membar_release" %}
7964 ins_encode();
7965 ins_pipe(empty);
7966 %}
7968 instruct store_fence() %{
7969 match(StoreFence);
7970 ins_cost(400);
7972 format %{ "MEMBAR @ store_fence" %}
7974 ins_encode %{
7975 __ sync();
7976 %}
7978 ins_pipe(pipe_slow);
7979 %}
7981 instruct membar_release_lock()
7982 %{
7983 match(MemBarReleaseLock);
7984 ins_cost(0);
7986 size(0);
7987 format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
7988 ins_encode();
7989 ins_pipe(empty);
7990 %}
7993 instruct membar_volatile() %{
7994 match(MemBarVolatile);
7995 ins_cost(400);
7997 format %{ "MEMBAR-volatile" %}
7998 ins_encode %{
7999 if( !os::is_MP() ) return; // Not needed on single CPU
8000 __ sync();
8002 %}
8003 ins_pipe(pipe_slow);
8004 %}
8006 instruct unnecessary_membar_volatile() %{
8007 match(MemBarVolatile);
8008 predicate(Matcher::post_store_load_barrier(n));
8009 ins_cost(0);
8011 size(0);
8012 format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
8013 ins_encode( );
8014 ins_pipe(empty);
8015 %}
8017 instruct membar_storestore() %{
8018 match(MemBarStoreStore);
8020 ins_cost(0);
8021 size(0);
8022 format %{ "MEMBAR-storestore (empty encoding) @ membar_storestore" %}
8023 ins_encode( );
8024 ins_pipe(empty);
8025 %}
8027 //----------Move Instructions--------------------------------------------------
8028 instruct castX2P(mRegP dst, mRegL src) %{
8029 match(Set dst (CastX2P src));
8030 format %{ "castX2P $dst, $src @ castX2P" %}
8031 ins_encode %{
8032 Register src = $src$$Register;
8033 Register dst = $dst$$Register;
8035 if(src != dst)
8036 __ move(dst, src);
8037 %}
8038 ins_cost(10);
8039 ins_pipe( ialu_regI_mov );
8040 %}
8042 instruct castP2X(mRegL dst, mRegP src ) %{
8043 match(Set dst (CastP2X src));
8045 format %{ "mov $dst, $src\t #@castP2X" %}
8046 ins_encode %{
8047 Register src = $src$$Register;
8048 Register dst = $dst$$Register;
8050 if(src != dst)
8051 __ move(dst, src);
8052 %}
8053 ins_pipe( ialu_regI_mov );
8054 %}
8056 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
8057 match(Set dst (MoveF2I src));
8058 effect(DEF dst, USE src);
8059 ins_cost(85);
8060 format %{ "MoveF2I $dst, $src @ MoveF2I_reg_reg" %}
8061 ins_encode %{
8062 Register dst = as_Register($dst$$reg);
8063 FloatRegister src = as_FloatRegister($src$$reg);
8065 __ mfc1(dst, src);
8066 %}
8067 ins_pipe( pipe_slow );
8068 %}
8070 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
8071 match(Set dst (MoveI2F src));
8072 effect(DEF dst, USE src);
8073 ins_cost(85);
8074 format %{ "MoveI2F $dst, $src @ MoveI2F_reg_reg" %}
8075 ins_encode %{
8076 Register src = as_Register($src$$reg);
8077 FloatRegister dst = as_FloatRegister($dst$$reg);
8079 __ mtc1(src, dst);
8080 %}
8081 ins_pipe( pipe_slow );
8082 %}
8084 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
8085 match(Set dst (MoveD2L src));
8086 effect(DEF dst, USE src);
8087 ins_cost(85);
8088 format %{ "MoveD2L $dst, $src @ MoveD2L_reg_reg" %}
8089 ins_encode %{
8090 Register dst = as_Register($dst$$reg);
8091 FloatRegister src = as_FloatRegister($src$$reg);
8093 __ dmfc1(dst, src);
8094 %}
8095 ins_pipe( pipe_slow );
8096 %}
8098 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
8099 match(Set dst (MoveL2D src));
8100 effect(DEF dst, USE src);
8101 ins_cost(85);
8102 format %{ "MoveL2D $dst, $src @ MoveL2D_reg_reg" %}
8103 ins_encode %{
8104 FloatRegister dst = as_FloatRegister($dst$$reg);
8105 Register src = as_Register($src$$reg);
8107 __ dmtc1(src, dst);
8108 %}
8109 ins_pipe( pipe_slow );
8110 %}
8112 //----------Conditional Move---------------------------------------------------
8113 // Conditional move
8114 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
8115 match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
8116 ins_cost(80);
8117 format %{
8118 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpI_reg_reg\n"
8119 "\tCMOV $dst,$src \t @cmovI_cmpI_reg_reg"
8120 %}
8122 ins_encode %{
8123 Register op1 = $tmp1$$Register;
8124 Register op2 = $tmp2$$Register;
8125 Register dst = $dst$$Register;
8126 Register src = $src$$Register;
8127 int flag = $cop$$cmpcode;
8129 switch(flag)
8130 {
8131 case 0x01: //equal
8132 __ subu32(AT, op1, op2);
8133 __ movz(dst, src, AT);
8134 break;
8136 case 0x02: //not_equal
8137 __ subu32(AT, op1, op2);
8138 __ movn(dst, src, AT);
8139 break;
8141 case 0x03: //great
8142 __ slt(AT, op2, op1);
8143 __ movn(dst, src, AT);
8144 break;
8146 case 0x04: //great_equal
8147 __ slt(AT, op1, op2);
8148 __ movz(dst, src, AT);
8149 break;
8151 case 0x05: //less
8152 __ slt(AT, op1, op2);
8153 __ movn(dst, src, AT);
8154 break;
8156 case 0x06: //less_equal
8157 __ slt(AT, op2, op1);
8158 __ movz(dst, src, AT);
8159 break;
8161 default:
8162 Unimplemented();
8163 }
8164 %}
8166 ins_pipe( pipe_slow );
8167 %}
8169 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
8170 match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
8171 ins_cost(80);
8172 format %{
8173 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
8174 "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
8175 %}
8176 ins_encode %{
8177 Register op1 = $tmp1$$Register;
8178 Register op2 = $tmp2$$Register;
8179 Register dst = $dst$$Register;
8180 Register src = $src$$Register;
8181 int flag = $cop$$cmpcode;
8183 switch(flag)
8184 {
8185 case 0x01: //equal
8186 __ subu(AT, op1, op2);
8187 __ movz(dst, src, AT);
8188 break;
8190 case 0x02: //not_equal
8191 __ subu(AT, op1, op2);
8192 __ movn(dst, src, AT);
8193 break;
8195 case 0x03: //above
8196 __ sltu(AT, op2, op1);
8197 __ movn(dst, src, AT);
8198 break;
8200 case 0x04: //above_equal
8201 __ sltu(AT, op1, op2);
8202 __ movz(dst, src, AT);
8203 break;
8205 case 0x05: //below
8206 __ sltu(AT, op1, op2);
8207 __ movn(dst, src, AT);
8208 break;
8210 case 0x06: //below_equal
8211 __ sltu(AT, op2, op1);
8212 __ movz(dst, src, AT);
8213 break;
8215 default:
8216 Unimplemented();
8217 }
8218 %}
8220 ins_pipe( pipe_slow );
8221 %}
8223 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
8224 match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
8225 ins_cost(80);
8226 format %{
8227 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
8228 "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
8229 %}
8230 ins_encode %{
8231 Register op1 = $tmp1$$Register;
8232 Register op2 = $tmp2$$Register;
8233 Register dst = $dst$$Register;
8234 Register src = $src$$Register;
8235 int flag = $cop$$cmpcode;
8237 switch(flag)
8238 {
8239 case 0x01: //equal
8240 __ subu32(AT, op1, op2);
8241 __ movz(dst, src, AT);
8242 break;
8244 case 0x02: //not_equal
8245 __ subu32(AT, op1, op2);
8246 __ movn(dst, src, AT);
8247 break;
8249 case 0x03: //above
8250 __ sltu(AT, op2, op1);
8251 __ movn(dst, src, AT);
8252 break;
8254 case 0x04: //above_equal
8255 __ sltu(AT, op1, op2);
8256 __ movz(dst, src, AT);
8257 break;
8259 case 0x05: //below
8260 __ sltu(AT, op1, op2);
8261 __ movn(dst, src, AT);
8262 break;
8264 case 0x06: //below_equal
8265 __ sltu(AT, op2, op1);
8266 __ movz(dst, src, AT);
8267 break;
8269 default:
8270 Unimplemented();
8271 }
8272 %}
8274 ins_pipe( pipe_slow );
8275 %}
8277 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
8278 match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
8279 ins_cost(80);
8280 format %{
8281 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
8282 "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
8283 %}
8284 ins_encode %{
8285 Register op1 = $tmp1$$Register;
8286 Register op2 = $tmp2$$Register;
8287 Register dst = $dst$$Register;
8288 Register src = $src$$Register;
8289 int flag = $cop$$cmpcode;
8291 switch(flag)
8292 {
8293 case 0x01: //equal
8294 __ subu32(AT, op1, op2);
8295 __ movz(dst, src, AT);
8296 break;
8298 case 0x02: //not_equal
8299 __ subu32(AT, op1, op2);
8300 __ movn(dst, src, AT);
8301 break;
8303 case 0x03: //above
8304 __ sltu(AT, op2, op1);
8305 __ movn(dst, src, AT);
8306 break;
8308 case 0x04: //above_equal
8309 __ sltu(AT, op1, op2);
8310 __ movz(dst, src, AT);
8311 break;
8313 case 0x05: //below
8314 __ sltu(AT, op1, op2);
8315 __ movn(dst, src, AT);
8316 break;
8318 case 0x06: //below_equal
8319 __ sltu(AT, op2, op1);
8320 __ movz(dst, src, AT);
8321 break;
8323 default:
8324 Unimplemented();
8325 }
8326 %}
8328 ins_pipe( pipe_slow );
8329 %}
8331 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
8332 match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
8333 ins_cost(80);
8334 format %{
8335 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
8336 "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
8337 %}
8338 ins_encode %{
8339 Register op1 = $tmp1$$Register;
8340 Register op2 = $tmp2$$Register;
8341 Register dst = $dst$$Register;
8342 Register src = $src$$Register;
8343 int flag = $cop$$cmpcode;
8345 switch(flag)
8346 {
8347 case 0x01: //equal
8348 __ subu(AT, op1, op2);
8349 __ movz(dst, src, AT);
8350 break;
8352 case 0x02: //not_equal
8353 __ subu(AT, op1, op2);
8354 __ movn(dst, src, AT);
8355 break;
8357 case 0x03: //above
8358 __ sltu(AT, op2, op1);
8359 __ movn(dst, src, AT);
8360 break;
8362 case 0x04: //above_equal
8363 __ sltu(AT, op1, op2);
8364 __ movz(dst, src, AT);
8365 break;
8367 case 0x05: //below
8368 __ sltu(AT, op1, op2);
8369 __ movn(dst, src, AT);
8370 break;
8372 case 0x06: //below_equal
8373 __ sltu(AT, op2, op1);
8374 __ movz(dst, src, AT);
8375 break;
8377 default:
8378 Unimplemented();
8379 }
8380 %}
8382 ins_pipe( pipe_slow );
8383 %}
8385 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
8386 match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
8387 ins_cost(80);
8388 format %{
8389 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpD_reg_reg\n"
8390 "\tCMOV $dst,$src \t @cmovP_cmpD_reg_reg"
8391 %}
8392 ins_encode %{
8393 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
8394 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
8395 Register dst = as_Register($dst$$reg);
8396 Register src = as_Register($src$$reg);
8398 int flag = $cop$$cmpcode;
8400 switch(flag)
8401 {
8402 case 0x01: //equal
8403 __ c_eq_d(reg_op1, reg_op2);
8404 __ movt(dst, src);
8405 break;
8406 case 0x02: //not_equal
8407 __ c_eq_d(reg_op1, reg_op2);
8408 __ movf(dst, src);
8409 break;
8410 case 0x03: //greater
8411 __ c_ole_d(reg_op1, reg_op2);
8412 __ movf(dst, src);
8413 break;
8414 case 0x04: //greater_equal
8415 __ c_olt_d(reg_op1, reg_op2);
8416 __ movf(dst, src);
8417 break;
8418 case 0x05: //less
8419 __ c_ult_d(reg_op1, reg_op2);
8420 __ movt(dst, src);
8421 break;
8422 case 0x06: //less_equal
8423 __ c_ule_d(reg_op1, reg_op2);
8424 __ movt(dst, src);
8425 break;
8426 default:
8427 Unimplemented();
8428 }
8429 %}
8431 ins_pipe( pipe_slow );
8432 %}
8435 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
8436 match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
8437 ins_cost(80);
8438 format %{
8439 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
8440 "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
8441 %}
8442 ins_encode %{
8443 Register op1 = $tmp1$$Register;
8444 Register op2 = $tmp2$$Register;
8445 Register dst = $dst$$Register;
8446 Register src = $src$$Register;
8447 int flag = $cop$$cmpcode;
8449 switch(flag)
8450 {
8451 case 0x01: //equal
8452 __ subu32(AT, op1, op2);
8453 __ movz(dst, src, AT);
8454 break;
8456 case 0x02: //not_equal
8457 __ subu32(AT, op1, op2);
8458 __ movn(dst, src, AT);
8459 break;
8461 case 0x03: //above
8462 __ sltu(AT, op2, op1);
8463 __ movn(dst, src, AT);
8464 break;
8466 case 0x04: //above_equal
8467 __ sltu(AT, op1, op2);
8468 __ movz(dst, src, AT);
8469 break;
8471 case 0x05: //below
8472 __ sltu(AT, op1, op2);
8473 __ movn(dst, src, AT);
8474 break;
8476 case 0x06: //below_equal
8477 __ sltu(AT, op2, op1);
8478 __ movz(dst, src, AT);
8479 break;
8481 default:
8482 Unimplemented();
8483 }
8484 %}
8486 ins_pipe( pipe_slow );
8487 %}
8490 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
8491 match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
8492 ins_cost(80);
8493 format %{
8494 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
8495 "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
8496 %}
8497 ins_encode %{
8498 Register op1 = $tmp1$$Register;
8499 Register op2 = $tmp2$$Register;
8500 Register dst = $dst$$Register;
8501 Register src = $src$$Register;
8502 int flag = $cop$$cmpcode;
8504 switch(flag)
8505 {
8506 case 0x01: //equal
8507 __ subu(AT, op1, op2);
8508 __ movz(dst, src, AT);
8509 break;
8511 case 0x02: //not_equal
8512 __ subu(AT, op1, op2);
8513 __ movn(dst, src, AT);
8514 break;
8516 case 0x03: //above
8517 __ sltu(AT, op2, op1);
8518 __ movn(dst, src, AT);
8519 break;
8521 case 0x04: //above_equal
8522 __ sltu(AT, op1, op2);
8523 __ movz(dst, src, AT);
8524 break;
8526 case 0x05: //below
8527 __ sltu(AT, op1, op2);
8528 __ movn(dst, src, AT);
8529 break;
8531 case 0x06: //below_equal
8532 __ sltu(AT, op2, op1);
8533 __ movz(dst, src, AT);
8534 break;
8536 default:
8537 Unimplemented();
8538 }
8539 %}
8541 ins_pipe( pipe_slow );
8542 %}
8544 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
8545 match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
8546 ins_cost(80);
8547 format %{
8548 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpL_reg_reg\n"
8549 "\tCMOV $dst,$src \t @cmovI_cmpL_reg_reg"
8550 %}
8551 ins_encode %{
8552 Register opr1 = as_Register($tmp1$$reg);
8553 Register opr2 = as_Register($tmp2$$reg);
8554 Register dst = $dst$$Register;
8555 Register src = $src$$Register;
8556 int flag = $cop$$cmpcode;
8558 switch(flag)
8559 {
8560 case 0x01: //equal
8561 __ subu(AT, opr1, opr2);
8562 __ movz(dst, src, AT);
8563 break;
8565 case 0x02: //not_equal
8566 __ subu(AT, opr1, opr2);
8567 __ movn(dst, src, AT);
8568 break;
8570 case 0x03: //greater
8571 __ slt(AT, opr2, opr1);
8572 __ movn(dst, src, AT);
8573 break;
8575 case 0x04: //greater_equal
8576 __ slt(AT, opr1, opr2);
8577 __ movz(dst, src, AT);
8578 break;
8580 case 0x05: //less
8581 __ slt(AT, opr1, opr2);
8582 __ movn(dst, src, AT);
8583 break;
8585 case 0x06: //less_equal
8586 __ slt(AT, opr2, opr1);
8587 __ movz(dst, src, AT);
8588 break;
8590 default:
8591 Unimplemented();
8592 }
8593 %}
8595 ins_pipe( pipe_slow );
8596 %}
8598 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
8599 match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
8600 ins_cost(80);
8601 format %{
8602 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpL_reg_reg\n"
8603 "\tCMOV $dst,$src \t @cmovP_cmpL_reg_reg"
8604 %}
8605 ins_encode %{
8606 Register opr1 = as_Register($tmp1$$reg);
8607 Register opr2 = as_Register($tmp2$$reg);
8608 Register dst = $dst$$Register;
8609 Register src = $src$$Register;
8610 int flag = $cop$$cmpcode;
8612 switch(flag)
8613 {
8614 case 0x01: //equal
8615 __ subu(AT, opr1, opr2);
8616 __ movz(dst, src, AT);
8617 break;
8619 case 0x02: //not_equal
8620 __ subu(AT, opr1, opr2);
8621 __ movn(dst, src, AT);
8622 break;
8624 case 0x03: //greater
8625 __ slt(AT, opr2, opr1);
8626 __ movn(dst, src, AT);
8627 break;
8629 case 0x04: //greater_equal
8630 __ slt(AT, opr1, opr2);
8631 __ movz(dst, src, AT);
8632 break;
8634 case 0x05: //less
8635 __ slt(AT, opr1, opr2);
8636 __ movn(dst, src, AT);
8637 break;
8639 case 0x06: //less_equal
8640 __ slt(AT, opr2, opr1);
8641 __ movz(dst, src, AT);
8642 break;
8644 default:
8645 Unimplemented();
8646 }
8647 %}
8649 ins_pipe( pipe_slow );
8650 %}
8652 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
8653 match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
8654 ins_cost(80);
8655 format %{
8656 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpD_reg_reg\n"
8657 "\tCMOV $dst,$src \t @cmovI_cmpD_reg_reg"
8658 %}
8659 ins_encode %{
8660 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
8661 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
8662 Register dst = as_Register($dst$$reg);
8663 Register src = as_Register($src$$reg);
8665 int flag = $cop$$cmpcode;
8667 switch(flag)
8668 {
8669 case 0x01: //equal
8670 __ c_eq_d(reg_op1, reg_op2);
8671 __ movt(dst, src);
8672 break;
8673 case 0x02: //not_equal
8674 //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.
8675 __ c_eq_d(reg_op1, reg_op2);
8676 __ movf(dst, src);
8677 break;
8678 case 0x03: //greater
8679 __ c_ole_d(reg_op1, reg_op2);
8680 __ movf(dst, src);
8681 break;
8682 case 0x04: //greater_equal
8683 __ c_olt_d(reg_op1, reg_op2);
8684 __ movf(dst, src);
8685 break;
8686 case 0x05: //less
8687 __ c_ult_d(reg_op1, reg_op2);
8688 __ movt(dst, src);
8689 break;
8690 case 0x06: //less_equal
8691 __ c_ule_d(reg_op1, reg_op2);
8692 __ movt(dst, src);
8693 break;
8694 default:
8695 Unimplemented();
8696 }
8697 %}
8699 ins_pipe( pipe_slow );
8700 %}
8703 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
8704 match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
8705 ins_cost(80);
8706 format %{
8707 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
8708 "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
8709 %}
8710 ins_encode %{
8711 Register op1 = $tmp1$$Register;
8712 Register op2 = $tmp2$$Register;
8713 Register dst = $dst$$Register;
8714 Register src = $src$$Register;
8715 int flag = $cop$$cmpcode;
8717 switch(flag)
8718 {
8719 case 0x01: //equal
8720 __ subu(AT, op1, op2);
8721 __ movz(dst, src, AT);
8722 break;
8724 case 0x02: //not_equal
8725 __ subu(AT, op1, op2);
8726 __ movn(dst, src, AT);
8727 break;
8729 case 0x03: //above
8730 __ sltu(AT, op2, op1);
8731 __ movn(dst, src, AT);
8732 break;
8734 case 0x04: //above_equal
8735 __ sltu(AT, op1, op2);
8736 __ movz(dst, src, AT);
8737 break;
8739 case 0x05: //below
8740 __ sltu(AT, op1, op2);
8741 __ movn(dst, src, AT);
8742 break;
8744 case 0x06: //below_equal
8745 __ sltu(AT, op2, op1);
8746 __ movz(dst, src, AT);
8747 break;
8749 default:
8750 Unimplemented();
8751 }
8752 %}
8754 ins_pipe( pipe_slow );
8755 %}
8757 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
8758 match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
8759 ins_cost(80);
8760 format %{
8761 "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
8762 "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
8763 %}
8764 ins_encode %{
8765 Register op1 = $tmp1$$Register;
8766 Register op2 = $tmp2$$Register;
8767 Register dst = $dst$$Register;
8768 Register src = $src$$Register;
8769 int flag = $cop$$cmpcode;
8771 switch(flag)
8772 {
8773 case 0x01: //equal
8774 __ subu32(AT, op1, op2);
8775 __ movz(dst, src, AT);
8776 break;
8778 case 0x02: //not_equal
8779 __ subu32(AT, op1, op2);
8780 __ movn(dst, src, AT);
8781 break;
8783 case 0x03: //above
8784 __ slt(AT, op2, op1);
8785 __ movn(dst, src, AT);
8786 break;
8788 case 0x04: //above_equal
8789 __ slt(AT, op1, op2);
8790 __ movz(dst, src, AT);
8791 break;
8793 case 0x05: //below
8794 __ slt(AT, op1, op2);
8795 __ movn(dst, src, AT);
8796 break;
8798 case 0x06: //below_equal
8799 __ slt(AT, op2, op1);
8800 __ movz(dst, src, AT);
8801 break;
8803 default:
8804 Unimplemented();
8805 }
8806 %}
8808 ins_pipe( pipe_slow );
8809 %}
8811 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
8812 match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
8813 ins_cost(80);
8814 format %{
8815 "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
8816 "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
8817 %}
8818 ins_encode %{
8819 Register op1 = $tmp1$$Register;
8820 Register op2 = $tmp2$$Register;
8821 Register dst = $dst$$Register;
8822 Register src = $src$$Register;
8823 int flag = $cop$$cmpcode;
8825 switch(flag)
8826 {
8827 case 0x01: //equal
8828 __ subu32(AT, op1, op2);
8829 __ movz(dst, src, AT);
8830 break;
8832 case 0x02: //not_equal
8833 __ subu32(AT, op1, op2);
8834 __ movn(dst, src, AT);
8835 break;
8837 case 0x03: //above
8838 __ slt(AT, op2, op1);
8839 __ movn(dst, src, AT);
8840 break;
8842 case 0x04: //above_equal
8843 __ slt(AT, op1, op2);
8844 __ movz(dst, src, AT);
8845 break;
8847 case 0x05: //below
8848 __ slt(AT, op1, op2);
8849 __ movn(dst, src, AT);
8850 break;
8852 case 0x06: //below_equal
8853 __ slt(AT, op2, op1);
8854 __ movz(dst, src, AT);
8855 break;
8857 default:
8858 Unimplemented();
8859 }
8860 %}
8862 ins_pipe( pipe_slow );
8863 %}
8866 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
8867 match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
8868 ins_cost(80);
8869 format %{
8870 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpI_reg_reg\n"
8871 "\tCMOV $dst,$src \t @cmovL_cmpI_reg_reg"
8872 %}
8874 ins_encode %{
8875 Register op1 = $tmp1$$Register;
8876 Register op2 = $tmp2$$Register;
8877 Register dst = as_Register($dst$$reg);
8878 Register src = as_Register($src$$reg);
8879 int flag = $cop$$cmpcode;
8881 switch(flag)
8882 {
8883 case 0x01: //equal
8884 __ subu32(AT, op1, op2);
8885 __ movz(dst, src, AT);
8886 break;
8888 case 0x02: //not_equal
8889 __ subu32(AT, op1, op2);
8890 __ movn(dst, src, AT);
8891 break;
8893 case 0x03: //great
8894 __ slt(AT, op2, op1);
8895 __ movn(dst, src, AT);
8896 break;
8898 case 0x04: //great_equal
8899 __ slt(AT, op1, op2);
8900 __ movz(dst, src, AT);
8901 break;
8903 case 0x05: //less
8904 __ slt(AT, op1, op2);
8905 __ movn(dst, src, AT);
8906 break;
8908 case 0x06: //less_equal
8909 __ slt(AT, op2, op1);
8910 __ movz(dst, src, AT);
8911 break;
8913 default:
8914 Unimplemented();
8915 }
8916 %}
8918 ins_pipe( pipe_slow );
8919 %}
8921 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
8922 match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
8923 ins_cost(80);
8924 format %{
8925 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpL_reg_reg\n"
8926 "\tCMOV $dst,$src \t @cmovL_cmpL_reg_reg"
8927 %}
8928 ins_encode %{
8929 Register opr1 = as_Register($tmp1$$reg);
8930 Register opr2 = as_Register($tmp2$$reg);
8931 Register dst = as_Register($dst$$reg);
8932 Register src = as_Register($src$$reg);
8933 int flag = $cop$$cmpcode;
8935 switch(flag)
8936 {
8937 case 0x01: //equal
8938 __ subu(AT, opr1, opr2);
8939 __ movz(dst, src, AT);
8940 break;
8942 case 0x02: //not_equal
8943 __ subu(AT, opr1, opr2);
8944 __ movn(dst, src, AT);
8945 break;
8947 case 0x03: //greater
8948 __ slt(AT, opr2, opr1);
8949 __ movn(dst, src, AT);
8950 break;
8952 case 0x04: //greater_equal
8953 __ slt(AT, opr1, opr2);
8954 __ movz(dst, src, AT);
8955 break;
8957 case 0x05: //less
8958 __ slt(AT, opr1, opr2);
8959 __ movn(dst, src, AT);
8960 break;
8962 case 0x06: //less_equal
8963 __ slt(AT, opr2, opr1);
8964 __ movz(dst, src, AT);
8965 break;
8967 default:
8968 Unimplemented();
8969 }
8970 %}
8972 ins_pipe( pipe_slow );
8973 %}
8975 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
8976 match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
8977 ins_cost(80);
8978 format %{
8979 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
8980 "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
8981 %}
8982 ins_encode %{
8983 Register op1 = $tmp1$$Register;
8984 Register op2 = $tmp2$$Register;
8985 Register dst = $dst$$Register;
8986 Register src = $src$$Register;
8987 int flag = $cop$$cmpcode;
8989 switch(flag)
8990 {
8991 case 0x01: //equal
8992 __ subu32(AT, op1, op2);
8993 __ movz(dst, src, AT);
8994 break;
8996 case 0x02: //not_equal
8997 __ subu32(AT, op1, op2);
8998 __ movn(dst, src, AT);
8999 break;
9001 case 0x03: //above
9002 __ sltu(AT, op2, op1);
9003 __ movn(dst, src, AT);
9004 break;
9006 case 0x04: //above_equal
9007 __ sltu(AT, op1, op2);
9008 __ movz(dst, src, AT);
9009 break;
9011 case 0x05: //below
9012 __ sltu(AT, op1, op2);
9013 __ movn(dst, src, AT);
9014 break;
9016 case 0x06: //below_equal
9017 __ sltu(AT, op2, op1);
9018 __ movz(dst, src, AT);
9019 break;
9021 default:
9022 Unimplemented();
9023 }
9024 %}
9026 ins_pipe( pipe_slow );
9027 %}
9030 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
9031 match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
9032 ins_cost(80);
9033 format %{
9034 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpD_reg_reg\n"
9035 "\tCMOV $dst,$src \t @cmovL_cmpD_reg_reg"
9036 %}
9037 ins_encode %{
9038 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
9039 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
9040 Register dst = as_Register($dst$$reg);
9041 Register src = as_Register($src$$reg);
9043 int flag = $cop$$cmpcode;
9045 switch(flag)
9046 {
9047 case 0x01: //equal
9048 __ c_eq_d(reg_op1, reg_op2);
9049 __ movt(dst, src);
9050 break;
9051 case 0x02: //not_equal
9052 __ c_eq_d(reg_op1, reg_op2);
9053 __ movf(dst, src);
9054 break;
9055 case 0x03: //greater
9056 __ c_ole_d(reg_op1, reg_op2);
9057 __ movf(dst, src);
9058 break;
9059 case 0x04: //greater_equal
9060 __ c_olt_d(reg_op1, reg_op2);
9061 __ movf(dst, src);
9062 break;
9063 case 0x05: //less
9064 __ c_ult_d(reg_op1, reg_op2);
9065 __ movt(dst, src);
9066 break;
9067 case 0x06: //less_equal
9068 __ c_ule_d(reg_op1, reg_op2);
9069 __ movt(dst, src);
9070 break;
9071 default:
9072 Unimplemented();
9073 }
9074 %}
9076 ins_pipe( pipe_slow );
9077 %}
9079 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
9080 match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
9081 ins_cost(200);
9082 format %{
9083 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpD_reg_reg\n"
9084 "\tCMOV $dst,$src \t @cmovD_cmpD_reg_reg"
9085 %}
9086 ins_encode %{
9087 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
9088 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
9089 FloatRegister dst = as_FloatRegister($dst$$reg);
9090 FloatRegister src = as_FloatRegister($src$$reg);
9092 int flag = $cop$$cmpcode;
9094 Label L;
9096 switch(flag)
9097 {
9098 case 0x01: //equal
9099 __ c_eq_d(reg_op1, reg_op2);
9100 __ bc1f(L);
9101 __ nop();
9102 __ mov_d(dst, src);
9103 __ bind(L);
9104 break;
9105 case 0x02: //not_equal
9106 //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.
9107 __ c_eq_d(reg_op1, reg_op2);
9108 __ bc1t(L);
9109 __ nop();
9110 __ mov_d(dst, src);
9111 __ bind(L);
9112 break;
9113 case 0x03: //greater
9114 __ c_ole_d(reg_op1, reg_op2);
9115 __ bc1t(L);
9116 __ nop();
9117 __ mov_d(dst, src);
9118 __ bind(L);
9119 break;
9120 case 0x04: //greater_equal
9121 __ c_olt_d(reg_op1, reg_op2);
9122 __ bc1t(L);
9123 __ nop();
9124 __ mov_d(dst, src);
9125 __ bind(L);
9126 break;
9127 case 0x05: //less
9128 __ c_ult_d(reg_op1, reg_op2);
9129 __ bc1f(L);
9130 __ nop();
9131 __ mov_d(dst, src);
9132 __ bind(L);
9133 break;
9134 case 0x06: //less_equal
9135 __ c_ule_d(reg_op1, reg_op2);
9136 __ bc1f(L);
9137 __ nop();
9138 __ mov_d(dst, src);
9139 __ bind(L);
9140 break;
9141 default:
9142 Unimplemented();
9143 }
9144 %}
9146 ins_pipe( pipe_slow );
9147 %}
9149 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9150 match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9151 ins_cost(200);
9152 format %{
9153 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpI_reg_reg\n"
9154 "\tCMOV $dst, $src \t @cmovF_cmpI_reg_reg"
9155 %}
9157 ins_encode %{
9158 Register op1 = $tmp1$$Register;
9159 Register op2 = $tmp2$$Register;
9160 FloatRegister dst = as_FloatRegister($dst$$reg);
9161 FloatRegister src = as_FloatRegister($src$$reg);
9162 int flag = $cop$$cmpcode;
9163 Label L;
9165 switch(flag)
9166 {
9167 case 0x01: //equal
9168 __ bne(op1, op2, L);
9169 __ nop();
9170 __ mov_s(dst, src);
9171 __ bind(L);
9172 break;
9173 case 0x02: //not_equal
9174 __ beq(op1, op2, L);
9175 __ nop();
9176 __ mov_s(dst, src);
9177 __ bind(L);
9178 break;
9179 case 0x03: //great
9180 __ slt(AT, op2, op1);
9181 __ beq(AT, R0, L);
9182 __ nop();
9183 __ mov_s(dst, src);
9184 __ bind(L);
9185 break;
9186 case 0x04: //great_equal
9187 __ slt(AT, op1, op2);
9188 __ bne(AT, R0, L);
9189 __ nop();
9190 __ mov_s(dst, src);
9191 __ bind(L);
9192 break;
9193 case 0x05: //less
9194 __ slt(AT, op1, op2);
9195 __ beq(AT, R0, L);
9196 __ nop();
9197 __ mov_s(dst, src);
9198 __ bind(L);
9199 break;
9200 case 0x06: //less_equal
9201 __ slt(AT, op2, op1);
9202 __ bne(AT, R0, L);
9203 __ nop();
9204 __ mov_s(dst, src);
9205 __ bind(L);
9206 break;
9207 default:
9208 Unimplemented();
9209 }
9210 %}
9212 ins_pipe( pipe_slow );
9213 %}
9215 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9216 match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9217 ins_cost(200);
9218 format %{
9219 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpI_reg_reg\n"
9220 "\tCMOV $dst, $src \t @cmovD_cmpI_reg_reg"
9221 %}
9223 ins_encode %{
9224 Register op1 = $tmp1$$Register;
9225 Register op2 = $tmp2$$Register;
9226 FloatRegister dst = as_FloatRegister($dst$$reg);
9227 FloatRegister src = as_FloatRegister($src$$reg);
9228 int flag = $cop$$cmpcode;
9229 Label L;
9231 switch(flag)
9232 {
9233 case 0x01: //equal
9234 __ bne(op1, op2, L);
9235 __ nop();
9236 __ mov_d(dst, src);
9237 __ bind(L);
9238 break;
9239 case 0x02: //not_equal
9240 __ beq(op1, op2, L);
9241 __ nop();
9242 __ mov_d(dst, src);
9243 __ bind(L);
9244 break;
9245 case 0x03: //great
9246 __ slt(AT, op2, op1);
9247 __ beq(AT, R0, L);
9248 __ nop();
9249 __ mov_d(dst, src);
9250 __ bind(L);
9251 break;
9252 case 0x04: //great_equal
9253 __ slt(AT, op1, op2);
9254 __ bne(AT, R0, L);
9255 __ nop();
9256 __ mov_d(dst, src);
9257 __ bind(L);
9258 break;
9259 case 0x05: //less
9260 __ slt(AT, op1, op2);
9261 __ beq(AT, R0, L);
9262 __ nop();
9263 __ mov_d(dst, src);
9264 __ bind(L);
9265 break;
9266 case 0x06: //less_equal
9267 __ slt(AT, op2, op1);
9268 __ bne(AT, R0, L);
9269 __ nop();
9270 __ mov_d(dst, src);
9271 __ bind(L);
9272 break;
9273 default:
9274 Unimplemented();
9275 }
9276 %}
9278 ins_pipe( pipe_slow );
9279 %}
9281 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
9282 match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9283 ins_cost(200);
9284 format %{
9285 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpP_reg_reg\n"
9286 "\tCMOV $dst, $src \t @cmovD_cmpP_reg_reg"
9287 %}
9289 ins_encode %{
9290 Register op1 = $tmp1$$Register;
9291 Register op2 = $tmp2$$Register;
9292 FloatRegister dst = as_FloatRegister($dst$$reg);
9293 FloatRegister src = as_FloatRegister($src$$reg);
9294 int flag = $cop$$cmpcode;
9295 Label L;
9297 switch(flag)
9298 {
9299 case 0x01: //equal
9300 __ bne(op1, op2, L);
9301 __ nop();
9302 __ mov_d(dst, src);
9303 __ bind(L);
9304 break;
9305 case 0x02: //not_equal
9306 __ beq(op1, op2, L);
9307 __ nop();
9308 __ mov_d(dst, src);
9309 __ bind(L);
9310 break;
9311 case 0x03: //great
9312 __ slt(AT, op2, op1);
9313 __ beq(AT, R0, L);
9314 __ nop();
9315 __ mov_d(dst, src);
9316 __ bind(L);
9317 break;
9318 case 0x04: //great_equal
9319 __ slt(AT, op1, op2);
9320 __ bne(AT, R0, L);
9321 __ nop();
9322 __ mov_d(dst, src);
9323 __ bind(L);
9324 break;
9325 case 0x05: //less
9326 __ slt(AT, op1, op2);
9327 __ beq(AT, R0, L);
9328 __ nop();
9329 __ mov_d(dst, src);
9330 __ bind(L);
9331 break;
9332 case 0x06: //less_equal
9333 __ slt(AT, op2, op1);
9334 __ bne(AT, R0, L);
9335 __ nop();
9336 __ mov_d(dst, src);
9337 __ bind(L);
9338 break;
9339 default:
9340 Unimplemented();
9341 }
9342 %}
9344 ins_pipe( pipe_slow );
9345 %}
9347 //FIXME
9348 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
9349 match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
9350 ins_cost(80);
9351 format %{
9352 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpF_reg_reg\n"
9353 "\tCMOV $dst,$src \t @cmovI_cmpF_reg_reg"
9354 %}
9356 ins_encode %{
9357 FloatRegister reg_op1 = $tmp1$$FloatRegister;
9358 FloatRegister reg_op2 = $tmp2$$FloatRegister;
9359 Register dst = $dst$$Register;
9360 Register src = $src$$Register;
9361 int flag = $cop$$cmpcode;
9363 switch(flag)
9364 {
9365 case 0x01: //equal
9366 __ c_eq_s(reg_op1, reg_op2);
9367 __ movt(dst, src);
9368 break;
9369 case 0x02: //not_equal
9370 __ c_eq_s(reg_op1, reg_op2);
9371 __ movf(dst, src);
9372 break;
9373 case 0x03: //greater
9374 __ c_ole_s(reg_op1, reg_op2);
9375 __ movf(dst, src);
9376 break;
9377 case 0x04: //greater_equal
9378 __ c_olt_s(reg_op1, reg_op2);
9379 __ movf(dst, src);
9380 break;
9381 case 0x05: //less
9382 __ c_ult_s(reg_op1, reg_op2);
9383 __ movt(dst, src);
9384 break;
9385 case 0x06: //less_equal
9386 __ c_ule_s(reg_op1, reg_op2);
9387 __ movt(dst, src);
9388 break;
9389 default:
9390 Unimplemented();
9391 }
9392 %}
9393 ins_pipe( pipe_slow );
9394 %}
9396 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
9397 match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
9398 ins_cost(200);
9399 format %{
9400 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpF_reg_reg\n"
9401 "\tCMOV $dst,$src \t @cmovF_cmpF_reg_reg"
9402 %}
9404 ins_encode %{
9405 FloatRegister reg_op1 = $tmp1$$FloatRegister;
9406 FloatRegister reg_op2 = $tmp2$$FloatRegister;
9407 FloatRegister dst = $dst$$FloatRegister;
9408 FloatRegister src = $src$$FloatRegister;
9409 Label L;
9410 int flag = $cop$$cmpcode;
9412 switch(flag)
9413 {
9414 case 0x01: //equal
9415 __ c_eq_s(reg_op1, reg_op2);
9416 __ bc1f(L);
9417 __ nop();
9418 __ mov_s(dst, src);
9419 __ bind(L);
9420 break;
9421 case 0x02: //not_equal
9422 __ c_eq_s(reg_op1, reg_op2);
9423 __ bc1t(L);
9424 __ nop();
9425 __ mov_s(dst, src);
9426 __ bind(L);
9427 break;
9428 case 0x03: //greater
9429 __ c_ole_s(reg_op1, reg_op2);
9430 __ bc1t(L);
9431 __ nop();
9432 __ mov_s(dst, src);
9433 __ bind(L);
9434 break;
9435 case 0x04: //greater_equal
9436 __ c_olt_s(reg_op1, reg_op2);
9437 __ bc1t(L);
9438 __ nop();
9439 __ mov_s(dst, src);
9440 __ bind(L);
9441 break;
9442 case 0x05: //less
9443 __ c_ult_s(reg_op1, reg_op2);
9444 __ bc1f(L);
9445 __ nop();
9446 __ mov_s(dst, src);
9447 __ bind(L);
9448 break;
9449 case 0x06: //less_equal
9450 __ c_ule_s(reg_op1, reg_op2);
9451 __ bc1f(L);
9452 __ nop();
9453 __ mov_s(dst, src);
9454 __ bind(L);
9455 break;
9456 default:
9457 Unimplemented();
9458 }
9459 %}
9460 ins_pipe( pipe_slow );
9461 %}
9463 // Manifest a CmpL result in an integer register. Very painful.
9464 // This is the test to avoid.
9465 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
9466 match(Set dst (CmpL3 src1 src2));
9467 ins_cost(1000);
9468 format %{ "cmpL3 $dst, $src1, $src2 @ cmpL3_reg_reg" %}
9469 ins_encode %{
9470 Register opr1 = as_Register($src1$$reg);
9471 Register opr2 = as_Register($src2$$reg);
9472 Register dst = as_Register($dst$$reg);
9474 Label p_one, done;
9476 __ subu(dst, opr1, opr2);
9478 __ beq(dst, R0, done);
9479 __ nop();
9481 __ bgtz(dst, done);
9482 __ delayed()->addiu32(dst, R0, 1);
9484 __ addiu32(dst, R0, -1);
9486 __ bind(done);
9487 %}
9488 ins_pipe( pipe_slow );
9489 %}
9491 //
9492 // less_rsult = -1
9493 // greater_result = 1
9494 // equal_result = 0
9495 // nan_result = -1
9496 //
9497 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
9498 match(Set dst (CmpF3 src1 src2));
9499 ins_cost(1000);
9500 format %{ "cmpF3 $dst, $src1, $src2 @ cmpF3_reg_reg" %}
9501 ins_encode %{
9502 FloatRegister src1 = as_FloatRegister($src1$$reg);
9503 FloatRegister src2 = as_FloatRegister($src2$$reg);
9504 Register dst = as_Register($dst$$reg);
9506 Label EQU, LESS, DONE;
9508 __ move(dst, 1);
9509 __ c_eq_s(src1, src2);
9510 __ bc1t(EQU);
9511 __ nop();
9512 __ c_ult_s(src1, src2);
9513 __ bc1t(LESS);
9514 __ nop();
9515 __ beq(R0, R0, DONE);
9516 __ nop();
9517 __ bind(EQU);
9518 __ move(dst, 0);
9519 __ beq(R0, R0, DONE);
9520 __ nop();
9521 __ bind(LESS);
9522 __ move(dst, -1);
9523 __ bind(DONE);
9524 %}
9525 ins_pipe( pipe_slow );
9526 %}
9528 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
9529 match(Set dst (CmpD3 src1 src2));
9530 ins_cost(1000);
9531 format %{ "cmpD3 $dst, $src1, $src2 @ cmpD3_reg_reg" %}
9532 ins_encode %{
9533 FloatRegister src1 = as_FloatRegister($src1$$reg);
9534 FloatRegister src2 = as_FloatRegister($src2$$reg);
9535 Register dst = as_Register($dst$$reg);
9537 Label EQU, LESS, DONE;
9539 __ move(dst, 1);
9540 __ c_eq_d(src1, src2);
9541 __ bc1t(EQU);
9542 __ nop();
9543 __ c_ult_d(src1, src2);
9544 __ bc1t(LESS);
9545 __ nop();
9546 __ beq(R0, R0, DONE);
9547 __ nop();
9548 __ bind(EQU);
9549 __ move(dst, 0);
9550 __ beq(R0, R0, DONE);
9551 __ nop();
9552 __ bind(LESS);
9553 __ move(dst, -1);
9554 __ bind(DONE);
9555 %}
9556 ins_pipe( pipe_slow );
9557 %}
9559 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
9560 match(Set dummy (ClearArray cnt base));
9561 format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
9562 ins_encode %{
9563 //Assume cnt is the number of bytes in an array to be cleared,
9564 //and base points to the starting address of the array.
9565 Register base = $base$$Register;
9566 Register num = $cnt$$Register;
9567 Label Loop, done;
9569 /* 2012/9/21 Jin: according to X86, $cnt is caculated by doublewords(8 bytes) */
9570 __ move(T9, num); /* T9 = words */
9571 __ beq(T9, R0, done);
9572 __ nop();
9573 __ move(AT, base);
9575 __ bind(Loop);
9576 __ sd(R0, Address(AT, 0));
9577 __ daddi(AT, AT, wordSize);
9578 __ daddi(T9, T9, -1);
9579 __ bne(T9, R0, Loop);
9580 __ delayed()->nop();
9581 __ bind(done);
9582 %}
9583 ins_pipe( pipe_slow );
9584 %}
9586 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2, mA7RegI cnt2, no_Ax_mRegI result) %{
9587 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
9588 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
9590 format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
9591 ins_encode %{
9592 // Get the first character position in both strings
9593 // [8] char array, [12] offset, [16] count
9594 Register str1 = $str1$$Register;
9595 Register str2 = $str2$$Register;
9596 Register cnt1 = $cnt1$$Register;
9597 Register cnt2 = $cnt2$$Register;
9598 Register result = $result$$Register;
9600 Label L, Loop, haveResult, done;
9602 // compute the and difference of lengths (in result)
9603 __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
9605 // compute the shorter length (in cnt1)
9606 __ slt(AT, cnt2, cnt1);
9607 __ movn(cnt1, cnt2, AT);
9609 // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
9610 __ bind(Loop); // Loop begin
9611 __ beq(cnt1, R0, done);
9612 __ delayed()->lhu(AT, str1, 0);;
9614 // compare current character
9615 __ lhu(cnt2, str2, 0);
9616 __ bne(AT, cnt2, haveResult);
9617 __ delayed()->addi(str1, str1, 2);
9618 __ addi(str2, str2, 2);
9619 __ b(Loop);
9620 __ delayed()->addi(cnt1, cnt1, -1); // Loop end
9622 __ bind(haveResult);
9623 __ subu(result, AT, cnt2);
9625 __ bind(done);
9626 %}
9628 ins_pipe( pipe_slow );
9629 %}
9631 // intrinsic optimization
9632 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
9633 match(Set result (StrEquals (Binary str1 str2) cnt));
9634 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
9636 format %{ "String Equal $str1, $str2, len:$cnt tmp:$temp -> $result @ string_equals" %}
9637 ins_encode %{
9638 // Get the first character position in both strings
9639 // [8] char array, [12] offset, [16] count
9640 Register str1 = $str1$$Register;
9641 Register str2 = $str2$$Register;
9642 Register cnt = $cnt$$Register;
9643 Register tmp = $temp$$Register;
9644 Register result = $result$$Register;
9646 Label Loop, done;
9649 __ beq(str1, str2, done); // same char[] ?
9650 __ daddiu(result, R0, 1);
9652 __ bind(Loop); // Loop begin
9653 __ beq(cnt, R0, done);
9654 __ daddiu(result, R0, 1); // count == 0
9656 // compare current character
9657 __ lhu(AT, str1, 0);;
9658 __ lhu(tmp, str2, 0);
9659 __ bne(AT, tmp, done);
9660 __ delayed()->daddi(result, R0, 0);
9661 __ addi(str1, str1, 2);
9662 __ addi(str2, str2, 2);
9663 __ b(Loop);
9664 __ delayed()->addi(cnt, cnt, -1); // Loop end
9666 __ bind(done);
9667 %}
9669 ins_pipe( pipe_slow );
9670 %}
9672 //----------Arithmetic Instructions-------------------------------------------
9673 //----------Addition Instructions---------------------------------------------
9674 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9675 match(Set dst (AddI src1 src2));
9677 format %{ "add $dst, $src1, $src2 #@addI_Reg_Reg" %}
9678 ins_encode %{
9679 Register dst = $dst$$Register;
9680 Register src1 = $src1$$Register;
9681 Register src2 = $src2$$Register;
9682 __ addu32(dst, src1, src2);
9683 %}
9684 ins_pipe( ialu_regI_regI );
9685 %}
9687 instruct addI_Reg_imm(mRegI dst, mRegI src1, immI src2) %{
9688 match(Set dst (AddI src1 src2));
9690 format %{ "add $dst, $src1, $src2 #@addI_Reg_imm" %}
9691 ins_encode %{
9692 Register dst = $dst$$Register;
9693 Register src1 = $src1$$Register;
9694 int imm = $src2$$constant;
9696 if(Assembler::is_simm16(imm)) {
9697 __ addiu32(dst, src1, imm);
9698 } else {
9699 __ move(AT, imm);
9700 __ addu32(dst, src1, AT);
9701 }
9702 %}
9703 ins_pipe( ialu_regI_regI );
9704 %}
9706 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
9707 match(Set dst (AddP src1 src2));
9709 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg" %}
9711 ins_encode %{
9712 Register dst = $dst$$Register;
9713 Register src1 = $src1$$Register;
9714 Register src2 = $src2$$Register;
9715 __ daddu(dst, src1, src2);
9716 %}
9718 ins_pipe( ialu_regI_regI );
9719 %}
9721 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
9722 match(Set dst (AddP src1 (ConvI2L src2)));
9724 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
9726 ins_encode %{
9727 Register dst = $dst$$Register;
9728 Register src1 = $src1$$Register;
9729 Register src2 = $src2$$Register;
9730 __ daddu(dst, src1, src2);
9731 %}
9733 ins_pipe( ialu_regI_regI );
9734 %}
9736 instruct addP_reg_imm(mRegP dst, mRegP src1, immL32 src2) %{
9737 match(Set dst (AddP src1 src2));
9738 // effect(KILL cr);
9740 format %{ "daddi $dst, $src1, $src2 #@addP_reg_imm" %}
9741 ins_encode %{
9742 Register src1 = $src1$$Register;
9743 long src2 = $src2$$constant;
9744 Register dst = $dst$$Register;
9746 if(Assembler::is_simm16(src2)) {
9747 __ daddiu(dst, src1, src2);
9748 } else {
9749 __ li(AT, src2);
9750 __ daddu(dst, src1, AT);
9751 }
9752 %}
9753 ins_pipe( ialu_regI_imm16 );
9754 %}
9756 // Add Long Register with Register
9757 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
9758 match(Set dst (AddL src1 src2));
9759 ins_cost(200);
9760 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
9762 ins_encode %{
9763 Register dst_reg = as_Register($dst$$reg);
9764 Register src1_reg = as_Register($src1$$reg);
9765 Register src2_reg = as_Register($src2$$reg);
9767 __ daddu(dst_reg, src1_reg, src2_reg);
9768 %}
9770 ins_pipe( ialu_regL_regL );
9771 %}
9773 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
9774 %{
9775 match(Set dst (AddL src1 src2));
9777 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_imm " %}
9778 ins_encode %{
9779 Register dst_reg = as_Register($dst$$reg);
9780 Register src1_reg = as_Register($src1$$reg);
9781 int src2_imm = $src2$$constant;
9783 __ daddiu(dst_reg, src1_reg, src2_imm);
9784 %}
9786 ins_pipe( ialu_regL_regL );
9787 %}
9789 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
9790 %{
9791 match(Set dst (AddL (ConvI2L src1) src2));
9793 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_imm " %}
9794 ins_encode %{
9795 Register dst_reg = as_Register($dst$$reg);
9796 Register src1_reg = as_Register($src1$$reg);
9797 int src2_imm = $src2$$constant;
9799 __ daddiu(dst_reg, src1_reg, src2_imm);
9800 %}
9802 ins_pipe( ialu_regL_regL );
9803 %}
9805 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
9806 match(Set dst (AddL (ConvI2L src1) src2));
9807 ins_cost(200);
9808 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
9810 ins_encode %{
9811 Register dst_reg = as_Register($dst$$reg);
9812 Register src1_reg = as_Register($src1$$reg);
9813 Register src2_reg = as_Register($src2$$reg);
9815 __ daddu(dst_reg, src1_reg, src2_reg);
9816 %}
9818 ins_pipe( ialu_regL_regL );
9819 %}
9821 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
9822 match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
9823 ins_cost(200);
9824 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
9826 ins_encode %{
9827 Register dst_reg = as_Register($dst$$reg);
9828 Register src1_reg = as_Register($src1$$reg);
9829 Register src2_reg = as_Register($src2$$reg);
9831 __ daddu(dst_reg, src1_reg, src2_reg);
9832 %}
9834 ins_pipe( ialu_regL_regL );
9835 %}
9837 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
9838 match(Set dst (AddL src1 (ConvI2L src2)));
9839 ins_cost(200);
9840 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
9842 ins_encode %{
9843 Register dst_reg = as_Register($dst$$reg);
9844 Register src1_reg = as_Register($src1$$reg);
9845 Register src2_reg = as_Register($src2$$reg);
9847 __ daddu(dst_reg, src1_reg, src2_reg);
9848 %}
9850 ins_pipe( ialu_regL_regL );
9851 %}
9853 //----------Subtraction Instructions-------------------------------------------
9854 // Integer Subtraction Instructions
9855 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9856 match(Set dst (SubI src1 src2));
9857 ins_cost(100);
9859 format %{ "sub $dst, $src1, $src2 #@subI_Reg_Reg" %}
9860 ins_encode %{
9861 Register dst = $dst$$Register;
9862 Register src1 = $src1$$Register;
9863 Register src2 = $src2$$Register;
9864 __ subu32(dst, src1, src2);
9865 %}
9866 ins_pipe( ialu_regI_regI );
9867 %}
9869 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1, immI16_sub src2) %{
9870 match(Set dst (SubI src1 src2));
9871 ins_cost(80);
9873 format %{ "sub $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
9874 ins_encode %{
9875 Register dst = $dst$$Register;
9876 Register src1 = $src1$$Register;
9877 __ addiu32(dst, src1, -1 * $src2$$constant);
9878 %}
9879 ins_pipe( ialu_regI_regI );
9880 %}
9882 instruct negI_Reg(mRegI dst, immI0 zero, mRegI src) %{
9883 match(Set dst (SubI zero src));
9884 ins_cost(80);
9886 format %{ "neg $dst, $src #@negI_Reg" %}
9887 ins_encode %{
9888 Register dst = $dst$$Register;
9889 Register src = $src$$Register;
9890 __ subu32(dst, R0, src);
9891 %}
9892 ins_pipe( ialu_regI_regI );
9893 %}
9895 instruct negL_Reg(mRegL dst, immL0 zero, mRegL src) %{
9896 match(Set dst (SubL zero src));
9897 ins_cost(80);
9899 format %{ "neg $dst, $src #@negL_Reg" %}
9900 ins_encode %{
9901 Register dst = $dst$$Register;
9902 Register src = $src$$Register;
9903 __ subu(dst, R0, src);
9904 %}
9905 ins_pipe( ialu_regI_regI );
9906 %}
9908 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1, immL16_sub src2) %{
9909 match(Set dst (SubL src1 src2));
9910 ins_cost(80);
9912 format %{ "sub $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
9913 ins_encode %{
9914 Register dst = $dst$$Register;
9915 Register src1 = $src1$$Register;
9916 __ daddiu(dst, src1, -1 * $src2$$constant);
9917 %}
9918 ins_pipe( ialu_regI_regI );
9919 %}
9921 // Subtract Long Register with Register.
9922 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
9923 match(Set dst (SubL src1 src2));
9924 ins_cost(100);
9925 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_Reg" %}
9926 ins_encode %{
9927 Register dst = as_Register($dst$$reg);
9928 Register src1 = as_Register($src1$$reg);
9929 Register src2 = as_Register($src2$$reg);
9931 __ subu(dst, src1, src2);
9932 %}
9933 ins_pipe( ialu_regL_regL );
9934 %}
9936 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
9937 match(Set dst (SubL src1 (ConvI2L src2)));
9938 ins_cost(100);
9939 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
9940 ins_encode %{
9941 Register dst = as_Register($dst$$reg);
9942 Register src1 = as_Register($src1$$reg);
9943 Register src2 = as_Register($src2$$reg);
9945 __ subu(dst, src1, src2);
9946 %}
9947 ins_pipe( ialu_regL_regL );
9948 %}
9950 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
9951 match(Set dst (SubL (ConvI2L src1) src2));
9952 ins_cost(200);
9953 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
9954 ins_encode %{
9955 Register dst = as_Register($dst$$reg);
9956 Register src1 = as_Register($src1$$reg);
9957 Register src2 = as_Register($src2$$reg);
9959 __ subu(dst, src1, src2);
9960 %}
9961 ins_pipe( ialu_regL_regL );
9962 %}
9964 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
9965 match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
9966 ins_cost(200);
9967 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
9968 ins_encode %{
9969 Register dst = as_Register($dst$$reg);
9970 Register src1 = as_Register($src1$$reg);
9971 Register src2 = as_Register($src2$$reg);
9973 __ subu(dst, src1, src2);
9974 %}
9975 ins_pipe( ialu_regL_regL );
9976 %}
9978 // Integer MOD with Register
9979 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9980 match(Set dst (ModI src1 src2));
9981 ins_cost(300);
9982 format %{ "modi $dst, $src1, $src2 @ modI_Reg_Reg" %}
9983 ins_encode %{
9984 Register dst = $dst$$Register;
9985 Register src1 = $src1$$Register;
9986 Register src2 = $src2$$Register;
9988 //if (UseLoongsonISA) {
9989 if (0) {
9990 // 2016.08.10
9991 // Experiments show that gsmod is slower that div+mfhi.
9992 // So I just disable it here.
9993 __ gsmod(dst, src1, src2);
9994 } else {
9995 __ div(src1, src2);
9996 __ mfhi(dst);
9997 }
9998 %}
10000 //ins_pipe( ialu_mod );
10001 ins_pipe( ialu_regI_regI );
10002 %}
10004 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
10005 match(Set dst (ModL src1 src2));
10006 format %{ "modL $dst, $src1, $src2 @modL_reg_reg" %}
10008 ins_encode %{
10009 Register dst = as_Register($dst$$reg);
10010 Register op1 = as_Register($src1$$reg);
10011 Register op2 = as_Register($src2$$reg);
10013 if (UseLoongsonISA) {
10014 __ gsdmod(dst, op1, op2);
10015 } else {
10016 __ ddiv(op1, op2);
10017 __ mfhi(dst);
10018 }
10019 %}
10020 ins_pipe( pipe_slow );
10021 %}
10023 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10024 match(Set dst (MulI src1 src2));
10026 ins_cost(300);
10027 format %{ "mul $dst, $src1, $src2 @ mulI_Reg_Reg" %}
10028 ins_encode %{
10029 Register src1 = $src1$$Register;
10030 Register src2 = $src2$$Register;
10031 Register dst = $dst$$Register;
10033 __ mul(dst, src1, src2);
10034 %}
10035 ins_pipe( ialu_mult );
10036 %}
10038 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
10039 match(Set dst (AddI (MulI src1 src2) src3));
10041 ins_cost(999);
10042 format %{ "madd $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
10043 ins_encode %{
10044 Register src1 = $src1$$Register;
10045 Register src2 = $src2$$Register;
10046 Register src3 = $src3$$Register;
10047 Register dst = $dst$$Register;
10049 __ mtlo(src3);
10050 __ madd(src1, src2);
10051 __ mflo(dst);
10052 %}
10053 ins_pipe( ialu_mult );
10054 %}
10056 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10057 match(Set dst (DivI src1 src2));
10059 ins_cost(300);
10060 format %{ "div $dst, $src1, $src2 @ divI_Reg_Reg" %}
10061 ins_encode %{
10062 Register src1 = $src1$$Register;
10063 Register src2 = $src2$$Register;
10064 Register dst = $dst$$Register;
10066 /* 2012/4/21 Jin: In MIPS, div does not cause exception.
10067 We must trap an exception manually. */
10068 __ teq(R0, src2, 0x7);
10070 if (UseLoongsonISA) {
10071 __ gsdiv(dst, src1, src2);
10072 } else {
10073 __ div(src1, src2);
10075 __ nop();
10076 __ nop();
10077 __ mflo(dst);
10078 }
10079 %}
10080 ins_pipe( ialu_mod );
10081 %}
10083 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
10084 match(Set dst (DivF src1 src2));
10086 ins_cost(300);
10087 format %{ "divF $dst, $src1, $src2 @ divF_Reg_Reg" %}
10088 ins_encode %{
10089 FloatRegister src1 = $src1$$FloatRegister;
10090 FloatRegister src2 = $src2$$FloatRegister;
10091 FloatRegister dst = $dst$$FloatRegister;
10093 /* Here do we need to trap an exception manually ? */
10094 __ div_s(dst, src1, src2);
10095 %}
10096 ins_pipe( pipe_slow );
10097 %}
10099 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
10100 match(Set dst (DivD src1 src2));
10102 ins_cost(300);
10103 format %{ "divD $dst, $src1, $src2 @ divD_Reg_Reg" %}
10104 ins_encode %{
10105 FloatRegister src1 = $src1$$FloatRegister;
10106 FloatRegister src2 = $src2$$FloatRegister;
10107 FloatRegister dst = $dst$$FloatRegister;
10109 /* Here do we need to trap an exception manually ? */
10110 __ div_d(dst, src1, src2);
10111 %}
10112 ins_pipe( pipe_slow );
10113 %}
10115 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
10116 match(Set dst (MulL src1 src2));
10117 format %{ "mulL $dst, $src1, $src2 @mulL_reg_reg" %}
10118 ins_encode %{
10119 Register dst = as_Register($dst$$reg);
10120 Register op1 = as_Register($src1$$reg);
10121 Register op2 = as_Register($src2$$reg);
10123 if (UseLoongsonISA) {
10124 __ gsdmult(dst, op1, op2);
10125 } else {
10126 __ dmult(op1, op2);
10127 __ mflo(dst);
10128 }
10129 %}
10130 ins_pipe( pipe_slow );
10131 %}
10133 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
10134 match(Set dst (DivL src1 src2));
10135 format %{ "divL $dst, $src1, $src2 @divL_reg_reg" %}
10137 ins_encode %{
10138 Register dst = as_Register($dst$$reg);
10139 Register op1 = as_Register($src1$$reg);
10140 Register op2 = as_Register($src2$$reg);
10142 if (UseLoongsonISA) {
10143 __ gsddiv(dst, op1, op2);
10144 } else {
10145 __ ddiv(op1, op2);
10146 __ mflo(dst);
10147 }
10148 %}
10149 ins_pipe( pipe_slow );
10150 %}
10152 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
10153 match(Set dst (AddF src1 src2));
10154 format %{ "AddF $dst, $src1, $src2 @addF_reg_reg" %}
10155 ins_encode %{
10156 FloatRegister src1 = as_FloatRegister($src1$$reg);
10157 FloatRegister src2 = as_FloatRegister($src2$$reg);
10158 FloatRegister dst = as_FloatRegister($dst$$reg);
10160 __ add_s(dst, src1, src2);
10161 %}
10162 ins_pipe( fpu_regF_regF );
10163 %}
10165 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
10166 match(Set dst (SubF src1 src2));
10167 format %{ "SubF $dst, $src1, $src2 @subF_reg_reg" %}
10168 ins_encode %{
10169 FloatRegister src1 = as_FloatRegister($src1$$reg);
10170 FloatRegister src2 = as_FloatRegister($src2$$reg);
10171 FloatRegister dst = as_FloatRegister($dst$$reg);
10173 __ sub_s(dst, src1, src2);
10174 %}
10175 ins_pipe( fpu_regF_regF );
10176 %}
10177 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
10178 match(Set dst (AddD src1 src2));
10179 format %{ "AddD $dst, $src1, $src2 @addD_reg_reg" %}
10180 ins_encode %{
10181 FloatRegister src1 = as_FloatRegister($src1$$reg);
10182 FloatRegister src2 = as_FloatRegister($src2$$reg);
10183 FloatRegister dst = as_FloatRegister($dst$$reg);
10185 __ add_d(dst, src1, src2);
10186 %}
10187 ins_pipe( fpu_regF_regF );
10188 %}
10190 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
10191 match(Set dst (SubD src1 src2));
10192 format %{ "SubD $dst, $src1, $src2 @subD_reg_reg" %}
10193 ins_encode %{
10194 FloatRegister src1 = as_FloatRegister($src1$$reg);
10195 FloatRegister src2 = as_FloatRegister($src2$$reg);
10196 FloatRegister dst = as_FloatRegister($dst$$reg);
10198 __ sub_d(dst, src1, src2);
10199 %}
10200 ins_pipe( fpu_regF_regF );
10201 %}
10203 instruct negF_reg(regF dst, regF src) %{
10204 match(Set dst (NegF src));
10205 format %{ "negF $dst, $src @negF_reg" %}
10206 ins_encode %{
10207 FloatRegister src = as_FloatRegister($src$$reg);
10208 FloatRegister dst = as_FloatRegister($dst$$reg);
10210 __ neg_s(dst, src);
10211 %}
10212 ins_pipe( fpu_regF_regF );
10213 %}
10215 instruct negD_reg(regD dst, regD src) %{
10216 match(Set dst (NegD src));
10217 format %{ "negD $dst, $src @negD_reg" %}
10218 ins_encode %{
10219 FloatRegister src = as_FloatRegister($src$$reg);
10220 FloatRegister dst = as_FloatRegister($dst$$reg);
10222 __ neg_d(dst, src);
10223 %}
10224 ins_pipe( fpu_regF_regF );
10225 %}
10228 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
10229 match(Set dst (MulF src1 src2));
10230 format %{ "MULF $dst, $src1, $src2 @mulF_reg_reg" %}
10231 ins_encode %{
10232 FloatRegister src1 = $src1$$FloatRegister;
10233 FloatRegister src2 = $src2$$FloatRegister;
10234 FloatRegister dst = $dst$$FloatRegister;
10236 __ mul_s(dst, src1, src2);
10237 %}
10238 ins_pipe( fpu_regF_regF );
10239 %}
10241 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
10242 match(Set dst (AddF (MulF src1 src2) src3));
10243 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
10244 ins_cost(44444);
10245 format %{ "maddF $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
10246 ins_encode %{
10247 FloatRegister src1 = $src1$$FloatRegister;
10248 FloatRegister src2 = $src2$$FloatRegister;
10249 FloatRegister src3 = $src3$$FloatRegister;
10250 FloatRegister dst = $dst$$FloatRegister;
10252 __ madd_s(dst, src1, src2, src3);
10253 %}
10254 ins_pipe( fpu_regF_regF );
10255 %}
10257 // Mul two double precision floating piont number
10258 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
10259 match(Set dst (MulD src1 src2));
10260 format %{ "MULD $dst, $src1, $src2 @mulD_reg_reg" %}
10261 ins_encode %{
10262 FloatRegister src1 = $src1$$FloatRegister;
10263 FloatRegister src2 = $src2$$FloatRegister;
10264 FloatRegister dst = $dst$$FloatRegister;
10266 __ mul_d(dst, src1, src2);
10267 %}
10268 ins_pipe( fpu_regF_regF );
10269 %}
10271 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
10272 match(Set dst (AddD (MulD src1 src2) src3));
10273 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
10274 ins_cost(44444);
10275 format %{ "maddD $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
10276 ins_encode %{
10277 FloatRegister src1 = $src1$$FloatRegister;
10278 FloatRegister src2 = $src2$$FloatRegister;
10279 FloatRegister src3 = $src3$$FloatRegister;
10280 FloatRegister dst = $dst$$FloatRegister;
10282 __ madd_d(dst, src1, src2, src3);
10283 %}
10284 ins_pipe( fpu_regF_regF );
10285 %}
10287 instruct absF_reg(regF dst, regF src) %{
10288 match(Set dst (AbsF src));
10289 ins_cost(100);
10290 format %{ "absF $dst, $src @absF_reg" %}
10291 ins_encode %{
10292 FloatRegister src = as_FloatRegister($src$$reg);
10293 FloatRegister dst = as_FloatRegister($dst$$reg);
10295 __ abs_s(dst, src);
10296 %}
10297 ins_pipe( fpu_regF_regF );
10298 %}
10301 // intrinsics for math_native.
10302 // AbsD SqrtD CosD SinD TanD LogD Log10D
10304 instruct absD_reg(regD dst, regD src) %{
10305 match(Set dst (AbsD src));
10306 ins_cost(100);
10307 format %{ "absD $dst, $src @absD_reg" %}
10308 ins_encode %{
10309 FloatRegister src = as_FloatRegister($src$$reg);
10310 FloatRegister dst = as_FloatRegister($dst$$reg);
10312 __ abs_d(dst, src);
10313 %}
10314 ins_pipe( fpu_regF_regF );
10315 %}
10317 instruct sqrtD_reg(regD dst, regD src) %{
10318 match(Set dst (SqrtD src));
10319 ins_cost(100);
10320 format %{ "SqrtD $dst, $src @sqrtD_reg" %}
10321 ins_encode %{
10322 FloatRegister src = as_FloatRegister($src$$reg);
10323 FloatRegister dst = as_FloatRegister($dst$$reg);
10325 __ sqrt_d(dst, src);
10326 %}
10327 ins_pipe( fpu_regF_regF );
10328 %}
10330 instruct sqrtF_reg(regF dst, regF src) %{
10331 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10332 ins_cost(100);
10333 format %{ "SqrtF $dst, $src @sqrtF_reg" %}
10334 ins_encode %{
10335 FloatRegister src = as_FloatRegister($src$$reg);
10336 FloatRegister dst = as_FloatRegister($dst$$reg);
10338 __ sqrt_s(dst, src);
10339 %}
10340 ins_pipe( fpu_regF_regF );
10341 %}
10342 //----------------------------------Logical Instructions----------------------
10343 //__________________________________Integer Logical Instructions-------------
10345 //And Instuctions
10346 // And Register with Immediate
10347 instruct andI_Reg_imm(mRegI dst, mRegI src1, immI src2) %{
10348 match(Set dst (AndI src1 src2));
10350 format %{ "and $dst, $src1, $src2 #@andI_Reg_imm" %}
10351 ins_encode %{
10352 Register dst = $dst$$Register;
10353 Register src = $src1$$Register;
10354 int val = $src2$$constant;
10356 __ move(AT, val);
10357 __ andr(dst, src, AT);
10358 %}
10359 ins_pipe( ialu_regI_regI );
10360 %}
10362 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
10363 match(Set dst (AndI src1 src2));
10364 ins_cost(60);
10366 format %{ "and $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
10367 ins_encode %{
10368 Register dst = $dst$$Register;
10369 Register src = $src1$$Register;
10370 int val = $src2$$constant;
10372 __ andi(dst, src, val);
10373 %}
10374 ins_pipe( ialu_regI_regI );
10375 %}
10377 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1, immI_nonneg_mask mask) %{
10378 match(Set dst (AndI src1 mask));
10379 ins_cost(60);
10381 format %{ "and $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
10382 ins_encode %{
10383 Register dst = $dst$$Register;
10384 Register src = $src1$$Register;
10385 int size = Assembler::is_int_mask($mask$$constant);
10387 __ ext(dst, src, 0, size);
10388 %}
10389 ins_pipe( ialu_regI_regI );
10390 %}
10392 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
10393 match(Set dst (XorI src1 src2));
10394 ins_cost(60);
10396 format %{ "xori $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
10397 ins_encode %{
10398 Register dst = $dst$$Register;
10399 Register src = $src1$$Register;
10400 int val = $src2$$constant;
10402 __ xori(dst, src, val);
10403 %}
10404 ins_pipe( ialu_regI_regI );
10405 %}
10407 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1, immI_M1 M1) %{
10408 match(Set dst (XorI src1 M1));
10409 predicate(UseLoongsonISA);
10410 ins_cost(60);
10412 format %{ "xor $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
10413 ins_encode %{
10414 Register dst = $dst$$Register;
10415 Register src = $src1$$Register;
10417 __ gsorn(dst, R0, src);
10418 %}
10419 ins_pipe( ialu_regI_regI );
10420 %}
10422 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
10423 match(Set dst (XorL src1 src2));
10424 ins_cost(60);
10426 format %{ "xori $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
10427 ins_encode %{
10428 Register dst = $dst$$Register;
10429 Register src = $src1$$Register;
10430 int val = $src2$$constant;
10432 __ xori(dst, src, val);
10433 %}
10434 ins_pipe( ialu_regI_regI );
10435 %}
10437 /*
10438 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1, immL_M1 M1) %{
10439 match(Set dst (XorL src1 M1));
10440 predicate(UseLoongsonISA);
10441 ins_cost(60);
10443 format %{ "xor $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
10444 ins_encode %{
10445 Register dst = $dst$$Register;
10446 Register src = $src1$$Register;
10448 __ gsorn(dst, R0, src);
10449 %}
10450 ins_pipe( ialu_regI_regI );
10451 %}
10452 */
10454 instruct lbu_and_lmask(mRegI dst, memory mem, immI_255 mask) %{
10455 match(Set dst (AndI mask (LoadB mem)));
10456 ins_cost(60);
10458 format %{ "lhu $dst, $mem #@lbu_and_lmask" %}
10459 ins_encode(load_UB_enc(dst, mem));
10460 ins_pipe( ialu_loadI );
10461 %}
10463 instruct lbu_and_rmask(mRegI dst, memory mem, immI_255 mask) %{
10464 match(Set dst (AndI (LoadB mem) mask));
10465 ins_cost(60);
10467 format %{ "lhu $dst, $mem #@lbu_and_rmask" %}
10468 ins_encode(load_UB_enc(dst, mem));
10469 ins_pipe( ialu_loadI );
10470 %}
10472 instruct andI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10473 match(Set dst (AndI src1 src2));
10475 format %{ "and $dst, $src1, $src2 #@andI_Reg_Reg" %}
10476 ins_encode %{
10477 Register dst = $dst$$Register;
10478 Register src1 = $src1$$Register;
10479 Register src2 = $src2$$Register;
10480 __ andr(dst, src1, src2);
10481 %}
10482 ins_pipe( ialu_regI_regI );
10483 %}
10485 instruct andnI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
10486 match(Set dst (AndI src1 (XorI src2 M1)));
10487 predicate(UseLoongsonISA);
10489 format %{ "andn $dst, $src1, $src2 #@andnI_Reg_nReg" %}
10490 ins_encode %{
10491 Register dst = $dst$$Register;
10492 Register src1 = $src1$$Register;
10493 Register src2 = $src2$$Register;
10495 __ gsandn(dst, src1, src2);
10496 %}
10497 ins_pipe( ialu_regI_regI );
10498 %}
10500 instruct ornI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
10501 match(Set dst (OrI src1 (XorI src2 M1)));
10502 predicate(UseLoongsonISA);
10504 format %{ "orn $dst, $src1, $src2 #@ornI_Reg_nReg" %}
10505 ins_encode %{
10506 Register dst = $dst$$Register;
10507 Register src1 = $src1$$Register;
10508 Register src2 = $src2$$Register;
10510 __ gsorn(dst, src1, src2);
10511 %}
10512 ins_pipe( ialu_regI_regI );
10513 %}
10515 instruct andnI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
10516 match(Set dst (AndI (XorI src1 M1) src2));
10517 predicate(UseLoongsonISA);
10519 format %{ "andn $dst, $src2, $src1 #@andnI_nReg_Reg" %}
10520 ins_encode %{
10521 Register dst = $dst$$Register;
10522 Register src1 = $src1$$Register;
10523 Register src2 = $src2$$Register;
10525 __ gsandn(dst, src2, src1);
10526 %}
10527 ins_pipe( ialu_regI_regI );
10528 %}
10530 instruct ornI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
10531 match(Set dst (OrI (XorI src1 M1) src2));
10532 predicate(UseLoongsonISA);
10534 format %{ "orn $dst, $src2, $src1 #@ornI_nReg_Reg" %}
10535 ins_encode %{
10536 Register dst = $dst$$Register;
10537 Register src1 = $src1$$Register;
10538 Register src2 = $src2$$Register;
10540 __ gsorn(dst, src2, src1);
10541 %}
10542 ins_pipe( ialu_regI_regI );
10543 %}
10545 // And Long Register with Register
10546 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10547 match(Set dst (AndL src1 src2));
10548 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
10549 ins_encode %{
10550 Register dst_reg = as_Register($dst$$reg);
10551 Register src1_reg = as_Register($src1$$reg);
10552 Register src2_reg = as_Register($src2$$reg);
10554 __ andr(dst_reg, src1_reg, src2_reg);
10555 %}
10556 ins_pipe( ialu_regL_regL );
10557 %}
10559 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
10560 match(Set dst (AndL src1 (ConvI2L src2)));
10561 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
10562 ins_encode %{
10563 Register dst_reg = as_Register($dst$$reg);
10564 Register src1_reg = as_Register($src1$$reg);
10565 Register src2_reg = as_Register($src2$$reg);
10567 __ andr(dst_reg, src1_reg, src2_reg);
10568 %}
10569 ins_pipe( ialu_regL_regL );
10570 %}
10572 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
10573 match(Set dst (AndL src1 src2));
10574 ins_cost(60);
10576 format %{ "and $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
10577 ins_encode %{
10578 Register dst = $dst$$Register;
10579 Register src = $src1$$Register;
10580 long val = $src2$$constant;
10582 __ andi(dst, src, val);
10583 %}
10584 ins_pipe( ialu_regI_regI );
10585 %}
10587 /*
10588 instruct andnL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
10589 match(Set dst (AndL src1 (XorL src2 M1)));
10590 predicate(UseLoongsonISA);
10592 format %{ "andn $dst, $src1, $src2 #@andnL_Reg_nReg" %}
10593 ins_encode %{
10594 Register dst = $dst$$Register;
10595 Register src1 = $src1$$Register;
10596 Register src2 = $src2$$Register;
10598 __ gsandn(dst, src1, src2);
10599 %}
10600 ins_pipe( ialu_regI_regI );
10601 %}
10602 */
10604 /*
10605 instruct ornL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
10606 match(Set dst (OrL src1 (XorL src2 M1)));
10607 predicate(UseLoongsonISA);
10609 format %{ "orn $dst, $src1, $src2 #@ornL_Reg_nReg" %}
10610 ins_encode %{
10611 Register dst = $dst$$Register;
10612 Register src1 = $src1$$Register;
10613 Register src2 = $src2$$Register;
10615 __ gsorn(dst, src1, src2);
10616 %}
10617 ins_pipe( ialu_regI_regI );
10618 %}
10619 */
10621 /*
10622 instruct andnL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
10623 match(Set dst (AndL (XorL src1 M1) src2));
10624 predicate(UseLoongsonISA);
10626 format %{ "andn $dst, $src2, $src1 #@andnL_nReg_Reg" %}
10627 ins_encode %{
10628 Register dst = $dst$$Register;
10629 Register src1 = $src1$$Register;
10630 Register src2 = $src2$$Register;
10632 __ gsandn(dst, src2, src1);
10633 %}
10634 ins_pipe( ialu_regI_regI );
10635 %}
10636 */
10638 /*
10639 instruct ornL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
10640 match(Set dst (OrL (XorL src1 M1) src2));
10641 predicate(UseLoongsonISA);
10643 format %{ "orn $dst, $src2, $src1 #@ornL_nReg_Reg" %}
10644 ins_encode %{
10645 Register dst = $dst$$Register;
10646 Register src1 = $src1$$Register;
10647 Register src2 = $src2$$Register;
10649 __ gsorn(dst, src2, src1);
10650 %}
10651 ins_pipe( ialu_regI_regI );
10652 %}
10653 */
10655 instruct andL_Reg_immL_M8(mRegL dst, immL_M8 M8) %{
10656 match(Set dst (AndL dst M8));
10657 ins_cost(60);
10659 format %{ "and $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
10660 ins_encode %{
10661 Register dst = $dst$$Register;
10663 __ dins(dst, R0, 0, 3);
10664 %}
10665 ins_pipe( ialu_regI_regI );
10666 %}
10668 instruct andL_Reg_immL_M5(mRegL dst, immL_M5 M5) %{
10669 match(Set dst (AndL dst M5));
10670 ins_cost(60);
10672 format %{ "and $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
10673 ins_encode %{
10674 Register dst = $dst$$Register;
10676 __ dins(dst, R0, 2, 1);
10677 %}
10678 ins_pipe( ialu_regI_regI );
10679 %}
10681 instruct andL_Reg_immL_M7(mRegL dst, immL_M7 M7) %{
10682 match(Set dst (AndL dst M7));
10683 ins_cost(60);
10685 format %{ "and $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
10686 ins_encode %{
10687 Register dst = $dst$$Register;
10689 __ dins(dst, R0, 1, 2);
10690 %}
10691 ins_pipe( ialu_regI_regI );
10692 %}
10694 instruct andL_Reg_immL_M4(mRegL dst, immL_M4 M4) %{
10695 match(Set dst (AndL dst M4));
10696 ins_cost(60);
10698 format %{ "and $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
10699 ins_encode %{
10700 Register dst = $dst$$Register;
10702 __ dins(dst, R0, 0, 2);
10703 %}
10704 ins_pipe( ialu_regI_regI );
10705 %}
10707 instruct andL_Reg_immL_M121(mRegL dst, immL_M121 M121) %{
10708 match(Set dst (AndL dst M121));
10709 ins_cost(60);
10711 format %{ "and $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
10712 ins_encode %{
10713 Register dst = $dst$$Register;
10715 __ dins(dst, R0, 3, 4);
10716 %}
10717 ins_pipe( ialu_regI_regI );
10718 %}
10720 // Or Long Register with Register
10721 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10722 match(Set dst (OrL src1 src2));
10723 format %{ "OR $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
10724 ins_encode %{
10725 Register dst_reg = $dst$$Register;
10726 Register src1_reg = $src1$$Register;
10727 Register src2_reg = $src2$$Register;
10729 __ orr(dst_reg, src1_reg, src2_reg);
10730 %}
10731 ins_pipe( ialu_regL_regL );
10732 %}
10734 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
10735 match(Set dst (OrL (CastP2X src1) src2));
10736 format %{ "OR $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
10737 ins_encode %{
10738 Register dst_reg = $dst$$Register;
10739 Register src1_reg = $src1$$Register;
10740 Register src2_reg = $src2$$Register;
10742 __ orr(dst_reg, src1_reg, src2_reg);
10743 %}
10744 ins_pipe( ialu_regL_regL );
10745 %}
10747 // Xor Long Register with Register
10748 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10749 match(Set dst (XorL src1 src2));
10750 format %{ "XOR $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
10751 ins_encode %{
10752 Register dst_reg = as_Register($dst$$reg);
10753 Register src1_reg = as_Register($src1$$reg);
10754 Register src2_reg = as_Register($src2$$reg);
10756 __ xorr(dst_reg, src1_reg, src2_reg);
10757 %}
10758 ins_pipe( ialu_regL_regL );
10759 %}
10761 // Shift Left by 8-bit immediate
10762 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
10763 match(Set dst (LShiftI src shift));
10765 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm" %}
10766 ins_encode %{
10767 Register src = $src$$Register;
10768 Register dst = $dst$$Register;
10769 int shamt = $shift$$constant;
10771 /*
10772 094 SHL S0, S0, #-7 #@salI_Reg_imm
10773 static int insn_RRSO(int rt, int rd, int sa, int op) { return (rt<<16) | (rd<<11) | (sa<<6) | op; }
10774 void sll (Register rd, Register rt , int sa) {
10775 emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, sll_op));
10776 }
10777 */
10779 if(0 <= shamt && shamt < 32) __ sll(dst, src, shamt);
10780 else {
10781 __ move(AT, shamt);
10782 __ sllv(dst, src, AT);
10783 }
10784 %}
10785 ins_pipe( ialu_regI_regI );
10786 %}
10788 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
10789 %{
10790 match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
10792 format %{ "andi $dst, $src, 7\t# @land7_2_s" %}
10793 ins_encode %{
10794 Register src = $src$$Register;
10795 Register dst = $dst$$Register;
10797 __ andi(dst, src, 7);
10798 %}
10799 ins_pipe(ialu_regI_regI);
10800 %}
10802 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
10803 %{
10804 match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
10806 format %{ "ori $dst, $src1, $src2\t# @ori2s" %}
10807 ins_encode %{
10808 Register src = $src1$$Register;
10809 int val = $src2$$constant;
10810 Register dst = $dst$$Register;
10812 __ ori(dst, src, val);
10813 %}
10814 ins_pipe(ialu_regI_regI);
10815 %}
10817 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
10818 // This idiom is used by the compiler the i2s bytecode.
10819 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
10820 %{
10821 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
10823 format %{ "i2s $dst, $src\t# @i2s" %}
10824 ins_encode %{
10825 Register src = $src$$Register;
10826 Register dst = $dst$$Register;
10828 __ seh(dst, src);
10829 %}
10830 ins_pipe(ialu_regI_regI);
10831 %}
10833 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
10834 // This idiom is used by the compiler for the i2b bytecode.
10835 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
10836 %{
10837 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
10839 format %{ "i2b $dst, $src\t# @i2b" %}
10840 ins_encode %{
10841 Register src = $src$$Register;
10842 Register dst = $dst$$Register;
10844 __ seb(dst, src);
10845 %}
10846 ins_pipe(ialu_regI_regI);
10847 %}
10850 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
10851 match(Set dst (LShiftI (ConvL2I src) shift));
10853 format %{ "SHL $dst, $src, $shift #@salI_RegL2I_imm" %}
10854 ins_encode %{
10855 Register src = $src$$Register;
10856 Register dst = $dst$$Register;
10857 int shamt = $shift$$constant;
10859 if(0 <= shamt && shamt < 32) __ sll(dst, src, shamt);
10860 else {
10861 __ move(AT, shamt);
10862 __ sllv(dst, src, AT);
10863 }
10864 %}
10865 ins_pipe( ialu_regI_regI );
10866 %}
10868 // Shift Left by 8-bit immediate
10869 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
10870 match(Set dst (LShiftI src shift));
10872 format %{ "SHL $dst, $src, $shift #@salI_Reg_Reg" %}
10873 ins_encode %{
10874 Register src = $src$$Register;
10875 Register dst = $dst$$Register;
10876 Register shamt = $shift$$Register;
10877 __ sllv(dst, src, shamt);
10878 %}
10879 ins_pipe( ialu_regI_regI );
10880 %}
10883 // Shift Left Long
10884 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
10885 //predicate(UseNewLongLShift);
10886 match(Set dst (LShiftL src shift));
10887 ins_cost(100);
10888 format %{ "salL $dst, $src, $shift @ salL_Reg_imm" %}
10889 ins_encode %{
10890 Register src_reg = as_Register($src$$reg);
10891 Register dst_reg = as_Register($dst$$reg);
10892 int shamt = $shift$$constant;
10894 if (__ is_simm(shamt, 5))
10895 __ dsll(dst_reg, src_reg, shamt);
10896 else
10897 {
10898 __ move(AT, shamt);
10899 __ dsllv(dst_reg, src_reg, AT);
10900 }
10901 %}
10902 ins_pipe( ialu_regL_regL );
10903 %}
10905 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
10906 //predicate(UseNewLongLShift);
10907 match(Set dst (LShiftL (ConvI2L src) shift));
10908 ins_cost(100);
10909 format %{ "salL $dst, $src, $shift @ salL_RegI2L_imm" %}
10910 ins_encode %{
10911 Register src_reg = as_Register($src$$reg);
10912 Register dst_reg = as_Register($dst$$reg);
10913 int shamt = $shift$$constant;
10915 if (__ is_simm(shamt, 5))
10916 __ dsll(dst_reg, src_reg, shamt);
10917 else
10918 {
10919 __ move(AT, shamt);
10920 __ dsllv(dst_reg, src_reg, AT);
10921 }
10922 %}
10923 ins_pipe( ialu_regL_regL );
10924 %}
10926 // Shift Left Long
10927 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
10928 //predicate(UseNewLongLShift);
10929 match(Set dst (LShiftL src shift));
10930 ins_cost(100);
10931 format %{ "salL $dst, $src, $shift @ salL_Reg_Reg" %}
10932 ins_encode %{
10933 Register creg = T9;
10934 Register src_reg = as_Register($src$$reg);
10935 Register dst_reg = as_Register($dst$$reg);
10937 __ move(creg, $shift$$Register);
10938 __ andi(creg, creg, 0x3f);
10939 __ dsllv(dst_reg, src_reg, creg);
10940 %}
10941 ins_pipe( ialu_regL_regL );
10942 %}
10944 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
10945 match(Set dst (LShiftL (ConvI2L src) shift));
10946 ins_cost(100);
10947 format %{ "salL $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
10948 ins_encode %{
10949 Register src_reg = as_Register($src$$reg);
10950 Register dst_reg = as_Register($dst$$reg);
10951 int shamt = $shift$$constant;
10953 if (__ is_simm(shamt, 5)) {
10954 __ dsll(dst_reg, src_reg, shamt);
10955 } else {
10956 __ move(AT, shamt);
10957 __ dsllv(dst_reg, src_reg, AT);
10958 }
10959 %}
10960 ins_pipe( ialu_regL_regL );
10961 %}
10963 // Shift Right Long
10964 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
10965 //predicate(UseNewLongLShift);
10966 match(Set dst (RShiftL src shift));
10967 ins_cost(100);
10968 format %{ "sarL $dst, $src, $shift @ sarL_Reg_imm" %}
10969 ins_encode %{
10970 Register src_reg = as_Register($src$$reg);
10971 Register dst_reg = as_Register($dst$$reg);
10972 int shamt = ($shift$$constant & 0x3f);
10973 if (__ is_simm(shamt, 5))
10974 __ dsra(dst_reg, src_reg, shamt);
10975 else
10976 {
10977 __ move(AT, shamt);
10978 __ dsrav(dst_reg, src_reg, AT);
10979 }
10980 %}
10981 ins_pipe( ialu_regL_regL );
10982 %}
10984 // Shift Right Long arithmetically
10985 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
10986 //predicate(UseNewLongLShift);
10987 match(Set dst (RShiftL src shift));
10988 ins_cost(100);
10989 format %{ "sarL $dst, $src, $shift @ sarL_Reg_Reg" %}
10990 ins_encode %{
10991 Register creg = T9;
10992 Register src_reg = as_Register($src$$reg);
10993 Register dst_reg = as_Register($dst$$reg);
10995 __ move(creg, $shift$$Register);
10996 __ andi(creg, creg, 0x3f);
10997 __ dsrav(dst_reg, src_reg, creg);
10998 %}
10999 ins_pipe( ialu_regL_regL );
11000 %}
11002 // Shift Right Long logically
11003 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
11004 match(Set dst (URShiftL src shift));
11005 ins_cost(100);
11006 format %{ "slrL $dst, $src, $shift @ slrL_Reg_Reg" %}
11007 ins_encode %{
11008 Register creg = T9;
11009 Register src_reg = as_Register($src$$reg);
11010 Register dst_reg = as_Register($dst$$reg);
11012 __ move(creg, $shift$$Register);
11013 __ andi(creg, creg, 0x3f);
11014 __ dsrlv(dst_reg, src_reg, creg);
11015 %}
11016 ins_pipe( ialu_regL_regL );
11017 %}
11019 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
11020 match(Set dst (URShiftL src shift));
11021 ins_cost(80);
11022 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
11023 ins_encode %{
11024 Register src_reg = as_Register($src$$reg);
11025 Register dst_reg = as_Register($dst$$reg);
11026 int shamt = $shift$$constant;
11028 __ dsrl(dst_reg, src_reg, shamt);
11029 %}
11030 ins_pipe( ialu_regL_regL );
11031 %}
11033 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
11034 match(Set dst (URShiftL (CastP2X src) shift));
11035 ins_cost(80);
11036 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
11037 ins_encode %{
11038 Register src_reg = as_Register($src$$reg);
11039 Register dst_reg = as_Register($dst$$reg);
11040 int shamt = $shift$$constant;
11042 __ dsrl(dst_reg, src_reg, shamt);
11043 %}
11044 ins_pipe( ialu_regL_regL );
11045 %}
11047 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
11048 match(Set dst (URShiftL src shift));
11049 ins_cost(80);
11050 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
11051 ins_encode %{
11052 Register src_reg = as_Register($src$$reg);
11053 Register dst_reg = as_Register($dst$$reg);
11054 int shamt = $shift$$constant;
11056 __ dsrl32(dst_reg, src_reg, shamt - 32);
11057 %}
11058 ins_pipe( ialu_regL_regL );
11059 %}
11061 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
11062 match(Set dst (URShiftL (CastP2X src) shift));
11063 ins_cost(80);
11064 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
11065 ins_encode %{
11066 Register src_reg = as_Register($src$$reg);
11067 Register dst_reg = as_Register($dst$$reg);
11068 int shamt = $shift$$constant;
11070 __ dsrl32(dst_reg, src_reg, shamt - 32);
11071 %}
11072 ins_pipe( ialu_regL_regL );
11073 %}
11075 // Xor Instructions
11076 // Xor Register with Register
11077 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11078 match(Set dst (XorI src1 src2));
11080 format %{ "XOR $dst, $src1, $src2 #@xorI_Reg_Reg" %}
11082 ins_encode %{
11083 Register dst = $dst$$Register;
11084 Register src1 = $src1$$Register;
11085 Register src2 = $src2$$Register;
11086 __ xorr(dst, src1, src2);
11087 __ sll(dst, dst, 0); /* long -> int */
11088 %}
11090 ins_pipe( ialu_regI_regI );
11091 %}
11093 // Or Instructions
11094 // Or Register with Register
11095 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11096 match(Set dst (OrI src1 src2));
11098 format %{ "OR $dst, $src1, $src2 #@orI_Reg_Reg" %}
11099 ins_encode %{
11100 Register dst = $dst$$Register;
11101 Register src1 = $src1$$Register;
11102 Register src2 = $src2$$Register;
11103 __ orr(dst, src1, src2);
11104 %}
11106 ins_pipe( ialu_regI_regI );
11107 %}
11109 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
11110 match(Set dst (OrI src1 (CastP2X src2)));
11112 format %{ "OR $dst, $src1, $src2 #@orI_Reg_castP2X" %}
11113 ins_encode %{
11114 Register dst = $dst$$Register;
11115 Register src1 = $src1$$Register;
11116 Register src2 = $src2$$Register;
11117 __ orr(dst, src1, src2);
11118 %}
11120 ins_pipe( ialu_regI_regI );
11121 %}
11123 // Logical Shift Right by 8-bit immediate
11124 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
11125 match(Set dst (URShiftI src shift));
11126 // effect(KILL cr);
11128 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_imm" %}
11129 ins_encode %{
11130 Register src = $src$$Register;
11131 Register dst = $dst$$Register;
11132 int shift = $shift$$constant;
11133 if (shift > 0)
11134 __ srl(dst, src, shift);
11135 else
11136 {
11137 __ move(AT, shift);
11138 __ srlv(dst, src, AT);
11139 }
11140 %}
11141 ins_pipe( ialu_regI_regI );
11142 %}
11144 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
11145 match(Set dst (AndI (URShiftI src shift) mask));
11147 format %{ "ext $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
11148 ins_encode %{
11149 Register src = $src$$Register;
11150 Register dst = $dst$$Register;
11151 int pos = $shift$$constant;
11152 int size = Assembler::is_int_mask($mask$$constant);
11154 __ ext(dst, src, pos, size);
11155 %}
11156 ins_pipe( ialu_regI_regI );
11157 %}
11159 // Logical Shift Right
11160 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
11161 match(Set dst (URShiftI src shift));
11163 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_Reg" %}
11164 ins_encode %{
11165 Register src = $src$$Register;
11166 Register dst = $dst$$Register;
11167 Register shift = $shift$$Register;
11168 __ srlv(dst, src, shift);
11169 %}
11170 ins_pipe( ialu_regI_regI );
11171 %}
11174 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
11175 match(Set dst (RShiftI src shift));
11176 // effect(KILL cr);
11178 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_imm" %}
11179 ins_encode %{
11180 Register src = $src$$Register;
11181 Register dst = $dst$$Register;
11182 int shift = $shift$$constant;
11183 __ sra(dst, src, shift);
11184 %}
11185 ins_pipe( ialu_regI_regI );
11186 %}
11188 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
11189 match(Set dst (RShiftI src shift));
11190 // effect(KILL cr);
11192 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_Reg" %}
11193 ins_encode %{
11194 Register src = $src$$Register;
11195 Register dst = $dst$$Register;
11196 Register shift = $shift$$Register;
11197 __ srav(dst, src, shift);
11198 %}
11199 ins_pipe( ialu_regI_regI );
11200 %}
11202 //----------Convert Int to Boolean---------------------------------------------
11204 instruct convI2B(mRegI dst, mRegI src) %{
11205 match(Set dst (Conv2B src));
11207 ins_cost(100);
11208 format %{ "convI2B $dst, $src @ convI2B" %}
11209 ins_encode %{
11210 Register dst = as_Register($dst$$reg);
11211 Register src = as_Register($src$$reg);
11213 if (dst != src) {
11214 __ daddiu(dst, R0, 1);
11215 __ movz(dst, R0, src);
11216 } else {
11217 __ move(AT, src);
11218 __ daddiu(dst, R0, 1);
11219 __ movz(dst, R0, AT);
11220 }
11221 %}
11223 ins_pipe( ialu_regL_regL );
11224 %}
11226 instruct convI2L_reg( mRegL dst, mRegI src) %{
11227 match(Set dst (ConvI2L src));
11229 ins_cost(100);
11230 format %{ "SLL $dst, $src @ convI2L_reg\t" %}
11231 ins_encode %{
11232 Register dst = as_Register($dst$$reg);
11233 Register src = as_Register($src$$reg);
11235 if(dst != src) __ sll(dst, src, 0);
11236 %}
11237 ins_pipe( ialu_regL_regL );
11238 %}
11241 instruct convL2I_reg( mRegI dst, mRegL src ) %{
11242 match(Set dst (ConvL2I src));
11244 format %{ "MOV $dst, $src @ convL2I_reg" %}
11245 ins_encode %{
11246 Register dst = as_Register($dst$$reg);
11247 Register src = as_Register($src$$reg);
11249 __ sll(dst, src, 0);
11250 %}
11252 ins_pipe( ialu_regI_regI );
11253 %}
11255 instruct convL2D_reg( regD dst, mRegL src ) %{
11256 match(Set dst (ConvL2D src));
11257 format %{ "convL2D $dst, $src @ convL2D_reg" %}
11258 ins_encode %{
11259 Register src = as_Register($src$$reg);
11260 FloatRegister dst = as_FloatRegister($dst$$reg);
11262 __ dmtc1(src, dst);
11263 __ cvt_d_l(dst, dst);
11264 %}
11266 ins_pipe( pipe_slow );
11267 %}
11269 instruct convD2L_reg( mRegL dst, regD src ) %{
11270 match(Set dst (ConvD2L src));
11271 format %{ "convD2L $dst, $src @ convD2L_reg" %}
11272 ins_encode %{
11273 Register dst = as_Register($dst$$reg);
11274 FloatRegister src = as_FloatRegister($src$$reg);
11276 Label L;
11278 __ c_un_d(src, src); //NaN?
11279 __ bc1t(L);
11280 __ delayed();
11281 __ move(dst, R0);
11283 __ trunc_l_d(F30, src);
11284 __ cfc1(AT, 31);
11285 __ li(T9, 0x10000);
11286 __ andr(AT, AT, T9);
11287 __ beq(AT, R0, L);
11288 __ delayed()->dmfc1(dst, F30);
11290 __ mov_d(F12, src);
11291 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
11292 __ move(dst, V0);
11293 __ bind(L);
11294 %}
11296 ins_pipe( pipe_slow );
11297 %}
11299 instruct convF2I_reg( mRegI dst, regF src ) %{
11300 match(Set dst (ConvF2I src));
11301 format %{ "convf2i $dst, $src @ convF2I_reg" %}
11302 ins_encode %{
11303 Register dreg = $dst$$Register;
11304 FloatRegister fval = $src$$FloatRegister;
11305 Label L;
11307 __ c_un_s(fval, fval); //NaN?
11308 __ bc1t(L);
11309 __ delayed();
11310 __ move(dreg, R0);
11312 __ trunc_w_s(F30, fval);
11314 /* Call SharedRuntime:f2i() to do valid convention */
11315 __ cfc1(AT, 31);
11316 __ li(T9, 0x10000);
11317 __ andr(AT, AT, T9);
11318 __ beq(AT, R0, L);
11319 __ delayed()->mfc1(dreg, F30);
11321 __ mov_s(F12, fval);
11323 /* 2014/01/08 Fu : This bug was found when running ezDS's control-panel.
11324 * J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
11325 *
11326 * An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
11327 * V0 is corrupted during call_VM_leaf(), and should be preserved.
11328 */
11329 if(dreg != V0) {
11330 __ push(V0);
11331 }
11332 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
11333 if(dreg != V0) {
11334 __ move(dreg, V0);
11335 __ pop(V0);
11336 }
11337 __ bind(L);
11338 %}
11340 ins_pipe( pipe_slow );
11341 %}
11343 instruct convF2L_reg( mRegL dst, regF src ) %{
11344 match(Set dst (ConvF2L src));
11345 format %{ "convf2l $dst, $src @ convF2L_reg" %}
11346 ins_encode %{
11347 Register dst = as_Register($dst$$reg);
11348 FloatRegister fval = $src$$FloatRegister;
11349 Label L;
11351 __ c_un_s(fval, fval); //NaN?
11352 __ bc1t(L);
11353 __ delayed();
11354 __ move(dst, R0);
11356 __ trunc_l_s(F30, fval);
11357 __ cfc1(AT, 31);
11358 __ li(T9, 0x10000);
11359 __ andr(AT, AT, T9);
11360 __ beq(AT, R0, L);
11361 __ delayed()->dmfc1(dst, F30);
11363 __ mov_s(F12, fval);
11364 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
11365 __ move(dst, V0);
11366 __ bind(L);
11367 %}
11369 ins_pipe( pipe_slow );
11370 %}
11372 instruct convL2F_reg( regF dst, mRegL src ) %{
11373 match(Set dst (ConvL2F src));
11374 format %{ "convl2f $dst, $src @ convL2F_reg" %}
11375 ins_encode %{
11376 FloatRegister dst = $dst$$FloatRegister;
11377 Register src = as_Register($src$$reg);
11378 Label L;
11380 __ dmtc1(src, dst);
11381 __ cvt_s_l(dst, dst);
11382 %}
11384 ins_pipe( pipe_slow );
11385 %}
11387 instruct convI2F_reg( regF dst, mRegI src ) %{
11388 match(Set dst (ConvI2F src));
11389 format %{ "convi2f $dst, $src @ convI2F_reg" %}
11390 ins_encode %{
11391 Register src = $src$$Register;
11392 FloatRegister dst = $dst$$FloatRegister;
11394 __ mtc1(src, dst);
11395 __ cvt_s_w(dst, dst);
11396 %}
11398 ins_pipe( fpu_regF_regF );
11399 %}
11401 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
11402 match(Set dst (CmpLTMask p zero));
11403 ins_cost(100);
11405 format %{ "sra $dst, $p, 31 @ cmpLTMask_immI0" %}
11406 ins_encode %{
11407 Register src = $p$$Register;
11408 Register dst = $dst$$Register;
11410 __ sra(dst, src, 31);
11411 %}
11412 ins_pipe( pipe_slow );
11413 %}
11416 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
11417 match(Set dst (CmpLTMask p q));
11418 ins_cost(400);
11420 format %{ "cmpLTMask $dst, $p, $q @ cmpLTMask" %}
11421 ins_encode %{
11422 Register p = $p$$Register;
11423 Register q = $q$$Register;
11424 Register dst = $dst$$Register;
11426 __ slt(dst, p, q);
11427 __ subu(dst, R0, dst);
11428 %}
11429 ins_pipe( pipe_slow );
11430 %}
11432 instruct convP2B(mRegI dst, mRegP src) %{
11433 match(Set dst (Conv2B src));
11435 ins_cost(100);
11436 format %{ "convP2B $dst, $src @ convP2B" %}
11437 ins_encode %{
11438 Register dst = as_Register($dst$$reg);
11439 Register src = as_Register($src$$reg);
11441 if (dst != src) {
11442 __ daddiu(dst, R0, 1);
11443 __ movz(dst, R0, src);
11444 } else {
11445 __ move(AT, src);
11446 __ daddiu(dst, R0, 1);
11447 __ movz(dst, R0, AT);
11448 }
11449 %}
11451 ins_pipe( ialu_regL_regL );
11452 %}
11455 instruct convI2D_reg_reg(regD dst, mRegI src) %{
11456 match(Set dst (ConvI2D src));
11457 format %{ "conI2D $dst, $src @convI2D_reg" %}
11458 ins_encode %{
11459 Register src = $src$$Register;
11460 FloatRegister dst = $dst$$FloatRegister;
11461 __ mtc1(src, dst);
11462 __ cvt_d_w(dst, dst);
11463 %}
11464 ins_pipe( fpu_regF_regF );
11465 %}
11467 instruct convF2I_reg_reg(mRegI dst, regF src) %{
11468 match(Set dst (ConvF2I src));
11469 format %{ "convF2I $dst, $src\t# @convF2D_reg_reg" %}
11470 ins_encode %{
11471 FloatRegister dst = $dst$$FloatRegister;
11472 FloatRegister src = $src$$FloatRegister;
11474 __ cvt_d_s(dst, src);
11475 %}
11476 ins_pipe( fpu_regF_regF );
11477 %}
11479 instruct convF2D_reg_reg(regD dst, regF src) %{
11480 match(Set dst (ConvF2D src));
11481 format %{ "convF2D $dst, $src\t# @convF2D_reg_reg" %}
11482 ins_encode %{
11483 FloatRegister dst = $dst$$FloatRegister;
11484 FloatRegister src = $src$$FloatRegister;
11486 __ cvt_d_s(dst, src);
11487 %}
11488 ins_pipe( fpu_regF_regF );
11489 %}
11491 instruct convD2F_reg_reg(regF dst, regD src) %{
11492 match(Set dst (ConvD2F src));
11493 format %{ "convD2F $dst, $src\t# @convD2F_reg_reg" %}
11494 ins_encode %{
11495 FloatRegister dst = $dst$$FloatRegister;
11496 FloatRegister src = $src$$FloatRegister;
11498 __ cvt_s_d(dst, src);
11499 %}
11500 ins_pipe( fpu_regF_regF );
11501 %}
11503 // Convert a double to an int. If the double is a NAN, stuff a zero in instead.
11504 instruct convD2I_reg_reg( mRegI dst, regD src ) %{
11505 match(Set dst (ConvD2I src));
11506 // effect( KILL tmp, KILL cr );//after this instruction, it will release register tmp and cr
11508 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg \n\t" %}
11510 ins_encode %{
11511 FloatRegister src = $src$$FloatRegister;
11512 Register dst = $dst$$Register;
11513 Label L;
11515 __ trunc_w_d(F30, src);
11516 __ cfc1(AT, 31);
11517 __ li(T9, 0x10000);
11518 __ andr(AT, AT, T9);
11519 __ beq(AT, R0, L);
11520 __ delayed()->mfc1(dst, F30);
11522 __ mov_d(F12, src);
11523 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
11524 __ move(dst, V0);
11525 __ bind(L);
11527 %}
11528 ins_pipe( pipe_slow );
11529 %}
11531 // Convert oop pointer into compressed form
11532 instruct encodeHeapOop(mRegN dst, mRegP src) %{
11533 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
11534 match(Set dst (EncodeP src));
11535 format %{ "encode_heap_oop $dst,$src" %}
11536 ins_encode %{
11537 Register src = $src$$Register;
11538 Register dst = $dst$$Register;
11539 if (src != dst) {
11540 __ move(dst, src);
11541 }
11542 __ encode_heap_oop(dst);
11543 %}
11544 ins_pipe( ialu_regL_regL );
11545 %}
11547 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
11548 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
11549 match(Set dst (EncodeP src));
11550 format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
11551 ins_encode %{
11552 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
11553 %}
11554 ins_pipe( ialu_regL_regL );
11555 %}
11557 instruct decodeHeapOop(mRegP dst, mRegN src) %{
11558 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
11559 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
11560 match(Set dst (DecodeN src));
11561 format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
11562 ins_encode %{
11563 Register s = $src$$Register;
11564 Register d = $dst$$Register;
11565 if (s != d) {
11566 __ move(d, s);
11567 }
11568 __ decode_heap_oop(d);
11569 %}
11570 ins_pipe( ialu_regL_regL );
11571 %}
11573 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
11574 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
11575 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
11576 match(Set dst (DecodeN src));
11577 format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
11578 ins_encode %{
11579 Register s = $src$$Register;
11580 Register d = $dst$$Register;
11581 if (s != d) {
11582 __ decode_heap_oop_not_null(d, s);
11583 } else {
11584 __ decode_heap_oop_not_null(d);
11585 }
11586 %}
11587 ins_pipe( ialu_regL_regL );
11588 %}
11590 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
11591 match(Set dst (EncodePKlass src));
11592 format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
11593 ins_encode %{
11594 __ encode_klass_not_null($dst$$Register, $src$$Register);
11595 %}
11596 ins_pipe( ialu_regL_regL );
11597 %}
11599 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
11600 match(Set dst (DecodeNKlass src));
11601 format %{ "decode_heap_klass_not_null $dst,$src" %}
11602 ins_encode %{
11603 Register s = $src$$Register;
11604 Register d = $dst$$Register;
11605 if (s != d) {
11606 __ decode_klass_not_null(d, s);
11607 } else {
11608 __ decode_klass_not_null(d);
11609 }
11610 %}
11611 ins_pipe( ialu_regL_regL );
11612 %}
11614 //FIXME
11615 instruct tlsLoadP(mRegP dst) %{
11616 match(Set dst (ThreadLocal));
11618 ins_cost(0);
11619 format %{ " get_thread in $dst #@tlsLoadP" %}
11620 ins_encode %{
11621 Register dst = $dst$$Register;
11622 #ifdef OPT_THREAD
11623 __ move(dst, TREG);
11624 #else
11625 __ get_thread(dst);
11626 #endif
11627 %}
11629 ins_pipe( ialu_loadI );
11630 %}
11633 instruct checkCastPP( mRegP dst ) %{
11634 match(Set dst (CheckCastPP dst));
11636 format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
11637 ins_encode( /*empty encoding*/ );
11638 ins_pipe( empty );
11639 %}
11641 instruct castPP(mRegP dst)
11642 %{
11643 match(Set dst (CastPP dst));
11645 size(0);
11646 format %{ "# castPP of $dst" %}
11647 ins_encode(/* empty encoding */);
11648 ins_pipe(empty);
11649 %}
11651 instruct castII( mRegI dst ) %{
11652 match(Set dst (CastII dst));
11653 format %{ "#castII of $dst empty encoding" %}
11654 ins_encode( /*empty encoding*/ );
11655 ins_cost(0);
11656 ins_pipe( empty );
11657 %}
11659 // Return Instruction
11660 // Remove the return address & jump to it.
11661 instruct Ret() %{
11662 match(Return);
11663 format %{ "RET #@Ret" %}
11665 ins_encode %{
11666 __ jr(RA);
11667 __ nop();
11668 %}
11670 ins_pipe( pipe_jump );
11671 %}
11673 /*
11674 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
11675 instruct jumpXtnd(mRegL switch_val) %{
11676 match(Jump switch_val);
11678 ins_cost(350);
11680 format %{ "load T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
11681 "jr T9\n\t"
11682 "nop" %}
11683 ins_encode %{
11684 Register table_base = $constanttablebase;
11685 int con_offset = $constantoffset;
11686 Register switch_reg = $switch_val$$Register;
11688 if (UseLoongsonISA) {
11689 if (Assembler::is_simm(con_offset, 8)) {
11690 __ gsldx(T9, table_base, switch_reg, con_offset);
11691 } else if (Assembler::is_simm16(con_offset)) {
11692 __ daddu(T9, table_base, switch_reg);
11693 __ ld(T9, T9, con_offset);
11694 } else {
11695 __ move(T9, con_offset);
11696 __ daddu(AT, table_base, switch_reg);
11697 __ gsldx(T9, AT, T9, 0);
11698 }
11699 } else {
11700 if (Assembler::is_simm16(con_offset)) {
11701 __ daddu(T9, table_base, switch_reg);
11702 __ ld(T9, T9, con_offset);
11703 } else {
11704 __ move(T9, con_offset);
11705 __ daddu(AT, table_base, switch_reg);
11706 __ daddu(AT, T9, AT);
11707 __ ld(T9, AT, 0);
11708 }
11709 }
11711 __ jr(T9);
11712 __ nop();
11714 %}
11715 ins_pipe(pipe_jump);
11716 %}
11717 */
11719 // Jump Direct - Label defines a relative address from JMP
11720 instruct jmpDir(label labl) %{
11721 match(Goto);
11722 effect(USE labl);
11724 ins_cost(300);
11725 format %{ "JMP $labl #@jmpDir" %}
11727 ins_encode %{
11728 Label &L = *($labl$$label);
11729 if(&L)
11730 __ b(L);
11731 else
11732 __ b(int(0));
11733 __ nop();
11734 %}
11736 ins_pipe( pipe_jump );
11737 ins_pc_relative(1);
11738 %}
11742 // Tail Jump; remove the return address; jump to target.
11743 // TailCall above leaves the return address around.
11744 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
11745 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
11746 // "restore" before this instruction (in Epilogue), we need to materialize it
11747 // in %i0.
11748 //FIXME
11749 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
11750 match( TailJump jump_target ex_oop );
11751 ins_cost(200);
11752 format %{ "Jmp $jump_target ; ex_oop = $ex_oop #@tailjmpInd" %}
11753 ins_encode %{
11754 Register target = $jump_target$$Register;
11756 /* 2012/9/14 Jin: V0, V1 are indicated in:
11757 * [stubGenerator_mips.cpp] generate_forward_exception()
11758 * [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
11759 */
11760 Register oop = $ex_oop$$Register;
11761 Register exception_oop = V0;
11762 Register exception_pc = V1;
11764 __ move(exception_pc, RA);
11765 __ move(exception_oop, oop);
11767 __ jr(target);
11768 __ nop();
11769 %}
11770 ins_pipe( pipe_jump );
11771 %}
11773 // ============================================================================
11774 // Procedure Call/Return Instructions
11775 // Call Java Static Instruction
11776 // Note: If this code changes, the corresponding ret_addr_offset() and
11777 // compute_padding() functions will have to be adjusted.
11778 instruct CallStaticJavaDirect(method meth) %{
11779 match(CallStaticJava);
11780 effect(USE meth);
11782 ins_cost(300);
11783 format %{ "CALL,static #@CallStaticJavaDirect " %}
11784 ins_encode( Java_Static_Call( meth ) );
11785 ins_pipe( pipe_slow );
11786 ins_pc_relative(1);
11787 ins_alignment(16);
11788 %}
11790 // Call Java Dynamic Instruction
11791 // Note: If this code changes, the corresponding ret_addr_offset() and
11792 // compute_padding() functions will have to be adjusted.
11793 instruct CallDynamicJavaDirect(method meth) %{
11794 match(CallDynamicJava);
11795 effect(USE meth);
11797 ins_cost(300);
11798 format %{"MOV IC_Klass, (oop)-1 @ CallDynamicJavaDirect\n\t"
11799 "CallDynamic @ CallDynamicJavaDirect" %}
11800 ins_encode( Java_Dynamic_Call( meth ) );
11801 ins_pipe( pipe_slow );
11802 ins_pc_relative(1);
11803 ins_alignment(16);
11804 %}
11806 instruct CallLeafNoFPDirect(method meth) %{
11807 match(CallLeafNoFP);
11808 effect(USE meth);
11810 ins_cost(300);
11811 format %{ "CALL_LEAF_NOFP,runtime " %}
11812 ins_encode(Java_To_Runtime(meth));
11813 ins_pipe( pipe_slow );
11814 ins_pc_relative(1);
11815 ins_alignment(16);
11816 %}
11818 // Prefetch instructions.
11820 instruct prefetchrNTA( memory mem ) %{
11821 match(PrefetchRead mem);
11822 ins_cost(125);
11824 format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
11825 ins_encode %{
11826 int base = $mem$$base;
11827 int index = $mem$$index;
11828 int scale = $mem$$scale;
11829 int disp = $mem$$disp;
11831 if( index != 0 ) {
11832 if (scale == 0) {
11833 __ daddu(AT, as_Register(base), as_Register(index));
11834 } else {
11835 __ dsll(AT, as_Register(index), scale);
11836 __ daddu(AT, as_Register(base), AT);
11837 }
11838 } else {
11839 __ move(AT, as_Register(base));
11840 }
11841 if( Assembler::is_simm16(disp) ) {
11842 __ daddiu(AT, as_Register(base), disp);
11843 __ daddiu(AT, AT, disp);
11844 } else {
11845 __ move(T9, disp);
11846 __ daddu(AT, as_Register(base), T9);
11847 }
11848 __ pref(0, AT, 0); //hint: 0:load
11849 %}
11850 ins_pipe(pipe_slow);
11851 %}
11853 instruct prefetchwNTA( memory mem ) %{
11854 match(PrefetchWrite mem);
11855 ins_cost(125);
11856 format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
11857 ins_encode %{
11858 int base = $mem$$base;
11859 int index = $mem$$index;
11860 int scale = $mem$$scale;
11861 int disp = $mem$$disp;
11863 if( index != 0 ) {
11864 if (scale == 0) {
11865 __ daddu(AT, as_Register(base), as_Register(index));
11866 } else {
11867 __ dsll(AT, as_Register(index), scale);
11868 __ daddu(AT, as_Register(base), AT);
11869 }
11870 } else {
11871 __ move(AT, as_Register(base));
11872 }
11873 if( Assembler::is_simm16(disp) ) {
11874 __ daddiu(AT, as_Register(base), disp);
11875 __ daddiu(AT, AT, disp);
11876 } else {
11877 __ move(T9, disp);
11878 __ daddu(AT, as_Register(base), T9);
11879 }
11880 __ pref(1, AT, 0); //hint: 1:store
11881 %}
11882 ins_pipe(pipe_slow);
11883 %}
11885 // Prefetch instructions for allocation.
11887 instruct prefetchAllocNTA( memory mem ) %{
11888 match(PrefetchAllocation mem);
11889 ins_cost(125);
11890 format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
11891 ins_encode %{
11892 int base = $mem$$base;
11893 int index = $mem$$index;
11894 int scale = $mem$$scale;
11895 int disp = $mem$$disp;
11897 Register dst = R0;
11899 if( index != 0 ) {
11900 if( Assembler::is_simm16(disp) ) {
11901 if( UseLoongsonISA ) {
11902 if (scale == 0) {
11903 __ gslbx(dst, as_Register(base), as_Register(index), disp);
11904 } else {
11905 __ dsll(AT, as_Register(index), scale);
11906 __ gslbx(dst, as_Register(base), AT, disp);
11907 }
11908 } else {
11909 if (scale == 0) {
11910 __ addu(AT, as_Register(base), as_Register(index));
11911 } else {
11912 __ dsll(AT, as_Register(index), scale);
11913 __ addu(AT, as_Register(base), AT);
11914 }
11915 __ lb(dst, AT, disp);
11916 }
11917 } else {
11918 if (scale == 0) {
11919 __ addu(AT, as_Register(base), as_Register(index));
11920 } else {
11921 __ dsll(AT, as_Register(index), scale);
11922 __ addu(AT, as_Register(base), AT);
11923 }
11924 __ move(T9, disp);
11925 if( UseLoongsonISA ) {
11926 __ gslbx(dst, AT, T9, 0);
11927 } else {
11928 __ addu(AT, AT, T9);
11929 __ lb(dst, AT, 0);
11930 }
11931 }
11932 } else {
11933 if( Assembler::is_simm16(disp) ) {
11934 __ lb(dst, as_Register(base), disp);
11935 } else {
11936 __ move(T9, disp);
11937 if( UseLoongsonISA ) {
11938 __ gslbx(dst, as_Register(base), T9, 0);
11939 } else {
11940 __ addu(AT, as_Register(base), T9);
11941 __ lb(dst, AT, 0);
11942 }
11943 }
11944 }
11945 %}
11946 ins_pipe(pipe_slow);
11947 %}
11950 // Call runtime without safepoint
11951 instruct CallLeafDirect(method meth) %{
11952 match(CallLeaf);
11953 effect(USE meth);
11955 ins_cost(300);
11956 format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
11957 ins_encode(Java_To_Runtime(meth));
11958 ins_pipe( pipe_slow );
11959 ins_pc_relative(1);
11960 ins_alignment(16);
11961 %}
11963 // Load Char (16bit unsigned)
11964 instruct loadUS(mRegI dst, memory mem) %{
11965 match(Set dst (LoadUS mem));
11967 ins_cost(125);
11968 format %{ "loadUS $dst,$mem @ loadC" %}
11969 ins_encode(load_C_enc(dst, mem));
11970 ins_pipe( ialu_loadI );
11971 %}
11973 instruct loadUS_convI2L(mRegL dst, memory mem) %{
11974 match(Set dst (ConvI2L (LoadUS mem)));
11976 ins_cost(125);
11977 format %{ "loadUS $dst,$mem @ loadUS_convI2L" %}
11978 ins_encode(load_C_enc(dst, mem));
11979 ins_pipe( ialu_loadI );
11980 %}
11982 // Store Char (16bit unsigned)
11983 instruct storeC(memory mem, mRegI src) %{
11984 match(Set mem (StoreC mem src));
11986 ins_cost(125);
11987 format %{ "storeC $src,$mem @ storeC" %}
11988 ins_encode(store_C_reg_enc(mem, src));
11989 ins_pipe( ialu_loadI );
11990 %}
11993 instruct loadConF0(regF dst, immF0 zero) %{
11994 match(Set dst zero);
11995 ins_cost(100);
11997 format %{ "mov $dst, zero @ loadConF0\n"%}
11998 ins_encode %{
11999 FloatRegister dst = $dst$$FloatRegister;
12001 __ mtc1(R0, dst);
12002 %}
12003 ins_pipe( fpu_loadF );
12004 %}
12007 instruct loadConF(regF dst, immF src) %{
12008 match(Set dst src);
12009 ins_cost(125);
12011 format %{ "lwc1 $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
12012 ins_encode %{
12013 int con_offset = $constantoffset($src);
12015 if (Assembler::is_simm16(con_offset)) {
12016 __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
12017 } else {
12018 __ set64(AT, con_offset);
12019 if (UseLoongsonISA) {
12020 __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
12021 } else {
12022 __ daddu(AT, $constanttablebase, AT);
12023 __ lwc1($dst$$FloatRegister, AT, 0);
12024 }
12025 }
12026 %}
12027 ins_pipe( fpu_loadF );
12028 %}
12031 instruct loadConD0(regD dst, immD0 zero) %{
12032 match(Set dst zero);
12033 ins_cost(100);
12035 format %{ "mov $dst, zero @ loadConD0"%}
12036 ins_encode %{
12037 FloatRegister dst = as_FloatRegister($dst$$reg);
12039 __ dmtc1(R0, dst);
12040 %}
12041 ins_pipe( fpu_loadF );
12042 %}
12044 instruct loadConD(regD dst, immD src) %{
12045 match(Set dst src);
12046 ins_cost(125);
12048 format %{ "ldc1 $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
12049 ins_encode %{
12050 int con_offset = $constantoffset($src);
12052 if (Assembler::is_simm16(con_offset)) {
12053 __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
12054 } else {
12055 __ set64(AT, con_offset);
12056 if (UseLoongsonISA) {
12057 __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
12058 } else {
12059 __ daddu(AT, $constanttablebase, AT);
12060 __ ldc1($dst$$FloatRegister, AT, 0);
12061 }
12062 }
12063 %}
12064 ins_pipe( fpu_loadF );
12065 %}
12067 // Store register Float value (it is faster than store from FPU register)
12068 instruct storeF_reg( memory mem, regF src) %{
12069 match(Set mem (StoreF mem src));
12071 ins_cost(50);
12072 format %{ "store $mem, $src\t# store float @ storeF_reg" %}
12073 ins_encode(store_F_reg_enc(mem, src));
12074 ins_pipe( fpu_storeF );
12075 %}
12077 instruct storeF_imm0( memory mem, immF0 zero) %{
12078 match(Set mem (StoreF mem zero));
12080 ins_cost(40);
12081 format %{ "store $mem, zero\t# store float @ storeF_imm0" %}
12082 ins_encode %{
12083 int base = $mem$$base;
12084 int index = $mem$$index;
12085 int scale = $mem$$scale;
12086 int disp = $mem$$disp;
12088 if( index != 0 ) {
12089 if(scale != 0) {
12090 __ dsll(T9, as_Register(index), scale);
12091 __ addu(AT, as_Register(base), T9);
12092 } else {
12093 __ daddu(AT, as_Register(base), as_Register(index));
12094 }
12095 if( Assembler::is_simm16(disp) ) {
12096 __ sw(R0, AT, disp);
12097 } else {
12098 __ move(T9, disp);
12099 __ addu(AT, AT, T9);
12100 __ sw(R0, AT, 0);
12101 }
12103 } else {
12104 if( Assembler::is_simm16(disp) ) {
12105 __ sw(R0, as_Register(base), disp);
12106 } else {
12107 __ move(T9, disp);
12108 __ addu(AT, as_Register(base), T9);
12109 __ sw(R0, AT, 0);
12110 }
12111 }
12112 %}
12113 ins_pipe( ialu_storeI );
12114 %}
12116 // Load Double
12117 instruct loadD(regD dst, memory mem) %{
12118 match(Set dst (LoadD mem));
12120 ins_cost(150);
12121 format %{ "loadD $dst, $mem #@loadD" %}
12122 ins_encode(load_D_enc(dst, mem));
12123 ins_pipe( ialu_loadI );
12124 %}
12126 // Load Double - UNaligned
12127 instruct loadD_unaligned(regD dst, memory mem ) %{
12128 match(Set dst (LoadD_unaligned mem));
12129 ins_cost(250);
12130 // FIXME: Jin: Need more effective ldl/ldr
12131 format %{ "loadD_unaligned $dst, $mem #@loadD_unaligned" %}
12132 ins_encode(load_D_enc(dst, mem));
12133 ins_pipe( ialu_loadI );
12134 %}
12136 instruct storeD_reg( memory mem, regD src) %{
12137 match(Set mem (StoreD mem src));
12139 ins_cost(50);
12140 format %{ "store $mem, $src\t# store float @ storeD_reg" %}
12141 ins_encode(store_D_reg_enc(mem, src));
12142 ins_pipe( fpu_storeF );
12143 %}
12145 instruct storeD_imm0( memory mem, immD0 zero) %{
12146 match(Set mem (StoreD mem zero));
12148 ins_cost(40);
12149 format %{ "store $mem, zero\t# store float @ storeD_imm0" %}
12150 ins_encode %{
12151 int base = $mem$$base;
12152 int index = $mem$$index;
12153 int scale = $mem$$scale;
12154 int disp = $mem$$disp;
12156 __ mtc1(R0, F30);
12157 __ cvt_d_w(F30, F30);
12159 if( index != 0 ) {
12160 if(scale != 0) {
12161 __ dsll(T9, as_Register(index), scale);
12162 __ addu(AT, as_Register(base), T9);
12163 } else {
12164 __ daddu(AT, as_Register(base), as_Register(index));
12165 }
12166 if( Assembler::is_simm16(disp) ) {
12167 __ sdc1(F30, AT, disp);
12168 } else {
12169 __ move(T9, disp);
12170 __ addu(AT, AT, T9);
12171 __ sdc1(F30, AT, 0);
12172 }
12174 } else {
12175 if( Assembler::is_simm16(disp) ) {
12176 __ sdc1(F30, as_Register(base), disp);
12177 } else {
12178 __ move(T9, disp);
12179 __ addu(AT, as_Register(base), T9);
12180 __ sdc1(F30, AT, 0);
12181 }
12182 }
12183 %}
12184 ins_pipe( ialu_storeI );
12185 %}
12187 instruct loadSSI(mRegI dst, stackSlotI src)
12188 %{
12189 match(Set dst src);
12191 ins_cost(125);
12192 format %{ "lw $dst, $src\t# int stk @ loadSSI" %}
12193 ins_encode %{
12194 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
12195 __ lw($dst$$Register, SP, $src$$disp);
12196 %}
12197 ins_pipe(ialu_loadI);
12198 %}
12200 instruct storeSSI(stackSlotI dst, mRegI src)
12201 %{
12202 match(Set dst src);
12204 ins_cost(100);
12205 format %{ "sw $dst, $src\t# int stk @ storeSSI" %}
12206 ins_encode %{
12207 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
12208 __ sw($src$$Register, SP, $dst$$disp);
12209 %}
12210 ins_pipe(ialu_storeI);
12211 %}
12213 instruct loadSSL(mRegL dst, stackSlotL src)
12214 %{
12215 match(Set dst src);
12217 ins_cost(125);
12218 format %{ "ld $dst, $src\t# long stk @ loadSSL" %}
12219 ins_encode %{
12220 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
12221 __ ld($dst$$Register, SP, $src$$disp);
12222 %}
12223 ins_pipe(ialu_loadI);
12224 %}
12226 instruct storeSSL(stackSlotL dst, mRegL src)
12227 %{
12228 match(Set dst src);
12230 ins_cost(100);
12231 format %{ "sd $dst, $src\t# long stk @ storeSSL" %}
12232 ins_encode %{
12233 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
12234 __ sd($src$$Register, SP, $dst$$disp);
12235 %}
12236 ins_pipe(ialu_storeI);
12237 %}
12239 instruct loadSSP(mRegP dst, stackSlotP src)
12240 %{
12241 match(Set dst src);
12243 ins_cost(125);
12244 format %{ "ld $dst, $src\t# ptr stk @ loadSSP" %}
12245 ins_encode %{
12246 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
12247 __ ld($dst$$Register, SP, $src$$disp);
12248 %}
12249 ins_pipe(ialu_loadI);
12250 %}
12252 instruct storeSSP(stackSlotP dst, mRegP src)
12253 %{
12254 match(Set dst src);
12256 ins_cost(100);
12257 format %{ "sd $dst, $src\t# ptr stk @ storeSSP" %}
12258 ins_encode %{
12259 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
12260 __ sd($src$$Register, SP, $dst$$disp);
12261 %}
12262 ins_pipe(ialu_storeI);
12263 %}
12265 instruct loadSSF(regF dst, stackSlotF src)
12266 %{
12267 match(Set dst src);
12269 ins_cost(125);
12270 format %{ "lwc1 $dst, $src\t# float stk @ loadSSF" %}
12271 ins_encode %{
12272 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
12273 __ lwc1($dst$$FloatRegister, SP, $src$$disp);
12274 %}
12275 ins_pipe(ialu_loadI);
12276 %}
12278 instruct storeSSF(stackSlotF dst, regF src)
12279 %{
12280 match(Set dst src);
12282 ins_cost(100);
12283 format %{ "swc1 $dst, $src\t# float stk @ storeSSF" %}
12284 ins_encode %{
12285 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
12286 __ swc1($src$$FloatRegister, SP, $dst$$disp);
12287 %}
12288 ins_pipe(fpu_storeF);
12289 %}
12291 // Use the same format since predicate() can not be used here.
12292 instruct loadSSD(regD dst, stackSlotD src)
12293 %{
12294 match(Set dst src);
12296 ins_cost(125);
12297 format %{ "ldc1 $dst, $src\t# double stk @ loadSSD" %}
12298 ins_encode %{
12299 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
12300 __ ldc1($dst$$FloatRegister, SP, $src$$disp);
12301 %}
12302 ins_pipe(ialu_loadI);
12303 %}
12305 instruct storeSSD(stackSlotD dst, regD src)
12306 %{
12307 match(Set dst src);
12309 ins_cost(100);
12310 format %{ "sdc1 $dst, $src\t# double stk @ storeSSD" %}
12311 ins_encode %{
12312 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
12313 __ sdc1($src$$FloatRegister, SP, $dst$$disp);
12314 %}
12315 ins_pipe(fpu_storeF);
12316 %}
12318 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
12319 match( Set cr (FastLock object box) );
12320 effect( TEMP tmp, TEMP scr, USE_KILL box );
12321 ins_cost(300);
12322 format %{ "FASTLOCK $cr $object, $box, $tmp #@ cmpFastLock" %}
12323 ins_encode %{
12324 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
12325 %}
12327 ins_pipe( pipe_slow );
12328 ins_pc_relative(1);
12329 %}
12331 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
12332 match( Set cr (FastUnlock object box) );
12333 effect( TEMP tmp, USE_KILL box );
12334 ins_cost(300);
12335 format %{ "FASTUNLOCK $object, $box, $tmp #@cmpFastUnlock" %}
12336 ins_encode %{
12337 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
12338 %}
12340 ins_pipe( pipe_slow );
12341 ins_pc_relative(1);
12342 %}
12344 // Store CMS card-mark Immediate
12345 instruct storeImmCM(memory mem, immI8 src) %{
12346 match(Set mem (StoreCM mem src));
12348 ins_cost(150);
12349 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %}
12350 // opcode(0xC6);
12351 ins_encode(store_B_immI_enc_sync(mem, src));
12352 ins_pipe( ialu_storeI );
12353 %}
12355 // Die now
12356 instruct ShouldNotReachHere( )
12357 %{
12358 match(Halt);
12359 ins_cost(300);
12361 // Use the following format syntax
12362 format %{ "ILLTRAP ;#@ShouldNotReachHere" %}
12363 ins_encode %{
12364 // Here we should emit illtrap !
12366 __ stop("in ShoudNotReachHere");
12368 %}
12369 ins_pipe( pipe_jump );
12370 %}
12372 instruct leaP8Narrow(mRegP dst, indOffset8Narrow mem)
12373 %{
12374 predicate(Universe::narrow_oop_shift() == 0);
12375 match(Set dst mem);
12377 ins_cost(110);
12378 format %{ "leaq $dst, $mem\t# ptr off8narrow @ leaP8Narrow" %}
12379 ins_encode %{
12380 Register dst = $dst$$Register;
12381 Register base = as_Register($mem$$base);
12382 int disp = $mem$$disp;
12384 __ daddiu(dst, base, disp);
12385 %}
12386 ins_pipe( ialu_regI_imm16 );
12387 %}
12389 instruct leaPPosIdxScaleOff8(mRegP dst, basePosIndexScaleOffset8 mem)
12390 %{
12391 match(Set dst mem);
12393 ins_cost(110);
12394 format %{ "leaq $dst, $mem\t# @ PosIdxScaleOff8" %}
12395 ins_encode %{
12396 Register dst = $dst$$Register;
12397 Register base = as_Register($mem$$base);
12398 Register index = as_Register($mem$$index);
12399 int scale = $mem$$scale;
12400 int disp = $mem$$disp;
12402 if (scale == 0) {
12403 __ daddu(AT, base, index);
12404 __ daddiu(dst, AT, disp);
12405 } else {
12406 __ dsll(AT, index, scale);
12407 __ daddu(AT, base, AT);
12408 __ daddiu(dst, AT, disp);
12409 }
12410 %}
12412 ins_pipe( ialu_regI_imm16 );
12413 %}
12415 instruct leaPIdxScale(mRegP dst, indIndexScale mem)
12416 %{
12417 match(Set dst mem);
12419 ins_cost(110);
12420 format %{ "leaq $dst, $mem\t# @ leaPIdxScale" %}
12421 ins_encode %{
12422 Register dst = $dst$$Register;
12423 Register base = as_Register($mem$$base);
12424 Register index = as_Register($mem$$index);
12425 int scale = $mem$$scale;
12427 if (scale == 0) {
12428 __ daddu(dst, base, index);
12429 } else {
12430 __ dsll(AT, index, scale);
12431 __ daddu(dst, base, AT);
12432 }
12433 %}
12435 ins_pipe( ialu_regI_imm16 );
12436 %}
12438 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12439 instruct jmpLoopEnd(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
12440 match(CountedLoopEnd cop (CmpI src1 src2));
12441 effect(USE labl);
12443 ins_cost(300);
12444 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd" %}
12445 ins_encode %{
12446 Register op1 = $src1$$Register;
12447 Register op2 = $src2$$Register;
12448 Label &L = *($labl$$label);
12449 int flag = $cop$$cmpcode;
12451 switch(flag)
12452 {
12453 case 0x01: //equal
12454 if (&L)
12455 __ beq(op1, op2, L);
12456 else
12457 __ beq(op1, op2, (int)0);
12458 break;
12459 case 0x02: //not_equal
12460 if (&L)
12461 __ bne(op1, op2, L);
12462 else
12463 __ bne(op1, op2, (int)0);
12464 break;
12465 case 0x03: //above
12466 __ slt(AT, op2, op1);
12467 if(&L)
12468 __ bne(AT, R0, L);
12469 else
12470 __ bne(AT, R0, (int)0);
12471 break;
12472 case 0x04: //above_equal
12473 __ slt(AT, op1, op2);
12474 if(&L)
12475 __ beq(AT, R0, L);
12476 else
12477 __ beq(AT, R0, (int)0);
12478 break;
12479 case 0x05: //below
12480 __ slt(AT, op1, op2);
12481 if(&L)
12482 __ bne(AT, R0, L);
12483 else
12484 __ bne(AT, R0, (int)0);
12485 break;
12486 case 0x06: //below_equal
12487 __ slt(AT, op2, op1);
12488 if(&L)
12489 __ beq(AT, R0, L);
12490 else
12491 __ beq(AT, R0, (int)0);
12492 break;
12493 default:
12494 Unimplemented();
12495 }
12496 __ nop();
12497 %}
12498 ins_pipe( pipe_jump );
12499 ins_pc_relative(1);
12500 %}
12503 instruct jmpLoopEnd_reg_imm16_sub(cmpOp cop, mRegI src1, immI16_sub src2, label labl) %{
12504 match(CountedLoopEnd cop (CmpI src1 src2));
12505 effect(USE labl);
12507 ins_cost(250);
12508 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_imm16_sub" %}
12509 ins_encode %{
12510 Register op1 = $src1$$Register;
12511 int op2 = $src2$$constant;
12512 Label &L = *($labl$$label);
12513 int flag = $cop$$cmpcode;
12515 __ addiu32(AT, op1, -1 * op2);
12517 switch(flag)
12518 {
12519 case 0x01: //equal
12520 if (&L)
12521 __ beq(AT, R0, L);
12522 else
12523 __ beq(AT, R0, (int)0);
12524 break;
12525 case 0x02: //not_equal
12526 if (&L)
12527 __ bne(AT, R0, L);
12528 else
12529 __ bne(AT, R0, (int)0);
12530 break;
12531 case 0x03: //above
12532 if(&L)
12533 __ bgtz(AT, L);
12534 else
12535 __ bgtz(AT, (int)0);
12536 break;
12537 case 0x04: //above_equal
12538 if(&L)
12539 __ bgez(AT, L);
12540 else
12541 __ bgez(AT,(int)0);
12542 break;
12543 case 0x05: //below
12544 if(&L)
12545 __ bltz(AT, L);
12546 else
12547 __ bltz(AT, (int)0);
12548 break;
12549 case 0x06: //below_equal
12550 if(&L)
12551 __ blez(AT, L);
12552 else
12553 __ blez(AT, (int)0);
12554 break;
12555 default:
12556 Unimplemented();
12557 }
12558 __ nop();
12559 %}
12560 ins_pipe( pipe_jump );
12561 ins_pc_relative(1);
12562 %}
12565 /*
12566 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12567 instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{
12568 match(CountedLoopEnd cop cmp);
12569 effect(USE labl);
12571 ins_cost(300);
12572 format %{ "J$cop,u $labl\t# Loop end" %}
12573 size(6);
12574 opcode(0x0F, 0x80);
12575 ins_encode( Jcc( cop, labl) );
12576 ins_pipe( pipe_jump );
12577 ins_pc_relative(1);
12578 %}
12580 instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{
12581 match(CountedLoopEnd cop cmp);
12582 effect(USE labl);
12584 ins_cost(200);
12585 format %{ "J$cop,u $labl\t# Loop end" %}
12586 opcode(0x0F, 0x80);
12587 ins_encode( Jcc( cop, labl) );
12588 ins_pipe( pipe_jump );
12589 ins_pc_relative(1);
12590 %}
12591 */
12593 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
12594 instruct jmpCon_flags(cmpOp cop, FlagsReg cr, label labl) %{
12595 match(If cop cr);
12596 effect(USE labl);
12598 ins_cost(300);
12599 format %{ "J$cop $labl #mips uses AT as eflag @jmpCon_flags" %}
12601 ins_encode %{
12602 Label &L = *($labl$$label);
12603 switch($cop$$cmpcode)
12604 {
12605 case 0x01: //equal
12606 if (&L)
12607 __ bne(AT, R0, L);
12608 else
12609 __ bne(AT, R0, (int)0);
12610 break;
12611 case 0x02: //not equal
12612 if (&L)
12613 __ beq(AT, R0, L);
12614 else
12615 __ beq(AT, R0, (int)0);
12616 break;
12617 default:
12618 Unimplemented();
12619 }
12620 __ nop();
12621 %}
12623 ins_pipe( pipe_jump );
12624 ins_pc_relative(1);
12625 %}
12628 // ============================================================================
12629 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
12630 // array for an instance of the superklass. Set a hidden internal cache on a
12631 // hit (cache is checked with exposed code in gen_subtype_check()). Return
12632 // NZ for a miss or zero for a hit. The encoding ALSO sets flags.
12633 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
12634 match(Set result (PartialSubtypeCheck sub super));
12635 effect(KILL tmp);
12636 ins_cost(1100); // slightly larger than the next version
12637 format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
12639 ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
12640 ins_pipe( pipe_slow );
12641 %}
12644 // Conditional-store of an int value.
12645 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
12646 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
12647 match(Set cr (StoreIConditional mem (Binary oldval newval)));
12648 // effect(KILL oldval);
12649 format %{ "CMPXCHG $newval, $mem, $oldval \t# @storeIConditional" %}
12651 ins_encode %{
12652 Register oldval = $oldval$$Register;
12653 Register newval = $newval$$Register;
12654 Address addr(as_Register($mem$$base), $mem$$disp);
12655 Label again, failure;
12657 // int base = $mem$$base;
12658 int index = $mem$$index;
12659 int scale = $mem$$scale;
12660 int disp = $mem$$disp;
12662 guarantee(Assembler::is_simm16(disp), "");
12664 if( index != 0 ) {
12665 __ stop("in storeIConditional: index != 0");
12666 } else {
12667 __ bind(again);
12668 __ sync();
12669 __ ll(AT, addr);
12670 __ bne(AT, oldval, failure);
12671 __ delayed()->addu(AT, R0, R0);
12673 __ addu(AT, newval, R0);
12674 __ sc(AT, addr);
12675 __ beq(AT, R0, again);
12676 __ delayed()->addiu(AT, R0, 0xFF);
12677 __ bind(failure);
12678 __ sync();
12679 }
12680 %}
12682 ins_pipe( long_memory_op );
12683 %}
12685 // Conditional-store of a long value.
12686 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
12687 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
12688 %{
12689 match(Set cr (StoreLConditional mem (Binary oldval newval)));
12690 effect(KILL oldval);
12692 format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
12693 ins_encode%{
12694 Register oldval = $oldval$$Register;
12695 Register newval = $newval$$Register;
12696 Address addr((Register)$mem$$base, $mem$$disp);
12698 int index = $mem$$index;
12699 int scale = $mem$$scale;
12700 int disp = $mem$$disp;
12702 guarantee(Assembler::is_simm16(disp), "");
12704 if( index != 0 ) {
12705 __ stop("in storeIConditional: index != 0");
12706 } else {
12707 __ cmpxchg(newval, addr, oldval);
12708 }
12709 %}
12710 ins_pipe( long_memory_op );
12711 %}
12714 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
12715 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
12716 effect(KILL oldval);
12717 // match(CompareAndSwapI mem_ptr (Binary oldval newval));
12718 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
12719 "MOV $res, 1 @ compareAndSwapI\n\t"
12720 "BNE AT, R0 @ compareAndSwapI\n\t"
12721 "MOV $res, 0 @ compareAndSwapI\n"
12722 "L:" %}
12723 ins_encode %{
12724 Register newval = $newval$$Register;
12725 Register oldval = $oldval$$Register;
12726 Register res = $res$$Register;
12727 Address addr($mem_ptr$$Register, 0);
12728 Label L;
12730 __ cmpxchg32(newval, addr, oldval);
12731 __ move(res, AT);
12732 %}
12733 ins_pipe( long_memory_op );
12734 %}
12736 //FIXME:
12737 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
12738 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
12739 effect(KILL oldval);
12740 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
12741 "MOV $res, AT @ compareAndSwapP\n\t"
12742 "L:" %}
12743 ins_encode %{
12744 Register newval = $newval$$Register;
12745 Register oldval = $oldval$$Register;
12746 Register res = $res$$Register;
12747 Address addr($mem_ptr$$Register, 0);
12748 Label L;
12750 __ cmpxchg(newval, addr, oldval);
12751 __ move(res, AT);
12752 %}
12753 ins_pipe( long_memory_op );
12754 %}
12756 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
12757 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
12758 effect(KILL oldval);
12759 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
12760 "MOV $res, AT @ compareAndSwapN\n\t"
12761 "L:" %}
12762 ins_encode %{
12763 Register newval = $newval$$Register;
12764 Register oldval = $oldval$$Register;
12765 Register res = $res$$Register;
12766 Address addr($mem_ptr$$Register, 0);
12767 Label L;
12769 /* 2013/7/19 Jin: cmpxchg32 is implemented with ll/sc, which will do sign extension.
12770 * Thus, we should extend oldval's sign for correct comparision.
12771 */
12772 __ sll(oldval, oldval, 0);
12774 __ cmpxchg32(newval, addr, oldval);
12775 __ move(res, AT);
12776 %}
12777 ins_pipe( long_memory_op );
12778 %}
12780 //----------Max and Min--------------------------------------------------------
12781 // Min Instructions
12782 ////
12783 // *** Min and Max using the conditional move are slower than the
12784 // *** branch version on a Pentium III.
12785 // // Conditional move for min
12786 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
12787 // effect( USE_DEF op2, USE op1, USE cr );
12788 // format %{ "CMOVlt $op2,$op1\t! min" %}
12789 // opcode(0x4C,0x0F);
12790 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
12791 // ins_pipe( pipe_cmov_reg );
12792 //%}
12793 //
12794 //// Min Register with Register (P6 version)
12795 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
12796 // predicate(VM_Version::supports_cmov() );
12797 // match(Set op2 (MinI op1 op2));
12798 // ins_cost(200);
12799 // expand %{
12800 // eFlagsReg cr;
12801 // compI_eReg(cr,op1,op2);
12802 // cmovI_reg_lt(op2,op1,cr);
12803 // %}
12804 //%}
12806 // Min Register with Register (generic version)
12807 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
12808 match(Set dst (MinI dst src));
12809 //effect(KILL flags);
12810 ins_cost(80);
12812 format %{ "MIN $dst, $src @minI_Reg_Reg" %}
12813 ins_encode %{
12814 Register dst = $dst$$Register;
12815 Register src = $src$$Register;
12817 __ slt(AT, src, dst);
12818 __ movn(dst, src, AT);
12820 %}
12822 ins_pipe( pipe_slow );
12823 %}
12825 // Max Register with Register
12826 // *** Min and Max using the conditional move are slower than the
12827 // *** branch version on a Pentium III.
12828 // // Conditional move for max
12829 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
12830 // effect( USE_DEF op2, USE op1, USE cr );
12831 // format %{ "CMOVgt $op2,$op1\t! max" %}
12832 // opcode(0x4F,0x0F);
12833 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
12834 // ins_pipe( pipe_cmov_reg );
12835 //%}
12836 //
12837 // // Max Register with Register (P6 version)
12838 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
12839 // predicate(VM_Version::supports_cmov() );
12840 // match(Set op2 (MaxI op1 op2));
12841 // ins_cost(200);
12842 // expand %{
12843 // eFlagsReg cr;
12844 // compI_eReg(cr,op1,op2);
12845 // cmovI_reg_gt(op2,op1,cr);
12846 // %}
12847 //%}
12849 // Max Register with Register (generic version)
12850 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
12851 match(Set dst (MaxI dst src));
12852 ins_cost(80);
12854 format %{ "MAX $dst, $src @maxI_Reg_Reg" %}
12856 ins_encode %{
12857 Register dst = $dst$$Register;
12858 Register src = $src$$Register;
12860 __ slt(AT, dst, src);
12861 __ movn(dst, src, AT);
12863 %}
12865 ins_pipe( pipe_slow );
12866 %}
12868 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
12869 match(Set dst (MaxI dst zero));
12870 ins_cost(50);
12872 format %{ "MAX $dst, 0 @maxI_Reg_zero" %}
12874 ins_encode %{
12875 Register dst = $dst$$Register;
12877 __ slt(AT, dst, R0);
12878 __ movn(dst, R0, AT);
12880 %}
12882 ins_pipe( pipe_slow );
12883 %}
12885 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
12886 %{
12887 match(Set dst (AndL src mask));
12889 format %{ "movl $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
12890 ins_encode %{
12891 Register dst = $dst$$Register;
12892 Register src = $src$$Register;
12894 __ dsll32(dst, src, 0);
12895 __ dsrl32(dst, dst, 0);
12896 %}
12897 ins_pipe(ialu_regI_regI);
12898 %}
12900 // Zero-extend convert int to long
12901 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
12902 %{
12903 match(Set dst (AndL (ConvI2L src) mask));
12905 format %{ "movl $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
12906 ins_encode %{
12907 Register dst = $dst$$Register;
12908 Register src = $src$$Register;
12910 __ dsll32(dst, src, 0);
12911 __ dsrl32(dst, dst, 0);
12912 %}
12913 ins_pipe(ialu_regI_regI);
12914 %}
12917 // Match loading integer and casting it to unsigned int in long register.
12918 // LoadI + ConvI2L + AndL 0xffffffff.
12919 instruct loadUI2L_rmask(mRegL dst, memory mem, immL_32bits mask) %{
12920 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
12922 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
12923 ins_encode (load_N_enc(dst, mem));
12924 ins_pipe(ialu_loadI);
12925 %}
12927 instruct loadUI2L_lmask(mRegL dst, memory mem, immL_32bits mask) %{
12928 match(Set dst (AndL mask (ConvI2L (LoadI mem))));
12930 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
12931 ins_encode (load_N_enc(dst, mem));
12932 ins_pipe(ialu_loadI);
12933 %}
12936 // ============================================================================
12937 // Safepoint Instruction
12938 instruct safePoint_poll(mRegP poll) %{
12939 match(SafePoint poll);
12940 effect(USE poll);
12942 ins_cost(125);
12943 format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll" %}
12945 ins_encode %{
12946 Register poll_reg = $poll$$Register;
12948 __ block_comment("Safepoint:");
12949 __ relocate(relocInfo::poll_type);
12950 __ lw(AT, poll_reg, 0);
12951 %}
12953 ins_pipe( ialu_storeI );
12954 %}
12956 //----------Arithmetic Conversion Instructions---------------------------------
12958 instruct roundFloat_nop(regF dst)
12959 %{
12960 match(Set dst (RoundFloat dst));
12962 ins_cost(0);
12963 ins_encode();
12964 ins_pipe(empty);
12965 %}
12967 instruct roundDouble_nop(regD dst)
12968 %{
12969 match(Set dst (RoundDouble dst));
12971 ins_cost(0);
12972 ins_encode();
12973 ins_pipe(empty);
12974 %}
12976 //---------- Zeros Count Instructions ------------------------------------------
12977 // CountLeadingZerosINode CountTrailingZerosINode
12978 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
12979 predicate(UseCountLeadingZerosInstruction);
12980 match(Set dst (CountLeadingZerosI src));
12982 format %{ "clz $dst, $src\t# count leading zeros (int)" %}
12983 ins_encode %{
12984 __ clz($dst$$Register, $src$$Register);
12985 %}
12986 ins_pipe( ialu_regL_regL );
12987 %}
12989 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
12990 predicate(UseCountLeadingZerosInstruction);
12991 match(Set dst (CountLeadingZerosL src));
12993 format %{ "dclz $dst, $src\t# count leading zeros (long)" %}
12994 ins_encode %{
12995 __ dclz($dst$$Register, $src$$Register);
12996 %}
12997 ins_pipe( ialu_regL_regL );
12998 %}
13000 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
13001 predicate(UseCountTrailingZerosInstruction);
13002 match(Set dst (CountTrailingZerosI src));
13004 format %{ "ctz $dst, $src\t# count trailing zeros (int)" %}
13005 ins_encode %{
13006 // ctz and dctz is gs instructions.
13007 __ ctz($dst$$Register, $src$$Register);
13008 %}
13009 ins_pipe( ialu_regL_regL );
13010 %}
13012 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
13013 predicate(UseCountTrailingZerosInstruction);
13014 match(Set dst (CountTrailingZerosL src));
13016 format %{ "dcto $dst, $src\t# count trailing zeros (long)" %}
13017 ins_encode %{
13018 __ dctz($dst$$Register, $src$$Register);
13019 %}
13020 ins_pipe( ialu_regL_regL );
13021 %}
13023 // ====================VECTOR INSTRUCTIONS=====================================
13025 // Load vectors (8 bytes long)
13026 instruct loadV8(vecD dst, memory mem) %{
13027 predicate(n->as_LoadVector()->memory_size() == 8);
13028 match(Set dst (LoadVector mem));
13029 ins_cost(125);
13030 format %{ "load $dst, $mem\t! load vector (8 bytes)" %}
13031 ins_encode(load_D_enc(dst, mem));
13032 ins_pipe( fpu_loadF );
13033 %}
13035 // Store vectors (8 bytes long)
13036 instruct storeV8(memory mem, vecD src) %{
13037 predicate(n->as_StoreVector()->memory_size() == 8);
13038 match(Set mem (StoreVector mem src));
13039 ins_cost(145);
13040 format %{ "store $mem, $src\t! store vector (8 bytes)" %}
13041 ins_encode(store_D_reg_enc(mem, src));
13042 ins_pipe( fpu_storeF );
13043 %}
13045 instruct Repl8B(vecD dst, mRegI src) %{
13046 predicate(n->as_Vector()->length() == 8);
13047 match(Set dst (ReplicateB src));
13048 format %{ "replv_ob AT, $src\n\t"
13049 "dmtc1 AT, $dst\t! replicate8B" %}
13050 ins_encode %{
13051 __ replv_ob(AT, $src$$Register);
13052 __ dmtc1(AT, $dst$$FloatRegister);
13053 %}
13054 ins_pipe( pipe_mtc1 );
13055 %}
13057 instruct Repl8B_imm(vecD dst, immI con) %{
13058 predicate(n->as_Vector()->length() == 8);
13059 match(Set dst (ReplicateB con));
13060 format %{ "repl_ob AT, [$con]\n\t"
13061 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
13062 ins_encode %{
13063 int val = $con$$constant;
13064 __ repl_ob(AT, val);
13065 __ dmtc1(AT, $dst$$FloatRegister);
13066 %}
13067 ins_pipe( pipe_mtc1 );
13068 %}
13070 instruct Repl8B_zero(vecD dst, immI0 zero) %{
13071 predicate(n->as_Vector()->length() == 8);
13072 match(Set dst (ReplicateB zero));
13073 format %{ "dmtc1 R0, $dst\t! replicate8B zero" %}
13074 ins_encode %{
13075 __ dmtc1(R0, $dst$$FloatRegister);
13076 %}
13077 ins_pipe( pipe_mtc1 );
13078 %}
13080 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
13081 predicate(n->as_Vector()->length() == 8);
13082 match(Set dst (ReplicateB M1));
13083 format %{ "dmtc1 -1, $dst\t! replicate8B -1" %}
13084 ins_encode %{
13085 __ nor(AT, R0, R0);
13086 __ dmtc1(AT, $dst$$FloatRegister);
13087 %}
13088 ins_pipe( pipe_mtc1 );
13089 %}
13091 instruct Repl4S(vecD dst, mRegI src) %{
13092 predicate(n->as_Vector()->length() == 4);
13093 match(Set dst (ReplicateS src));
13094 format %{ "replv_qh AT, $src\n\t"
13095 "dmtc1 AT, $dst\t! replicate4S" %}
13096 ins_encode %{
13097 __ replv_qh(AT, $src$$Register);
13098 __ dmtc1(AT, $dst$$FloatRegister);
13099 %}
13100 ins_pipe( pipe_mtc1 );
13101 %}
13103 instruct Repl4S_imm(vecD dst, immI con) %{
13104 predicate(n->as_Vector()->length() == 4);
13105 match(Set dst (ReplicateS con));
13106 format %{ "replv_qh AT, [$con]\n\t"
13107 "dmtc1 AT, $dst\t! replicate4S($con)" %}
13108 ins_encode %{
13109 int val = $con$$constant;
13110 if ( Assembler::is_simm(val, 10)) {
13111 //repl_qh supports 10 bits immediate
13112 __ repl_qh(AT, val);
13113 } else {
13114 __ li32(AT, val);
13115 __ replv_qh(AT, AT);
13116 }
13117 __ dmtc1(R0, $dst$$FloatRegister);
13118 %}
13119 ins_pipe( pipe_mtc1 );
13120 %}
13122 instruct Repl4S_zero(vecD dst, immI0 zero) %{
13123 predicate(n->as_Vector()->length() == 4);
13124 match(Set dst (ReplicateS zero));
13125 format %{ "dmtc1 R0, $dst\t! replicate4S zero" %}
13126 ins_encode %{
13127 __ dmtc1(R0, $dst$$FloatRegister);
13128 %}
13129 ins_pipe( pipe_mtc1 );
13130 %}
13132 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
13133 predicate(n->as_Vector()->length() == 4);
13134 match(Set dst (ReplicateS M1));
13135 format %{ "dmtc1 -1, $dst\t! replicate4S -1" %}
13136 ins_encode %{
13137 __ nor(AT, R0, R0);
13138 __ dmtc1(AT, $dst$$FloatRegister);
13139 %}
13140 ins_pipe( pipe_mtc1 );
13141 %}
13143 // Replicate integer (4 byte) scalar to be vector
13144 instruct Repl2I(vecD dst, mRegI src) %{
13145 predicate(n->as_Vector()->length() == 2);
13146 match(Set dst (ReplicateI src));
13147 format %{ "dins AT, $src, 0, 32\n\t"
13148 "dinsu AT, $src, 32, 32\n\t"
13149 "dmtc1 AT, $dst\t! replicate2I" %}
13150 ins_encode %{
13151 __ dins(AT, $src$$Register, 0, 32);
13152 __ dinsu(AT, $src$$Register, 32, 32);
13153 __ dmtc1(AT, $dst$$FloatRegister);
13154 %}
13155 ins_pipe( pipe_mtc1 );
13156 %}
13158 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
13159 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
13160 predicate(n->as_Vector()->length() == 2);
13161 match(Set dst (ReplicateI con));
13162 effect(KILL tmp);
13163 format %{ "li32 AT, [$con], 32\n\t"
13164 "replv_pw AT, AT\n\t"
13165 "dmtc1 AT, $dst\t! replicate2I($con)" %}
13166 ins_encode %{
13167 int val = $con$$constant;
13168 __ li32(AT, val);
13169 __ replv_pw(AT, AT);
13170 __ dmtc1(AT, $dst$$FloatRegister);
13171 %}
13172 ins_pipe( pipe_mtc1 );
13173 %}
13175 // Replicate integer (4 byte) scalar zero to be vector
13176 instruct Repl2I_zero(vecD dst, immI0 zero) %{
13177 predicate(n->as_Vector()->length() == 2);
13178 match(Set dst (ReplicateI zero));
13179 format %{ "dmtc1 R0, $dst\t! replicate2I zero" %}
13180 ins_encode %{
13181 __ dmtc1(R0, $dst$$FloatRegister);
13182 %}
13183 ins_pipe( pipe_mtc1 );
13184 %}
13186 // Replicate integer (4 byte) scalar -1 to be vector
13187 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
13188 predicate(n->as_Vector()->length() == 2);
13189 match(Set dst (ReplicateI M1));
13190 format %{ "dmtc1 -1, $dst\t! replicate2I -1, use AT" %}
13191 ins_encode %{
13192 __ nor(AT, R0, R0);
13193 __ dmtc1(AT, $dst$$FloatRegister);
13194 %}
13195 ins_pipe( pipe_mtc1 );
13196 %}
13198 // Replicate float (4 byte) scalar to be vector
13199 instruct Repl2F(vecD dst, regF src) %{
13200 predicate(n->as_Vector()->length() == 2);
13201 match(Set dst (ReplicateF src));
13202 format %{ "cvt.ps $dst, $src, $src\t! replicate2F" %}
13203 ins_encode %{
13204 __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
13205 %}
13206 ins_pipe( pipe_slow );
13207 %}
13209 // Replicate float (4 byte) scalar zero to be vector
13210 instruct Repl2F_zero(vecD dst, immF0 zero) %{
13211 predicate(n->as_Vector()->length() == 2);
13212 match(Set dst (ReplicateF zero));
13213 format %{ "dmtc1 R0, $dst\t! replicate2F zero" %}
13214 ins_encode %{
13215 __ dmtc1(R0, $dst$$FloatRegister);
13216 %}
13217 ins_pipe( pipe_mtc1 );
13218 %}
13221 // ====================VECTOR ARITHMETIC=======================================
13223 // --------------------------------- ADD --------------------------------------
13225 // Floats vector add
13226 instruct vadd2F(vecD dst, vecD src) %{
13227 predicate(n->as_Vector()->length() == 2);
13228 match(Set dst (AddVF dst src));
13229 format %{ "add.ps $dst,$src\t! add packed2F" %}
13230 ins_encode %{
13231 __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
13232 %}
13233 ins_pipe( pipe_slow );
13234 %}
13236 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
13237 predicate(n->as_Vector()->length() == 2);
13238 match(Set dst (AddVF src1 src2));
13239 format %{ "add.ps $dst,$src1,$src2\t! add packed2F" %}
13240 ins_encode %{
13241 __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
13242 %}
13243 ins_pipe( fpu_regF_regF );
13244 %}
13246 // --------------------------------- SUB --------------------------------------
13248 // Floats vector sub
13249 instruct vsub2F(vecD dst, vecD src) %{
13250 predicate(n->as_Vector()->length() == 2);
13251 match(Set dst (SubVF dst src));
13252 format %{ "sub.ps $dst,$src\t! sub packed2F" %}
13253 ins_encode %{
13254 __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
13255 %}
13256 ins_pipe( fpu_regF_regF );
13257 %}
13259 // --------------------------------- MUL --------------------------------------
13261 // Floats vector mul
13262 instruct vmul2F(vecD dst, vecD src) %{
13263 predicate(n->as_Vector()->length() == 2);
13264 match(Set dst (MulVF dst src));
13265 format %{ "mul.ps $dst, $src\t! mul packed2F" %}
13266 ins_encode %{
13267 __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
13268 %}
13269 ins_pipe( fpu_regF_regF );
13270 %}
13272 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
13273 predicate(n->as_Vector()->length() == 2);
13274 match(Set dst (MulVF src1 src2));
13275 format %{ "mul.ps $dst, $src1, $src2\t! mul packed2F" %}
13276 ins_encode %{
13277 __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
13278 %}
13279 ins_pipe( fpu_regF_regF );
13280 %}
13282 // --------------------------------- DIV --------------------------------------
13283 // MIPS do not have div.ps
13286 //----------PEEPHOLE RULES-----------------------------------------------------
13287 // These must follow all instruction definitions as they use the names
13288 // defined in the instructions definitions.
13289 //
13290 // peepmatch ( root_instr_name [preceeding_instruction]* );
13291 //
13292 // peepconstraint %{
13293 // (instruction_number.operand_name relational_op instruction_number.operand_name
13294 // [, ...] );
13295 // // instruction numbers are zero-based using left to right order in peepmatch
13296 //
13297 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
13298 // // provide an instruction_number.operand_name for each operand that appears
13299 // // in the replacement instruction's match rule
13300 //
13301 // ---------VM FLAGS---------------------------------------------------------
13302 //
13303 // All peephole optimizations can be turned off using -XX:-OptoPeephole
13304 //
13305 // Each peephole rule is given an identifying number starting with zero and
13306 // increasing by one in the order seen by the parser. An individual peephole
13307 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
13308 // on the command-line.
13309 //
13310 // ---------CURRENT LIMITATIONS----------------------------------------------
13311 //
13312 // Only match adjacent instructions in same basic block
13313 // Only equality constraints
13314 // Only constraints between operands, not (0.dest_reg == EAX_enc)
13315 // Only one replacement instruction
13316 //
13317 // ---------EXAMPLE----------------------------------------------------------
13318 //
13319 // // pertinent parts of existing instructions in architecture description
13320 // instruct movI(eRegI dst, eRegI src) %{
13321 // match(Set dst (CopyI src));
13322 // %}
13323 //
13324 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
13325 // match(Set dst (AddI dst src));
13326 // effect(KILL cr);
13327 // %}
13328 //
13329 // // Change (inc mov) to lea
13330 // peephole %{
13331 // // increment preceeded by register-register move
13332 // peepmatch ( incI_eReg movI );
13333 // // require that the destination register of the increment
13334 // // match the destination register of the move
13335 // peepconstraint ( 0.dst == 1.dst );
13336 // // construct a replacement instruction that sets
13337 // // the destination to ( move's source register + one )
13338 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13339 // %}
13340 //
13341 // Implementation no longer uses movX instructions since
13342 // machine-independent system no longer uses CopyX nodes.
13343 //
13344 // peephole %{
13345 // peepmatch ( incI_eReg movI );
13346 // peepconstraint ( 0.dst == 1.dst );
13347 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13348 // %}
13349 //
13350 // peephole %{
13351 // peepmatch ( decI_eReg movI );
13352 // peepconstraint ( 0.dst == 1.dst );
13353 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13354 // %}
13355 //
13356 // peephole %{
13357 // peepmatch ( addI_eReg_imm movI );
13358 // peepconstraint ( 0.dst == 1.dst );
13359 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13360 // %}
13361 //
13362 // peephole %{
13363 // peepmatch ( addP_eReg_imm movP );
13364 // peepconstraint ( 0.dst == 1.dst );
13365 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
13366 // %}
13368 // // Change load of spilled value to only a spill
13369 // instruct storeI(memory mem, eRegI src) %{
13370 // match(Set mem (StoreI mem src));
13371 // %}
13372 //
13373 // instruct loadI(eRegI dst, memory mem) %{
13374 // match(Set dst (LoadI mem));
13375 // %}
13376 //
13377 //peephole %{
13378 // peepmatch ( loadI storeI );
13379 // peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
13380 // peepreplace ( storeI( 1.mem 1.mem 1.src ) );
13381 //%}
13383 //----------SMARTSPILL RULES---------------------------------------------------
13384 // These must follow all instruction definitions as they use the names
13385 // defined in the instructions definitions.