Thu, 24 May 2018 19:32:53 +0800
[Code Reorganization] update copyright 2018
1 //
2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 // Copyright (c) 2015, 2018, Loongson Technology. All rights reserved.
4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 //
6 // This code is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License version 2 only, as
8 // published by the Free Software Foundation.
9 //
10 // This code is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // version 2 for more details (a copy is included in the LICENSE file that
14 // accompanied this code).
15 //
16 // You should have received a copy of the GNU General Public License version
17 // 2 along with this work; if not, write to the Free Software Foundation,
18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 // or visit www.oracle.com if you need additional information or have any
22 // questions.
23 //
24 //
26 // GodSon3 Architecture Description File
28 //----------REGISTER DEFINITION BLOCK------------------------------------------
29 // This information is used by the matcher and the register allocator to
30 // describe individual registers and classes of registers within the target
31 // archtecture.
33 // format:
34 // reg_def name (call convention, c-call convention, ideal type, encoding);
35 // call convention :
36 // NS = No-Save
37 // SOC = Save-On-Call
38 // SOE = Save-On-Entry
39 // AS = Always-Save
40 // ideal type :
41 // see opto/opcodes.hpp for more info
42 // reg_class name (reg, ...);
43 // alloc_class name (reg, ...);
44 register %{
46 // General Registers
47 // Integer Registers
48 reg_def R0 ( NS, NS, Op_RegI, 0, VMRegImpl::Bad());
49 reg_def AT ( NS, NS, Op_RegI, 1, AT->as_VMReg());
50 reg_def AT_H ( NS, NS, Op_RegI, 1, AT->as_VMReg()->next());
51 reg_def V0 (SOC, SOC, Op_RegI, 2, V0->as_VMReg());
52 reg_def V0_H (SOC, SOC, Op_RegI, 2, V0->as_VMReg()->next());
53 reg_def V1 (SOC, SOC, Op_RegI, 3, V1->as_VMReg());
54 reg_def V1_H (SOC, SOC, Op_RegI, 3, V1->as_VMReg()->next());
55 reg_def A0 (SOC, SOC, Op_RegI, 4, A0->as_VMReg());
56 reg_def A0_H (SOC, SOC, Op_RegI, 4, A0->as_VMReg()->next());
57 reg_def A1 (SOC, SOC, Op_RegI, 5, A1->as_VMReg());
58 reg_def A1_H (SOC, SOC, Op_RegI, 5, A1->as_VMReg()->next());
59 reg_def A2 (SOC, SOC, Op_RegI, 6, A2->as_VMReg());
60 reg_def A2_H (SOC, SOC, Op_RegI, 6, A2->as_VMReg()->next());
61 reg_def A3 (SOC, SOC, Op_RegI, 7, A3->as_VMReg());
62 reg_def A3_H (SOC, SOC, Op_RegI, 7, A3->as_VMReg()->next());
63 reg_def A4 (SOC, SOC, Op_RegI, 8, A4->as_VMReg());
64 reg_def A4_H (SOC, SOC, Op_RegI, 8, A4->as_VMReg()->next());
65 reg_def A5 (SOC, SOC, Op_RegI, 9, A5->as_VMReg());
66 reg_def A5_H (SOC, SOC, Op_RegI, 9, A5->as_VMReg()->next());
67 reg_def A6 (SOC, SOC, Op_RegI, 10, A6->as_VMReg());
68 reg_def A6_H (SOC, SOC, Op_RegI, 10, A6->as_VMReg()->next());
69 reg_def A7 (SOC, SOC, Op_RegI, 11, A7->as_VMReg());
70 reg_def A7_H (SOC, SOC, Op_RegI, 11, A7->as_VMReg()->next());
71 reg_def T0 (SOC, SOC, Op_RegI, 12, T0->as_VMReg());
72 reg_def T0_H (SOC, SOC, Op_RegI, 12, T0->as_VMReg()->next());
73 reg_def T1 (SOC, SOC, Op_RegI, 13, T1->as_VMReg());
74 reg_def T1_H (SOC, SOC, Op_RegI, 13, T1->as_VMReg()->next());
75 reg_def T2 (SOC, SOC, Op_RegI, 14, T2->as_VMReg());
76 reg_def T2_H (SOC, SOC, Op_RegI, 14, T2->as_VMReg()->next());
77 reg_def T3 (SOC, SOC, Op_RegI, 15, T3->as_VMReg());
78 reg_def T3_H (SOC, SOC, Op_RegI, 15, T3->as_VMReg()->next());
79 reg_def S0 (SOC, SOE, Op_RegI, 16, S0->as_VMReg());
80 reg_def S0_H (SOC, SOE, Op_RegI, 16, S0->as_VMReg()->next());
81 reg_def S1 (SOC, SOE, Op_RegI, 17, S1->as_VMReg());
82 reg_def S1_H (SOC, SOE, Op_RegI, 17, S1->as_VMReg()->next());
83 reg_def S2 (SOC, SOE, Op_RegI, 18, S2->as_VMReg());
84 reg_def S2_H (SOC, SOE, Op_RegI, 18, S2->as_VMReg()->next());
85 reg_def S3 (SOC, SOE, Op_RegI, 19, S3->as_VMReg());
86 reg_def S3_H (SOC, SOE, Op_RegI, 19, S3->as_VMReg()->next());
87 reg_def S4 (SOC, SOE, Op_RegI, 20, S4->as_VMReg());
88 reg_def S4_H (SOC, SOE, Op_RegI, 20, S4->as_VMReg()->next());
89 reg_def S5 (SOC, SOE, Op_RegI, 21, S5->as_VMReg());
90 reg_def S5_H (SOC, SOE, Op_RegI, 21, S5->as_VMReg()->next());
91 reg_def S6 (SOC, SOE, Op_RegI, 22, S6->as_VMReg());
92 reg_def S6_H (SOC, SOE, Op_RegI, 22, S6->as_VMReg()->next());
93 reg_def S7 (SOC, SOE, Op_RegI, 23, S7->as_VMReg());
94 reg_def S7_H (SOC, SOE, Op_RegI, 23, S7->as_VMReg()->next());
95 reg_def T8 (SOC, SOC, Op_RegI, 24, T8->as_VMReg());
96 reg_def T8_H (SOC, SOC, Op_RegI, 24, T8->as_VMReg()->next());
97 reg_def T9 (SOC, SOC, Op_RegI, 25, T9->as_VMReg());
98 reg_def T9_H (SOC, SOC, Op_RegI, 25, T9->as_VMReg()->next());
100 // Special Registers
101 reg_def K0 ( NS, NS, Op_RegI, 26, K0->as_VMReg());
102 reg_def K1 ( NS, NS, Op_RegI, 27, K1->as_VMReg());
103 reg_def GP ( NS, NS, Op_RegI, 28, GP->as_VMReg());
104 reg_def GP_H ( NS, NS, Op_RegI, 28, GP->as_VMReg()->next());
105 reg_def SP ( NS, NS, Op_RegI, 29, SP->as_VMReg());
106 reg_def SP_H ( NS, NS, Op_RegI, 29, SP->as_VMReg()->next());
107 reg_def FP ( NS, NS, Op_RegI, 30, FP->as_VMReg());
108 reg_def FP_H ( NS, NS, Op_RegI, 30, FP->as_VMReg()->next());
109 reg_def RA ( NS, NS, Op_RegI, 31, RA->as_VMReg());
110 reg_def RA_H ( NS, NS, Op_RegI, 31, RA->as_VMReg()->next());
112 // Floating registers.
113 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg());
114 reg_def F0_H ( SOC, SOC, Op_RegF, 0, F0->as_VMReg()->next());
115 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg());
116 reg_def F1_H ( SOC, SOC, Op_RegF, 1, F1->as_VMReg()->next());
117 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg());
118 reg_def F2_H ( SOC, SOC, Op_RegF, 2, F2->as_VMReg()->next());
119 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg());
120 reg_def F3_H ( SOC, SOC, Op_RegF, 3, F3->as_VMReg()->next());
121 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg());
122 reg_def F4_H ( SOC, SOC, Op_RegF, 4, F4->as_VMReg()->next());
123 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg());
124 reg_def F5_H ( SOC, SOC, Op_RegF, 5, F5->as_VMReg()->next());
125 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg());
126 reg_def F6_H ( SOC, SOC, Op_RegF, 6, F6->as_VMReg()->next());
127 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg());
128 reg_def F7_H ( SOC, SOC, Op_RegF, 7, F7->as_VMReg()->next());
129 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg());
130 reg_def F8_H ( SOC, SOC, Op_RegF, 8, F8->as_VMReg()->next());
131 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg());
132 reg_def F9_H ( SOC, SOC, Op_RegF, 9, F9->as_VMReg()->next());
133 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg());
134 reg_def F10_H ( SOC, SOC, Op_RegF, 10, F10->as_VMReg()->next());
135 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg());
136 reg_def F11_H ( SOC, SOC, Op_RegF, 11, F11->as_VMReg()->next());
137 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg());
138 reg_def F12_H ( SOC, SOC, Op_RegF, 12, F12->as_VMReg()->next());
139 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg());
140 reg_def F13_H ( SOC, SOC, Op_RegF, 13, F13->as_VMReg()->next());
141 reg_def F14 ( SOC, SOC, Op_RegF, 14, F14->as_VMReg());
142 reg_def F14_H ( SOC, SOC, Op_RegF, 14, F14->as_VMReg()->next());
143 reg_def F15 ( SOC, SOC, Op_RegF, 15, F15->as_VMReg());
144 reg_def F15_H ( SOC, SOC, Op_RegF, 15, F15->as_VMReg()->next());
145 reg_def F16 ( SOC, SOC, Op_RegF, 16, F16->as_VMReg());
146 reg_def F16_H ( SOC, SOC, Op_RegF, 16, F16->as_VMReg()->next());
147 reg_def F17 ( SOC, SOC, Op_RegF, 17, F17->as_VMReg());
148 reg_def F17_H ( SOC, SOC, Op_RegF, 17, F17->as_VMReg()->next());
149 reg_def F18 ( SOC, SOC, Op_RegF, 18, F18->as_VMReg());
150 reg_def F18_H ( SOC, SOC, Op_RegF, 18, F18->as_VMReg()->next());
151 reg_def F19 ( SOC, SOC, Op_RegF, 19, F19->as_VMReg());
152 reg_def F19_H ( SOC, SOC, Op_RegF, 19, F19->as_VMReg()->next());
153 reg_def F20 ( SOC, SOC, Op_RegF, 20, F20->as_VMReg());
154 reg_def F20_H ( SOC, SOC, Op_RegF, 20, F20->as_VMReg()->next());
155 reg_def F21 ( SOC, SOC, Op_RegF, 21, F21->as_VMReg());
156 reg_def F21_H ( SOC, SOC, Op_RegF, 21, F21->as_VMReg()->next());
157 reg_def F22 ( SOC, SOC, Op_RegF, 22, F22->as_VMReg());
158 reg_def F22_H ( SOC, SOC, Op_RegF, 22, F22->as_VMReg()->next());
159 reg_def F23 ( SOC, SOC, Op_RegF, 23, F23->as_VMReg());
160 reg_def F23_H ( SOC, SOC, Op_RegF, 23, F23->as_VMReg()->next());
161 reg_def F24 ( SOC, SOC, Op_RegF, 24, F24->as_VMReg());
162 reg_def F24_H ( SOC, SOC, Op_RegF, 24, F24->as_VMReg()->next());
163 reg_def F25 ( SOC, SOC, Op_RegF, 25, F25->as_VMReg());
164 reg_def F25_H ( SOC, SOC, Op_RegF, 25, F25->as_VMReg()->next());
165 reg_def F26 ( SOC, SOC, Op_RegF, 26, F26->as_VMReg());
166 reg_def F26_H ( SOC, SOC, Op_RegF, 26, F26->as_VMReg()->next());
167 reg_def F27 ( SOC, SOC, Op_RegF, 27, F27->as_VMReg());
168 reg_def F27_H ( SOC, SOC, Op_RegF, 27, F27->as_VMReg()->next());
169 reg_def F28 ( SOC, SOC, Op_RegF, 28, F28->as_VMReg());
170 reg_def F28_H ( SOC, SOC, Op_RegF, 28, F28->as_VMReg()->next());
171 reg_def F29 ( SOC, SOC, Op_RegF, 29, F29->as_VMReg());
172 reg_def F29_H ( SOC, SOC, Op_RegF, 29, F29->as_VMReg()->next());
173 reg_def F30 ( SOC, SOC, Op_RegF, 30, F30->as_VMReg());
174 reg_def F30_H ( SOC, SOC, Op_RegF, 30, F30->as_VMReg()->next());
175 reg_def F31 ( SOC, SOC, Op_RegF, 31, F31->as_VMReg());
176 reg_def F31_H ( SOC, SOC, Op_RegF, 31, F31->as_VMReg()->next());
179 // ----------------------------
180 // Special Registers
181 // Condition Codes Flag Registers
182 reg_def MIPS_FLAG (SOC, SOC, Op_RegFlags, 1, as_Register(1)->as_VMReg());
183 //S6 is used for get_thread(S6)
184 //S5 is uesd for heapbase of compressed oop
185 alloc_class chunk0(
186 S7, S7_H,
187 S0, S0_H,
188 S1, S1_H,
189 S2, S2_H,
190 S4, S4_H,
191 S5, S5_H,
192 S6, S6_H,
193 S3, S3_H,
194 T2, T2_H,
195 T3, T3_H,
196 T8, T8_H,
197 T9, T9_H,
198 T1, T1_H, // inline_cache_reg
199 V1, V1_H,
200 A7, A7_H,
201 A6, A6_H,
202 A5, A5_H,
203 A4, A4_H,
204 V0, V0_H,
205 A3, A3_H,
206 A2, A2_H,
207 A1, A1_H,
208 A0, A0_H,
209 T0, T0_H,
210 GP, GP_H
211 RA, RA_H,
212 SP, SP_H, // stack_pointer
213 FP, FP_H // frame_pointer
214 );
216 alloc_class chunk1( F0, F0_H,
217 F1, F1_H,
218 F2, F2_H,
219 F3, F3_H,
220 F4, F4_H,
221 F5, F5_H,
222 F6, F6_H,
223 F7, F7_H,
224 F8, F8_H,
225 F9, F9_H,
226 F10, F10_H,
227 F11, F11_H,
228 F20, F20_H,
229 F21, F21_H,
230 F22, F22_H,
231 F23, F23_H,
232 F24, F24_H,
233 F25, F25_H,
234 F26, F26_H,
235 F27, F27_H,
236 F28, F28_H,
237 F19, F19_H,
238 F18, F18_H,
239 F17, F17_H,
240 F16, F16_H,
241 F15, F15_H,
242 F14, F14_H,
243 F13, F13_H,
244 F12, F12_H,
245 F29, F29_H,
246 F30, F30_H,
247 F31, F31_H);
249 alloc_class chunk2(MIPS_FLAG);
251 reg_class s_reg( S0, S1, S2, S3, S4, S5, S6, S7 );
252 reg_class s0_reg( S0 );
253 reg_class s1_reg( S1 );
254 reg_class s2_reg( S2 );
255 reg_class s3_reg( S3 );
256 reg_class s4_reg( S4 );
257 reg_class s5_reg( S5 );
258 reg_class s6_reg( S6 );
259 reg_class s7_reg( S7 );
261 reg_class t_reg( T0, T1, T2, T3, T8, T9 );
262 reg_class t0_reg( T0 );
263 reg_class t1_reg( T1 );
264 reg_class t2_reg( T2 );
265 reg_class t3_reg( T3 );
266 reg_class t8_reg( T8 );
267 reg_class t9_reg( T9 );
269 reg_class a_reg( A0, A1, A2, A3, A4, A5, A6, A7 );
270 reg_class a0_reg( A0 );
271 reg_class a1_reg( A1 );
272 reg_class a2_reg( A2 );
273 reg_class a3_reg( A3 );
274 reg_class a4_reg( A4 );
275 reg_class a5_reg( A5 );
276 reg_class a6_reg( A6 );
277 reg_class a7_reg( A7 );
279 reg_class v0_reg( V0 );
280 reg_class v1_reg( V1 );
282 reg_class sp_reg( SP, SP_H );
283 reg_class fp_reg( FP, FP_H );
285 reg_class mips_flags(MIPS_FLAG);
287 reg_class v0_long_reg( V0, V0_H );
288 reg_class v1_long_reg( V1, V1_H );
289 reg_class a0_long_reg( A0, A0_H );
290 reg_class a1_long_reg( A1, A1_H );
291 reg_class a2_long_reg( A2, A2_H );
292 reg_class a3_long_reg( A3, A3_H );
293 reg_class a4_long_reg( A4, A4_H );
294 reg_class a5_long_reg( A5, A5_H );
295 reg_class a6_long_reg( A6, A6_H );
296 reg_class a7_long_reg( A7, A7_H );
297 reg_class t0_long_reg( T0, T0_H );
298 reg_class t1_long_reg( T1, T1_H );
299 reg_class t2_long_reg( T2, T2_H );
300 reg_class t3_long_reg( T3, T3_H );
301 reg_class t8_long_reg( T8, T8_H );
302 reg_class t9_long_reg( T9, T9_H );
303 reg_class s0_long_reg( S0, S0_H );
304 reg_class s1_long_reg( S1, S1_H );
305 reg_class s2_long_reg( S2, S2_H );
306 reg_class s3_long_reg( S3, S3_H );
307 reg_class s4_long_reg( S4, S4_H );
308 reg_class s5_long_reg( S5, S5_H );
309 reg_class s6_long_reg( S6, S6_H );
310 reg_class s7_long_reg( S7, S7_H );
312 reg_class int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, A7, A6, A5, A4, V0, A3, A2, A1, A0, T0 );
314 reg_class no_Ax_int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, V0, T0 );
316 reg_class p_reg(
317 S7, S7_H,
318 S0, S0_H,
319 S1, S1_H,
320 S2, S2_H,
321 S4, S4_H,
322 S3, S3_H,
323 T8, T8_H,
324 T2, T2_H,
325 T3, T3_H,
326 T1, T1_H,
327 A7, A7_H,
328 A6, A6_H,
329 A5, A5_H,
330 A4, A4_H,
331 A3, A3_H,
332 A2, A2_H,
333 A1, A1_H,
334 A0, A0_H,
335 T0, T0_H
336 );
338 reg_class no_T8_p_reg(
339 S7, S7_H,
340 S0, S0_H,
341 S1, S1_H,
342 S2, S2_H,
343 S4, S4_H,
344 S3, S3_H,
345 T2, T2_H,
346 T3, T3_H,
347 T1, T1_H,
348 A7, A7_H,
349 A6, A6_H,
350 A5, A5_H,
351 A4, A4_H,
352 A3, A3_H,
353 A2, A2_H,
354 A1, A1_H,
355 A0, A0_H,
356 T0, T0_H
357 );
359 reg_class long_reg(
360 S7, S7_H,
361 S0, S0_H,
362 S1, S1_H,
363 S2, S2_H,
364 S4, S4_H,
365 S3, S3_H,
366 T8, T8_H,
367 T2, T2_H,
368 T3, T3_H,
369 T1, T1_H,
370 A7, A7_H,
371 A6, A6_H,
372 A5, A5_H,
373 A4, A4_H,
374 A3, A3_H,
375 A2, A2_H,
376 A1, A1_H,
377 A0, A0_H,
378 T0, T0_H
379 );
382 // Floating point registers.
383 // 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 int size = NativeCall::instruction_size;
503 return round_to(size, 16);
504 }
506 #ifdef _LP64
507 static uint size_deopt_handler() {
508 int size = NativeCall::instruction_size;
509 return round_to(size, 16);
510 }
511 #else
512 static uint size_deopt_handler() {
513 // NativeCall instruction size is the same as NativeJump.
514 // exception handler starts out as jump and can be patched to
515 // a call be deoptimization. (4932387)
516 // Note that this value is also credited (in output.cpp) to
517 // the size of the code section.
518 return 5 + NativeJump::instruction_size; // pushl(); jmp;
519 }
520 #endif
521 };
523 %} // end source_hpp
525 source %{
527 #define NO_INDEX 0
528 #define RELOC_IMM64 Assembler::imm_operand
529 #define RELOC_DISP32 Assembler::disp32_operand
532 #define __ _masm.
535 // Emit exception handler code.
536 // Stuff framesize into a register and call a VM stub routine.
537 int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
538 // Note that the code buffer's insts_mark is always relative to insts.
539 // That's why we must use the macroassembler to generate a handler.
540 MacroAssembler _masm(&cbuf);
541 address base = __ start_a_stub(size_exception_handler());
542 if (base == NULL) {
543 ciEnv::current()->record_failure("CodeCache is full");
544 return 0; // CodeBuffer::expand failed
545 }
547 int offset = __ offset();
549 __ block_comment("; emit_exception_handler");
551 cbuf.set_insts_mark();
552 __ relocate(relocInfo::runtime_call_type);
553 __ patchable_jump((address)OptoRuntime::exception_blob()->entry_point());
554 __ align(16);
555 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
556 __ end_a_stub();
557 return offset;
558 }
560 // Emit deopt handler code.
561 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
562 // Note that the code buffer's insts_mark is always relative to insts.
563 // That's why we must use the macroassembler to generate a handler.
564 MacroAssembler _masm(&cbuf);
565 address base = __ start_a_stub(size_deopt_handler());
566 if (base == NULL) {
567 ciEnv::current()->record_failure("CodeCache is full");
568 return 0; // CodeBuffer::expand failed
569 }
571 int offset = __ offset();
573 __ block_comment("; emit_deopt_handler");
575 cbuf.set_insts_mark();
576 __ relocate(relocInfo::runtime_call_type);
577 __ patchable_call(SharedRuntime::deopt_blob()->unpack());
578 __ align(16);
579 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
580 __ end_a_stub();
581 return offset;
582 }
585 const bool Matcher::match_rule_supported(int opcode) {
586 if (!has_match_rule(opcode))
587 return false;
589 switch (opcode) {
590 //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
591 case Op_CountLeadingZerosI:
592 case Op_CountLeadingZerosL:
593 if (!UseCountLeadingZerosInstruction)
594 return false;
595 break;
596 case Op_CountTrailingZerosI:
597 case Op_CountTrailingZerosL:
598 if (!UseCountTrailingZerosInstruction)
599 return false;
600 break;
601 }
603 return true; // Per default match rules are supported.
604 }
606 //FIXME
607 // emit call stub, compiled java to interpreter
608 void emit_java_to_interp(CodeBuffer &cbuf ) {
609 // Stub is fixed up when the corresponding call is converted from calling
610 // compiled code to calling interpreted code.
611 // mov rbx,0
612 // jmp -1
614 address mark = cbuf.insts_mark(); // get mark within main instrs section
616 // Note that the code buffer's insts_mark is always relative to insts.
617 // That's why we must use the macroassembler to generate a stub.
618 MacroAssembler _masm(&cbuf);
620 address base = __ start_a_stub(Compile::MAX_stubs_size);
621 if (base == NULL) { // CodeBuffer::expand failed
622 ciEnv::current()->record_failure("CodeCache is full");
623 }
625 // static stub relocation stores the instruction address of the call
627 __ relocate(static_stub_Relocation::spec(mark), 0);
629 // static stub relocation also tags the methodOop in the code-stream.
630 __ patchable_set48(S3, (long)0);
631 // This is recognized as unresolved by relocs/nativeInst/ic code
633 __ relocate(relocInfo::runtime_call_type);
635 cbuf.set_insts_mark();
636 address call_pc = (address)-1;
637 __ patchable_jump(call_pc);
638 __ align(16);
639 __ end_a_stub();
640 // Update current stubs pointer and restore code_end.
641 }
643 // size of call stub, compiled java to interpretor
644 uint size_java_to_interp() {
645 int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
646 return round_to(size, 16);
647 }
649 // relocation entries for call stub, compiled java to interpreter
650 uint reloc_java_to_interp() {
651 return 16; // in emit_java_to_interp + in Java_Static_Call
652 }
654 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
655 int offs = offset - br_size + 4;
656 // To be conservative on MIPS
657 const int safety_zone = 3 * BytesPerInstWord;
658 return Assembler::is_simm16((offs<0 ? offs-safety_zone : offs+safety_zone) >> 2);
659 }
662 // No additional cost for CMOVL.
663 const int Matcher::long_cmove_cost() { return 0; }
665 // No CMOVF/CMOVD with SSE2
666 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
668 // Does the CPU require late expand (see block.cpp for description of late expand)?
669 const bool Matcher::require_postalloc_expand = false;
671 // Should the Matcher clone shifts on addressing modes, expecting them
672 // to be subsumed into complex addressing expressions or compute them
673 // into registers? True for Intel but false for most RISCs
674 const bool Matcher::clone_shift_expressions = false;
676 // Do we need to mask the count passed to shift instructions or does
677 // the cpu only look at the lower 5/6 bits anyway?
678 const bool Matcher::need_masked_shift_count = false;
680 bool Matcher::narrow_oop_use_complex_address() {
681 NOT_LP64(ShouldNotCallThis());
682 assert(UseCompressedOops, "only for compressed oops code");
683 return false;
684 }
686 bool Matcher::narrow_klass_use_complex_address() {
687 NOT_LP64(ShouldNotCallThis());
688 assert(UseCompressedClassPointers, "only for compressed klass code");
689 return false;
690 }
692 // This is UltraSparc specific, true just means we have fast l2f conversion
693 const bool Matcher::convL2FSupported(void) {
694 return true;
695 }
697 // Max vector size in bytes. 0 if not supported.
698 const int Matcher::vector_width_in_bytes(BasicType bt) {
699 if (MaxVectorSize == 0)
700 return 0;
701 assert(MaxVectorSize == 8, "");
702 return 8;
703 }
705 // Vector ideal reg
706 const int Matcher::vector_ideal_reg(int size) {
707 assert(MaxVectorSize == 8, "");
708 switch(size) {
709 case 8: return Op_VecD;
710 }
711 ShouldNotReachHere();
712 return 0;
713 }
715 // Only lowest bits of xmm reg are used for vector shift count.
716 const int Matcher::vector_shift_count_ideal_reg(int size) {
717 fatal("vector shift is not supported");
718 return Node::NotAMachineReg;
719 }
721 // Limits on vector size (number of elements) loaded into vector.
722 const int Matcher::max_vector_size(const BasicType bt) {
723 assert(is_java_primitive(bt), "only primitive type vectors");
724 return vector_width_in_bytes(bt)/type2aelembytes(bt);
725 }
727 const int Matcher::min_vector_size(const BasicType bt) {
728 return max_vector_size(bt); // Same as max.
729 }
731 // MIPS supports misaligned vectors store/load? FIXME
732 const bool Matcher::misaligned_vectors_ok() {
733 return false;
734 //return !AlignVector; // can be changed by flag
735 }
737 // Register for DIVI projection of divmodI
738 RegMask Matcher::divI_proj_mask() {
739 ShouldNotReachHere();
740 return RegMask();
741 }
743 // Register for MODI projection of divmodI
744 RegMask Matcher::modI_proj_mask() {
745 ShouldNotReachHere();
746 return RegMask();
747 }
749 // Register for DIVL projection of divmodL
750 RegMask Matcher::divL_proj_mask() {
751 ShouldNotReachHere();
752 return RegMask();
753 }
755 int Matcher::regnum_to_fpu_offset(int regnum) {
756 return regnum - 32; // The FP registers are in the second chunk
757 }
760 const bool Matcher::isSimpleConstant64(jlong value) {
761 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
762 return true;
763 }
766 // Return whether or not this register is ever used as an argument. This
767 // function is used on startup to build the trampoline stubs in generateOptoStub.
768 // Registers not mentioned will be killed by the VM call in the trampoline, and
769 // arguments in those registers not be available to the callee.
770 bool Matcher::can_be_java_arg( int reg ) {
771 /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
772 if ( reg == T0_num || reg == T0_H_num
773 || reg == A0_num || reg == A0_H_num
774 || reg == A1_num || reg == A1_H_num
775 || reg == A2_num || reg == A2_H_num
776 || reg == A3_num || reg == A3_H_num
777 || reg == A4_num || reg == A4_H_num
778 || reg == A5_num || reg == A5_H_num
779 || reg == A6_num || reg == A6_H_num
780 || reg == A7_num || reg == A7_H_num )
781 return true;
783 if ( reg == F12_num || reg == F12_H_num
784 || reg == F13_num || reg == F13_H_num
785 || reg == F14_num || reg == F14_H_num
786 || reg == F15_num || reg == F15_H_num
787 || reg == F16_num || reg == F16_H_num
788 || reg == F17_num || reg == F17_H_num
789 || reg == F18_num || reg == F18_H_num
790 || reg == F19_num || reg == F19_H_num )
791 return true;
793 return false;
794 }
796 bool Matcher::is_spillable_arg( int reg ) {
797 return can_be_java_arg(reg);
798 }
800 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
801 return false;
802 }
804 // Register for MODL projection of divmodL
805 RegMask Matcher::modL_proj_mask() {
806 ShouldNotReachHere();
807 return RegMask();
808 }
810 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
811 return FP_REG_mask();
812 }
814 // MIPS doesn't support AES intrinsics
815 const bool Matcher::pass_original_key_for_aes() {
816 return false;
817 }
819 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
820 //lui
821 //ori
822 //dsll
823 //ori
825 //jalr
826 //nop
828 return round_to(current_offset, alignment_required()) - current_offset;
829 }
831 int CallLeafDirectNode::compute_padding(int current_offset) const {
832 //lui
833 //ori
834 //dsll
835 //ori
837 //jalr
838 //nop
840 return round_to(current_offset, alignment_required()) - current_offset;
841 }
843 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
844 //lui
845 //ori
846 //dsll
847 //ori
849 //jalr
850 //nop
852 return round_to(current_offset, alignment_required()) - current_offset;
853 }
855 // If CPU can load and store mis-aligned doubles directly then no fixup is
856 // needed. Else we split the double into 2 integer pieces and move it
857 // piece-by-piece. Only happens when passing doubles into C code as the
858 // Java calling convention forces doubles to be aligned.
859 const bool Matcher::misaligned_doubles_ok = false;
860 // Do floats take an entire double register or just half?
861 //const bool Matcher::float_in_double = true;
862 bool Matcher::float_in_double() { return false; }
863 // Threshold size for cleararray.
864 const int Matcher::init_array_short_size = 8 * BytesPerLong;
865 // Do ints take an entire long register or just half?
866 const bool Matcher::int_in_long = true;
867 // Is it better to copy float constants, or load them directly from memory?
868 // Intel can load a float constant from a direct address, requiring no
869 // extra registers. Most RISCs will have to materialize an address into a
870 // register first, so they would do better to copy the constant from stack.
871 const bool Matcher::rematerialize_float_constants = false;
872 // Advertise here if the CPU requires explicit rounding operations
873 // to implement the UseStrictFP mode.
874 const bool Matcher::strict_fp_requires_explicit_rounding = false;
875 // The ecx parameter to rep stos for the ClearArray node is in dwords.
876 const bool Matcher::init_array_count_is_in_bytes = false;
879 // Indicate if the safepoint node needs the polling page as an input.
880 // Since MIPS doesn't have absolute addressing, it needs.
881 bool SafePointNode::needs_polling_address_input() {
882 return false;
883 }
885 // !!!!! Special hack to get all type of calls to specify the byte offset
886 // from the start of the call to the point where the return address
887 // will point.
888 int MachCallStaticJavaNode::ret_addr_offset() {
889 //lui
890 //ori
891 //nop
892 //nop
893 //jalr
894 //nop
895 return 24;
896 }
898 int MachCallDynamicJavaNode::ret_addr_offset() {
899 //lui IC_Klass,
900 //ori IC_Klass,
901 //dsll IC_Klass
902 //ori IC_Klass
904 //lui T9
905 //ori T9
906 //nop
907 //nop
908 //jalr T9
909 //nop
910 return 4 * 4 + 4 * 6;
911 }
913 //=============================================================================
915 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
916 enum RC { rc_bad, rc_int, rc_float, rc_stack };
917 static enum RC rc_class( OptoReg::Name reg ) {
918 if( !OptoReg::is_valid(reg) ) return rc_bad;
919 if (OptoReg::is_stack(reg)) return rc_stack;
920 VMReg r = OptoReg::as_VMReg(reg);
921 if (r->is_Register()) return rc_int;
922 assert(r->is_FloatRegister(), "must be");
923 return rc_float;
924 }
926 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
927 // Get registers to move
928 OptoReg::Name src_second = ra_->get_reg_second(in(1));
929 OptoReg::Name src_first = ra_->get_reg_first(in(1));
930 OptoReg::Name dst_second = ra_->get_reg_second(this );
931 OptoReg::Name dst_first = ra_->get_reg_first(this );
933 enum RC src_second_rc = rc_class(src_second);
934 enum RC src_first_rc = rc_class(src_first);
935 enum RC dst_second_rc = rc_class(dst_second);
936 enum RC dst_first_rc = rc_class(dst_first);
938 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
940 // Generate spill code!
941 int size = 0;
943 if( src_first == dst_first && src_second == dst_second )
944 return 0; // Self copy, no move
946 if (src_first_rc == rc_stack) {
947 // mem ->
948 if (dst_first_rc == rc_stack) {
949 // mem -> mem
950 assert(src_second != dst_first, "overlap");
951 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
952 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
953 // 64-bit
954 int src_offset = ra_->reg2offset(src_first);
955 int dst_offset = ra_->reg2offset(dst_first);
956 if (cbuf) {
957 MacroAssembler _masm(cbuf);
958 __ ld(AT, Address(SP, src_offset));
959 __ sd(AT, Address(SP, dst_offset));
960 #ifndef PRODUCT
961 } else {
962 if(!do_size){
963 if (size != 0) st->print("\n\t");
964 st->print("ld AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
965 "sd AT, [SP + #%d]",
966 src_offset, dst_offset);
967 }
968 #endif
969 }
970 size += 8;
971 } else {
972 // 32-bit
973 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
974 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
975 // No pushl/popl, so:
976 int src_offset = ra_->reg2offset(src_first);
977 int dst_offset = ra_->reg2offset(dst_first);
978 if (cbuf) {
979 MacroAssembler _masm(cbuf);
980 __ lw(AT, Address(SP, src_offset));
981 __ sw(AT, Address(SP, dst_offset));
982 #ifndef PRODUCT
983 } else {
984 if(!do_size){
985 if (size != 0) st->print("\n\t");
986 st->print("lw AT, [SP + #%d] spill 2\n\t"
987 "sw AT, [SP + #%d]\n\t",
988 src_offset, dst_offset);
989 }
990 #endif
991 }
992 size += 8;
993 }
994 return size;
995 } else if (dst_first_rc == rc_int) {
996 // mem -> gpr
997 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
998 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
999 // 64-bit
1000 int offset = ra_->reg2offset(src_first);
1001 if (cbuf) {
1002 MacroAssembler _masm(cbuf);
1003 __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1004 #ifndef PRODUCT
1005 } else {
1006 if(!do_size){
1007 if (size != 0) st->print("\n\t");
1008 st->print("ld %s, [SP + #%d]\t# spill 3",
1009 Matcher::regName[dst_first],
1010 offset);
1011 }
1012 #endif
1013 }
1014 size += 4;
1015 } else {
1016 // 32-bit
1017 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1018 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1019 int offset = ra_->reg2offset(src_first);
1020 if (cbuf) {
1021 MacroAssembler _masm(cbuf);
1022 if (this->ideal_reg() == Op_RegI)
1023 __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1024 else
1025 __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1026 #ifndef PRODUCT
1027 } else {
1028 if(!do_size){
1029 if (size != 0) st->print("\n\t");
1030 if (this->ideal_reg() == Op_RegI)
1031 st->print("lw %s, [SP + #%d]\t# spill 4",
1032 Matcher::regName[dst_first],
1033 offset);
1034 else
1035 st->print("lwu %s, [SP + #%d]\t# spill 5",
1036 Matcher::regName[dst_first],
1037 offset);
1038 }
1039 #endif
1040 }
1041 size += 4;
1042 }
1043 return size;
1044 } else if (dst_first_rc == rc_float) {
1045 // mem-> xmm
1046 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1047 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1048 // 64-bit
1049 int offset = ra_->reg2offset(src_first);
1050 if (cbuf) {
1051 MacroAssembler _masm(cbuf);
1052 __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1053 #ifndef PRODUCT
1054 } else {
1055 if (!do_size) {
1056 if (size != 0) st->print("\n\t");
1057 st->print("ldc1 %s, [SP + #%d]\t# spill 6",
1058 Matcher::regName[dst_first],
1059 offset);
1060 }
1061 #endif
1062 }
1063 size += 4;
1064 } else {
1065 // 32-bit
1066 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1067 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1068 int offset = ra_->reg2offset(src_first);
1069 if (cbuf) {
1070 MacroAssembler _masm(cbuf);
1071 __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1072 #ifndef PRODUCT
1073 } else {
1074 if(!do_size){
1075 if (size != 0) st->print("\n\t");
1076 st->print("lwc1 %s, [SP + #%d]\t# spill 7",
1077 Matcher::regName[dst_first],
1078 offset);
1079 }
1080 #endif
1081 }
1082 size += 4;
1083 }
1084 return size;
1085 }
1086 } else if (src_first_rc == rc_int) {
1087 // gpr ->
1088 if (dst_first_rc == rc_stack) {
1089 // gpr -> mem
1090 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1091 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1092 // 64-bit
1093 int offset = ra_->reg2offset(dst_first);
1094 if (cbuf) {
1095 MacroAssembler _masm(cbuf);
1096 __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1097 #ifndef PRODUCT
1098 } else {
1099 if(!do_size){
1100 if (size != 0) st->print("\n\t");
1101 st->print("sd %s, [SP + #%d] # spill 8",
1102 Matcher::regName[src_first],
1103 offset);
1104 }
1105 #endif
1106 }
1107 size += 4;
1108 } else {
1109 // 32-bit
1110 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1111 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1112 int offset = ra_->reg2offset(dst_first);
1113 if (cbuf) {
1114 MacroAssembler _masm(cbuf);
1115 __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1116 #ifndef PRODUCT
1117 } else {
1118 if (!do_size) {
1119 if (size != 0) st->print("\n\t");
1120 st->print("sw %s, [SP + #%d]\t# spill 9",
1121 Matcher::regName[src_first], offset);
1122 }
1123 #endif
1124 }
1125 size += 4;
1126 }
1127 return size;
1128 } else if (dst_first_rc == rc_int) {
1129 // gpr -> gpr
1130 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1131 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1132 // 64-bit
1133 if (cbuf) {
1134 MacroAssembler _masm(cbuf);
1135 __ move(as_Register(Matcher::_regEncode[dst_first]),
1136 as_Register(Matcher::_regEncode[src_first]));
1137 #ifndef PRODUCT
1138 } else {
1139 if(!do_size){
1140 if (size != 0) st->print("\n\t");
1141 st->print("move(64bit) %s <-- %s\t# spill 10",
1142 Matcher::regName[dst_first],
1143 Matcher::regName[src_first]);
1144 }
1145 #endif
1146 }
1147 size += 4;
1148 return size;
1149 } else {
1150 // 32-bit
1151 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1152 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1153 if (cbuf) {
1154 MacroAssembler _masm(cbuf);
1155 if (this->ideal_reg() == Op_RegI)
1156 __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1157 else
1158 __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
1159 #ifndef PRODUCT
1160 } else {
1161 if (!do_size) {
1162 if (size != 0) st->print("\n\t");
1163 st->print("move(32-bit) %s <-- %s\t# spill 11",
1164 Matcher::regName[dst_first],
1165 Matcher::regName[src_first]);
1166 }
1167 #endif
1168 }
1169 size += 4;
1170 return size;
1171 }
1172 } else if (dst_first_rc == rc_float) {
1173 // gpr -> xmm
1174 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1175 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1176 // 64-bit
1177 if (cbuf) {
1178 MacroAssembler _masm(cbuf);
1179 __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
1180 #ifndef PRODUCT
1181 } else {
1182 if(!do_size){
1183 if (size != 0) st->print("\n\t");
1184 st->print("dmtc1 %s, %s\t# spill 12",
1185 Matcher::regName[dst_first],
1186 Matcher::regName[src_first]);
1187 }
1188 #endif
1189 }
1190 size += 4;
1191 } else {
1192 // 32-bit
1193 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1194 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1195 if (cbuf) {
1196 MacroAssembler _masm(cbuf);
1197 __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
1198 #ifndef PRODUCT
1199 } else {
1200 if(!do_size){
1201 if (size != 0) st->print("\n\t");
1202 st->print("mtc1 %s, %s\t# spill 13",
1203 Matcher::regName[dst_first],
1204 Matcher::regName[src_first]);
1205 }
1206 #endif
1207 }
1208 size += 4;
1209 }
1210 return size;
1211 }
1212 } else if (src_first_rc == rc_float) {
1213 // xmm ->
1214 if (dst_first_rc == rc_stack) {
1215 // xmm -> mem
1216 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1217 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1218 // 64-bit
1219 int offset = ra_->reg2offset(dst_first);
1220 if (cbuf) {
1221 MacroAssembler _masm(cbuf);
1222 __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
1223 #ifndef PRODUCT
1224 } else {
1225 if(!do_size){
1226 if (size != 0) st->print("\n\t");
1227 st->print("sdc1 %s, [SP + #%d]\t# spill 14",
1228 Matcher::regName[src_first],
1229 offset);
1230 }
1231 #endif
1232 }
1233 size += 4;
1234 } else {
1235 // 32-bit
1236 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1237 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1238 int offset = ra_->reg2offset(dst_first);
1239 if (cbuf) {
1240 MacroAssembler _masm(cbuf);
1241 __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
1242 #ifndef PRODUCT
1243 } else {
1244 if(!do_size){
1245 if (size != 0) st->print("\n\t");
1246 st->print("swc1 %s, [SP + #%d]\t# spill 15",
1247 Matcher::regName[src_first],
1248 offset);
1249 }
1250 #endif
1251 }
1252 size += 4;
1253 }
1254 return size;
1255 } else if (dst_first_rc == rc_int) {
1256 // xmm -> gpr
1257 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1258 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1259 // 64-bit
1260 if (cbuf) {
1261 MacroAssembler _masm(cbuf);
1262 __ dmfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1263 #ifndef PRODUCT
1264 } else {
1265 if(!do_size){
1266 if (size != 0) st->print("\n\t");
1267 st->print("dmfc1 %s, %s\t# spill 16",
1268 Matcher::regName[dst_first],
1269 Matcher::regName[src_first]);
1270 }
1271 #endif
1272 }
1273 size += 4;
1274 } else {
1275 // 32-bit
1276 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1277 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1278 if (cbuf) {
1279 MacroAssembler _masm(cbuf);
1280 __ mfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1281 #ifndef PRODUCT
1282 } else {
1283 if(!do_size){
1284 if (size != 0) st->print("\n\t");
1285 st->print("mfc1 %s, %s\t# spill 17",
1286 Matcher::regName[dst_first],
1287 Matcher::regName[src_first]);
1288 }
1289 #endif
1290 }
1291 size += 4;
1292 }
1293 return size;
1294 } else if (dst_first_rc == rc_float) {
1295 // xmm -> xmm
1296 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1297 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1298 // 64-bit
1299 if (cbuf) {
1300 MacroAssembler _masm(cbuf);
1301 __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1302 #ifndef PRODUCT
1303 } else {
1304 if(!do_size){
1305 if (size != 0) st->print("\n\t");
1306 st->print("mov_d %s <-- %s\t# spill 18",
1307 Matcher::regName[dst_first],
1308 Matcher::regName[src_first]);
1309 }
1310 #endif
1311 }
1312 size += 4;
1313 } else {
1314 // 32-bit
1315 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1316 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1317 if (cbuf) {
1318 MacroAssembler _masm(cbuf);
1319 __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1320 #ifndef PRODUCT
1321 } else {
1322 if(!do_size){
1323 if (size != 0) st->print("\n\t");
1324 st->print("mov_s %s <-- %s\t# spill 19",
1325 Matcher::regName[dst_first],
1326 Matcher::regName[src_first]);
1327 }
1328 #endif
1329 }
1330 size += 4;
1331 }
1332 return size;
1333 }
1334 }
1336 assert(0," foo ");
1337 Unimplemented();
1338 return size;
1340 }
1342 #ifndef PRODUCT
1343 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1344 implementation( NULL, ra_, false, st );
1345 }
1346 #endif
1348 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1349 implementation( &cbuf, ra_, false, NULL );
1350 }
1352 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1353 return implementation( NULL, ra_, true, NULL );
1354 }
1356 //=============================================================================
1357 #
1359 #ifndef PRODUCT
1360 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
1361 st->print("INT3");
1362 }
1363 #endif
1365 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
1366 MacroAssembler _masm(&cbuf);
1367 __ int3();
1368 }
1370 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
1371 return MachNode::size(ra_);
1372 }
1375 //=============================================================================
1376 #ifndef PRODUCT
1377 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1378 Compile *C = ra_->C;
1379 int framesize = C->frame_size_in_bytes();
1381 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1383 st->print("daddiu SP, SP, %d # Rlease stack @ MachEpilogNode",framesize);
1384 st->cr(); st->print("\t");
1385 if (UseLoongsonISA) {
1386 st->print("gslq RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
1387 } else {
1388 st->print("ld RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
1389 st->cr(); st->print("\t");
1390 st->print("ld FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
1391 }
1393 if( do_polling() && C->is_method_compilation() ) {
1394 st->print("Poll Safepoint # MachEpilogNode");
1395 }
1396 }
1397 #endif
1399 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1400 Compile *C = ra_->C;
1401 MacroAssembler _masm(&cbuf);
1402 int framesize = C->frame_size_in_bytes();
1404 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1406 __ daddiu(SP, SP, framesize);
1408 if (UseLoongsonISA) {
1409 __ gslq(RA, FP, SP, -wordSize*2);
1410 } else {
1411 __ ld(RA, SP, -wordSize );
1412 __ ld(FP, SP, -wordSize*2 );
1413 }
1415 if( do_polling() && C->is_method_compilation() ) {
1416 __ set64(AT, (long)os::get_polling_page());
1417 __ relocate(relocInfo::poll_return_type);
1418 __ lw(AT, AT, 0);
1419 }
1420 }
1422 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1423 return MachNode::size(ra_); // too many variables; just compute it the hard way fujie debug
1424 }
1426 int MachEpilogNode::reloc() const {
1427 return 0; // a large enough number
1428 }
1430 const Pipeline * MachEpilogNode::pipeline() const {
1431 return MachNode::pipeline_class();
1432 }
1434 int MachEpilogNode::safepoint_offset() const { return 0; }
1436 //=============================================================================
1438 #ifndef PRODUCT
1439 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1440 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1441 int reg = ra_->get_reg_first(this);
1442 st->print("ADDI %s, SP, %d @BoxLockNode",Matcher::regName[reg],offset);
1443 }
1444 #endif
1447 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1448 return 4;
1449 }
1451 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1452 MacroAssembler _masm(&cbuf);
1453 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1454 int reg = ra_->get_encode(this);
1456 __ addi(as_Register(reg), SP, offset);
1457 }
1460 //static int sizeof_FFree_Float_Stack_All = -1;
1462 int MachCallRuntimeNode::ret_addr_offset() {
1463 //lui
1464 //ori
1465 //dsll
1466 //ori
1467 //jalr
1468 //nop
1469 assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
1470 return NativeCall::instruction_size;
1471 }
1474 //=============================================================================
1475 #ifndef PRODUCT
1476 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
1477 st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
1478 }
1479 #endif
1481 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
1482 MacroAssembler _masm(&cbuf);
1483 int i = 0;
1484 for(i = 0; i < _count; i++)
1485 __ nop();
1486 }
1488 uint MachNopNode::size(PhaseRegAlloc *) const {
1489 return 4 * _count;
1490 }
1491 const Pipeline* MachNopNode::pipeline() const {
1492 return MachNode::pipeline_class();
1493 }
1495 //=============================================================================
1497 //=============================================================================
1498 #ifndef PRODUCT
1499 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1500 st->print_cr("load_klass(T9, T0)");
1501 st->print_cr("\tbeq(T9, iCache, L)");
1502 st->print_cr("\tnop");
1503 st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
1504 st->print_cr("\tnop");
1505 st->print_cr("\tnop");
1506 st->print_cr(" L:");
1507 }
1508 #endif
1511 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1512 MacroAssembler _masm(&cbuf);
1513 #ifdef ASSERT
1514 //uint code_size = cbuf.code_size();
1515 #endif
1516 int ic_reg = Matcher::inline_cache_reg_encode();
1517 Label L;
1518 Register receiver = T0;
1519 Register iCache = as_Register(ic_reg);
1520 __ load_klass(T9, receiver);
1521 __ beq(T9, iCache, L);
1522 __ nop();
1524 __ relocate(relocInfo::runtime_call_type);
1525 __ patchable_jump((address)SharedRuntime::get_ic_miss_stub());
1527 /* WARNING these NOPs are critical so that verified entry point is properly
1528 * 8 bytes aligned for patching by NativeJump::patch_verified_entry() */
1529 __ align(CodeEntryAlignment);
1530 __ bind(L);
1531 }
1533 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1534 return MachNode::size(ra_);
1535 }
1539 //=============================================================================
1541 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
1543 int Compile::ConstantTable::calculate_table_base_offset() const {
1544 return 0; // absolute addressing, no offset
1545 }
1547 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1548 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1549 ShouldNotReachHere();
1550 }
1552 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1553 Compile* C = ra_->C;
1554 Compile::ConstantTable& constant_table = C->constant_table();
1555 MacroAssembler _masm(&cbuf);
1557 Register Rtoc = as_Register(ra_->get_encode(this));
1558 CodeSection* consts_section = __ code()->consts();
1559 int consts_size = consts_section->align_at_start(consts_section->size());
1560 assert(constant_table.size() == consts_size, "must be equal");
1562 if (consts_section->size()) {
1563 // Materialize the constant table base.
1564 address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
1565 // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
1566 __ relocate(relocInfo::internal_word_type);
1567 __ patchable_set48(Rtoc, (long)baseaddr);
1568 }
1569 }
1571 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1572 // patchable_set48 (4 insts)
1573 return 4 * 4;
1574 }
1576 #ifndef PRODUCT
1577 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1578 Register r = as_Register(ra_->get_encode(this));
1579 st->print("patchable_set48 %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
1580 }
1581 #endif
1584 //=============================================================================
1585 #ifndef PRODUCT
1586 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1587 Compile* C = ra_->C;
1589 int framesize = C->frame_size_in_bytes();
1590 int bangsize = C->bang_size_in_bytes();
1591 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1593 // Calls to C2R adapters often do not accept exceptional returns.
1594 // We require that their callers must bang for them. But be careful, because
1595 // some VM calls (such as call site linkage) can use several kilobytes of
1596 // stack. But the stack safety zone should account for that.
1597 // See bugs 4446381, 4468289, 4497237.
1598 if (C->need_stack_bang(bangsize)) {
1599 st->print_cr("# stack bang"); st->print("\t");
1600 }
1601 if (UseLoongsonISA) {
1602 st->print("gssq RA, FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1603 } else {
1604 st->print("sd RA, %d(SP) @ MachPrologNode\n\t", -wordSize);
1605 st->print("sd FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1606 }
1607 st->print("daddiu FP, SP, -%d \n\t", wordSize*2);
1608 st->print("daddiu SP, SP, -%d \t",framesize);
1609 }
1610 #endif
1613 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1614 Compile* C = ra_->C;
1615 MacroAssembler _masm(&cbuf);
1617 int framesize = C->frame_size_in_bytes();
1618 int bangsize = C->bang_size_in_bytes();
1620 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1622 if (C->need_stack_bang(bangsize)) {
1623 __ generate_stack_overflow_check(bangsize);
1624 }
1626 if (UseLoongsonISA) {
1627 __ gssq(RA, FP, SP, -wordSize*2);
1628 } else {
1629 __ sd(RA, SP, -wordSize);
1630 __ sd(FP, SP, -wordSize*2);
1631 }
1632 __ daddiu(FP, SP, -wordSize*2);
1633 __ daddiu(SP, SP, -framesize);
1634 __ nop(); /* 2013.10.22 Jin: Make enough room for patch_verified_entry() */
1635 __ nop();
1637 C->set_frame_complete(cbuf.insts_size());
1638 if (C->has_mach_constant_base_node()) {
1639 // NOTE: We set the table base offset here because users might be
1640 // emitted before MachConstantBaseNode.
1641 Compile::ConstantTable& constant_table = C->constant_table();
1642 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1643 }
1645 }
1648 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1649 return MachNode::size(ra_); // too many variables; just compute it the hard way
1650 }
1652 int MachPrologNode::reloc() const {
1653 return 0; // a large enough number
1654 }
1656 %}
1658 //----------ENCODING BLOCK-----------------------------------------------------
1659 // This block specifies the encoding classes used by the compiler to output
1660 // byte streams. Encoding classes generate functions which are called by
1661 // Machine Instruction Nodes in order to generate the bit encoding of the
1662 // instruction. Operands specify their base encoding interface with the
1663 // interface keyword. There are currently supported four interfaces,
1664 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
1665 // operand to generate a function which returns its register number when
1666 // queried. CONST_INTER causes an operand to generate a function which
1667 // returns the value of the constant when queried. MEMORY_INTER causes an
1668 // operand to generate four functions which return the Base Register, the
1669 // Index Register, the Scale Value, and the Offset Value of the operand when
1670 // queried. COND_INTER causes an operand to generate six functions which
1671 // return the encoding code (ie - encoding bits for the instruction)
1672 // associated with each basic boolean condition for a conditional instruction.
1673 // Instructions specify two basic values for encoding. They use the
1674 // ins_encode keyword to specify their encoding class (which must be one of
1675 // the class names specified in the encoding block), and they use the
1676 // opcode keyword to specify, in order, their primary, secondary, and
1677 // tertiary opcode. Only the opcode sections which a particular instruction
1678 // needs for encoding need to be specified.
1679 encode %{
1681 //Load byte signed
1682 enc_class load_B_enc (mRegI dst, memory mem) %{
1683 MacroAssembler _masm(&cbuf);
1684 int dst = $dst$$reg;
1685 int base = $mem$$base;
1686 int index = $mem$$index;
1687 int scale = $mem$$scale;
1688 int disp = $mem$$disp;
1690 if( index != 0 ) {
1691 if( Assembler::is_simm16(disp) ) {
1692 if( UseLoongsonISA ) {
1693 if (scale == 0) {
1694 __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
1695 } else {
1696 __ dsll(AT, as_Register(index), scale);
1697 __ gslbx(as_Register(dst), as_Register(base), AT, disp);
1698 }
1699 } else {
1700 if (scale == 0) {
1701 __ addu(AT, as_Register(base), as_Register(index));
1702 } else {
1703 __ dsll(AT, as_Register(index), scale);
1704 __ addu(AT, as_Register(base), AT);
1705 }
1706 __ lb(as_Register(dst), AT, disp);
1707 }
1708 } else {
1709 if (scale == 0) {
1710 __ addu(AT, as_Register(base), as_Register(index));
1711 } else {
1712 __ dsll(AT, as_Register(index), scale);
1713 __ addu(AT, as_Register(base), AT);
1714 }
1715 __ move(T9, disp);
1716 if( UseLoongsonISA ) {
1717 __ gslbx(as_Register(dst), AT, T9, 0);
1718 } else {
1719 __ addu(AT, AT, T9);
1720 __ lb(as_Register(dst), AT, 0);
1721 }
1722 }
1723 } else {
1724 if( Assembler::is_simm16(disp) ) {
1725 __ lb(as_Register(dst), as_Register(base), disp);
1726 } else {
1727 __ move(T9, disp);
1728 if( UseLoongsonISA ) {
1729 __ gslbx(as_Register(dst), as_Register(base), T9, 0);
1730 } else {
1731 __ addu(AT, as_Register(base), T9);
1732 __ lb(as_Register(dst), AT, 0);
1733 }
1734 }
1735 }
1736 %}
1738 //Load byte unsigned
1739 enc_class load_UB_enc (mRegI dst, memory mem) %{
1740 MacroAssembler _masm(&cbuf);
1741 int dst = $dst$$reg;
1742 int base = $mem$$base;
1743 int index = $mem$$index;
1744 int scale = $mem$$scale;
1745 int disp = $mem$$disp;
1747 if( index != 0 ) {
1748 if (scale == 0) {
1749 __ daddu(AT, as_Register(base), as_Register(index));
1750 } else {
1751 __ dsll(AT, as_Register(index), scale);
1752 __ daddu(AT, as_Register(base), AT);
1753 }
1754 if( Assembler::is_simm16(disp) ) {
1755 __ lbu(as_Register(dst), AT, disp);
1756 } else {
1757 __ move(T9, disp);
1758 __ daddu(AT, AT, T9);
1759 __ lbu(as_Register(dst), AT, 0);
1760 }
1761 } else {
1762 if( Assembler::is_simm16(disp) ) {
1763 __ lbu(as_Register(dst), as_Register(base), disp);
1764 } else {
1765 __ move(T9, disp);
1766 __ daddu(AT, as_Register(base), T9);
1767 __ lbu(as_Register(dst), AT, 0);
1768 }
1769 }
1770 %}
1772 enc_class store_B_reg_enc (memory mem, mRegI src) %{
1773 MacroAssembler _masm(&cbuf);
1774 int src = $src$$reg;
1775 int base = $mem$$base;
1776 int index = $mem$$index;
1777 int scale = $mem$$scale;
1778 int disp = $mem$$disp;
1780 if( index != 0 ) {
1781 if (scale == 0) {
1782 if( Assembler::is_simm(disp, 8) ) {
1783 if (UseLoongsonISA) {
1784 __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
1785 } else {
1786 __ addu(AT, as_Register(base), as_Register(index));
1787 __ sb(as_Register(src), AT, disp);
1788 }
1789 } else if( Assembler::is_simm16(disp) ) {
1790 __ addu(AT, as_Register(base), as_Register(index));
1791 __ sb(as_Register(src), AT, disp);
1792 } else {
1793 __ addu(AT, as_Register(base), as_Register(index));
1794 __ move(T9, disp);
1795 if (UseLoongsonISA) {
1796 __ gssbx(as_Register(src), AT, T9, 0);
1797 } else {
1798 __ addu(AT, AT, T9);
1799 __ sb(as_Register(src), AT, 0);
1800 }
1801 }
1802 } else {
1803 __ dsll(AT, as_Register(index), scale);
1804 if( Assembler::is_simm(disp, 8) ) {
1805 if (UseLoongsonISA) {
1806 __ gssbx(as_Register(src), AT, as_Register(base), disp);
1807 } else {
1808 __ addu(AT, as_Register(base), AT);
1809 __ sb(as_Register(src), AT, disp);
1810 }
1811 } else if( Assembler::is_simm16(disp) ) {
1812 __ addu(AT, as_Register(base), AT);
1813 __ sb(as_Register(src), AT, disp);
1814 } else {
1815 __ addu(AT, as_Register(base), AT);
1816 __ move(T9, disp);
1817 if (UseLoongsonISA) {
1818 __ gssbx(as_Register(src), AT, T9, 0);
1819 } else {
1820 __ addu(AT, AT, T9);
1821 __ sb(as_Register(src), AT, 0);
1822 }
1823 }
1824 }
1825 } else {
1826 if( Assembler::is_simm16(disp) ) {
1827 __ sb(as_Register(src), as_Register(base), disp);
1828 } else {
1829 __ move(T9, disp);
1830 if (UseLoongsonISA) {
1831 __ gssbx(as_Register(src), as_Register(base), T9, 0);
1832 } else {
1833 __ addu(AT, as_Register(base), T9);
1834 __ sb(as_Register(src), AT, 0);
1835 }
1836 }
1837 }
1838 %}
1840 enc_class store_B_immI_enc (memory mem, immI8 src) %{
1841 MacroAssembler _masm(&cbuf);
1842 int base = $mem$$base;
1843 int index = $mem$$index;
1844 int scale = $mem$$scale;
1845 int disp = $mem$$disp;
1846 int value = $src$$constant;
1848 if( index != 0 ) {
1849 if (!UseLoongsonISA) {
1850 if (scale == 0) {
1851 __ daddu(AT, as_Register(base), as_Register(index));
1852 } else {
1853 __ dsll(AT, as_Register(index), scale);
1854 __ daddu(AT, as_Register(base), AT);
1855 }
1856 if( Assembler::is_simm16(disp) ) {
1857 if (value == 0) {
1858 __ sb(R0, AT, disp);
1859 } else {
1860 __ move(T9, value);
1861 __ sb(T9, AT, disp);
1862 }
1863 } else {
1864 if (value == 0) {
1865 __ move(T9, disp);
1866 __ daddu(AT, AT, T9);
1867 __ sb(R0, AT, 0);
1868 } else {
1869 __ move(T9, disp);
1870 __ daddu(AT, AT, T9);
1871 __ move(T9, value);
1872 __ sb(T9, AT, 0);
1873 }
1874 }
1875 } else {
1877 if (scale == 0) {
1878 if( Assembler::is_simm(disp, 8) ) {
1879 if (value == 0) {
1880 __ gssbx(R0, as_Register(base), as_Register(index), disp);
1881 } else {
1882 __ move(T9, value);
1883 __ gssbx(T9, as_Register(base), as_Register(index), disp);
1884 }
1885 } else if( Assembler::is_simm16(disp) ) {
1886 __ daddu(AT, as_Register(base), as_Register(index));
1887 if (value == 0) {
1888 __ sb(R0, AT, disp);
1889 } else {
1890 __ move(T9, value);
1891 __ sb(T9, AT, disp);
1892 }
1893 } else {
1894 if (value == 0) {
1895 __ daddu(AT, as_Register(base), as_Register(index));
1896 __ move(T9, disp);
1897 __ gssbx(R0, AT, T9, 0);
1898 } else {
1899 __ move(AT, disp);
1900 __ move(T9, value);
1901 __ daddu(AT, as_Register(base), AT);
1902 __ gssbx(T9, AT, as_Register(index), 0);
1903 }
1904 }
1906 } else {
1908 if( Assembler::is_simm(disp, 8) ) {
1909 __ dsll(AT, as_Register(index), scale);
1910 if (value == 0) {
1911 __ gssbx(R0, as_Register(base), AT, disp);
1912 } else {
1913 __ move(T9, value);
1914 __ gssbx(T9, as_Register(base), AT, disp);
1915 }
1916 } else if( Assembler::is_simm16(disp) ) {
1917 __ dsll(AT, as_Register(index), scale);
1918 __ daddu(AT, as_Register(base), AT);
1919 if (value == 0) {
1920 __ sb(R0, AT, disp);
1921 } else {
1922 __ move(T9, value);
1923 __ sb(T9, AT, disp);
1924 }
1925 } else {
1926 __ dsll(AT, as_Register(index), scale);
1927 if (value == 0) {
1928 __ daddu(AT, as_Register(base), AT);
1929 __ move(T9, disp);
1930 __ gssbx(R0, AT, T9, 0);
1931 } else {
1932 __ move(T9, disp);
1933 __ daddu(AT, AT, T9);
1934 __ move(T9, value);
1935 __ gssbx(T9, as_Register(base), AT, 0);
1936 }
1937 }
1938 }
1939 }
1940 } else {
1941 if( Assembler::is_simm16(disp) ) {
1942 if (value == 0) {
1943 __ sb(R0, as_Register(base), disp);
1944 } else {
1945 __ move(AT, value);
1946 __ sb(AT, as_Register(base), disp);
1947 }
1948 } else {
1949 if (value == 0) {
1950 __ move(T9, disp);
1951 if (UseLoongsonISA) {
1952 __ gssbx(R0, as_Register(base), T9, 0);
1953 } else {
1954 __ daddu(AT, as_Register(base), T9);
1955 __ sb(R0, AT, 0);
1956 }
1957 } else {
1958 __ move(T9, disp);
1959 if (UseLoongsonISA) {
1960 __ move(AT, value);
1961 __ gssbx(AT, as_Register(base), T9, 0);
1962 } else {
1963 __ daddu(AT, as_Register(base), T9);
1964 __ move(T9, value);
1965 __ sb(T9, AT, 0);
1966 }
1967 }
1968 }
1969 }
1970 %}
1973 enc_class store_B_immI_enc_sync (memory mem, immI8 src) %{
1974 MacroAssembler _masm(&cbuf);
1975 int base = $mem$$base;
1976 int index = $mem$$index;
1977 int scale = $mem$$scale;
1978 int disp = $mem$$disp;
1979 int value = $src$$constant;
1981 if( index != 0 ) {
1982 if ( UseLoongsonISA ) {
1983 if ( Assembler::is_simm(disp,8) ) {
1984 if ( scale == 0 ) {
1985 if ( value == 0 ) {
1986 __ gssbx(R0, as_Register(base), as_Register(index), disp);
1987 } else {
1988 __ move(AT, value);
1989 __ gssbx(AT, as_Register(base), as_Register(index), disp);
1990 }
1991 } else {
1992 __ dsll(AT, as_Register(index), scale);
1993 if ( value == 0 ) {
1994 __ gssbx(R0, as_Register(base), AT, disp);
1995 } else {
1996 __ move(T9, value);
1997 __ gssbx(T9, as_Register(base), AT, disp);
1998 }
1999 }
2000 } else if ( Assembler::is_simm16(disp) ) {
2001 if ( scale == 0 ) {
2002 __ daddu(AT, as_Register(base), as_Register(index));
2003 if ( value == 0 ){
2004 __ sb(R0, AT, disp);
2005 } else {
2006 __ move(T9, value);
2007 __ sb(T9, AT, disp);
2008 }
2009 } else {
2010 __ dsll(AT, as_Register(index), scale);
2011 __ daddu(AT, as_Register(base), AT);
2012 if ( value == 0 ) {
2013 __ sb(R0, AT, disp);
2014 } else {
2015 __ move(T9, value);
2016 __ sb(T9, AT, disp);
2017 }
2018 }
2019 } else {
2020 if ( scale == 0 ) {
2021 __ move(AT, disp);
2022 __ daddu(AT, as_Register(index), AT);
2023 if ( value == 0 ) {
2024 __ gssbx(R0, as_Register(base), AT, 0);
2025 } else {
2026 __ move(T9, value);
2027 __ gssbx(T9, as_Register(base), AT, 0);
2028 }
2029 } else {
2030 __ dsll(AT, as_Register(index), scale);
2031 __ move(T9, disp);
2032 __ daddu(AT, AT, T9);
2033 if ( value == 0 ) {
2034 __ gssbx(R0, as_Register(base), AT, 0);
2035 } else {
2036 __ move(T9, value);
2037 __ gssbx(T9, as_Register(base), AT, 0);
2038 }
2039 }
2040 }
2041 } else { //not use loongson isa
2042 if (scale == 0) {
2043 __ daddu(AT, as_Register(base), as_Register(index));
2044 } else {
2045 __ dsll(AT, as_Register(index), scale);
2046 __ daddu(AT, as_Register(base), AT);
2047 }
2048 if( Assembler::is_simm16(disp) ) {
2049 if (value == 0) {
2050 __ sb(R0, AT, disp);
2051 } else {
2052 __ move(T9, value);
2053 __ sb(T9, AT, disp);
2054 }
2055 } else {
2056 if (value == 0) {
2057 __ move(T9, disp);
2058 __ daddu(AT, AT, T9);
2059 __ sb(R0, AT, 0);
2060 } else {
2061 __ move(T9, disp);
2062 __ daddu(AT, AT, T9);
2063 __ move(T9, value);
2064 __ sb(T9, AT, 0);
2065 }
2066 }
2067 }
2068 } else {
2069 if ( UseLoongsonISA ){
2070 if ( Assembler::is_simm16(disp) ){
2071 if ( value == 0 ) {
2072 __ sb(R0, as_Register(base), disp);
2073 } else {
2074 __ move(AT, value);
2075 __ sb(AT, as_Register(base), disp);
2076 }
2077 } else {
2078 __ move(AT, disp);
2079 if ( value == 0 ) {
2080 __ gssbx(R0, as_Register(base), AT, 0);
2081 } else {
2082 __ move(T9, value);
2083 __ gssbx(T9, as_Register(base), AT, 0);
2084 }
2085 }
2086 } else {
2087 if( Assembler::is_simm16(disp) ) {
2088 if (value == 0) {
2089 __ sb(R0, as_Register(base), disp);
2090 } else {
2091 __ move(AT, value);
2092 __ sb(AT, as_Register(base), disp);
2093 }
2094 } else {
2095 if (value == 0) {
2096 __ move(T9, disp);
2097 __ daddu(AT, as_Register(base), T9);
2098 __ sb(R0, AT, 0);
2099 } else {
2100 __ move(T9, disp);
2101 __ daddu(AT, as_Register(base), T9);
2102 __ move(T9, value);
2103 __ sb(T9, AT, 0);
2104 }
2105 }
2106 }
2107 }
2109 __ sync();
2110 %}
2112 // Load Short (16bit signed)
2113 enc_class load_S_enc (mRegI dst, memory mem) %{
2114 MacroAssembler _masm(&cbuf);
2115 int dst = $dst$$reg;
2116 int base = $mem$$base;
2117 int index = $mem$$index;
2118 int scale = $mem$$scale;
2119 int disp = $mem$$disp;
2121 if( index != 0 ) {
2122 if ( UseLoongsonISA ) {
2123 if ( Assembler::is_simm(disp, 8) ) {
2124 if (scale == 0) {
2125 __ gslhx(as_Register(dst), as_Register(base), as_Register(index), disp);
2126 } else {
2127 __ dsll(AT, as_Register(index), scale);
2128 __ gslhx(as_Register(dst), as_Register(base), AT, disp);
2129 }
2130 } else if ( Assembler::is_simm16(disp) ) {
2131 if (scale == 0) {
2132 __ daddu(AT, as_Register(base), as_Register(index));
2133 __ lh(as_Register(dst), AT, disp);
2134 } else {
2135 __ dsll(AT, as_Register(index), scale);
2136 __ daddu(AT, as_Register(base), AT);
2137 __ lh(as_Register(dst), AT, disp);
2138 }
2139 } else {
2140 if (scale == 0) {
2141 __ move(AT, disp);
2142 __ daddu(AT, as_Register(index), AT);
2143 __ gslhx(as_Register(dst), as_Register(base), AT, 0);
2144 } else {
2145 __ dsll(AT, as_Register(index), scale);
2146 __ move(T9, disp);
2147 __ daddu(AT, AT, T9);
2148 __ gslhx(as_Register(dst), as_Register(base), AT, 0);
2149 }
2150 }
2151 } else { // not use loongson isa
2152 if (scale == 0) {
2153 __ daddu(AT, as_Register(base), as_Register(index));
2154 } else {
2155 __ dsll(AT, as_Register(index), scale);
2156 __ daddu(AT, as_Register(base), AT);
2157 }
2158 if( Assembler::is_simm16(disp) ) {
2159 __ lh(as_Register(dst), AT, disp);
2160 } else {
2161 __ move(T9, disp);
2162 __ daddu(AT, AT, T9);
2163 __ lh(as_Register(dst), AT, 0);
2164 }
2165 }
2166 } else { // index is 0
2167 if ( UseLoongsonISA ) {
2168 if ( Assembler::is_simm16(disp) ) {
2169 __ lh(as_Register(dst), as_Register(base), disp);
2170 } else {
2171 __ move(T9, disp);
2172 __ gslhx(as_Register(dst), as_Register(base), T9, 0);
2173 }
2174 } else { //not use loongson isa
2175 if( Assembler::is_simm16(disp) ) {
2176 __ lh(as_Register(dst), as_Register(base), disp);
2177 } else {
2178 __ move(T9, disp);
2179 __ daddu(AT, as_Register(base), T9);
2180 __ lh(as_Register(dst), AT, 0);
2181 }
2182 }
2183 }
2184 %}
2186 // Load Char (16bit unsigned)
2187 enc_class load_C_enc (mRegI dst, memory mem) %{
2188 MacroAssembler _masm(&cbuf);
2189 int dst = $dst$$reg;
2190 int base = $mem$$base;
2191 int index = $mem$$index;
2192 int scale = $mem$$scale;
2193 int disp = $mem$$disp;
2195 if( index != 0 ) {
2196 if (scale == 0) {
2197 __ daddu(AT, as_Register(base), as_Register(index));
2198 } else {
2199 __ dsll(AT, as_Register(index), scale);
2200 __ daddu(AT, as_Register(base), AT);
2201 }
2202 if( Assembler::is_simm16(disp) ) {
2203 __ lhu(as_Register(dst), AT, disp);
2204 } else {
2205 __ move(T9, disp);
2206 __ addu(AT, AT, T9);
2207 __ lhu(as_Register(dst), AT, 0);
2208 }
2209 } else {
2210 if( Assembler::is_simm16(disp) ) {
2211 __ lhu(as_Register(dst), as_Register(base), disp);
2212 } else {
2213 __ move(T9, disp);
2214 __ daddu(AT, as_Register(base), T9);
2215 __ lhu(as_Register(dst), AT, 0);
2216 }
2217 }
2218 %}
2220 // Store Char (16bit unsigned)
2221 enc_class store_C_reg_enc (memory mem, mRegI src) %{
2222 MacroAssembler _masm(&cbuf);
2223 int src = $src$$reg;
2224 int base = $mem$$base;
2225 int index = $mem$$index;
2226 int scale = $mem$$scale;
2227 int disp = $mem$$disp;
2229 if( index != 0 ) {
2230 if( Assembler::is_simm16(disp) ) {
2231 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2232 if (scale == 0) {
2233 __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
2234 } else {
2235 __ dsll(AT, as_Register(index), scale);
2236 __ gsshx(as_Register(src), as_Register(base), AT, disp);
2237 }
2238 } else {
2239 if (scale == 0) {
2240 __ addu(AT, as_Register(base), as_Register(index));
2241 } else {
2242 __ dsll(AT, as_Register(index), scale);
2243 __ addu(AT, as_Register(base), AT);
2244 }
2245 __ sh(as_Register(src), AT, disp);
2246 }
2247 } else {
2248 if (scale == 0) {
2249 __ addu(AT, as_Register(base), as_Register(index));
2250 } else {
2251 __ dsll(AT, as_Register(index), scale);
2252 __ addu(AT, as_Register(base), AT);
2253 }
2254 __ move(T9, disp);
2255 if( UseLoongsonISA ) {
2256 __ gsshx(as_Register(src), AT, T9, 0);
2257 } else {
2258 __ addu(AT, AT, T9);
2259 __ sh(as_Register(src), AT, 0);
2260 }
2261 }
2262 } else {
2263 if( Assembler::is_simm16(disp) ) {
2264 __ sh(as_Register(src), as_Register(base), disp);
2265 } else {
2266 __ move(T9, disp);
2267 if( UseLoongsonISA ) {
2268 __ gsshx(as_Register(src), as_Register(base), T9, 0);
2269 } else {
2270 __ addu(AT, as_Register(base), T9);
2271 __ sh(as_Register(src), AT, 0);
2272 }
2273 }
2274 }
2275 %}
2277 enc_class store_C0_enc (memory mem) %{
2278 MacroAssembler _masm(&cbuf);
2279 int base = $mem$$base;
2280 int index = $mem$$index;
2281 int scale = $mem$$scale;
2282 int disp = $mem$$disp;
2284 if( index != 0 ) {
2285 if( Assembler::is_simm16(disp) ) {
2286 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2287 if (scale == 0) {
2288 __ gsshx(R0, as_Register(base), as_Register(index), disp);
2289 } else {
2290 __ dsll(AT, as_Register(index), scale);
2291 __ gsshx(R0, as_Register(base), AT, disp);
2292 }
2293 } else {
2294 if (scale == 0) {
2295 __ addu(AT, as_Register(base), as_Register(index));
2296 } else {
2297 __ dsll(AT, as_Register(index), scale);
2298 __ addu(AT, as_Register(base), AT);
2299 }
2300 __ sh(R0, AT, disp);
2301 }
2302 } else {
2303 if (scale == 0) {
2304 __ addu(AT, as_Register(base), as_Register(index));
2305 } else {
2306 __ dsll(AT, as_Register(index), scale);
2307 __ addu(AT, as_Register(base), AT);
2308 }
2309 __ move(T9, disp);
2310 if( UseLoongsonISA ) {
2311 __ gsshx(R0, AT, T9, 0);
2312 } else {
2313 __ addu(AT, AT, T9);
2314 __ sh(R0, AT, 0);
2315 }
2316 }
2317 } else {
2318 if( Assembler::is_simm16(disp) ) {
2319 __ sh(R0, as_Register(base), disp);
2320 } else {
2321 __ move(T9, disp);
2322 if( UseLoongsonISA ) {
2323 __ gsshx(R0, as_Register(base), T9, 0);
2324 } else {
2325 __ addu(AT, as_Register(base), T9);
2326 __ sh(R0, AT, 0);
2327 }
2328 }
2329 }
2330 %}
2332 enc_class load_I_enc (mRegI dst, memory mem) %{
2333 MacroAssembler _masm(&cbuf);
2334 int dst = $dst$$reg;
2335 int base = $mem$$base;
2336 int index = $mem$$index;
2337 int scale = $mem$$scale;
2338 int disp = $mem$$disp;
2340 if( index != 0 ) {
2341 if( Assembler::is_simm16(disp) ) {
2342 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2343 if (scale == 0) {
2344 __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
2345 } else {
2346 __ dsll(AT, as_Register(index), scale);
2347 __ gslwx(as_Register(dst), as_Register(base), AT, disp);
2348 }
2349 } else {
2350 if (scale == 0) {
2351 __ addu(AT, as_Register(base), as_Register(index));
2352 } else {
2353 __ dsll(AT, as_Register(index), scale);
2354 __ addu(AT, as_Register(base), AT);
2355 }
2356 __ lw(as_Register(dst), AT, disp);
2357 }
2358 } else {
2359 if (scale == 0) {
2360 __ addu(AT, as_Register(base), as_Register(index));
2361 } else {
2362 __ dsll(AT, as_Register(index), scale);
2363 __ addu(AT, as_Register(base), AT);
2364 }
2365 __ move(T9, disp);
2366 if( UseLoongsonISA ) {
2367 __ gslwx(as_Register(dst), AT, T9, 0);
2368 } else {
2369 __ addu(AT, AT, T9);
2370 __ lw(as_Register(dst), AT, 0);
2371 }
2372 }
2373 } else {
2374 if( Assembler::is_simm16(disp) ) {
2375 __ lw(as_Register(dst), as_Register(base), disp);
2376 } else {
2377 __ move(T9, disp);
2378 if( UseLoongsonISA ) {
2379 __ gslwx(as_Register(dst), as_Register(base), T9, 0);
2380 } else {
2381 __ addu(AT, as_Register(base), T9);
2382 __ lw(as_Register(dst), AT, 0);
2383 }
2384 }
2385 }
2386 %}
2388 enc_class store_I_reg_enc (memory mem, mRegI src) %{
2389 MacroAssembler _masm(&cbuf);
2390 int src = $src$$reg;
2391 int base = $mem$$base;
2392 int index = $mem$$index;
2393 int scale = $mem$$scale;
2394 int disp = $mem$$disp;
2396 if( index != 0 ) {
2397 if( Assembler::is_simm16(disp) ) {
2398 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2399 if (scale == 0) {
2400 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
2401 } else {
2402 __ dsll(AT, as_Register(index), scale);
2403 __ gsswx(as_Register(src), as_Register(base), AT, disp);
2404 }
2405 } else {
2406 if (scale == 0) {
2407 __ addu(AT, as_Register(base), as_Register(index));
2408 } else {
2409 __ dsll(AT, as_Register(index), scale);
2410 __ addu(AT, as_Register(base), AT);
2411 }
2412 __ sw(as_Register(src), AT, disp);
2413 }
2414 } else {
2415 if (scale == 0) {
2416 __ addu(AT, as_Register(base), as_Register(index));
2417 } else {
2418 __ dsll(AT, as_Register(index), scale);
2419 __ addu(AT, as_Register(base), AT);
2420 }
2421 __ move(T9, disp);
2422 if( UseLoongsonISA ) {
2423 __ gsswx(as_Register(src), AT, T9, 0);
2424 } else {
2425 __ addu(AT, AT, T9);
2426 __ sw(as_Register(src), AT, 0);
2427 }
2428 }
2429 } else {
2430 if( Assembler::is_simm16(disp) ) {
2431 __ sw(as_Register(src), as_Register(base), disp);
2432 } else {
2433 __ move(T9, disp);
2434 if( UseLoongsonISA ) {
2435 __ gsswx(as_Register(src), as_Register(base), T9, 0);
2436 } else {
2437 __ addu(AT, as_Register(base), T9);
2438 __ sw(as_Register(src), AT, 0);
2439 }
2440 }
2441 }
2442 %}
2444 enc_class store_I_immI_enc (memory mem, immI src) %{
2445 MacroAssembler _masm(&cbuf);
2446 int base = $mem$$base;
2447 int index = $mem$$index;
2448 int scale = $mem$$scale;
2449 int disp = $mem$$disp;
2450 int value = $src$$constant;
2452 if( index != 0 ) {
2453 if ( UseLoongsonISA ) {
2454 if ( Assembler::is_simm(disp, 8) ) {
2455 if ( scale == 0 ) {
2456 if ( value == 0 ) {
2457 __ gsswx(R0, as_Register(base), as_Register(index), disp);
2458 } else {
2459 __ move(T9, value);
2460 __ gsswx(T9, as_Register(base), as_Register(index), disp);
2461 }
2462 } else {
2463 __ dsll(AT, as_Register(index), scale);
2464 if ( value == 0 ) {
2465 __ gsswx(R0, as_Register(base), AT, disp);
2466 } else {
2467 __ move(T9, value);
2468 __ gsswx(T9, as_Register(base), AT, disp);
2469 }
2470 }
2471 } else if ( Assembler::is_simm16(disp) ) {
2472 if ( scale == 0 ) {
2473 __ daddu(AT, as_Register(base), as_Register(index));
2474 if ( value == 0 ) {
2475 __ sw(R0, AT, disp);
2476 } else {
2477 __ move(T9, value);
2478 __ sw(T9, AT, disp);
2479 }
2480 } else {
2481 __ dsll(AT, as_Register(index), scale);
2482 __ daddu(AT, as_Register(base), AT);
2483 if ( value == 0 ) {
2484 __ sw(R0, AT, disp);
2485 } else {
2486 __ move(T9, value);
2487 __ sw(T9, AT, disp);
2488 }
2489 }
2490 } else {
2491 if ( scale == 0 ) {
2492 __ move(T9, disp);
2493 __ daddu(AT, as_Register(index), T9);
2494 if ( value ==0 ) {
2495 __ gsswx(R0, as_Register(base), AT, 0);
2496 } else {
2497 __ move(T9, value);
2498 __ gsswx(T9, as_Register(base), AT, 0);
2499 }
2500 } else {
2501 __ dsll(AT, as_Register(index), scale);
2502 __ move(T9, disp);
2503 __ daddu(AT, AT, T9);
2504 if ( value == 0 ) {
2505 __ gsswx(R0, as_Register(base), AT, 0);
2506 } else {
2507 __ move(T9, value);
2508 __ gsswx(T9, as_Register(base), AT, 0);
2509 }
2510 }
2511 }
2512 } else { //not use loongson isa
2513 if (scale == 0) {
2514 __ daddu(AT, as_Register(base), as_Register(index));
2515 } else {
2516 __ dsll(AT, as_Register(index), scale);
2517 __ daddu(AT, as_Register(base), AT);
2518 }
2519 if( Assembler::is_simm16(disp) ) {
2520 if (value == 0) {
2521 __ sw(R0, AT, disp);
2522 } else {
2523 __ move(T9, value);
2524 __ sw(T9, AT, disp);
2525 }
2526 } else {
2527 if (value == 0) {
2528 __ move(T9, disp);
2529 __ daddu(AT, AT, T9);
2530 __ sw(R0, AT, 0);
2531 } else {
2532 __ move(T9, disp);
2533 __ daddu(AT, AT, T9);
2534 __ move(T9, value);
2535 __ sw(T9, AT, 0);
2536 }
2537 }
2538 }
2539 } else {
2540 if ( UseLoongsonISA ) {
2541 if ( Assembler::is_simm16(disp) ) {
2542 if ( value == 0 ) {
2543 __ sw(R0, as_Register(base), disp);
2544 } else {
2545 __ move(AT, value);
2546 __ sw(AT, as_Register(base), disp);
2547 }
2548 } else {
2549 __ move(T9, disp);
2550 if ( value == 0 ) {
2551 __ gsswx(R0, as_Register(base), T9, 0);
2552 } else {
2553 __ move(AT, value);
2554 __ gsswx(AT, as_Register(base), T9, 0);
2555 }
2556 }
2557 } else {
2558 if( Assembler::is_simm16(disp) ) {
2559 if (value == 0) {
2560 __ sw(R0, as_Register(base), disp);
2561 } else {
2562 __ move(AT, value);
2563 __ sw(AT, as_Register(base), disp);
2564 }
2565 } else {
2566 if (value == 0) {
2567 __ move(T9, disp);
2568 __ daddu(AT, as_Register(base), T9);
2569 __ sw(R0, AT, 0);
2570 } else {
2571 __ move(T9, disp);
2572 __ daddu(AT, as_Register(base), T9);
2573 __ move(T9, value);
2574 __ sw(T9, AT, 0);
2575 }
2576 }
2577 }
2578 }
2579 %}
2581 enc_class load_N_enc (mRegN dst, memory mem) %{
2582 MacroAssembler _masm(&cbuf);
2583 int dst = $dst$$reg;
2584 int base = $mem$$base;
2585 int index = $mem$$index;
2586 int scale = $mem$$scale;
2587 int disp = $mem$$disp;
2588 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2589 assert(disp_reloc == relocInfo::none, "cannot have 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 __ lwu(as_Register(dst), AT, disp);
2600 } else {
2601 __ set64(T9, disp);
2602 __ daddu(AT, AT, T9);
2603 __ lwu(as_Register(dst), AT, 0);
2604 }
2605 } else {
2606 if( Assembler::is_simm16(disp) ) {
2607 __ lwu(as_Register(dst), as_Register(base), disp);
2608 } else {
2609 __ set64(T9, disp);
2610 __ daddu(AT, as_Register(base), T9);
2611 __ lwu(as_Register(dst), AT, 0);
2612 }
2613 }
2614 %}
2617 enc_class load_P_enc (mRegP dst, memory mem) %{
2618 MacroAssembler _masm(&cbuf);
2619 int dst = $dst$$reg;
2620 int base = $mem$$base;
2621 int index = $mem$$index;
2622 int scale = $mem$$scale;
2623 int disp = $mem$$disp;
2624 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2625 assert(disp_reloc == relocInfo::none, "cannot have disp");
2627 if( index != 0 ) {
2628 if ( UseLoongsonISA ) {
2629 if ( Assembler::is_simm(disp, 8) ) {
2630 if ( scale != 0 ) {
2631 __ dsll(AT, as_Register(index), scale);
2632 __ gsldx(as_Register(dst), as_Register(base), AT, disp);
2633 } else {
2634 __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
2635 }
2636 } else if ( Assembler::is_simm16(disp) ){
2637 if ( scale != 0 ) {
2638 __ dsll(AT, as_Register(index), scale);
2639 __ daddu(AT, AT, as_Register(base));
2640 } else {
2641 __ daddu(AT, as_Register(index), as_Register(base));
2642 }
2643 __ ld(as_Register(dst), AT, disp);
2644 } else {
2645 if ( scale != 0 ) {
2646 __ dsll(AT, as_Register(index), scale);
2647 __ move(T9, disp);
2648 __ daddu(AT, AT, T9);
2649 } else {
2650 __ move(T9, disp);
2651 __ daddu(AT, as_Register(index), T9);
2652 }
2653 __ gsldx(as_Register(dst), as_Register(base), AT, 0);
2654 }
2655 } else { //not use loongson isa
2656 if (scale == 0) {
2657 __ daddu(AT, as_Register(base), as_Register(index));
2658 } else {
2659 __ dsll(AT, as_Register(index), scale);
2660 __ daddu(AT, as_Register(base), AT);
2661 }
2662 if( Assembler::is_simm16(disp) ) {
2663 __ ld(as_Register(dst), AT, disp);
2664 } else {
2665 __ set64(T9, disp);
2666 __ daddu(AT, AT, T9);
2667 __ ld(as_Register(dst), AT, 0);
2668 }
2669 }
2670 } else {
2671 if ( UseLoongsonISA ) {
2672 if ( Assembler::is_simm16(disp) ){
2673 __ ld(as_Register(dst), as_Register(base), disp);
2674 } else {
2675 __ set64(T9, disp);
2676 __ gsldx(as_Register(dst), as_Register(base), T9, 0);
2677 }
2678 } else { //not use loongson isa
2679 if( Assembler::is_simm16(disp) ) {
2680 __ ld(as_Register(dst), as_Register(base), disp);
2681 } else {
2682 __ set64(T9, disp);
2683 __ daddu(AT, as_Register(base), T9);
2684 __ ld(as_Register(dst), AT, 0);
2685 }
2686 }
2687 }
2688 %}
2690 enc_class store_P_reg_enc (memory mem, mRegP src) %{
2691 MacroAssembler _masm(&cbuf);
2692 int src = $src$$reg;
2693 int base = $mem$$base;
2694 int index = $mem$$index;
2695 int scale = $mem$$scale;
2696 int disp = $mem$$disp;
2698 if( index != 0 ) {
2699 if ( UseLoongsonISA ){
2700 if ( Assembler::is_simm(disp, 8) ) {
2701 if ( scale == 0 ) {
2702 __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
2703 } else {
2704 __ dsll(AT, as_Register(index), scale);
2705 __ gssdx(as_Register(src), as_Register(base), AT, disp);
2706 }
2707 } else if ( Assembler::is_simm16(disp) ) {
2708 if ( scale == 0 ) {
2709 __ daddu(AT, as_Register(base), as_Register(index));
2710 } else {
2711 __ dsll(AT, as_Register(index), scale);
2712 __ daddu(AT, as_Register(base), AT);
2713 }
2714 __ sd(as_Register(src), AT, disp);
2715 } else {
2716 if ( scale == 0 ) {
2717 __ move(T9, disp);
2718 __ daddu(AT, as_Register(index), T9);
2719 } else {
2720 __ dsll(AT, as_Register(index), scale);
2721 __ move(T9, disp);
2722 __ daddu(AT, AT, T9);
2723 }
2724 __ gssdx(as_Register(src), as_Register(base), AT, 0);
2725 }
2726 } else { //not use loongson isa
2727 if (scale == 0) {
2728 __ daddu(AT, as_Register(base), as_Register(index));
2729 } else {
2730 __ dsll(AT, as_Register(index), scale);
2731 __ daddu(AT, as_Register(base), AT);
2732 }
2733 if( Assembler::is_simm16(disp) ) {
2734 __ sd(as_Register(src), AT, disp);
2735 } else {
2736 __ move(T9, disp);
2737 __ daddu(AT, AT, T9);
2738 __ sd(as_Register(src), AT, 0);
2739 }
2740 }
2741 } else {
2742 if ( UseLoongsonISA ) {
2743 if ( Assembler::is_simm16(disp) ) {
2744 __ sd(as_Register(src), as_Register(base), disp);
2745 } else {
2746 __ move(T9, disp);
2747 __ gssdx(as_Register(src), as_Register(base), T9, 0);
2748 }
2749 } else {
2750 if( Assembler::is_simm16(disp) ) {
2751 __ sd(as_Register(src), as_Register(base), disp);
2752 } else {
2753 __ move(T9, disp);
2754 __ daddu(AT, as_Register(base), T9);
2755 __ sd(as_Register(src), AT, 0);
2756 }
2757 }
2758 }
2759 %}
2761 enc_class store_N_reg_enc (memory mem, mRegN src) %{
2762 MacroAssembler _masm(&cbuf);
2763 int src = $src$$reg;
2764 int base = $mem$$base;
2765 int index = $mem$$index;
2766 int scale = $mem$$scale;
2767 int disp = $mem$$disp;
2769 if( index != 0 ) {
2770 if ( UseLoongsonISA ){
2771 if ( Assembler::is_simm(disp, 8) ) {
2772 if ( scale == 0 ) {
2773 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
2774 } else {
2775 __ dsll(AT, as_Register(index), scale);
2776 __ gsswx(as_Register(src), as_Register(base), AT, disp);
2777 }
2778 } else if ( Assembler::is_simm16(disp) ) {
2779 if ( scale == 0 ) {
2780 __ daddu(AT, as_Register(base), as_Register(index));
2781 } else {
2782 __ dsll(AT, as_Register(index), scale);
2783 __ daddu(AT, as_Register(base), AT);
2784 }
2785 __ sw(as_Register(src), AT, disp);
2786 } else {
2787 if ( scale == 0 ) {
2788 __ move(T9, disp);
2789 __ daddu(AT, as_Register(index), T9);
2790 } else {
2791 __ dsll(AT, as_Register(index), scale);
2792 __ move(T9, disp);
2793 __ daddu(AT, AT, T9);
2794 }
2795 __ gsswx(as_Register(src), as_Register(base), AT, 0);
2796 }
2797 } else { //not use loongson isa
2798 if (scale == 0) {
2799 __ daddu(AT, as_Register(base), as_Register(index));
2800 } else {
2801 __ dsll(AT, as_Register(index), scale);
2802 __ daddu(AT, as_Register(base), AT);
2803 }
2804 if( Assembler::is_simm16(disp) ) {
2805 __ sw(as_Register(src), AT, disp);
2806 } else {
2807 __ move(T9, disp);
2808 __ daddu(AT, AT, T9);
2809 __ sw(as_Register(src), AT, 0);
2810 }
2811 }
2812 } else {
2813 if ( UseLoongsonISA ) {
2814 if ( Assembler::is_simm16(disp) ) {
2815 __ sw(as_Register(src), as_Register(base), disp);
2816 } else {
2817 __ move(T9, disp);
2818 __ gsswx(as_Register(src), as_Register(base), T9, 0);
2819 }
2820 } else {
2821 if( Assembler::is_simm16(disp) ) {
2822 __ sw(as_Register(src), as_Register(base), disp);
2823 } else {
2824 __ move(T9, disp);
2825 __ daddu(AT, as_Register(base), T9);
2826 __ sw(as_Register(src), AT, 0);
2827 }
2828 }
2829 }
2830 %}
2832 enc_class store_P_immP0_enc (memory mem) %{
2833 MacroAssembler _masm(&cbuf);
2834 int base = $mem$$base;
2835 int index = $mem$$index;
2836 int scale = $mem$$scale;
2837 int disp = $mem$$disp;
2839 if( index != 0 ) {
2840 if (scale == 0) {
2841 if( Assembler::is_simm16(disp) ) {
2842 if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
2843 __ gssdx(R0, as_Register(base), as_Register(index), disp);
2844 } else {
2845 __ daddu(AT, as_Register(base), as_Register(index));
2846 __ sd(R0, AT, disp);
2847 }
2848 } else {
2849 __ daddu(AT, as_Register(base), as_Register(index));
2850 __ move(T9, disp);
2851 if(UseLoongsonISA) {
2852 __ gssdx(R0, AT, T9, 0);
2853 } else {
2854 __ daddu(AT, AT, T9);
2855 __ sd(R0, AT, 0);
2856 }
2857 }
2858 } else {
2859 __ dsll(AT, as_Register(index), scale);
2860 if( Assembler::is_simm16(disp) ) {
2861 if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
2862 __ gssdx(R0, as_Register(base), AT, disp);
2863 } else {
2864 __ daddu(AT, as_Register(base), AT);
2865 __ sd(R0, AT, disp);
2866 }
2867 } else {
2868 __ daddu(AT, as_Register(base), AT);
2869 __ move(T9, disp);
2870 if (UseLoongsonISA) {
2871 __ gssdx(R0, AT, T9, 0);
2872 } else {
2873 __ daddu(AT, AT, T9);
2874 __ sd(R0, AT, 0);
2875 }
2876 }
2877 }
2878 } else {
2879 if( Assembler::is_simm16(disp) ) {
2880 __ sd(R0, as_Register(base), disp);
2881 } else {
2882 __ move(T9, disp);
2883 if (UseLoongsonISA) {
2884 __ gssdx(R0, as_Register(base), T9, 0);
2885 } else {
2886 __ daddu(AT, as_Register(base), T9);
2887 __ sd(R0, AT, 0);
2888 }
2889 }
2890 }
2891 %}
2893 enc_class storeImmN0_enc(memory mem, ImmN0 src) %{
2894 MacroAssembler _masm(&cbuf);
2895 int base = $mem$$base;
2896 int index = $mem$$index;
2897 int scale = $mem$$scale;
2898 int disp = $mem$$disp;
2900 if(index!=0){
2901 if (scale == 0) {
2902 __ daddu(AT, as_Register(base), as_Register(index));
2903 } else {
2904 __ dsll(AT, as_Register(index), scale);
2905 __ daddu(AT, as_Register(base), AT);
2906 }
2908 if( Assembler::is_simm16(disp) ) {
2909 __ sw(R0, AT, disp);
2910 } else {
2911 __ move(T9, disp);
2912 __ daddu(AT, AT, T9);
2913 __ sw(R0, AT, 0);
2914 }
2915 } else {
2916 if( Assembler::is_simm16(disp) ) {
2917 __ sw(R0, as_Register(base), disp);
2918 } else {
2919 __ move(T9, disp);
2920 __ daddu(AT, as_Register(base), T9);
2921 __ sw(R0, AT, 0);
2922 }
2923 }
2924 %}
2926 enc_class load_L_enc (mRegL dst, memory mem) %{
2927 MacroAssembler _masm(&cbuf);
2928 int base = $mem$$base;
2929 int index = $mem$$index;
2930 int scale = $mem$$scale;
2931 int disp = $mem$$disp;
2932 Register dst_reg = as_Register($dst$$reg);
2934 if( index != 0 ) {
2935 if (scale == 0) {
2936 __ daddu(AT, as_Register(base), as_Register(index));
2937 } else {
2938 __ dsll(AT, as_Register(index), scale);
2939 __ daddu(AT, as_Register(base), AT);
2940 }
2941 if( Assembler::is_simm16(disp) ) {
2942 __ ld(dst_reg, AT, disp);
2943 } else {
2944 __ move(T9, disp);
2945 __ daddu(AT, AT, T9);
2946 __ ld(dst_reg, AT, 0);
2947 }
2948 } else {
2949 if( Assembler::is_simm16(disp) ) {
2950 __ ld(dst_reg, as_Register(base), disp);
2951 } else {
2952 __ move(T9, disp);
2953 __ daddu(AT, as_Register(base), T9);
2954 __ ld(dst_reg, AT, 0);
2955 }
2956 }
2957 %}
2959 enc_class store_L_reg_enc (memory mem, mRegL 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;
2965 Register src_reg = as_Register($src$$reg);
2967 if( index != 0 ) {
2968 if (scale == 0) {
2969 __ daddu(AT, as_Register(base), as_Register(index));
2970 } else {
2971 __ dsll(AT, as_Register(index), scale);
2972 __ daddu(AT, as_Register(base), AT);
2973 }
2974 if( Assembler::is_simm16(disp) ) {
2975 __ sd(src_reg, AT, disp);
2976 } else {
2977 __ move(T9, disp);
2978 __ daddu(AT, AT, T9);
2979 __ sd(src_reg, AT, 0);
2980 }
2981 } else {
2982 if( Assembler::is_simm16(disp) ) {
2983 __ sd(src_reg, as_Register(base), disp);
2984 } else {
2985 __ move(T9, disp);
2986 __ daddu(AT, as_Register(base), T9);
2987 __ sd(src_reg, AT, 0);
2988 }
2989 }
2990 %}
2992 enc_class store_L_immL0_enc (memory mem, immL0 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;
2999 if( index != 0 ) {
3000 if (scale == 0) {
3001 __ daddu(AT, as_Register(base), as_Register(index));
3002 } else {
3003 __ dsll(AT, as_Register(index), scale);
3004 __ daddu(AT, as_Register(base), AT);
3005 }
3006 if( Assembler::is_simm16(disp) ) {
3007 __ sd(R0, AT, disp);
3008 } else {
3009 __ move(T9, disp);
3010 __ addu(AT, AT, T9);
3011 __ sd(R0, AT, 0);
3012 }
3013 } else {
3014 if( Assembler::is_simm16(disp) ) {
3015 __ sd(R0, as_Register(base), disp);
3016 } else {
3017 __ move(T9, disp);
3018 __ addu(AT, as_Register(base), T9);
3019 __ sd(R0, AT, 0);
3020 }
3021 }
3022 %}
3024 enc_class store_L_immL_enc (memory mem, immL src) %{
3025 MacroAssembler _masm(&cbuf);
3026 int base = $mem$$base;
3027 int index = $mem$$index;
3028 int scale = $mem$$scale;
3029 int disp = $mem$$disp;
3030 long imm = $src$$constant;
3032 if( index != 0 ) {
3033 if (scale == 0) {
3034 __ daddu(AT, as_Register(base), as_Register(index));
3035 } else {
3036 __ dsll(AT, as_Register(index), scale);
3037 __ daddu(AT, as_Register(base), AT);
3038 }
3039 if( Assembler::is_simm16(disp) ) {
3040 __ set64(T9, imm);
3041 __ sd(T9, AT, disp);
3042 } else {
3043 __ move(T9, disp);
3044 __ addu(AT, AT, T9);
3045 __ set64(T9, imm);
3046 __ sd(T9, AT, 0);
3047 }
3048 } else {
3049 if( Assembler::is_simm16(disp) ) {
3050 __ move(AT, as_Register(base));
3051 __ set64(T9, imm);
3052 __ sd(T9, AT, disp);
3053 } else {
3054 __ move(T9, disp);
3055 __ addu(AT, as_Register(base), T9);
3056 __ set64(T9, imm);
3057 __ sd(T9, AT, 0);
3058 }
3059 }
3060 %}
3062 enc_class load_F_enc (regF dst, memory mem) %{
3063 MacroAssembler _masm(&cbuf);
3064 int base = $mem$$base;
3065 int index = $mem$$index;
3066 int scale = $mem$$scale;
3067 int disp = $mem$$disp;
3068 FloatRegister dst = $dst$$FloatRegister;
3070 if( index != 0 ) {
3071 if( Assembler::is_simm16(disp) ) {
3072 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3073 if (scale == 0) {
3074 __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
3075 } else {
3076 __ dsll(AT, as_Register(index), scale);
3077 __ gslwxc1(dst, as_Register(base), AT, disp);
3078 }
3079 } else {
3080 if (scale == 0) {
3081 __ daddu(AT, as_Register(base), as_Register(index));
3082 } else {
3083 __ dsll(AT, as_Register(index), scale);
3084 __ daddu(AT, as_Register(base), AT);
3085 }
3086 __ lwc1(dst, AT, disp);
3087 }
3088 } else {
3089 if (scale == 0) {
3090 __ daddu(AT, as_Register(base), as_Register(index));
3091 } else {
3092 __ dsll(AT, as_Register(index), scale);
3093 __ daddu(AT, as_Register(base), AT);
3094 }
3095 __ move(T9, disp);
3096 if( UseLoongsonISA ) {
3097 __ gslwxc1(dst, AT, T9, 0);
3098 } else {
3099 __ daddu(AT, AT, T9);
3100 __ lwc1(dst, AT, 0);
3101 }
3102 }
3103 } else {
3104 if( Assembler::is_simm16(disp) ) {
3105 __ lwc1(dst, as_Register(base), disp);
3106 } else {
3107 __ move(T9, disp);
3108 if( UseLoongsonISA ) {
3109 __ gslwxc1(dst, as_Register(base), T9, 0);
3110 } else {
3111 __ daddu(AT, as_Register(base), T9);
3112 __ lwc1(dst, AT, 0);
3113 }
3114 }
3115 }
3116 %}
3118 enc_class store_F_reg_enc (memory mem, regF src) %{
3119 MacroAssembler _masm(&cbuf);
3120 int base = $mem$$base;
3121 int index = $mem$$index;
3122 int scale = $mem$$scale;
3123 int disp = $mem$$disp;
3124 FloatRegister src = $src$$FloatRegister;
3126 if( index != 0 ) {
3127 if( Assembler::is_simm16(disp) ) {
3128 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3129 if (scale == 0) {
3130 __ gsswxc1(src, as_Register(base), as_Register(index), disp);
3131 } else {
3132 __ dsll(AT, as_Register(index), scale);
3133 __ gsswxc1(src, as_Register(base), AT, disp);
3134 }
3135 } else {
3136 if (scale == 0) {
3137 __ daddu(AT, as_Register(base), as_Register(index));
3138 } else {
3139 __ dsll(AT, as_Register(index), scale);
3140 __ daddu(AT, as_Register(base), AT);
3141 }
3142 __ swc1(src, AT, disp);
3143 }
3144 } else {
3145 if (scale == 0) {
3146 __ daddu(AT, as_Register(base), as_Register(index));
3147 } else {
3148 __ dsll(AT, as_Register(index), scale);
3149 __ daddu(AT, as_Register(base), AT);
3150 }
3151 __ move(T9, disp);
3152 if( UseLoongsonISA ) {
3153 __ gsswxc1(src, AT, T9, 0);
3154 } else {
3155 __ daddu(AT, AT, T9);
3156 __ swc1(src, AT, 0);
3157 }
3158 }
3159 } else {
3160 if( Assembler::is_simm16(disp) ) {
3161 __ swc1(src, as_Register(base), disp);
3162 } else {
3163 __ move(T9, disp);
3164 if( UseLoongsonISA ) {
3165 __ gsswxc1(src, as_Register(base), T9, 0);
3166 } else {
3167 __ daddu(AT, as_Register(base), T9);
3168 __ swc1(src, AT, 0);
3169 }
3170 }
3171 }
3172 %}
3174 enc_class load_D_enc (regD dst, memory mem) %{
3175 MacroAssembler _masm(&cbuf);
3176 int base = $mem$$base;
3177 int index = $mem$$index;
3178 int scale = $mem$$scale;
3179 int disp = $mem$$disp;
3180 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3182 if( index != 0 ) {
3183 if( Assembler::is_simm16(disp) ) {
3184 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3185 if (scale == 0) {
3186 __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
3187 } else {
3188 __ dsll(AT, as_Register(index), scale);
3189 __ gsldxc1(dst_reg, as_Register(base), AT, disp);
3190 }
3191 } else {
3192 if (scale == 0) {
3193 __ daddu(AT, as_Register(base), as_Register(index));
3194 } else {
3195 __ dsll(AT, as_Register(index), scale);
3196 __ daddu(AT, as_Register(base), AT);
3197 }
3198 __ ldc1(dst_reg, AT, disp);
3199 }
3200 } else {
3201 if (scale == 0) {
3202 __ daddu(AT, as_Register(base), as_Register(index));
3203 } else {
3204 __ dsll(AT, as_Register(index), scale);
3205 __ daddu(AT, as_Register(base), AT);
3206 }
3207 __ move(T9, disp);
3208 if( UseLoongsonISA ) {
3209 __ gsldxc1(dst_reg, AT, T9, 0);
3210 } else {
3211 __ addu(AT, AT, T9);
3212 __ ldc1(dst_reg, AT, 0);
3213 }
3214 }
3215 } else {
3216 if( Assembler::is_simm16(disp) ) {
3217 __ ldc1(dst_reg, as_Register(base), disp);
3218 } else {
3219 __ move(T9, disp);
3220 if( UseLoongsonISA ) {
3221 __ gsldxc1(dst_reg, as_Register(base), T9, 0);
3222 } else {
3223 __ addu(AT, as_Register(base), T9);
3224 __ ldc1(dst_reg, AT, 0);
3225 }
3226 }
3227 }
3228 %}
3230 enc_class store_D_reg_enc (memory mem, regD src) %{
3231 MacroAssembler _masm(&cbuf);
3232 int base = $mem$$base;
3233 int index = $mem$$index;
3234 int scale = $mem$$scale;
3235 int disp = $mem$$disp;
3236 FloatRegister src_reg = as_FloatRegister($src$$reg);
3238 if( index != 0 ) {
3239 if( Assembler::is_simm16(disp) ) {
3240 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3241 if (scale == 0) {
3242 __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
3243 } else {
3244 __ dsll(AT, as_Register(index), scale);
3245 __ gssdxc1(src_reg, as_Register(base), AT, disp);
3246 }
3247 } else {
3248 if (scale == 0) {
3249 __ daddu(AT, as_Register(base), as_Register(index));
3250 } else {
3251 __ dsll(AT, as_Register(index), scale);
3252 __ daddu(AT, as_Register(base), AT);
3253 }
3254 __ sdc1(src_reg, AT, disp);
3255 }
3256 } else {
3257 if (scale == 0) {
3258 __ daddu(AT, as_Register(base), as_Register(index));
3259 } else {
3260 __ dsll(AT, as_Register(index), scale);
3261 __ daddu(AT, as_Register(base), AT);
3262 }
3263 __ move(T9, disp);
3264 if( UseLoongsonISA ) {
3265 __ gssdxc1(src_reg, AT, T9, 0);
3266 } else {
3267 __ addu(AT, AT, T9);
3268 __ sdc1(src_reg, AT, 0);
3269 }
3270 }
3271 } else {
3272 if( Assembler::is_simm16(disp) ) {
3273 __ sdc1(src_reg, as_Register(base), disp);
3274 } else {
3275 __ move(T9, disp);
3276 if( UseLoongsonISA ) {
3277 __ gssdxc1(src_reg, as_Register(base), T9, 0);
3278 } else {
3279 __ addu(AT, as_Register(base), T9);
3280 __ sdc1(src_reg, AT, 0);
3281 }
3282 }
3283 }
3284 %}
3286 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf
3287 MacroAssembler _masm(&cbuf);
3288 // This is the instruction starting address for relocation info.
3289 __ block_comment("Java_To_Runtime");
3290 cbuf.set_insts_mark();
3291 __ relocate(relocInfo::runtime_call_type);
3293 __ patchable_call((address)$meth$$method);
3294 %}
3296 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
3297 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
3298 // who we intended to call.
3299 MacroAssembler _masm(&cbuf);
3300 cbuf.set_insts_mark();
3302 if ( !_method ) {
3303 __ relocate(relocInfo::runtime_call_type);
3304 } else if(_optimized_virtual) {
3305 __ relocate(relocInfo::opt_virtual_call_type);
3306 } else {
3307 __ relocate(relocInfo::static_call_type);
3308 }
3310 __ patchable_call((address)($meth$$method));
3311 if( _method ) { // Emit stub for static call
3312 emit_java_to_interp(cbuf);
3313 }
3314 %}
3317 /*
3318 * [Ref: LIR_Assembler::ic_call() ]
3319 */
3320 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL
3321 MacroAssembler _masm(&cbuf);
3322 __ block_comment("Java_Dynamic_Call");
3323 __ ic_call((address)$meth$$method);
3324 %}
3327 enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
3328 Register flags = $cr$$Register;
3329 Label L;
3331 MacroAssembler _masm(&cbuf);
3333 __ addu(flags, R0, R0);
3334 __ beq(AT, R0, L);
3335 __ delayed()->nop();
3336 __ move(flags, 0xFFFFFFFF);
3337 __ bind(L);
3338 %}
3340 enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
3341 Register result = $result$$Register;
3342 Register sub = $sub$$Register;
3343 Register super = $super$$Register;
3344 Register length = $tmp$$Register;
3345 Register tmp = T9;
3346 Label miss;
3348 /* 2012/9/28 Jin: result may be the same as sub
3349 * 47c B40: # B21 B41 <- B20 Freq: 0.155379
3350 * 47c partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
3351 * 4bc mov S2, NULL #@loadConP
3352 * 4c0 beq S1, S2, B21 #@branchConP P=0.999999 C=-1.000000
3353 */
3354 MacroAssembler _masm(&cbuf);
3355 Label done;
3356 __ check_klass_subtype_slow_path(sub, super, length, tmp,
3357 NULL, &miss,
3358 /*set_cond_codes:*/ true);
3359 /* 2013/7/22 Jin: Refer to X86_64's RDI */
3360 __ move(result, 0);
3361 __ b(done);
3362 __ nop();
3364 __ bind(miss);
3365 __ move(result, 1);
3366 __ bind(done);
3367 %}
3369 %}
3372 //---------MIPS FRAME--------------------------------------------------------------
3373 // Definition of frame structure and management information.
3374 //
3375 // S T A C K L A Y O U T Allocators stack-slot number
3376 // | (to get allocators register number
3377 // G Owned by | | v add SharedInfo::stack0)
3378 // r CALLER | |
3379 // o | +--------+ pad to even-align allocators stack-slot
3380 // w V | pad0 | numbers; owned by CALLER
3381 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
3382 // h ^ | in | 5
3383 // | | args | 4 Holes in incoming args owned by SELF
3384 // | | old | | 3
3385 // | | SP-+--------+----> Matcher::_old_SP, even aligned
3386 // v | | ret | 3 return address
3387 // Owned by +--------+
3388 // Self | pad2 | 2 pad to align old SP
3389 // | +--------+ 1
3390 // | | locks | 0
3391 // | +--------+----> SharedInfo::stack0, even aligned
3392 // | | pad1 | 11 pad to align new SP
3393 // | +--------+
3394 // | | | 10
3395 // | | spills | 9 spills
3396 // V | | 8 (pad0 slot for callee)
3397 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
3398 // ^ | out | 7
3399 // | | args | 6 Holes in outgoing args owned by CALLEE
3400 // Owned by new | |
3401 // Callee SP-+--------+----> Matcher::_new_SP, even aligned
3402 // | |
3403 //
3404 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
3405 // known from SELF's arguments and the Java calling convention.
3406 // Region 6-7 is determined per call site.
3407 // Note 2: If the calling convention leaves holes in the incoming argument
3408 // area, those holes are owned by SELF. Holes in the outgoing area
3409 // are owned by the CALLEE. Holes should not be nessecary in the
3410 // incoming area, as the Java calling convention is completely under
3411 // the control of the AD file. Doubles can be sorted and packed to
3412 // avoid holes. Holes in the outgoing arguments may be nessecary for
3413 // varargs C calling conventions.
3414 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
3415 // even aligned with pad0 as needed.
3416 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
3417 // region 6-11 is even aligned; it may be padded out more so that
3418 // the region from SP to FP meets the minimum stack alignment.
3419 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3420 // alignment. Region 11, pad1, may be dynamically extended so that
3421 // SP meets the minimum alignment.
3424 frame %{
3426 stack_direction(TOWARDS_LOW);
3428 // These two registers define part of the calling convention
3429 // between compiled code and the interpreter.
3430 // SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention
3431 // for more information. by yjl 3/16/2006
3433 inline_cache_reg(T1); // Inline Cache Register
3434 interpreter_method_oop_reg(S3); // Method Oop Register when calling interpreter
3436 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
3437 cisc_spilling_operand_name(indOffset32);
3439 // Number of stack slots consumed by locking an object
3440 // generate Compile::sync_stack_slots
3441 #ifdef _LP64
3442 sync_stack_slots(2);
3443 #else
3444 sync_stack_slots(1);
3445 #endif
3447 frame_pointer(SP);
3449 // Interpreter stores its frame pointer in a register which is
3450 // stored to the stack by I2CAdaptors.
3451 // I2CAdaptors convert from interpreted java to compiled java.
3453 interpreter_frame_pointer(FP);
3455 // generate Matcher::stack_alignment
3456 stack_alignment(StackAlignmentInBytes); //wordSize = sizeof(char*);
3458 // Number of stack slots between incoming argument block and the start of
3459 // a new frame. The PROLOG must add this many slots to the stack. The
3460 // EPILOG must remove this many slots. Intel needs one slot for
3461 // return address.
3462 // generate Matcher::in_preserve_stack_slots
3463 //in_preserve_stack_slots(VerifyStackAtCalls + 2); //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
3464 in_preserve_stack_slots(4); //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
3466 // Number of outgoing stack slots killed above the out_preserve_stack_slots
3467 // for calls to C. Supports the var-args backing area for register parms.
3468 varargs_C_out_slots_killed(0);
3470 // The after-PROLOG location of the return address. Location of
3471 // return address specifies a type (REG or STACK) and a number
3472 // representing the register number (i.e. - use a register name) or
3473 // stack slot.
3474 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3475 // Otherwise, it is above the locks and verification slot and alignment word
3476 //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
3477 return_addr(REG RA);
3479 // Body of function which returns an integer array locating
3480 // arguments either in registers or in stack slots. Passed an array
3481 // of ideal registers called "sig" and a "length" count. Stack-slot
3482 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3483 // arguments for a CALLEE. Incoming stack arguments are
3484 // automatically biased by the preserve_stack_slots field above.
3487 // will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
3488 // StartNode::calling_convention call this. by yjl 3/16/2006
3489 calling_convention %{
3490 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3491 %}
3496 // Body of function which returns an integer array locating
3497 // arguments either in registers or in stack slots. Passed an array
3498 // of ideal registers called "sig" and a "length" count. Stack-slot
3499 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3500 // arguments for a CALLEE. Incoming stack arguments are
3501 // automatically biased by the preserve_stack_slots field above.
3504 // SEE CallRuntimeNode::calling_convention for more information. by yjl 3/16/2006
3505 c_calling_convention %{
3506 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
3507 %}
3510 // Location of C & interpreter return values
3511 // register(s) contain(s) return value for Op_StartI2C and Op_StartOSR.
3512 // SEE Matcher::match. by yjl 3/16/2006
3513 c_return_value %{
3514 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3515 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
3516 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
3517 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num };
3518 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3519 %}
3521 // Location of return values
3522 // register(s) contain(s) return value for Op_StartC2I and Op_Start.
3523 // SEE Matcher::match. by yjl 3/16/2006
3525 return_value %{
3526 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3527 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
3528 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
3529 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num};
3530 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3531 %}
3533 %}
3535 //----------ATTRIBUTES---------------------------------------------------------
3536 //----------Operand Attributes-------------------------------------------------
3537 op_attrib op_cost(0); // Required cost attribute
3539 //----------Instruction Attributes---------------------------------------------
3540 ins_attrib ins_cost(100); // Required cost attribute
3541 ins_attrib ins_size(32); // Required size attribute (in bits)
3542 ins_attrib ins_pc_relative(0); // Required PC Relative flag
3543 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
3544 // non-matching short branch variant of some
3545 // long branch?
3546 ins_attrib ins_alignment(4); // Required alignment attribute (must be a power of 2)
3547 // specifies the alignment that some part of the instruction (not
3548 // necessarily the start) requires. If > 1, a compute_padding()
3549 // function must be provided for the instruction
3551 //----------OPERANDS-----------------------------------------------------------
3552 // Operand definitions must precede instruction definitions for correct parsing
3553 // in the ADLC because operands constitute user defined types which are used in
3554 // instruction definitions.
3556 // Vectors
3557 operand vecD() %{
3558 constraint(ALLOC_IN_RC(dbl_reg));
3559 match(VecD);
3561 format %{ %}
3562 interface(REG_INTER);
3563 %}
3565 // Flags register, used as output of compare instructions
3566 operand FlagsReg() %{
3567 constraint(ALLOC_IN_RC(mips_flags));
3568 match(RegFlags);
3570 format %{ "AT" %}
3571 interface(REG_INTER);
3572 %}
3574 //----------Simple Operands----------------------------------------------------
3575 //TODO: Should we need to define some more special immediate number ?
3576 // Immediate Operands
3577 // Integer Immediate
3578 operand immI() %{
3579 match(ConI);
3580 //TODO: should not match immI8 here LEE
3581 match(immI8);
3583 op_cost(20);
3584 format %{ %}
3585 interface(CONST_INTER);
3586 %}
3588 // Long Immediate 8-bit
3589 operand immL8()
3590 %{
3591 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3592 match(ConL);
3594 op_cost(5);
3595 format %{ %}
3596 interface(CONST_INTER);
3597 %}
3599 // Constant for test vs zero
3600 operand immI0() %{
3601 predicate(n->get_int() == 0);
3602 match(ConI);
3604 op_cost(0);
3605 format %{ %}
3606 interface(CONST_INTER);
3607 %}
3609 // Constant for increment
3610 operand immI1() %{
3611 predicate(n->get_int() == 1);
3612 match(ConI);
3614 op_cost(0);
3615 format %{ %}
3616 interface(CONST_INTER);
3617 %}
3619 // Constant for decrement
3620 operand immI_M1() %{
3621 predicate(n->get_int() == -1);
3622 match(ConI);
3624 op_cost(0);
3625 format %{ %}
3626 interface(CONST_INTER);
3627 %}
3629 operand immI_MaxI() %{
3630 predicate(n->get_int() == 2147483647);
3631 match(ConI);
3633 op_cost(0);
3634 format %{ %}
3635 interface(CONST_INTER);
3636 %}
3638 // Valid scale values for addressing modes
3639 operand immI2() %{
3640 predicate(0 <= n->get_int() && (n->get_int() <= 3));
3641 match(ConI);
3643 format %{ %}
3644 interface(CONST_INTER);
3645 %}
3647 operand immI8() %{
3648 predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
3649 match(ConI);
3651 op_cost(5);
3652 format %{ %}
3653 interface(CONST_INTER);
3654 %}
3656 operand immI16() %{
3657 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
3658 match(ConI);
3660 op_cost(10);
3661 format %{ %}
3662 interface(CONST_INTER);
3663 %}
3665 // Constant for long shifts
3666 operand immI_32() %{
3667 predicate( n->get_int() == 32 );
3668 match(ConI);
3670 op_cost(0);
3671 format %{ %}
3672 interface(CONST_INTER);
3673 %}
3675 operand immI_63() %{
3676 predicate( n->get_int() == 63 );
3677 match(ConI);
3679 op_cost(0);
3680 format %{ %}
3681 interface(CONST_INTER);
3682 %}
3684 operand immI_0_31() %{
3685 predicate( n->get_int() >= 0 && n->get_int() <= 31 );
3686 match(ConI);
3688 op_cost(0);
3689 format %{ %}
3690 interface(CONST_INTER);
3691 %}
3693 // Operand for non-negtive integer mask
3694 operand immI_nonneg_mask() %{
3695 predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
3696 match(ConI);
3698 op_cost(0);
3699 format %{ %}
3700 interface(CONST_INTER);
3701 %}
3703 operand immI_32_63() %{
3704 predicate( n->get_int() >= 32 && n->get_int() <= 63 );
3705 match(ConI);
3706 op_cost(0);
3708 format %{ %}
3709 interface(CONST_INTER);
3710 %}
3712 operand immI16_sub() %{
3713 predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
3714 match(ConI);
3716 op_cost(10);
3717 format %{ %}
3718 interface(CONST_INTER);
3719 %}
3721 operand immI_0_32767() %{
3722 predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
3723 match(ConI);
3724 op_cost(0);
3726 format %{ %}
3727 interface(CONST_INTER);
3728 %}
3730 operand immI_0_65535() %{
3731 predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
3732 match(ConI);
3733 op_cost(0);
3735 format %{ %}
3736 interface(CONST_INTER);
3737 %}
3739 operand immI_1() %{
3740 predicate( n->get_int() == 1 );
3741 match(ConI);
3743 op_cost(0);
3744 format %{ %}
3745 interface(CONST_INTER);
3746 %}
3748 operand immI_2() %{
3749 predicate( n->get_int() == 2 );
3750 match(ConI);
3752 op_cost(0);
3753 format %{ %}
3754 interface(CONST_INTER);
3755 %}
3757 operand immI_3() %{
3758 predicate( n->get_int() == 3 );
3759 match(ConI);
3761 op_cost(0);
3762 format %{ %}
3763 interface(CONST_INTER);
3764 %}
3766 operand immI_7() %{
3767 predicate( n->get_int() == 7 );
3768 match(ConI);
3770 format %{ %}
3771 interface(CONST_INTER);
3772 %}
3774 // Immediates for special shifts (sign extend)
3776 // Constants for increment
3777 operand immI_16() %{
3778 predicate( n->get_int() == 16 );
3779 match(ConI);
3781 format %{ %}
3782 interface(CONST_INTER);
3783 %}
3785 operand immI_24() %{
3786 predicate( n->get_int() == 24 );
3787 match(ConI);
3789 format %{ %}
3790 interface(CONST_INTER);
3791 %}
3793 // Constant for byte-wide masking
3794 operand immI_255() %{
3795 predicate( n->get_int() == 255 );
3796 match(ConI);
3798 op_cost(0);
3799 format %{ %}
3800 interface(CONST_INTER);
3801 %}
3803 operand immI_65535() %{
3804 predicate( n->get_int() == 65535 );
3805 match(ConI);
3807 op_cost(5);
3808 format %{ %}
3809 interface(CONST_INTER);
3810 %}
3812 operand immI_65536() %{
3813 predicate( n->get_int() == 65536 );
3814 match(ConI);
3816 op_cost(5);
3817 format %{ %}
3818 interface(CONST_INTER);
3819 %}
3821 operand immI_M65536() %{
3822 predicate( n->get_int() == -65536 );
3823 match(ConI);
3825 op_cost(5);
3826 format %{ %}
3827 interface(CONST_INTER);
3828 %}
3830 // Pointer Immediate
3831 operand immP() %{
3832 match(ConP);
3834 op_cost(10);
3835 format %{ %}
3836 interface(CONST_INTER);
3837 %}
3839 // NULL Pointer Immediate
3840 operand immP0() %{
3841 predicate( n->get_ptr() == 0 );
3842 match(ConP);
3843 op_cost(0);
3845 format %{ %}
3846 interface(CONST_INTER);
3847 %}
3849 // Pointer Immediate: 64-bit
3850 operand immP_set() %{
3851 match(ConP);
3853 op_cost(5);
3854 // formats are generated automatically for constants and base registers
3855 format %{ %}
3856 interface(CONST_INTER);
3857 %}
3859 // Pointer Immediate: 64-bit
3860 operand immP_load() %{
3861 predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
3862 match(ConP);
3864 op_cost(5);
3865 // formats are generated automatically for constants and base registers
3866 format %{ %}
3867 interface(CONST_INTER);
3868 %}
3870 // Pointer Immediate: 64-bit
3871 operand immP_no_oop_cheap() %{
3872 predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
3873 match(ConP);
3875 op_cost(5);
3876 // formats are generated automatically for constants and base registers
3877 format %{ %}
3878 interface(CONST_INTER);
3879 %}
3881 // Pointer for polling page
3882 operand immP_poll() %{
3883 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
3884 match(ConP);
3885 op_cost(5);
3887 format %{ %}
3888 interface(CONST_INTER);
3889 %}
3891 // Pointer Immediate
3892 operand immN() %{
3893 match(ConN);
3895 op_cost(10);
3896 format %{ %}
3897 interface(CONST_INTER);
3898 %}
3900 operand immNKlass() %{
3901 match(ConNKlass);
3903 op_cost(10);
3904 format %{ %}
3905 interface(CONST_INTER);
3906 %}
3908 // NULL Pointer Immediate
3909 operand immN0() %{
3910 predicate(n->get_narrowcon() == 0);
3911 match(ConN);
3913 op_cost(5);
3914 format %{ %}
3915 interface(CONST_INTER);
3916 %}
3918 // Long Immediate
3919 operand immL() %{
3920 match(ConL);
3922 op_cost(20);
3923 format %{ %}
3924 interface(CONST_INTER);
3925 %}
3927 // Long Immediate zero
3928 operand immL0() %{
3929 predicate( n->get_long() == 0L );
3930 match(ConL);
3931 op_cost(0);
3933 format %{ %}
3934 interface(CONST_INTER);
3935 %}
3937 operand immL7() %{
3938 predicate( n->get_long() == 7L );
3939 match(ConL);
3940 op_cost(0);
3942 format %{ %}
3943 interface(CONST_INTER);
3944 %}
3946 operand immL_M1() %{
3947 predicate( n->get_long() == -1L );
3948 match(ConL);
3949 op_cost(0);
3951 format %{ %}
3952 interface(CONST_INTER);
3953 %}
3955 // bit 0..2 zero
3956 operand immL_M8() %{
3957 predicate( n->get_long() == -8L );
3958 match(ConL);
3959 op_cost(0);
3961 format %{ %}
3962 interface(CONST_INTER);
3963 %}
3965 // bit 2 zero
3966 operand immL_M5() %{
3967 predicate( n->get_long() == -5L );
3968 match(ConL);
3969 op_cost(0);
3971 format %{ %}
3972 interface(CONST_INTER);
3973 %}
3975 // bit 1..2 zero
3976 operand immL_M7() %{
3977 predicate( n->get_long() == -7L );
3978 match(ConL);
3979 op_cost(0);
3981 format %{ %}
3982 interface(CONST_INTER);
3983 %}
3985 // bit 0..1 zero
3986 operand immL_M4() %{
3987 predicate( n->get_long() == -4L );
3988 match(ConL);
3989 op_cost(0);
3991 format %{ %}
3992 interface(CONST_INTER);
3993 %}
3995 // bit 3..6 zero
3996 operand immL_M121() %{
3997 predicate( n->get_long() == -121L );
3998 match(ConL);
3999 op_cost(0);
4001 format %{ %}
4002 interface(CONST_INTER);
4003 %}
4005 // Long immediate from 0 to 127.
4006 // Used for a shorter form of long mul by 10.
4007 operand immL_127() %{
4008 predicate((0 <= n->get_long()) && (n->get_long() <= 127));
4009 match(ConL);
4010 op_cost(0);
4012 format %{ %}
4013 interface(CONST_INTER);
4014 %}
4016 // Operand for non-negtive long mask
4017 operand immL_nonneg_mask() %{
4018 predicate( (n->get_long() >= 0) && (Assembler::is_jlong_mask(n->get_long()) != -1) );
4019 match(ConL);
4021 op_cost(0);
4022 format %{ %}
4023 interface(CONST_INTER);
4024 %}
4026 operand immL_0_65535() %{
4027 predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
4028 match(ConL);
4029 op_cost(0);
4031 format %{ %}
4032 interface(CONST_INTER);
4033 %}
4035 // Long Immediate: cheap (materialize in <= 3 instructions)
4036 operand immL_cheap() %{
4037 predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
4038 match(ConL);
4039 op_cost(0);
4041 format %{ %}
4042 interface(CONST_INTER);
4043 %}
4045 // Long Immediate: expensive (materialize in > 3 instructions)
4046 operand immL_expensive() %{
4047 predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
4048 match(ConL);
4049 op_cost(0);
4051 format %{ %}
4052 interface(CONST_INTER);
4053 %}
4055 operand immL16() %{
4056 predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
4057 match(ConL);
4059 op_cost(10);
4060 format %{ %}
4061 interface(CONST_INTER);
4062 %}
4064 operand immL16_sub() %{
4065 predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
4066 match(ConL);
4068 op_cost(10);
4069 format %{ %}
4070 interface(CONST_INTER);
4071 %}
4073 // Long Immediate: low 32-bit mask
4074 operand immL_32bits() %{
4075 predicate(n->get_long() == 0xFFFFFFFFL);
4076 match(ConL);
4077 op_cost(20);
4079 format %{ %}
4080 interface(CONST_INTER);
4081 %}
4083 // Long Immediate 32-bit signed
4084 operand immL32()
4085 %{
4086 predicate(n->get_long() == (int) (n->get_long()));
4087 match(ConL);
4089 op_cost(15);
4090 format %{ %}
4091 interface(CONST_INTER);
4092 %}
4095 //single-precision floating-point zero
4096 operand immF0() %{
4097 predicate(jint_cast(n->getf()) == 0);
4098 match(ConF);
4100 op_cost(5);
4101 format %{ %}
4102 interface(CONST_INTER);
4103 %}
4105 //single-precision floating-point immediate
4106 operand immF() %{
4107 match(ConF);
4109 op_cost(20);
4110 format %{ %}
4111 interface(CONST_INTER);
4112 %}
4114 //double-precision floating-point zero
4115 operand immD0() %{
4116 predicate(jlong_cast(n->getd()) == 0);
4117 match(ConD);
4119 op_cost(5);
4120 format %{ %}
4121 interface(CONST_INTER);
4122 %}
4124 //double-precision floating-point immediate
4125 operand immD() %{
4126 match(ConD);
4128 op_cost(20);
4129 format %{ %}
4130 interface(CONST_INTER);
4131 %}
4133 // Register Operands
4134 // Integer Register
4135 operand mRegI() %{
4136 constraint(ALLOC_IN_RC(int_reg));
4137 match(RegI);
4139 format %{ %}
4140 interface(REG_INTER);
4141 %}
4143 operand no_Ax_mRegI() %{
4144 constraint(ALLOC_IN_RC(no_Ax_int_reg));
4145 match(RegI);
4146 match(mRegI);
4148 format %{ %}
4149 interface(REG_INTER);
4150 %}
4152 operand mS0RegI() %{
4153 constraint(ALLOC_IN_RC(s0_reg));
4154 match(RegI);
4155 match(mRegI);
4157 format %{ "S0" %}
4158 interface(REG_INTER);
4159 %}
4161 operand mS1RegI() %{
4162 constraint(ALLOC_IN_RC(s1_reg));
4163 match(RegI);
4164 match(mRegI);
4166 format %{ "S1" %}
4167 interface(REG_INTER);
4168 %}
4170 operand mS2RegI() %{
4171 constraint(ALLOC_IN_RC(s2_reg));
4172 match(RegI);
4173 match(mRegI);
4175 format %{ "S2" %}
4176 interface(REG_INTER);
4177 %}
4179 operand mS3RegI() %{
4180 constraint(ALLOC_IN_RC(s3_reg));
4181 match(RegI);
4182 match(mRegI);
4184 format %{ "S3" %}
4185 interface(REG_INTER);
4186 %}
4188 operand mS4RegI() %{
4189 constraint(ALLOC_IN_RC(s4_reg));
4190 match(RegI);
4191 match(mRegI);
4193 format %{ "S4" %}
4194 interface(REG_INTER);
4195 %}
4197 operand mS5RegI() %{
4198 constraint(ALLOC_IN_RC(s5_reg));
4199 match(RegI);
4200 match(mRegI);
4202 format %{ "S5" %}
4203 interface(REG_INTER);
4204 %}
4206 operand mS6RegI() %{
4207 constraint(ALLOC_IN_RC(s6_reg));
4208 match(RegI);
4209 match(mRegI);
4211 format %{ "S6" %}
4212 interface(REG_INTER);
4213 %}
4215 operand mS7RegI() %{
4216 constraint(ALLOC_IN_RC(s7_reg));
4217 match(RegI);
4218 match(mRegI);
4220 format %{ "S7" %}
4221 interface(REG_INTER);
4222 %}
4225 operand mT0RegI() %{
4226 constraint(ALLOC_IN_RC(t0_reg));
4227 match(RegI);
4228 match(mRegI);
4230 format %{ "T0" %}
4231 interface(REG_INTER);
4232 %}
4234 operand mT1RegI() %{
4235 constraint(ALLOC_IN_RC(t1_reg));
4236 match(RegI);
4237 match(mRegI);
4239 format %{ "T1" %}
4240 interface(REG_INTER);
4241 %}
4243 operand mT2RegI() %{
4244 constraint(ALLOC_IN_RC(t2_reg));
4245 match(RegI);
4246 match(mRegI);
4248 format %{ "T2" %}
4249 interface(REG_INTER);
4250 %}
4252 operand mT3RegI() %{
4253 constraint(ALLOC_IN_RC(t3_reg));
4254 match(RegI);
4255 match(mRegI);
4257 format %{ "T3" %}
4258 interface(REG_INTER);
4259 %}
4261 operand mT8RegI() %{
4262 constraint(ALLOC_IN_RC(t8_reg));
4263 match(RegI);
4264 match(mRegI);
4266 format %{ "T8" %}
4267 interface(REG_INTER);
4268 %}
4270 operand mT9RegI() %{
4271 constraint(ALLOC_IN_RC(t9_reg));
4272 match(RegI);
4273 match(mRegI);
4275 format %{ "T9" %}
4276 interface(REG_INTER);
4277 %}
4279 operand mA0RegI() %{
4280 constraint(ALLOC_IN_RC(a0_reg));
4281 match(RegI);
4282 match(mRegI);
4284 format %{ "A0" %}
4285 interface(REG_INTER);
4286 %}
4288 operand mA1RegI() %{
4289 constraint(ALLOC_IN_RC(a1_reg));
4290 match(RegI);
4291 match(mRegI);
4293 format %{ "A1" %}
4294 interface(REG_INTER);
4295 %}
4297 operand mA2RegI() %{
4298 constraint(ALLOC_IN_RC(a2_reg));
4299 match(RegI);
4300 match(mRegI);
4302 format %{ "A2" %}
4303 interface(REG_INTER);
4304 %}
4306 operand mA3RegI() %{
4307 constraint(ALLOC_IN_RC(a3_reg));
4308 match(RegI);
4309 match(mRegI);
4311 format %{ "A3" %}
4312 interface(REG_INTER);
4313 %}
4315 operand mA4RegI() %{
4316 constraint(ALLOC_IN_RC(a4_reg));
4317 match(RegI);
4318 match(mRegI);
4320 format %{ "A4" %}
4321 interface(REG_INTER);
4322 %}
4324 operand mA5RegI() %{
4325 constraint(ALLOC_IN_RC(a5_reg));
4326 match(RegI);
4327 match(mRegI);
4329 format %{ "A5" %}
4330 interface(REG_INTER);
4331 %}
4333 operand mA6RegI() %{
4334 constraint(ALLOC_IN_RC(a6_reg));
4335 match(RegI);
4336 match(mRegI);
4338 format %{ "A6" %}
4339 interface(REG_INTER);
4340 %}
4342 operand mA7RegI() %{
4343 constraint(ALLOC_IN_RC(a7_reg));
4344 match(RegI);
4345 match(mRegI);
4347 format %{ "A7" %}
4348 interface(REG_INTER);
4349 %}
4351 operand mV0RegI() %{
4352 constraint(ALLOC_IN_RC(v0_reg));
4353 match(RegI);
4354 match(mRegI);
4356 format %{ "V0" %}
4357 interface(REG_INTER);
4358 %}
4360 operand mV1RegI() %{
4361 constraint(ALLOC_IN_RC(v1_reg));
4362 match(RegI);
4363 match(mRegI);
4365 format %{ "V1" %}
4366 interface(REG_INTER);
4367 %}
4369 operand mRegN() %{
4370 constraint(ALLOC_IN_RC(int_reg));
4371 match(RegN);
4373 format %{ %}
4374 interface(REG_INTER);
4375 %}
4377 operand t0_RegN() %{
4378 constraint(ALLOC_IN_RC(t0_reg));
4379 match(RegN);
4380 match(mRegN);
4382 format %{ %}
4383 interface(REG_INTER);
4384 %}
4386 operand t1_RegN() %{
4387 constraint(ALLOC_IN_RC(t1_reg));
4388 match(RegN);
4389 match(mRegN);
4391 format %{ %}
4392 interface(REG_INTER);
4393 %}
4395 operand t2_RegN() %{
4396 constraint(ALLOC_IN_RC(t2_reg));
4397 match(RegN);
4398 match(mRegN);
4400 format %{ %}
4401 interface(REG_INTER);
4402 %}
4404 operand t3_RegN() %{
4405 constraint(ALLOC_IN_RC(t3_reg));
4406 match(RegN);
4407 match(mRegN);
4409 format %{ %}
4410 interface(REG_INTER);
4411 %}
4413 operand t8_RegN() %{
4414 constraint(ALLOC_IN_RC(t8_reg));
4415 match(RegN);
4416 match(mRegN);
4418 format %{ %}
4419 interface(REG_INTER);
4420 %}
4422 operand t9_RegN() %{
4423 constraint(ALLOC_IN_RC(t9_reg));
4424 match(RegN);
4425 match(mRegN);
4427 format %{ %}
4428 interface(REG_INTER);
4429 %}
4431 operand a0_RegN() %{
4432 constraint(ALLOC_IN_RC(a0_reg));
4433 match(RegN);
4434 match(mRegN);
4436 format %{ %}
4437 interface(REG_INTER);
4438 %}
4440 operand a1_RegN() %{
4441 constraint(ALLOC_IN_RC(a1_reg));
4442 match(RegN);
4443 match(mRegN);
4445 format %{ %}
4446 interface(REG_INTER);
4447 %}
4449 operand a2_RegN() %{
4450 constraint(ALLOC_IN_RC(a2_reg));
4451 match(RegN);
4452 match(mRegN);
4454 format %{ %}
4455 interface(REG_INTER);
4456 %}
4458 operand a3_RegN() %{
4459 constraint(ALLOC_IN_RC(a3_reg));
4460 match(RegN);
4461 match(mRegN);
4463 format %{ %}
4464 interface(REG_INTER);
4465 %}
4467 operand a4_RegN() %{
4468 constraint(ALLOC_IN_RC(a4_reg));
4469 match(RegN);
4470 match(mRegN);
4472 format %{ %}
4473 interface(REG_INTER);
4474 %}
4476 operand a5_RegN() %{
4477 constraint(ALLOC_IN_RC(a5_reg));
4478 match(RegN);
4479 match(mRegN);
4481 format %{ %}
4482 interface(REG_INTER);
4483 %}
4485 operand a6_RegN() %{
4486 constraint(ALLOC_IN_RC(a6_reg));
4487 match(RegN);
4488 match(mRegN);
4490 format %{ %}
4491 interface(REG_INTER);
4492 %}
4494 operand a7_RegN() %{
4495 constraint(ALLOC_IN_RC(a7_reg));
4496 match(RegN);
4497 match(mRegN);
4499 format %{ %}
4500 interface(REG_INTER);
4501 %}
4503 operand s0_RegN() %{
4504 constraint(ALLOC_IN_RC(s0_reg));
4505 match(RegN);
4506 match(mRegN);
4508 format %{ %}
4509 interface(REG_INTER);
4510 %}
4512 operand s1_RegN() %{
4513 constraint(ALLOC_IN_RC(s1_reg));
4514 match(RegN);
4515 match(mRegN);
4517 format %{ %}
4518 interface(REG_INTER);
4519 %}
4521 operand s2_RegN() %{
4522 constraint(ALLOC_IN_RC(s2_reg));
4523 match(RegN);
4524 match(mRegN);
4526 format %{ %}
4527 interface(REG_INTER);
4528 %}
4530 operand s3_RegN() %{
4531 constraint(ALLOC_IN_RC(s3_reg));
4532 match(RegN);
4533 match(mRegN);
4535 format %{ %}
4536 interface(REG_INTER);
4537 %}
4539 operand s4_RegN() %{
4540 constraint(ALLOC_IN_RC(s4_reg));
4541 match(RegN);
4542 match(mRegN);
4544 format %{ %}
4545 interface(REG_INTER);
4546 %}
4548 operand s5_RegN() %{
4549 constraint(ALLOC_IN_RC(s5_reg));
4550 match(RegN);
4551 match(mRegN);
4553 format %{ %}
4554 interface(REG_INTER);
4555 %}
4557 operand s6_RegN() %{
4558 constraint(ALLOC_IN_RC(s6_reg));
4559 match(RegN);
4560 match(mRegN);
4562 format %{ %}
4563 interface(REG_INTER);
4564 %}
4566 operand s7_RegN() %{
4567 constraint(ALLOC_IN_RC(s7_reg));
4568 match(RegN);
4569 match(mRegN);
4571 format %{ %}
4572 interface(REG_INTER);
4573 %}
4575 operand v0_RegN() %{
4576 constraint(ALLOC_IN_RC(v0_reg));
4577 match(RegN);
4578 match(mRegN);
4580 format %{ %}
4581 interface(REG_INTER);
4582 %}
4584 operand v1_RegN() %{
4585 constraint(ALLOC_IN_RC(v1_reg));
4586 match(RegN);
4587 match(mRegN);
4589 format %{ %}
4590 interface(REG_INTER);
4591 %}
4593 // Pointer Register
4594 operand mRegP() %{
4595 constraint(ALLOC_IN_RC(p_reg));
4596 match(RegP);
4598 format %{ %}
4599 interface(REG_INTER);
4600 %}
4602 operand no_T8_mRegP() %{
4603 constraint(ALLOC_IN_RC(no_T8_p_reg));
4604 match(RegP);
4605 match(mRegP);
4607 format %{ %}
4608 interface(REG_INTER);
4609 %}
4611 operand s0_RegP()
4612 %{
4613 constraint(ALLOC_IN_RC(s0_long_reg));
4614 match(RegP);
4615 match(mRegP);
4616 match(no_T8_mRegP);
4618 format %{ %}
4619 interface(REG_INTER);
4620 %}
4622 operand s1_RegP()
4623 %{
4624 constraint(ALLOC_IN_RC(s1_long_reg));
4625 match(RegP);
4626 match(mRegP);
4627 match(no_T8_mRegP);
4629 format %{ %}
4630 interface(REG_INTER);
4631 %}
4633 operand s2_RegP()
4634 %{
4635 constraint(ALLOC_IN_RC(s2_long_reg));
4636 match(RegP);
4637 match(mRegP);
4638 match(no_T8_mRegP);
4640 format %{ %}
4641 interface(REG_INTER);
4642 %}
4644 operand s3_RegP()
4645 %{
4646 constraint(ALLOC_IN_RC(s3_long_reg));
4647 match(RegP);
4648 match(mRegP);
4649 match(no_T8_mRegP);
4651 format %{ %}
4652 interface(REG_INTER);
4653 %}
4655 operand s4_RegP()
4656 %{
4657 constraint(ALLOC_IN_RC(s4_long_reg));
4658 match(RegP);
4659 match(mRegP);
4660 match(no_T8_mRegP);
4662 format %{ %}
4663 interface(REG_INTER);
4664 %}
4666 operand s5_RegP()
4667 %{
4668 constraint(ALLOC_IN_RC(s5_long_reg));
4669 match(RegP);
4670 match(mRegP);
4671 match(no_T8_mRegP);
4673 format %{ %}
4674 interface(REG_INTER);
4675 %}
4677 operand s6_RegP()
4678 %{
4679 constraint(ALLOC_IN_RC(s6_long_reg));
4680 match(RegP);
4681 match(mRegP);
4682 match(no_T8_mRegP);
4684 format %{ %}
4685 interface(REG_INTER);
4686 %}
4688 operand s7_RegP()
4689 %{
4690 constraint(ALLOC_IN_RC(s7_long_reg));
4691 match(RegP);
4692 match(mRegP);
4693 match(no_T8_mRegP);
4695 format %{ %}
4696 interface(REG_INTER);
4697 %}
4699 operand t0_RegP()
4700 %{
4701 constraint(ALLOC_IN_RC(t0_long_reg));
4702 match(RegP);
4703 match(mRegP);
4704 match(no_T8_mRegP);
4706 format %{ %}
4707 interface(REG_INTER);
4708 %}
4710 operand t1_RegP()
4711 %{
4712 constraint(ALLOC_IN_RC(t1_long_reg));
4713 match(RegP);
4714 match(mRegP);
4715 match(no_T8_mRegP);
4717 format %{ %}
4718 interface(REG_INTER);
4719 %}
4721 operand t2_RegP()
4722 %{
4723 constraint(ALLOC_IN_RC(t2_long_reg));
4724 match(RegP);
4725 match(mRegP);
4726 match(no_T8_mRegP);
4728 format %{ %}
4729 interface(REG_INTER);
4730 %}
4732 operand t3_RegP()
4733 %{
4734 constraint(ALLOC_IN_RC(t3_long_reg));
4735 match(RegP);
4736 match(mRegP);
4737 match(no_T8_mRegP);
4739 format %{ %}
4740 interface(REG_INTER);
4741 %}
4743 operand t8_RegP()
4744 %{
4745 constraint(ALLOC_IN_RC(t8_long_reg));
4746 match(RegP);
4747 match(mRegP);
4749 format %{ %}
4750 interface(REG_INTER);
4751 %}
4753 operand t9_RegP()
4754 %{
4755 constraint(ALLOC_IN_RC(t9_long_reg));
4756 match(RegP);
4757 match(mRegP);
4758 match(no_T8_mRegP);
4760 format %{ %}
4761 interface(REG_INTER);
4762 %}
4764 operand a0_RegP()
4765 %{
4766 constraint(ALLOC_IN_RC(a0_long_reg));
4767 match(RegP);
4768 match(mRegP);
4769 match(no_T8_mRegP);
4771 format %{ %}
4772 interface(REG_INTER);
4773 %}
4775 operand a1_RegP()
4776 %{
4777 constraint(ALLOC_IN_RC(a1_long_reg));
4778 match(RegP);
4779 match(mRegP);
4780 match(no_T8_mRegP);
4782 format %{ %}
4783 interface(REG_INTER);
4784 %}
4786 operand a2_RegP()
4787 %{
4788 constraint(ALLOC_IN_RC(a2_long_reg));
4789 match(RegP);
4790 match(mRegP);
4791 match(no_T8_mRegP);
4793 format %{ %}
4794 interface(REG_INTER);
4795 %}
4797 operand a3_RegP()
4798 %{
4799 constraint(ALLOC_IN_RC(a3_long_reg));
4800 match(RegP);
4801 match(mRegP);
4802 match(no_T8_mRegP);
4804 format %{ %}
4805 interface(REG_INTER);
4806 %}
4808 operand a4_RegP()
4809 %{
4810 constraint(ALLOC_IN_RC(a4_long_reg));
4811 match(RegP);
4812 match(mRegP);
4813 match(no_T8_mRegP);
4815 format %{ %}
4816 interface(REG_INTER);
4817 %}
4820 operand a5_RegP()
4821 %{
4822 constraint(ALLOC_IN_RC(a5_long_reg));
4823 match(RegP);
4824 match(mRegP);
4825 match(no_T8_mRegP);
4827 format %{ %}
4828 interface(REG_INTER);
4829 %}
4831 operand a6_RegP()
4832 %{
4833 constraint(ALLOC_IN_RC(a6_long_reg));
4834 match(RegP);
4835 match(mRegP);
4836 match(no_T8_mRegP);
4838 format %{ %}
4839 interface(REG_INTER);
4840 %}
4842 operand a7_RegP()
4843 %{
4844 constraint(ALLOC_IN_RC(a7_long_reg));
4845 match(RegP);
4846 match(mRegP);
4847 match(no_T8_mRegP);
4849 format %{ %}
4850 interface(REG_INTER);
4851 %}
4853 operand v0_RegP()
4854 %{
4855 constraint(ALLOC_IN_RC(v0_long_reg));
4856 match(RegP);
4857 match(mRegP);
4858 match(no_T8_mRegP);
4860 format %{ %}
4861 interface(REG_INTER);
4862 %}
4864 operand v1_RegP()
4865 %{
4866 constraint(ALLOC_IN_RC(v1_long_reg));
4867 match(RegP);
4868 match(mRegP);
4869 match(no_T8_mRegP);
4871 format %{ %}
4872 interface(REG_INTER);
4873 %}
4875 /*
4876 operand mSPRegP(mRegP reg) %{
4877 constraint(ALLOC_IN_RC(sp_reg));
4878 match(reg);
4880 format %{ "SP" %}
4881 interface(REG_INTER);
4882 %}
4884 operand mFPRegP(mRegP reg) %{
4885 constraint(ALLOC_IN_RC(fp_reg));
4886 match(reg);
4888 format %{ "FP" %}
4889 interface(REG_INTER);
4890 %}
4891 */
4893 operand mRegL() %{
4894 constraint(ALLOC_IN_RC(long_reg));
4895 match(RegL);
4897 format %{ %}
4898 interface(REG_INTER);
4899 %}
4901 operand v0RegL() %{
4902 constraint(ALLOC_IN_RC(v0_long_reg));
4903 match(RegL);
4904 match(mRegL);
4906 format %{ %}
4907 interface(REG_INTER);
4908 %}
4910 operand v1RegL() %{
4911 constraint(ALLOC_IN_RC(v1_long_reg));
4912 match(RegL);
4913 match(mRegL);
4915 format %{ %}
4916 interface(REG_INTER);
4917 %}
4919 operand a0RegL() %{
4920 constraint(ALLOC_IN_RC(a0_long_reg));
4921 match(RegL);
4922 match(mRegL);
4924 format %{ "A0" %}
4925 interface(REG_INTER);
4926 %}
4928 operand a1RegL() %{
4929 constraint(ALLOC_IN_RC(a1_long_reg));
4930 match(RegL);
4931 match(mRegL);
4933 format %{ %}
4934 interface(REG_INTER);
4935 %}
4937 operand a2RegL() %{
4938 constraint(ALLOC_IN_RC(a2_long_reg));
4939 match(RegL);
4940 match(mRegL);
4942 format %{ %}
4943 interface(REG_INTER);
4944 %}
4946 operand a3RegL() %{
4947 constraint(ALLOC_IN_RC(a3_long_reg));
4948 match(RegL);
4949 match(mRegL);
4951 format %{ %}
4952 interface(REG_INTER);
4953 %}
4955 operand t0RegL() %{
4956 constraint(ALLOC_IN_RC(t0_long_reg));
4957 match(RegL);
4958 match(mRegL);
4960 format %{ %}
4961 interface(REG_INTER);
4962 %}
4964 operand t1RegL() %{
4965 constraint(ALLOC_IN_RC(t1_long_reg));
4966 match(RegL);
4967 match(mRegL);
4969 format %{ %}
4970 interface(REG_INTER);
4971 %}
4973 operand t2RegL() %{
4974 constraint(ALLOC_IN_RC(t2_long_reg));
4975 match(RegL);
4976 match(mRegL);
4978 format %{ %}
4979 interface(REG_INTER);
4980 %}
4982 operand t3RegL() %{
4983 constraint(ALLOC_IN_RC(t3_long_reg));
4984 match(RegL);
4985 match(mRegL);
4987 format %{ %}
4988 interface(REG_INTER);
4989 %}
4991 operand t8RegL() %{
4992 constraint(ALLOC_IN_RC(t8_long_reg));
4993 match(RegL);
4994 match(mRegL);
4996 format %{ %}
4997 interface(REG_INTER);
4998 %}
5000 operand a4RegL() %{
5001 constraint(ALLOC_IN_RC(a4_long_reg));
5002 match(RegL);
5003 match(mRegL);
5005 format %{ %}
5006 interface(REG_INTER);
5007 %}
5009 operand a5RegL() %{
5010 constraint(ALLOC_IN_RC(a5_long_reg));
5011 match(RegL);
5012 match(mRegL);
5014 format %{ %}
5015 interface(REG_INTER);
5016 %}
5018 operand a6RegL() %{
5019 constraint(ALLOC_IN_RC(a6_long_reg));
5020 match(RegL);
5021 match(mRegL);
5023 format %{ %}
5024 interface(REG_INTER);
5025 %}
5027 operand a7RegL() %{
5028 constraint(ALLOC_IN_RC(a7_long_reg));
5029 match(RegL);
5030 match(mRegL);
5032 format %{ %}
5033 interface(REG_INTER);
5034 %}
5036 operand s0RegL() %{
5037 constraint(ALLOC_IN_RC(s0_long_reg));
5038 match(RegL);
5039 match(mRegL);
5041 format %{ %}
5042 interface(REG_INTER);
5043 %}
5045 operand s1RegL() %{
5046 constraint(ALLOC_IN_RC(s1_long_reg));
5047 match(RegL);
5048 match(mRegL);
5050 format %{ %}
5051 interface(REG_INTER);
5052 %}
5054 operand s2RegL() %{
5055 constraint(ALLOC_IN_RC(s2_long_reg));
5056 match(RegL);
5057 match(mRegL);
5059 format %{ %}
5060 interface(REG_INTER);
5061 %}
5063 operand s3RegL() %{
5064 constraint(ALLOC_IN_RC(s3_long_reg));
5065 match(RegL);
5066 match(mRegL);
5068 format %{ %}
5069 interface(REG_INTER);
5070 %}
5072 operand s4RegL() %{
5073 constraint(ALLOC_IN_RC(s4_long_reg));
5074 match(RegL);
5075 match(mRegL);
5077 format %{ %}
5078 interface(REG_INTER);
5079 %}
5081 operand s7RegL() %{
5082 constraint(ALLOC_IN_RC(s7_long_reg));
5083 match(RegL);
5084 match(mRegL);
5086 format %{ %}
5087 interface(REG_INTER);
5088 %}
5090 // Floating register operands
5091 operand regF() %{
5092 constraint(ALLOC_IN_RC(flt_reg));
5093 match(RegF);
5095 format %{ %}
5096 interface(REG_INTER);
5097 %}
5099 //Double Precision Floating register operands
5100 operand regD() %{
5101 constraint(ALLOC_IN_RC(dbl_reg));
5102 match(RegD);
5104 format %{ %}
5105 interface(REG_INTER);
5106 %}
5108 //----------Memory Operands----------------------------------------------------
5109 // Indirect Memory Operand
5110 operand indirect(mRegP reg) %{
5111 constraint(ALLOC_IN_RC(p_reg));
5112 match(reg);
5114 format %{ "[$reg] @ indirect" %}
5115 interface(MEMORY_INTER) %{
5116 base($reg);
5117 index(0x0); /* NO_INDEX */
5118 scale(0x0);
5119 disp(0x0);
5120 %}
5121 %}
5123 // Indirect Memory Plus Short Offset Operand
5124 operand indOffset8(mRegP reg, immL8 off)
5125 %{
5126 constraint(ALLOC_IN_RC(p_reg));
5127 match(AddP reg off);
5129 op_cost(10);
5130 format %{ "[$reg + $off (8-bit)] @ indOffset8" %}
5131 interface(MEMORY_INTER) %{
5132 base($reg);
5133 index(0x0); /* NO_INDEX */
5134 scale(0x0);
5135 disp($off);
5136 %}
5137 %}
5139 // Indirect Memory Times Scale Plus Index Register
5140 operand indIndexScale(mRegP reg, mRegL lreg, immI2 scale)
5141 %{
5142 constraint(ALLOC_IN_RC(p_reg));
5143 match(AddP reg (LShiftL lreg scale));
5145 op_cost(10);
5146 format %{"[$reg + $lreg << $scale] @ indIndexScale" %}
5147 interface(MEMORY_INTER) %{
5148 base($reg);
5149 index($lreg);
5150 scale($scale);
5151 disp(0x0);
5152 %}
5153 %}
5156 // [base + index + offset]
5157 operand baseIndexOffset8(mRegP base, mRegL index, immL8 off)
5158 %{
5159 constraint(ALLOC_IN_RC(p_reg));
5160 op_cost(5);
5161 match(AddP (AddP base index) off);
5163 format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8" %}
5164 interface(MEMORY_INTER) %{
5165 base($base);
5166 index($index);
5167 scale(0x0);
5168 disp($off);
5169 %}
5170 %}
5172 // [base + index + offset]
5173 operand baseIndexOffset8_convI2L(mRegP base, mRegI index, immL8 off)
5174 %{
5175 constraint(ALLOC_IN_RC(p_reg));
5176 op_cost(5);
5177 match(AddP (AddP base (ConvI2L index)) off);
5179 format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8_convI2L" %}
5180 interface(MEMORY_INTER) %{
5181 base($base);
5182 index($index);
5183 scale(0x0);
5184 disp($off);
5185 %}
5186 %}
5188 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5189 operand indIndexScaleOffset8(mRegP reg, immL8 off, mRegL lreg, immI2 scale)
5190 %{
5191 constraint(ALLOC_IN_RC(p_reg));
5192 match(AddP (AddP reg (LShiftL lreg scale)) off);
5194 op_cost(10);
5195 format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffset8" %}
5196 interface(MEMORY_INTER) %{
5197 base($reg);
5198 index($lreg);
5199 scale($scale);
5200 disp($off);
5201 %}
5202 %}
5204 operand indIndexScaleOffset8_convI2L(mRegP reg, immL8 off, mRegI ireg, immI2 scale)
5205 %{
5206 constraint(ALLOC_IN_RC(p_reg));
5207 match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
5209 op_cost(10);
5210 format %{"[$reg + $off + $ireg << $scale] @ indIndexScaleOffset8_convI2L" %}
5211 interface(MEMORY_INTER) %{
5212 base($reg);
5213 index($ireg);
5214 scale($scale);
5215 disp($off);
5216 %}
5217 %}
5219 // [base + index<<scale + offset]
5220 operand basePosIndexScaleOffset8(mRegP base, mRegI index, immL8 off, immI_0_31 scale)
5221 %{
5222 constraint(ALLOC_IN_RC(p_reg));
5223 //predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5224 op_cost(10);
5225 match(AddP (AddP base (LShiftL (ConvI2L index) scale)) off);
5227 format %{ "[$base + $index << $scale + $off (8-bit)] @ basePosIndexScaleOffset8" %}
5228 interface(MEMORY_INTER) %{
5229 base($base);
5230 index($index);
5231 scale($scale);
5232 disp($off);
5233 %}
5234 %}
5236 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5237 operand indIndexScaleOffsetNarrow(mRegN reg, immL8 off, mRegL lreg, immI2 scale)
5238 %{
5239 predicate(Universe::narrow_oop_shift() == 0);
5240 constraint(ALLOC_IN_RC(p_reg));
5241 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
5243 op_cost(10);
5244 format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffsetNarrow" %}
5245 interface(MEMORY_INTER) %{
5246 base($reg);
5247 index($lreg);
5248 scale($scale);
5249 disp($off);
5250 %}
5251 %}
5253 // [base + index<<scale + offset] for compressd Oops
5254 operand indPosIndexI2LScaleOffset8Narrow(mRegN base, mRegI index, immL8 off, immI_0_31 scale)
5255 %{
5256 constraint(ALLOC_IN_RC(p_reg));
5257 //predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5258 predicate(Universe::narrow_oop_shift() == 0);
5259 op_cost(10);
5260 match(AddP (AddP (DecodeN base) (LShiftL (ConvI2L index) scale)) off);
5262 format %{ "[$base + $index << $scale + $off (8-bit)] @ indPosIndexI2LScaleOffset8Narrow" %}
5263 interface(MEMORY_INTER) %{
5264 base($base);
5265 index($index);
5266 scale($scale);
5267 disp($off);
5268 %}
5269 %}
5271 //FIXME: I think it's better to limit the immI to be 16-bit at most!
5272 // Indirect Memory Plus Long Offset Operand
5273 operand indOffset32(mRegP reg, immL32 off) %{
5274 constraint(ALLOC_IN_RC(p_reg));
5275 op_cost(20);
5276 match(AddP reg off);
5278 format %{ "[$reg + $off (32-bit)] @ indOffset32" %}
5279 interface(MEMORY_INTER) %{
5280 base($reg);
5281 index(0x0); /* NO_INDEX */
5282 scale(0x0);
5283 disp($off);
5284 %}
5285 %}
5287 // Indirect Memory Plus Index Register
5288 operand indIndex(mRegP addr, mRegL index) %{
5289 constraint(ALLOC_IN_RC(p_reg));
5290 match(AddP addr index);
5292 op_cost(20);
5293 format %{"[$addr + $index] @ indIndex" %}
5294 interface(MEMORY_INTER) %{
5295 base($addr);
5296 index($index);
5297 scale(0x0);
5298 disp(0x0);
5299 %}
5300 %}
5302 operand indirectNarrowKlass(mRegN reg)
5303 %{
5304 predicate(Universe::narrow_klass_shift() == 0);
5305 constraint(ALLOC_IN_RC(p_reg));
5306 op_cost(10);
5307 match(DecodeNKlass reg);
5309 format %{ "[$reg] @ indirectNarrowKlass" %}
5310 interface(MEMORY_INTER) %{
5311 base($reg);
5312 index(0x0);
5313 scale(0x0);
5314 disp(0x0);
5315 %}
5316 %}
5318 operand indOffset8NarrowKlass(mRegN reg, immL8 off)
5319 %{
5320 predicate(Universe::narrow_klass_shift() == 0);
5321 constraint(ALLOC_IN_RC(p_reg));
5322 op_cost(10);
5323 match(AddP (DecodeNKlass reg) off);
5325 format %{ "[$reg + $off (8-bit)] @ indOffset8NarrowKlass" %}
5326 interface(MEMORY_INTER) %{
5327 base($reg);
5328 index(0x0);
5329 scale(0x0);
5330 disp($off);
5331 %}
5332 %}
5334 operand indOffset32NarrowKlass(mRegN reg, immL32 off)
5335 %{
5336 predicate(Universe::narrow_klass_shift() == 0);
5337 constraint(ALLOC_IN_RC(p_reg));
5338 op_cost(10);
5339 match(AddP (DecodeNKlass reg) off);
5341 format %{ "[$reg + $off (32-bit)] @ indOffset32NarrowKlass" %}
5342 interface(MEMORY_INTER) %{
5343 base($reg);
5344 index(0x0);
5345 scale(0x0);
5346 disp($off);
5347 %}
5348 %}
5350 operand indIndexOffsetNarrowKlass(mRegN reg, mRegL lreg, immL32 off)
5351 %{
5352 predicate(Universe::narrow_klass_shift() == 0);
5353 constraint(ALLOC_IN_RC(p_reg));
5354 match(AddP (AddP (DecodeNKlass reg) lreg) off);
5356 op_cost(10);
5357 format %{"[$reg + $off + $lreg] @ indIndexOffsetNarrowKlass" %}
5358 interface(MEMORY_INTER) %{
5359 base($reg);
5360 index($lreg);
5361 scale(0x0);
5362 disp($off);
5363 %}
5364 %}
5366 operand indIndexNarrowKlass(mRegN reg, mRegL lreg)
5367 %{
5368 predicate(Universe::narrow_klass_shift() == 0);
5369 constraint(ALLOC_IN_RC(p_reg));
5370 match(AddP (DecodeNKlass reg) lreg);
5372 op_cost(10);
5373 format %{"[$reg + $lreg] @ indIndexNarrowKlass" %}
5374 interface(MEMORY_INTER) %{
5375 base($reg);
5376 index($lreg);
5377 scale(0x0);
5378 disp(0x0);
5379 %}
5380 %}
5382 // Indirect Memory Operand
5383 operand indirectNarrow(mRegN reg)
5384 %{
5385 predicate(Universe::narrow_oop_shift() == 0);
5386 constraint(ALLOC_IN_RC(p_reg));
5387 op_cost(10);
5388 match(DecodeN reg);
5390 format %{ "[$reg] @ indirectNarrow" %}
5391 interface(MEMORY_INTER) %{
5392 base($reg);
5393 index(0x0);
5394 scale(0x0);
5395 disp(0x0);
5396 %}
5397 %}
5399 // Indirect Memory Plus Short Offset Operand
5400 operand indOffset8Narrow(mRegN reg, immL8 off)
5401 %{
5402 predicate(Universe::narrow_oop_shift() == 0);
5403 constraint(ALLOC_IN_RC(p_reg));
5404 op_cost(10);
5405 match(AddP (DecodeN reg) off);
5407 format %{ "[$reg + $off (8-bit)] @ indOffset8Narrow" %}
5408 interface(MEMORY_INTER) %{
5409 base($reg);
5410 index(0x0);
5411 scale(0x0);
5412 disp($off);
5413 %}
5414 %}
5416 // Indirect Memory Plus Index Register Plus Offset Operand
5417 operand indIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
5418 %{
5419 predicate(Universe::narrow_oop_shift() == 0);
5420 constraint(ALLOC_IN_RC(p_reg));
5421 match(AddP (AddP (DecodeN reg) lreg) off);
5423 op_cost(10);
5424 format %{"[$reg + $off + $lreg] @ indIndexOffset8Narrow" %}
5425 interface(MEMORY_INTER) %{
5426 base($reg);
5427 index($lreg);
5428 scale(0x0);
5429 disp($off);
5430 %}
5431 %}
5433 //----------Load Long Memory Operands------------------------------------------
5434 // The load-long idiom will use it's address expression again after loading
5435 // the first word of the long. If the load-long destination overlaps with
5436 // registers used in the addressing expression, the 2nd half will be loaded
5437 // from a clobbered address. Fix this by requiring that load-long use
5438 // address registers that do not overlap with the load-long target.
5440 // load-long support
5441 operand load_long_RegP() %{
5442 constraint(ALLOC_IN_RC(p_reg));
5443 match(RegP);
5444 match(mRegP);
5445 op_cost(100);
5446 format %{ %}
5447 interface(REG_INTER);
5448 %}
5450 // Indirect Memory Operand Long
5451 operand load_long_indirect(load_long_RegP reg) %{
5452 constraint(ALLOC_IN_RC(p_reg));
5453 match(reg);
5455 format %{ "[$reg]" %}
5456 interface(MEMORY_INTER) %{
5457 base($reg);
5458 index(0x0);
5459 scale(0x0);
5460 disp(0x0);
5461 %}
5462 %}
5464 // Indirect Memory Plus Long Offset Operand
5465 operand load_long_indOffset32(load_long_RegP reg, immL32 off) %{
5466 match(AddP reg off);
5468 format %{ "[$reg + $off]" %}
5469 interface(MEMORY_INTER) %{
5470 base($reg);
5471 index(0x0);
5472 scale(0x0);
5473 disp($off);
5474 %}
5475 %}
5477 //----------Conditional Branch Operands----------------------------------------
5478 // Comparison Op - This is the operation of the comparison, and is limited to
5479 // the following set of codes:
5480 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5481 //
5482 // Other attributes of the comparison, such as unsignedness, are specified
5483 // by the comparison instruction that sets a condition code flags register.
5484 // That result is represented by a flags operand whose subtype is appropriate
5485 // to the unsignedness (etc.) of the comparison.
5486 //
5487 // Later, the instruction which matches both the Comparison Op (a Bool) and
5488 // the flags (produced by the Cmp) specifies the coding of the comparison op
5489 // by matching a specific subtype of Bool operand below, such as cmpOpU.
5491 // Comparision Code
5492 operand cmpOp() %{
5493 match(Bool);
5495 format %{ "" %}
5496 interface(COND_INTER) %{
5497 equal(0x01);
5498 not_equal(0x02);
5499 greater(0x03);
5500 greater_equal(0x04);
5501 less(0x05);
5502 less_equal(0x06);
5503 overflow(0x7);
5504 no_overflow(0x8);
5505 %}
5506 %}
5509 // Comparision Code
5510 // Comparison Code, unsigned compare. Used by FP also, with
5511 // C2 (unordered) turned into GT or LT already. The other bits
5512 // C0 and C3 are turned into Carry & Zero flags.
5513 operand cmpOpU() %{
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 overflow(0x7);
5525 no_overflow(0x8);
5526 %}
5527 %}
5530 //----------Special Memory Operands--------------------------------------------
5531 // Stack Slot Operand - This operand is used for loading and storing temporary
5532 // values on the stack where a match requires a value to
5533 // flow through memory.
5534 operand stackSlotP(sRegP reg) %{
5535 constraint(ALLOC_IN_RC(stack_slots));
5536 // No match rule because this operand is only generated in matching
5537 op_cost(50);
5538 format %{ "[$reg]" %}
5539 interface(MEMORY_INTER) %{
5540 base(0x1d); // SP
5541 index(0x0); // No Index
5542 scale(0x0); // No Scale
5543 disp($reg); // Stack Offset
5544 %}
5545 %}
5547 operand stackSlotI(sRegI 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 stackSlotF(sRegF 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 stackSlotD(sRegD 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 stackSlotL(sRegL 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 %}
5600 //------------------------OPERAND CLASSES--------------------------------------
5601 //opclass memory( direct, indirect, indOffset16, indOffset32, indOffset32X, indIndexOffset );
5602 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);
5605 //----------PIPELINE-----------------------------------------------------------
5606 // Rules which define the behavior of the target architectures pipeline.
5608 pipeline %{
5610 //----------ATTRIBUTES---------------------------------------------------------
5611 attributes %{
5612 fixed_size_instructions; // Fixed size instructions
5613 branch_has_delay_slot; // branch have delay slot in gs2
5614 max_instructions_per_bundle = 1; // 1 instruction per bundle
5615 max_bundles_per_cycle = 4; // Up to 4 bundles per cycle
5616 bundle_unit_size=4;
5617 instruction_unit_size = 4; // An instruction is 4 bytes long
5618 instruction_fetch_unit_size = 16; // The processor fetches one line
5619 instruction_fetch_units = 1; // of 16 bytes
5621 // List of nop instructions
5622 nops( MachNop );
5623 %}
5625 //----------RESOURCES----------------------------------------------------------
5626 // Resources are the functional units available to the machine
5628 resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4, ALU1, ALU2, ALU = ALU1 | ALU2, FPU1, FPU2, FPU = FPU1 | FPU2, MEM, BR);
5630 //----------PIPELINE DESCRIPTION-----------------------------------------------
5631 // Pipeline Description specifies the stages in the machine's pipeline
5633 // IF: fetch
5634 // ID: decode
5635 // RD: read
5636 // CA: caculate
5637 // WB: write back
5638 // CM: commit
5640 pipe_desc(IF, ID, RD, CA, WB, CM);
5643 //----------PIPELINE CLASSES---------------------------------------------------
5644 // Pipeline Classes describe the stages in which input and output are
5645 // referenced by the hardware pipeline.
5647 //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
5648 pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
5649 single_instruction;
5650 src1 : RD(read);
5651 src2 : RD(read);
5652 dst : WB(write)+1;
5653 DECODE : ID;
5654 ALU : CA;
5655 %}
5657 //No.19 Integer mult operation : dst <-- reg1 mult reg2
5658 pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
5659 src1 : RD(read);
5660 src2 : RD(read);
5661 dst : WB(write)+5;
5662 DECODE : ID;
5663 ALU2 : CA;
5664 %}
5666 pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
5667 src1 : RD(read);
5668 src2 : RD(read);
5669 dst : WB(write)+10;
5670 DECODE : ID;
5671 ALU2 : CA;
5672 %}
5674 //No.19 Integer div operation : dst <-- reg1 div reg2
5675 pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
5676 src1 : RD(read);
5677 src2 : RD(read);
5678 dst : WB(write)+10;
5679 DECODE : ID;
5680 ALU2 : CA;
5681 %}
5683 //No.19 Integer mod operation : dst <-- reg1 mod reg2
5684 pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
5685 instruction_count(2);
5686 src1 : RD(read);
5687 src2 : RD(read);
5688 dst : WB(write)+10;
5689 DECODE : ID;
5690 ALU2 : CA;
5691 %}
5693 //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
5694 pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
5695 instruction_count(2);
5696 src1 : RD(read);
5697 src2 : RD(read);
5698 dst : WB(write);
5699 DECODE : ID;
5700 ALU : CA;
5701 %}
5703 //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
5704 pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
5705 instruction_count(2);
5706 src : RD(read);
5707 dst : WB(write);
5708 DECODE : ID;
5709 ALU : CA;
5710 %}
5712 //no.16 load Long from memory :
5713 pipe_class ialu_loadL(mRegL dst, memory mem) %{
5714 instruction_count(2);
5715 mem : RD(read);
5716 dst : WB(write)+5;
5717 DECODE : ID;
5718 MEM : RD;
5719 %}
5721 //No.17 Store Long to Memory :
5722 pipe_class ialu_storeL(mRegL src, memory mem) %{
5723 instruction_count(2);
5724 mem : RD(read);
5725 src : RD(read);
5726 DECODE : ID;
5727 MEM : RD;
5728 %}
5730 //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
5731 pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
5732 single_instruction;
5733 src : RD(read);
5734 dst : WB(write);
5735 DECODE : ID;
5736 ALU : CA;
5737 %}
5739 //No.3 Integer move operation : dst <-- reg
5740 pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
5741 src : RD(read);
5742 dst : WB(write);
5743 DECODE : ID;
5744 ALU : CA;
5745 %}
5747 //No.4 No instructions : do nothing
5748 pipe_class empty( ) %{
5749 instruction_count(0);
5750 %}
5752 //No.5 UnConditional branch :
5753 pipe_class pipe_jump( label labl ) %{
5754 multiple_bundles;
5755 DECODE : ID;
5756 BR : RD;
5757 %}
5759 //No.6 ALU Conditional branch :
5760 pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
5761 multiple_bundles;
5762 src1 : RD(read);
5763 src2 : RD(read);
5764 DECODE : ID;
5765 BR : RD;
5766 %}
5768 //no.7 load integer from memory :
5769 pipe_class ialu_loadI(mRegI dst, memory mem) %{
5770 mem : RD(read);
5771 dst : WB(write)+3;
5772 DECODE : ID;
5773 MEM : RD;
5774 %}
5776 //No.8 Store Integer to Memory :
5777 pipe_class ialu_storeI(mRegI src, memory mem) %{
5778 mem : RD(read);
5779 src : RD(read);
5780 DECODE : ID;
5781 MEM : RD;
5782 %}
5785 //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
5786 pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
5787 src1 : RD(read);
5788 src2 : RD(read);
5789 dst : WB(write);
5790 DECODE : ID;
5791 FPU : CA;
5792 %}
5794 //No.22 Floating div operation : dst <-- reg1 div reg2
5795 pipe_class fpu_div(regF dst, regF src1, regF src2) %{
5796 src1 : RD(read);
5797 src2 : RD(read);
5798 dst : WB(write);
5799 DECODE : ID;
5800 FPU2 : CA;
5801 %}
5803 pipe_class fcvt_I2D(regD dst, mRegI src) %{
5804 src : RD(read);
5805 dst : WB(write);
5806 DECODE : ID;
5807 FPU1 : CA;
5808 %}
5810 pipe_class fcvt_D2I(mRegI dst, regD src) %{
5811 src : RD(read);
5812 dst : WB(write);
5813 DECODE : ID;
5814 FPU1 : CA;
5815 %}
5817 pipe_class pipe_mfc1(mRegI dst, regD src) %{
5818 src : RD(read);
5819 dst : WB(write);
5820 DECODE : ID;
5821 MEM : RD;
5822 %}
5824 pipe_class pipe_mtc1(regD dst, mRegI src) %{
5825 src : RD(read);
5826 dst : WB(write);
5827 DECODE : ID;
5828 MEM : RD(5);
5829 %}
5831 //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
5832 pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
5833 multiple_bundles;
5834 src1 : RD(read);
5835 src2 : RD(read);
5836 dst : WB(write);
5837 DECODE : ID;
5838 FPU2 : CA;
5839 %}
5841 //No.11 Load Floating from Memory :
5842 pipe_class fpu_loadF(regF dst, memory mem) %{
5843 instruction_count(1);
5844 mem : RD(read);
5845 dst : WB(write)+3;
5846 DECODE : ID;
5847 MEM : RD;
5848 %}
5850 //No.12 Store Floating to Memory :
5851 pipe_class fpu_storeF(regF src, memory mem) %{
5852 instruction_count(1);
5853 mem : RD(read);
5854 src : RD(read);
5855 DECODE : ID;
5856 MEM : RD;
5857 %}
5859 //No.13 FPU Conditional branch :
5860 pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
5861 multiple_bundles;
5862 src1 : RD(read);
5863 src2 : RD(read);
5864 DECODE : ID;
5865 BR : RD;
5866 %}
5868 //No.14 Floating FPU reg operation : dst <-- op reg
5869 pipe_class fpu1_regF(regF dst, regF src) %{
5870 src : RD(read);
5871 dst : WB(write);
5872 DECODE : ID;
5873 FPU : CA;
5874 %}
5876 pipe_class long_memory_op() %{
5877 instruction_count(10); multiple_bundles; force_serialization;
5878 fixed_latency(30);
5879 %}
5881 pipe_class simple_call() %{
5882 instruction_count(10); multiple_bundles; force_serialization;
5883 fixed_latency(200);
5884 BR : RD;
5885 %}
5887 pipe_class call() %{
5888 instruction_count(10); multiple_bundles; force_serialization;
5889 fixed_latency(200);
5890 %}
5892 //FIXME:
5893 //No.9 Piple slow : for multi-instructions
5894 pipe_class pipe_slow( ) %{
5895 instruction_count(20);
5896 force_serialization;
5897 multiple_bundles;
5898 fixed_latency(50);
5899 %}
5901 %}
5905 //----------INSTRUCTIONS-------------------------------------------------------
5906 //
5907 // match -- States which machine-independent subtree may be replaced
5908 // by this instruction.
5909 // ins_cost -- The estimated cost of this instruction is used by instruction
5910 // selection to identify a minimum cost tree of machine
5911 // instructions that matches a tree of machine-independent
5912 // instructions.
5913 // format -- A string providing the disassembly for this instruction.
5914 // The value of an instruction's operand may be inserted
5915 // by referring to it with a '$' prefix.
5916 // opcode -- Three instruction opcodes may be provided. These are referred
5917 // to within an encode class as $primary, $secondary, and $tertiary
5918 // respectively. The primary opcode is commonly used to
5919 // indicate the type of machine instruction, while secondary
5920 // and tertiary are often used for prefix options or addressing
5921 // modes.
5922 // ins_encode -- A list of encode classes with parameters. The encode class
5923 // name must have been defined in an 'enc_class' specification
5924 // in the encode section of the architecture description.
5927 // Load Integer
5928 instruct loadI(mRegI dst, memory mem) %{
5929 match(Set dst (LoadI mem));
5931 ins_cost(125);
5932 format %{ "lw $dst, $mem #@loadI" %}
5933 ins_encode (load_I_enc(dst, mem));
5934 ins_pipe( ialu_loadI );
5935 %}
5937 instruct loadI_convI2L(mRegL dst, memory mem) %{
5938 match(Set dst (ConvI2L (LoadI mem)));
5940 ins_cost(125);
5941 format %{ "lw $dst, $mem #@loadI_convI2L" %}
5942 ins_encode (load_I_enc(dst, mem));
5943 ins_pipe( ialu_loadI );
5944 %}
5946 // Load Integer (32 bit signed) to Byte (8 bit signed)
5947 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
5948 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
5950 ins_cost(125);
5951 format %{ "lb $dst, $mem\t# int -> byte #@loadI2B" %}
5952 ins_encode(load_B_enc(dst, mem));
5953 ins_pipe(ialu_loadI);
5954 %}
5956 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
5957 instruct loadI2UB(mRegI dst, memory mem, immI_255 mask) %{
5958 match(Set dst (AndI (LoadI mem) mask));
5960 ins_cost(125);
5961 format %{ "lbu $dst, $mem\t# int -> ubyte #@loadI2UB" %}
5962 ins_encode(load_UB_enc(dst, mem));
5963 ins_pipe(ialu_loadI);
5964 %}
5966 // Load Integer (32 bit signed) to Short (16 bit signed)
5967 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
5968 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
5970 ins_cost(125);
5971 format %{ "lh $dst, $mem\t# int -> short #@loadI2S" %}
5972 ins_encode(load_S_enc(dst, mem));
5973 ins_pipe(ialu_loadI);
5974 %}
5976 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
5977 instruct loadI2US(mRegI dst, memory mem, immI_65535 mask) %{
5978 match(Set dst (AndI (LoadI mem) mask));
5980 ins_cost(125);
5981 format %{ "lhu $dst, $mem\t# int -> ushort/char #@loadI2US" %}
5982 ins_encode(load_C_enc(dst, mem));
5983 ins_pipe(ialu_loadI);
5984 %}
5986 // Load Long.
5987 instruct loadL(mRegL dst, memory mem) %{
5988 // predicate(!((LoadLNode*)n)->require_atomic_access());
5989 match(Set dst (LoadL mem));
5991 ins_cost(250);
5992 format %{ "ld $dst, $mem #@loadL" %}
5993 ins_encode(load_L_enc(dst, mem));
5994 ins_pipe( ialu_loadL );
5995 %}
5997 // Load Long - UNaligned
5998 instruct loadL_unaligned(mRegL dst, memory mem) %{
5999 match(Set dst (LoadL_unaligned mem));
6001 // FIXME: Jin: Need more effective ldl/ldr
6002 ins_cost(450);
6003 format %{ "ld $dst, $mem #@loadL_unaligned\n\t" %}
6004 ins_encode(load_L_enc(dst, mem));
6005 ins_pipe( ialu_loadL );
6006 %}
6008 // Store Long
6009 instruct storeL_reg(memory mem, mRegL src) %{
6010 match(Set mem (StoreL mem src));
6012 ins_cost(200);
6013 format %{ "sd $mem, $src #@storeL_reg\n" %}
6014 ins_encode(store_L_reg_enc(mem, src));
6015 ins_pipe( ialu_storeL );
6016 %}
6018 instruct storeL_immL0(memory mem, immL0 zero) %{
6019 match(Set mem (StoreL mem zero));
6021 ins_cost(180);
6022 format %{ "sd zero, $mem #@storeL_immL0" %}
6023 ins_encode(store_L_immL0_enc(mem, zero));
6024 ins_pipe( ialu_storeL );
6025 %}
6027 instruct storeL_imm(memory mem, immL src) %{
6028 match(Set mem (StoreL mem src));
6030 ins_cost(200);
6031 format %{ "sd $src, $mem #@storeL_imm" %}
6032 ins_encode(store_L_immL_enc(mem, src));
6033 ins_pipe( ialu_storeL );
6034 %}
6036 // Load Compressed Pointer
6037 instruct loadN(mRegN dst, memory mem)
6038 %{
6039 match(Set dst (LoadN mem));
6041 ins_cost(125); // XXX
6042 format %{ "lwu $dst, $mem\t# compressed ptr @ loadN" %}
6043 ins_encode (load_N_enc(dst, mem));
6044 ins_pipe( ialu_loadI ); // XXX
6045 %}
6047 instruct loadN2P(mRegP dst, memory mem)
6048 %{
6049 match(Set dst (DecodeN (LoadN mem)));
6050 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6052 ins_cost(125); // XXX
6053 format %{ "lwu $dst, $mem\t# @ loadN2P" %}
6054 ins_encode (load_N_enc(dst, mem));
6055 ins_pipe( ialu_loadI ); // XXX
6056 %}
6058 // Load Pointer
6059 instruct loadP(mRegP dst, memory mem) %{
6060 match(Set dst (LoadP mem));
6062 ins_cost(125);
6063 format %{ "ld $dst, $mem #@loadP" %}
6064 ins_encode (load_P_enc(dst, mem));
6065 ins_pipe( ialu_loadI );
6066 %}
6068 // Load Klass Pointer
6069 instruct loadKlass(mRegP dst, memory mem) %{
6070 match(Set dst (LoadKlass mem));
6072 ins_cost(125);
6073 format %{ "MOV $dst,$mem @ loadKlass" %}
6074 ins_encode (load_P_enc(dst, mem));
6075 ins_pipe( ialu_loadI );
6076 %}
6078 // Load narrow Klass Pointer
6079 instruct loadNKlass(mRegN dst, memory mem)
6080 %{
6081 match(Set dst (LoadNKlass mem));
6083 ins_cost(125); // XXX
6084 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
6085 ins_encode (load_N_enc(dst, mem));
6086 ins_pipe( ialu_loadI ); // XXX
6087 %}
6089 instruct loadN2PKlass(mRegP dst, memory mem)
6090 %{
6091 match(Set dst (DecodeNKlass (LoadNKlass mem)));
6092 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
6094 ins_cost(125); // XXX
6095 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
6096 ins_encode (load_N_enc(dst, mem));
6097 ins_pipe( ialu_loadI ); // XXX
6098 %}
6100 // Load Constant
6101 instruct loadConI(mRegI dst, immI src) %{
6102 match(Set dst src);
6104 ins_cost(150);
6105 format %{ "mov $dst, $src #@loadConI" %}
6106 ins_encode %{
6107 Register dst = $dst$$Register;
6108 int value = $src$$constant;
6109 __ move(dst, value);
6110 %}
6111 ins_pipe( ialu_regI_regI );
6112 %}
6115 instruct loadConL_set64(mRegL dst, immL src) %{
6116 match(Set dst src);
6117 ins_cost(120);
6118 format %{ "li $dst, $src @ loadConL_set64" %}
6119 ins_encode %{
6120 __ set64($dst$$Register, $src$$constant);
6121 %}
6122 ins_pipe(ialu_regL_regL);
6123 %}
6125 /*
6126 // Load long value from constant table (predicated by immL_expensive).
6127 instruct loadConL_load(mRegL dst, immL_expensive src) %{
6128 match(Set dst src);
6129 ins_cost(150);
6130 format %{ "ld $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
6131 ins_encode %{
6132 int con_offset = $constantoffset($src);
6134 if (Assembler::is_simm16(con_offset)) {
6135 __ ld($dst$$Register, $constanttablebase, con_offset);
6136 } else {
6137 __ set64(AT, con_offset);
6138 if (UseLoongsonISA) {
6139 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
6140 } else {
6141 __ daddu(AT, $constanttablebase, AT);
6142 __ ld($dst$$Register, AT, 0);
6143 }
6144 }
6145 %}
6146 ins_pipe(ialu_loadI);
6147 %}
6148 */
6150 instruct loadConL16(mRegL dst, immL16 src) %{
6151 match(Set dst src);
6152 ins_cost(105);
6153 format %{ "mov $dst, $src #@loadConL16" %}
6154 ins_encode %{
6155 Register dst_reg = as_Register($dst$$reg);
6156 int value = $src$$constant;
6157 __ daddiu(dst_reg, R0, value);
6158 %}
6159 ins_pipe( ialu_regL_regL );
6160 %}
6163 instruct loadConL0(mRegL dst, immL0 src) %{
6164 match(Set dst src);
6165 ins_cost(100);
6166 format %{ "mov $dst, zero #@loadConL0" %}
6167 ins_encode %{
6168 Register dst_reg = as_Register($dst$$reg);
6169 __ daddu(dst_reg, R0, R0);
6170 %}
6171 ins_pipe( ialu_regL_regL );
6172 %}
6174 // Load Range
6175 instruct loadRange(mRegI dst, memory mem) %{
6176 match(Set dst (LoadRange mem));
6178 ins_cost(125);
6179 format %{ "MOV $dst,$mem @ loadRange" %}
6180 ins_encode(load_I_enc(dst, mem));
6181 ins_pipe( ialu_loadI );
6182 %}
6185 instruct storeP(memory mem, mRegP src ) %{
6186 match(Set mem (StoreP mem src));
6188 ins_cost(125);
6189 format %{ "sd $src, $mem #@storeP" %}
6190 ins_encode(store_P_reg_enc(mem, src));
6191 ins_pipe( ialu_storeI );
6192 %}
6194 // Store NULL Pointer, mark word, or other simple pointer constant.
6195 instruct storeImmP0(memory mem, immP0 zero) %{
6196 match(Set mem (StoreP mem zero));
6198 ins_cost(125);
6199 format %{ "mov $mem, $zero #@storeImmP0" %}
6200 ins_encode(store_P_immP0_enc(mem));
6201 ins_pipe( ialu_storeI );
6202 %}
6204 // Store Byte Immediate
6205 instruct storeImmB(memory mem, immI8 src) %{
6206 match(Set mem (StoreB mem src));
6208 ins_cost(150);
6209 format %{ "movb $mem, $src #@storeImmB" %}
6210 ins_encode(store_B_immI_enc(mem, src));
6211 ins_pipe( ialu_storeI );
6212 %}
6214 // Store Compressed Pointer
6215 instruct storeN(memory mem, mRegN src)
6216 %{
6217 match(Set mem (StoreN mem src));
6219 ins_cost(125); // XXX
6220 format %{ "sw $mem, $src\t# compressed ptr @ storeN" %}
6221 ins_encode(store_N_reg_enc(mem, src));
6222 ins_pipe( ialu_storeI );
6223 %}
6225 instruct storeP2N(memory mem, mRegP src)
6226 %{
6227 match(Set mem (StoreN mem (EncodeP src)));
6228 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6230 ins_cost(125); // XXX
6231 format %{ "sw $mem, $src\t# @ storeP2N" %}
6232 ins_encode(store_N_reg_enc(mem, src));
6233 ins_pipe( ialu_storeI );
6234 %}
6236 instruct storeNKlass(memory mem, mRegN src)
6237 %{
6238 match(Set mem (StoreNKlass mem src));
6240 ins_cost(125); // XXX
6241 format %{ "sw $mem, $src\t# compressed klass ptr @ storeNKlass" %}
6242 ins_encode(store_N_reg_enc(mem, src));
6243 ins_pipe( ialu_storeI );
6244 %}
6246 instruct storeP2NKlass(memory mem, mRegP src)
6247 %{
6248 match(Set mem (StoreNKlass mem (EncodePKlass src)));
6249 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
6251 ins_cost(125); // XXX
6252 format %{ "sw $mem, $src\t# @ storeP2NKlass" %}
6253 ins_encode(store_N_reg_enc(mem, src));
6254 ins_pipe( ialu_storeI );
6255 %}
6257 instruct storeImmN0(memory mem, immN0 zero)
6258 %{
6259 match(Set mem (StoreN mem zero));
6261 ins_cost(125); // XXX
6262 format %{ "storeN0 zero, $mem\t# compressed ptr" %}
6263 ins_encode(storeImmN0_enc(mem, zero));
6264 ins_pipe( ialu_storeI );
6265 %}
6267 // Store Byte
6268 instruct storeB(memory mem, mRegI src) %{
6269 match(Set mem (StoreB mem src));
6271 ins_cost(125);
6272 format %{ "sb $src, $mem #@storeB" %}
6273 ins_encode(store_B_reg_enc(mem, src));
6274 ins_pipe( ialu_storeI );
6275 %}
6277 instruct storeB_convL2I(memory mem, mRegL src) %{
6278 match(Set mem (StoreB mem (ConvL2I src)));
6280 ins_cost(125);
6281 format %{ "sb $src, $mem #@storeB_convL2I" %}
6282 ins_encode(store_B_reg_enc(mem, src));
6283 ins_pipe( ialu_storeI );
6284 %}
6286 // Load Byte (8bit signed)
6287 instruct loadB(mRegI dst, memory mem) %{
6288 match(Set dst (LoadB mem));
6290 ins_cost(125);
6291 format %{ "lb $dst, $mem #@loadB" %}
6292 ins_encode(load_B_enc(dst, mem));
6293 ins_pipe( ialu_loadI );
6294 %}
6296 instruct loadB_convI2L(mRegL dst, memory mem) %{
6297 match(Set dst (ConvI2L (LoadB mem)));
6299 ins_cost(125);
6300 format %{ "lb $dst, $mem #@loadB_convI2L" %}
6301 ins_encode(load_B_enc(dst, mem));
6302 ins_pipe( ialu_loadI );
6303 %}
6305 // Load Byte (8bit UNsigned)
6306 instruct loadUB(mRegI dst, memory mem) %{
6307 match(Set dst (LoadUB mem));
6309 ins_cost(125);
6310 format %{ "lbu $dst, $mem #@loadUB" %}
6311 ins_encode(load_UB_enc(dst, mem));
6312 ins_pipe( ialu_loadI );
6313 %}
6315 instruct loadUB_convI2L(mRegL dst, memory mem) %{
6316 match(Set dst (ConvI2L (LoadUB mem)));
6318 ins_cost(125);
6319 format %{ "lbu $dst, $mem #@loadUB_convI2L" %}
6320 ins_encode(load_UB_enc(dst, mem));
6321 ins_pipe( ialu_loadI );
6322 %}
6324 // Load Short (16bit signed)
6325 instruct loadS(mRegI dst, memory mem) %{
6326 match(Set dst (LoadS mem));
6328 ins_cost(125);
6329 format %{ "lh $dst, $mem #@loadS" %}
6330 ins_encode(load_S_enc(dst, mem));
6331 ins_pipe( ialu_loadI );
6332 %}
6334 // Load Short (16 bit signed) to Byte (8 bit signed)
6335 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
6336 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
6338 ins_cost(125);
6339 format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
6340 ins_encode(load_B_enc(dst, mem));
6341 ins_pipe(ialu_loadI);
6342 %}
6344 instruct loadS_convI2L(mRegL dst, memory mem) %{
6345 match(Set dst (ConvI2L (LoadS mem)));
6347 ins_cost(125);
6348 format %{ "lh $dst, $mem #@loadS_convI2L" %}
6349 ins_encode(load_S_enc(dst, mem));
6350 ins_pipe( ialu_loadI );
6351 %}
6353 // Store Integer Immediate
6354 instruct storeImmI(memory mem, immI src) %{
6355 match(Set mem (StoreI mem src));
6357 ins_cost(150);
6358 format %{ "mov $mem, $src #@storeImmI" %}
6359 ins_encode(store_I_immI_enc(mem, src));
6360 ins_pipe( ialu_storeI );
6361 %}
6363 // Store Integer
6364 instruct storeI(memory mem, mRegI src) %{
6365 match(Set mem (StoreI mem src));
6367 ins_cost(125);
6368 format %{ "sw $mem, $src #@storeI" %}
6369 ins_encode(store_I_reg_enc(mem, src));
6370 ins_pipe( ialu_storeI );
6371 %}
6373 instruct storeI_convL2I(memory mem, mRegL src) %{
6374 match(Set mem (StoreI mem (ConvL2I src)));
6376 ins_cost(125);
6377 format %{ "sw $mem, $src #@storeI_convL2I" %}
6378 ins_encode(store_I_reg_enc(mem, src));
6379 ins_pipe( ialu_storeI );
6380 %}
6382 // Load Float
6383 instruct loadF(regF dst, memory mem) %{
6384 match(Set dst (LoadF mem));
6386 ins_cost(150);
6387 format %{ "loadF $dst, $mem #@loadF" %}
6388 ins_encode(load_F_enc(dst, mem));
6389 ins_pipe( ialu_loadI );
6390 %}
6392 instruct loadConP_general(mRegP dst, immP src) %{
6393 match(Set dst src);
6395 ins_cost(120);
6396 format %{ "li $dst, $src #@loadConP_general" %}
6398 ins_encode %{
6399 Register dst = $dst$$Register;
6400 long* value = (long*)$src$$constant;
6402 if($src->constant_reloc() == relocInfo::metadata_type){
6403 int klass_index = __ oop_recorder()->find_index((Klass*)value);
6404 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
6406 __ relocate(rspec);
6407 __ patchable_set48(dst, (long)value);
6408 }else if($src->constant_reloc() == relocInfo::oop_type){
6409 int oop_index = __ oop_recorder()->find_index((jobject)value);
6410 RelocationHolder rspec = oop_Relocation::spec(oop_index);
6412 __ relocate(rspec);
6413 __ patchable_set48(dst, (long)value);
6414 } else if ($src->constant_reloc() == relocInfo::none) {
6415 __ set64(dst, (long)value);
6416 }
6417 %}
6419 ins_pipe( ialu_regI_regI );
6420 %}
6422 /*
6423 instruct loadConP_load(mRegP dst, immP_load src) %{
6424 match(Set dst src);
6426 ins_cost(100);
6427 format %{ "ld $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
6429 ins_encode %{
6431 int con_offset = $constantoffset($src);
6433 if (Assembler::is_simm16(con_offset)) {
6434 __ ld($dst$$Register, $constanttablebase, con_offset);
6435 } else {
6436 __ set64(AT, con_offset);
6437 if (UseLoongsonISA) {
6438 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
6439 } else {
6440 __ daddu(AT, $constanttablebase, AT);
6441 __ ld($dst$$Register, AT, 0);
6442 }
6443 }
6444 %}
6446 ins_pipe(ialu_loadI);
6447 %}
6448 */
6450 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
6451 match(Set dst src);
6453 ins_cost(80);
6454 format %{ "li $dst, $src @ loadConP_no_oop_cheap" %}
6456 ins_encode %{
6457 __ set64($dst$$Register, $src$$constant);
6458 %}
6460 ins_pipe(ialu_regI_regI);
6461 %}
6464 instruct loadConP_poll(mRegP dst, immP_poll src) %{
6465 match(Set dst src);
6467 ins_cost(50);
6468 format %{ "li $dst, $src #@loadConP_poll" %}
6470 ins_encode %{
6471 Register dst = $dst$$Register;
6472 intptr_t value = (intptr_t)$src$$constant;
6474 __ set64(dst, (jlong)value);
6475 %}
6477 ins_pipe( ialu_regI_regI );
6478 %}
6480 instruct loadConP0(mRegP dst, immP0 src)
6481 %{
6482 match(Set dst src);
6484 ins_cost(50);
6485 format %{ "mov $dst, R0\t# ptr" %}
6486 ins_encode %{
6487 Register dst_reg = $dst$$Register;
6488 __ daddu(dst_reg, R0, R0);
6489 %}
6490 ins_pipe( ialu_regI_regI );
6491 %}
6493 instruct loadConN0(mRegN dst, immN0 src) %{
6494 match(Set dst src);
6495 format %{ "move $dst, R0\t# compressed NULL ptr" %}
6496 ins_encode %{
6497 __ move($dst$$Register, R0);
6498 %}
6499 ins_pipe( ialu_regI_regI );
6500 %}
6502 instruct loadConN(mRegN dst, immN src) %{
6503 match(Set dst src);
6505 ins_cost(125);
6506 format %{ "li $dst, $src\t# compressed ptr @ loadConN" %}
6507 ins_encode %{
6508 Register dst = $dst$$Register;
6509 __ set_narrow_oop(dst, (jobject)$src$$constant);
6510 %}
6511 ins_pipe( ialu_regI_regI ); // XXX
6512 %}
6514 instruct loadConNKlass(mRegN dst, immNKlass src) %{
6515 match(Set dst src);
6517 ins_cost(125);
6518 format %{ "li $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
6519 ins_encode %{
6520 Register dst = $dst$$Register;
6521 __ set_narrow_klass(dst, (Klass*)$src$$constant);
6522 %}
6523 ins_pipe( ialu_regI_regI ); // XXX
6524 %}
6526 //FIXME
6527 // Tail Call; Jump from runtime stub to Java code.
6528 // Also known as an 'interprocedural jump'.
6529 // Target of jump will eventually return to caller.
6530 // TailJump below removes the return address.
6531 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
6532 match(TailCall jump_target method_oop );
6533 ins_cost(300);
6534 format %{ "JMP $jump_target \t# @TailCalljmpInd" %}
6536 ins_encode %{
6537 Register target = $jump_target$$Register;
6538 Register oop = $method_oop$$Register;
6540 /* 2012/10/12 Jin: RA will be used in generate_forward_exception() */
6541 __ push(RA);
6543 __ move(S3, oop);
6544 __ jr(target);
6545 __ nop();
6546 %}
6548 ins_pipe( pipe_jump );
6549 %}
6551 // Create exception oop: created by stack-crawling runtime code.
6552 // Created exception is now available to this handler, and is setup
6553 // just prior to jumping to this handler. No code emitted.
6554 instruct CreateException( a0_RegP ex_oop )
6555 %{
6556 match(Set ex_oop (CreateEx));
6558 // use the following format syntax
6559 format %{ "# exception oop is in A0; no code emitted @CreateException" %}
6560 ins_encode %{
6561 /* Jin: X86 leaves this function empty */
6562 __ block_comment("CreateException is empty in X86/MIPS");
6563 %}
6564 ins_pipe( empty );
6565 // ins_pipe( pipe_jump );
6566 %}
6569 /* 2012/9/14 Jin: The mechanism of exception handling is clear now.
6571 - Common try/catch:
6572 2012/9/14 Jin: [stubGenerator_mips.cpp] generate_forward_exception()
6573 |- V0, V1 are created
6574 |- T9 <= SharedRuntime::exception_handler_for_return_address
6575 `- jr T9
6576 `- the caller's exception_handler
6577 `- jr OptoRuntime::exception_blob
6578 `- here
6579 - Rethrow(e.g. 'unwind'):
6580 * The callee:
6581 |- an exception is triggered during execution
6582 `- exits the callee method through RethrowException node
6583 |- The callee pushes exception_oop(T0) and exception_pc(RA)
6584 `- The callee jumps to OptoRuntime::rethrow_stub()
6585 * In OptoRuntime::rethrow_stub:
6586 |- The VM calls _rethrow_Java to determine the return address in the caller method
6587 `- exits the stub with tailjmpInd
6588 |- pops exception_oop(V0) and exception_pc(V1)
6589 `- jumps to the return address(usually an exception_handler)
6590 * The caller:
6591 `- continues processing the exception_blob with V0/V1
6592 */
6594 /*
6595 Disassembling OptoRuntime::rethrow_stub()
6597 ; locals
6598 0x2d3bf320: addiu sp, sp, 0xfffffff8
6599 0x2d3bf324: sw ra, 0x4(sp)
6600 0x2d3bf328: sw fp, 0x0(sp)
6601 0x2d3bf32c: addu fp, sp, zero
6602 0x2d3bf330: addiu sp, sp, 0xfffffff0
6603 0x2d3bf334: sw ra, 0x8(sp)
6604 0x2d3bf338: sw t0, 0x4(sp)
6605 0x2d3bf33c: sw sp, 0x0(sp)
6607 ; get_thread(S2)
6608 0x2d3bf340: addu s2, sp, zero
6609 0x2d3bf344: srl s2, s2, 12
6610 0x2d3bf348: sll s2, s2, 2
6611 0x2d3bf34c: lui at, 0x2c85
6612 0x2d3bf350: addu at, at, s2
6613 0x2d3bf354: lw s2, 0xffffcc80(at)
6615 0x2d3bf358: lw s0, 0x0(sp)
6616 0x2d3bf35c: sw s0, 0x118(s2) // last_sp -> threa
6617 0x2d3bf360: sw s2, 0xc(sp)
6619 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
6620 0x2d3bf364: lw a0, 0x4(sp)
6621 0x2d3bf368: lw a1, 0xc(sp)
6622 0x2d3bf36c: lw a2, 0x8(sp)
6623 ;; Java_To_Runtime
6624 0x2d3bf370: lui t9, 0x2c34
6625 0x2d3bf374: addiu t9, t9, 0xffff8a48
6626 0x2d3bf378: jalr t9
6627 0x2d3bf37c: nop
6629 0x2d3bf380: addu s3, v0, zero ; S3: SharedRuntime::raw_exception_handler_for_return_address()
6631 0x2d3bf384: lw s0, 0xc(sp)
6632 0x2d3bf388: sw zero, 0x118(s0)
6633 0x2d3bf38c: sw zero, 0x11c(s0)
6634 0x2d3bf390: lw s1, 0x144(s0) ; ex_oop: S1
6635 0x2d3bf394: addu s2, s0, zero
6636 0x2d3bf398: sw zero, 0x144(s2)
6637 0x2d3bf39c: lw s0, 0x4(s2)
6638 0x2d3bf3a0: addiu s4, zero, 0x0
6639 0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
6640 0x2d3bf3a8: nop
6641 0x2d3bf3ac: addiu sp, sp, 0x10
6642 0x2d3bf3b0: addiu sp, sp, 0x8
6643 0x2d3bf3b4: lw ra, 0xfffffffc(sp)
6644 0x2d3bf3b8: lw fp, 0xfffffff8(sp)
6645 0x2d3bf3bc: lui at, 0x2b48
6646 0x2d3bf3c0: lw at, 0x100(at)
6648 ; tailjmpInd: Restores exception_oop & exception_pc
6649 0x2d3bf3c4: addu v1, ra, zero
6650 0x2d3bf3c8: addu v0, s1, zero
6651 0x2d3bf3cc: jr s3
6652 0x2d3bf3d0: nop
6653 ; Exception:
6654 0x2d3bf3d4: lui s1, 0x2cc8 ; generate_forward_exception()
6655 0x2d3bf3d8: addiu s1, s1, 0x40
6656 0x2d3bf3dc: addiu s2, zero, 0x0
6657 0x2d3bf3e0: addiu sp, sp, 0x10
6658 0x2d3bf3e4: addiu sp, sp, 0x8
6659 0x2d3bf3e8: lw ra, 0xfffffffc(sp)
6660 0x2d3bf3ec: lw fp, 0xfffffff8(sp)
6661 0x2d3bf3f0: lui at, 0x2b48
6662 0x2d3bf3f4: lw at, 0x100(at)
6663 ; TailCalljmpInd
6664 __ push(RA); ; to be used in generate_forward_exception()
6665 0x2d3bf3f8: addu t7, s2, zero
6666 0x2d3bf3fc: jr s1
6667 0x2d3bf400: nop
6668 */
6669 // Rethrow exception:
6670 // The exception oop will come in the first argument position.
6671 // Then JUMP (not call) to the rethrow stub code.
6672 instruct RethrowException()
6673 %{
6674 match(Rethrow);
6676 // use the following format syntax
6677 format %{ "JMP rethrow_stub #@RethrowException" %}
6678 ins_encode %{
6679 __ block_comment("@ RethrowException");
6681 cbuf.set_insts_mark();
6682 cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
6684 // call OptoRuntime::rethrow_stub to get the exception handler in parent method
6685 __ patchable_jump((address)OptoRuntime::rethrow_stub());
6686 %}
6687 ins_pipe( pipe_jump );
6688 %}
6690 // ============================================================================
6691 // Branch Instructions --- long offset versions
6693 // Jump Direct
6694 instruct jmpDir_long(label labl) %{
6695 match(Goto);
6696 effect(USE labl);
6698 ins_cost(300);
6699 format %{ "JMP $labl #@jmpDir_long" %}
6701 ins_encode %{
6702 Label* L = $labl$$label;
6703 __ jmp_far(*L);
6704 %}
6706 ins_pipe( pipe_jump );
6707 //ins_pc_relative(1);
6708 %}
6710 // Jump Direct Conditional - Label defines a relative address from Jcc+1
6711 instruct jmpLoopEnd_long(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
6712 match(CountedLoopEnd cop (CmpI src1 src2));
6713 effect(USE labl);
6715 ins_cost(300);
6716 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_long" %}
6717 ins_encode %{
6718 Register op1 = $src1$$Register;
6719 Register op2 = $src2$$Register;
6720 Label* L = $labl$$label;
6721 int flag = $cop$$cmpcode;
6723 switch(flag) {
6724 case 0x01: //equal
6725 __ beq_long(op1, op2, *L);
6726 break;
6727 case 0x02: //not_equal
6728 __ bne_long(op1, op2, *L);
6729 break;
6730 case 0x03: //above
6731 __ slt(AT, op2, op1);
6732 __ bne_long(AT, R0, *L);
6733 break;
6734 case 0x04: //above_equal
6735 __ slt(AT, op1, op2);
6736 __ beq_long(AT, R0, *L);
6737 break;
6738 case 0x05: //below
6739 __ slt(AT, op1, op2);
6740 __ bne_long(AT, R0, *L);
6741 break;
6742 case 0x06: //below_equal
6743 __ slt(AT, op2, op1);
6744 __ beq_long(AT, R0, *L);
6745 break;
6746 default:
6747 Unimplemented();
6748 }
6749 %}
6750 ins_pipe( pipe_jump );
6751 ins_pc_relative(1);
6752 %}
6754 instruct jmpLoopEnd_reg_immI_long(cmpOp cop, mRegI src1, immI src2, label labl) %{
6755 match(CountedLoopEnd cop (CmpI src1 src2));
6756 effect(USE labl);
6758 ins_cost(300);
6759 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_immI_long" %}
6760 ins_encode %{
6761 Register op1 = $src1$$Register;
6762 Register op2 = AT;
6763 Label* L = $labl$$label;
6764 int flag = $cop$$cmpcode;
6766 __ move(op2, $src2$$constant);
6768 switch(flag) {
6769 case 0x01: //equal
6770 __ beq_long(op1, op2, *L);
6771 break;
6772 case 0x02: //not_equal
6773 __ bne_long(op1, op2, *L);
6774 break;
6775 case 0x03: //above
6776 __ slt(AT, op2, op1);
6777 __ bne_long(AT, R0, *L);
6778 break;
6779 case 0x04: //above_equal
6780 __ slt(AT, op1, op2);
6781 __ beq_long(AT, R0, *L);
6782 break;
6783 case 0x05: //below
6784 __ slt(AT, op1, op2);
6785 __ bne_long(AT, R0, *L);
6786 break;
6787 case 0x06: //below_equal
6788 __ slt(AT, op2, op1);
6789 __ beq_long(AT, R0, *L);
6790 break;
6791 default:
6792 Unimplemented();
6793 }
6794 %}
6795 ins_pipe( pipe_jump );
6796 ins_pc_relative(1);
6797 %}
6800 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
6801 instruct jmpCon_flags_long(cmpOp cop, FlagsReg cr, label labl) %{
6802 match(If cop cr);
6803 effect(USE labl);
6805 ins_cost(300);
6806 format %{ "J$cop $labl #mips uses AT as eflag @jmpCon_flags_long" %}
6808 ins_encode %{
6809 Label* L = $labl$$label;
6810 switch($cop$$cmpcode) {
6811 case 0x01: //equal
6812 __ bne_long(AT, R0, *L);
6813 break;
6814 case 0x02: //not equal
6815 __ beq_long(AT, R0, *L);
6816 break;
6817 default:
6818 Unimplemented();
6819 }
6820 %}
6822 ins_pipe( pipe_jump );
6823 ins_pc_relative(1);
6824 %}
6826 // Conditional jumps
6827 instruct branchConP_zero_long(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
6828 match(If cmp (CmpP op1 zero));
6829 effect(USE labl);
6831 ins_cost(180);
6832 format %{ "b$cmp $op1, R0, $labl #@branchConP_zero_long" %}
6834 ins_encode %{
6835 Register op1 = $op1$$Register;
6836 Register op2 = R0;
6837 Label* L = $labl$$label;
6838 int flag = $cmp$$cmpcode;
6840 switch(flag) {
6841 case 0x01: //equal
6842 __ beq_long(op1, op2, *L);
6843 break;
6844 case 0x02: //not_equal
6845 __ bne_long(op1, op2, *L);
6846 break;
6847 default:
6848 Unimplemented();
6849 }
6850 %}
6852 ins_pc_relative(1);
6853 ins_pipe( pipe_alu_branch );
6854 %}
6856 instruct branchConN2P_zero_long(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
6857 match(If cmp (CmpP (DecodeN op1) zero));
6858 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6859 effect(USE labl);
6861 ins_cost(180);
6862 format %{ "b$cmp $op1, R0, $labl #@branchConN2P_zero_long" %}
6864 ins_encode %{
6865 Register op1 = $op1$$Register;
6866 Register op2 = R0;
6867 Label* L = $labl$$label;
6868 int flag = $cmp$$cmpcode;
6870 switch(flag)
6871 {
6872 case 0x01: //equal
6873 __ beq_long(op1, op2, *L);
6874 break;
6875 case 0x02: //not_equal
6876 __ bne_long(op1, op2, *L);
6877 break;
6878 default:
6879 Unimplemented();
6880 }
6881 %}
6883 ins_pc_relative(1);
6884 ins_pipe( pipe_alu_branch );
6885 %}
6888 instruct branchConP_long(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
6889 match(If cmp (CmpP op1 op2));
6890 // predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
6891 effect(USE labl);
6893 ins_cost(200);
6894 format %{ "b$cmp $op1, $op2, $labl #@branchConP_long" %}
6896 ins_encode %{
6897 Register op1 = $op1$$Register;
6898 Register op2 = $op2$$Register;
6899 Label* L = $labl$$label;
6900 int flag = $cmp$$cmpcode;
6902 switch(flag) {
6903 case 0x01: //equal
6904 __ beq_long(op1, op2, *L);
6905 break;
6906 case 0x02: //not_equal
6907 __ bne_long(op1, op2, *L);
6908 break;
6909 case 0x03: //above
6910 __ sltu(AT, op2, op1);
6911 __ bne_long(R0, AT, *L);
6912 break;
6913 case 0x04: //above_equal
6914 __ sltu(AT, op1, op2);
6915 __ beq_long(AT, R0, *L);
6916 break;
6917 case 0x05: //below
6918 __ sltu(AT, op1, op2);
6919 __ bne_long(R0, AT, *L);
6920 break;
6921 case 0x06: //below_equal
6922 __ sltu(AT, op2, op1);
6923 __ beq_long(AT, R0, *L);
6924 break;
6925 default:
6926 Unimplemented();
6927 }
6928 %}
6930 ins_pc_relative(1);
6931 ins_pipe( pipe_alu_branch );
6932 %}
6934 instruct cmpN_null_branch_long(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
6935 match(If cmp (CmpN op1 null));
6936 effect(USE labl);
6938 ins_cost(180);
6939 format %{ "CMP $op1,0\t! compressed ptr\n\t"
6940 "BP$cmp $labl @ cmpN_null_branch_long" %}
6941 ins_encode %{
6942 Register op1 = $op1$$Register;
6943 Register op2 = R0;
6944 Label* L = $labl$$label;
6945 int flag = $cmp$$cmpcode;
6947 switch(flag) {
6948 case 0x01: //equal
6949 __ beq_long(op1, op2, *L);
6950 break;
6951 case 0x02: //not_equal
6952 __ bne_long(op1, op2, *L);
6953 break;
6954 default:
6955 Unimplemented();
6956 }
6957 %}
6958 //TODO: pipe_branchP or create pipe_branchN LEE
6959 ins_pc_relative(1);
6960 ins_pipe( pipe_alu_branch );
6961 %}
6963 instruct cmpN_reg_branch_long(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
6964 match(If cmp (CmpN op1 op2));
6965 effect(USE labl);
6967 ins_cost(180);
6968 format %{ "CMP $op1,$op2\t! compressed ptr\n\t"
6969 "BP$cmp $labl @ cmpN_reg_branch_long" %}
6970 ins_encode %{
6971 Register op1_reg = $op1$$Register;
6972 Register op2_reg = $op2$$Register;
6973 Label* L = $labl$$label;
6974 int flag = $cmp$$cmpcode;
6976 switch(flag) {
6977 case 0x01: //equal
6978 __ beq_long(op1_reg, op2_reg, *L);
6979 break;
6980 case 0x02: //not_equal
6981 __ bne_long(op1_reg, op2_reg, *L);
6982 break;
6983 case 0x03: //above
6984 __ sltu(AT, op2_reg, op1_reg);
6985 __ bne_long(R0, AT, *L);
6986 break;
6987 case 0x04: //above_equal
6988 __ sltu(AT, op1_reg, op2_reg);
6989 __ beq_long(AT, R0, *L);
6990 break;
6991 case 0x05: //below
6992 __ sltu(AT, op1_reg, op2_reg);
6993 __ bne_long(R0, AT, *L);
6994 break;
6995 case 0x06: //below_equal
6996 __ sltu(AT, op2_reg, op1_reg);
6997 __ beq_long(AT, R0, *L);
6998 break;
6999 default:
7000 Unimplemented();
7001 }
7002 %}
7003 ins_pc_relative(1);
7004 ins_pipe( pipe_alu_branch );
7005 %}
7007 instruct branchConIU_reg_reg_long(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
7008 match( If cmp (CmpU src1 src2) );
7009 effect(USE labl);
7010 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_reg_long" %}
7012 ins_encode %{
7013 Register op1 = $src1$$Register;
7014 Register op2 = $src2$$Register;
7015 Label* L = $labl$$label;
7016 int flag = $cmp$$cmpcode;
7018 switch(flag) {
7019 case 0x01: //equal
7020 __ beq_long(op1, op2, *L);
7021 break;
7022 case 0x02: //not_equal
7023 __ bne_long(op1, op2, *L);
7024 break;
7025 case 0x03: //above
7026 __ sltu(AT, op2, op1);
7027 __ bne_long(AT, R0, *L);
7028 break;
7029 case 0x04: //above_equal
7030 __ sltu(AT, op1, op2);
7031 __ beq_long(AT, R0, *L);
7032 break;
7033 case 0x05: //below
7034 __ sltu(AT, op1, op2);
7035 __ bne_long(AT, R0, *L);
7036 break;
7037 case 0x06: //below_equal
7038 __ sltu(AT, op2, op1);
7039 __ beq_long(AT, R0, *L);
7040 break;
7041 default:
7042 Unimplemented();
7043 }
7044 %}
7046 ins_pc_relative(1);
7047 ins_pipe( pipe_alu_branch );
7048 %}
7051 instruct branchConIU_reg_imm_long(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
7052 match( If cmp (CmpU src1 src2) );
7053 effect(USE labl);
7054 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_imm_long" %}
7056 ins_encode %{
7057 Register op1 = $src1$$Register;
7058 int val = $src2$$constant;
7059 Label* L = $labl$$label;
7060 int flag = $cmp$$cmpcode;
7062 __ move(AT, val);
7063 switch(flag) {
7064 case 0x01: //equal
7065 __ beq_long(op1, AT, *L);
7066 break;
7067 case 0x02: //not_equal
7068 __ bne_long(op1, AT, *L);
7069 break;
7070 case 0x03: //above
7071 __ sltu(AT, AT, op1);
7072 __ bne_long(R0, AT, *L);
7073 break;
7074 case 0x04: //above_equal
7075 __ sltu(AT, op1, AT);
7076 __ beq_long(AT, R0, *L);
7077 break;
7078 case 0x05: //below
7079 __ sltu(AT, op1, AT);
7080 __ bne_long(R0, AT, *L);
7081 break;
7082 case 0x06: //below_equal
7083 __ sltu(AT, AT, op1);
7084 __ beq_long(AT, R0, *L);
7085 break;
7086 default:
7087 Unimplemented();
7088 }
7089 %}
7091 ins_pc_relative(1);
7092 ins_pipe( pipe_alu_branch );
7093 %}
7095 instruct branchConI_reg_reg_long(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
7096 match( If cmp (CmpI src1 src2) );
7097 effect(USE labl);
7098 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_reg_long" %}
7100 ins_encode %{
7101 Register op1 = $src1$$Register;
7102 Register op2 = $src2$$Register;
7103 Label* L = $labl$$label;
7104 int flag = $cmp$$cmpcode;
7106 switch(flag) {
7107 case 0x01: //equal
7108 __ beq_long(op1, op2, *L);
7109 break;
7110 case 0x02: //not_equal
7111 __ bne_long(op1, op2, *L);
7112 break;
7113 case 0x03: //above
7114 __ slt(AT, op2, op1);
7115 __ bne_long(R0, AT, *L);
7116 break;
7117 case 0x04: //above_equal
7118 __ slt(AT, op1, op2);
7119 __ beq_long(AT, R0, *L);
7120 break;
7121 case 0x05: //below
7122 __ slt(AT, op1, op2);
7123 __ bne_long(R0, AT, *L);
7124 break;
7125 case 0x06: //below_equal
7126 __ slt(AT, op2, op1);
7127 __ beq_long(AT, R0, *L);
7128 break;
7129 default:
7130 Unimplemented();
7131 }
7132 %}
7134 ins_pc_relative(1);
7135 ins_pipe( pipe_alu_branch );
7136 %}
7138 instruct branchConI_reg_imm0_long(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
7139 match( If cmp (CmpI src1 src2) );
7140 effect(USE labl);
7141 ins_cost(170);
7142 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm0_long" %}
7144 ins_encode %{
7145 Register op1 = $src1$$Register;
7146 Label* L = $labl$$label;
7147 int flag = $cmp$$cmpcode;
7149 switch(flag) {
7150 case 0x01: //equal
7151 __ beq_long(op1, R0, *L);
7152 break;
7153 case 0x02: //not_equal
7154 __ bne_long(op1, R0, *L);
7155 break;
7156 case 0x03: //greater
7157 __ slt(AT, R0, op1);
7158 __ bne_long(R0, AT, *L);
7159 break;
7160 case 0x04: //greater_equal
7161 __ slt(AT, op1, R0);
7162 __ beq_long(AT, R0, *L);
7163 break;
7164 case 0x05: //less
7165 __ slt(AT, op1, R0);
7166 __ bne_long(R0, AT, *L);
7167 break;
7168 case 0x06: //less_equal
7169 __ slt(AT, R0, op1);
7170 __ beq_long(AT, R0, *L);
7171 break;
7172 default:
7173 Unimplemented();
7174 }
7175 %}
7177 ins_pc_relative(1);
7178 ins_pipe( pipe_alu_branch );
7179 %}
7181 instruct branchConI_reg_imm_long(cmpOp cmp, mRegI src1, immI src2, label labl) %{
7182 match( If cmp (CmpI src1 src2) );
7183 effect(USE labl);
7184 ins_cost(200);
7185 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm_long" %}
7187 ins_encode %{
7188 Register op1 = $src1$$Register;
7189 int val = $src2$$constant;
7190 Label* L = $labl$$label;
7191 int flag = $cmp$$cmpcode;
7193 __ move(AT, val);
7194 switch(flag) {
7195 case 0x01: //equal
7196 __ beq_long(op1, AT, *L);
7197 break;
7198 case 0x02: //not_equal
7199 __ bne_long(op1, AT, *L);
7200 break;
7201 case 0x03: //greater
7202 __ slt(AT, AT, op1);
7203 __ bne_long(R0, AT, *L);
7204 break;
7205 case 0x04: //greater_equal
7206 __ slt(AT, op1, AT);
7207 __ beq_long(AT, R0, *L);
7208 break;
7209 case 0x05: //less
7210 __ slt(AT, op1, AT);
7211 __ bne_long(R0, AT, *L);
7212 break;
7213 case 0x06: //less_equal
7214 __ slt(AT, AT, op1);
7215 __ beq_long(AT, R0, *L);
7216 break;
7217 default:
7218 Unimplemented();
7219 }
7220 %}
7222 ins_pc_relative(1);
7223 ins_pipe( pipe_alu_branch );
7224 %}
7226 instruct branchConIU_reg_imm0_long(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
7227 match( If cmp (CmpU src1 zero) );
7228 effect(USE labl);
7229 format %{ "BR$cmp $src1, zero, $labl #@branchConIU_reg_imm0_long" %}
7231 ins_encode %{
7232 Register op1 = $src1$$Register;
7233 Label* L = $labl$$label;
7234 int flag = $cmp$$cmpcode;
7236 switch(flag) {
7237 case 0x01: //equal
7238 __ beq_long(op1, R0, *L);
7239 break;
7240 case 0x02: //not_equal
7241 __ bne_long(op1, R0, *L);
7242 break;
7243 case 0x03: //above
7244 __ bne_long(R0, op1, *L);
7245 break;
7246 case 0x04: //above_equal
7247 __ beq_long(R0, R0, *L);
7248 break;
7249 case 0x05: //below
7250 return;
7251 break;
7252 case 0x06: //below_equal
7253 __ beq_long(op1, R0, *L);
7254 break;
7255 default:
7256 Unimplemented();
7257 }
7258 %}
7260 ins_pc_relative(1);
7261 ins_pipe( pipe_alu_branch );
7262 %}
7265 instruct branchConIU_reg_immI16_long(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
7266 match( If cmp (CmpU src1 src2) );
7267 effect(USE labl);
7268 ins_cost(180);
7269 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_immI16_long" %}
7271 ins_encode %{
7272 Register op1 = $src1$$Register;
7273 int val = $src2$$constant;
7274 Label* L = $labl$$label;
7275 int flag = $cmp$$cmpcode;
7277 switch(flag) {
7278 case 0x01: //equal
7279 __ move(AT, val);
7280 __ beq_long(op1, AT, *L);
7281 break;
7282 case 0x02: //not_equal
7283 __ move(AT, val);
7284 __ bne_long(op1, AT, *L);
7285 break;
7286 case 0x03: //above
7287 __ move(AT, val);
7288 __ sltu(AT, AT, op1);
7289 __ bne_long(R0, AT, *L);
7290 break;
7291 case 0x04: //above_equal
7292 __ sltiu(AT, op1, val);
7293 __ beq_long(AT, R0, *L);
7294 break;
7295 case 0x05: //below
7296 __ sltiu(AT, op1, val);
7297 __ bne_long(R0, AT, *L);
7298 break;
7299 case 0x06: //below_equal
7300 __ move(AT, val);
7301 __ sltu(AT, AT, op1);
7302 __ beq_long(AT, R0, *L);
7303 break;
7304 default:
7305 Unimplemented();
7306 }
7307 %}
7309 ins_pc_relative(1);
7310 ins_pipe( pipe_alu_branch );
7311 %}
7314 instruct branchConL_regL_regL_long(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
7315 match( If cmp (CmpL src1 src2) );
7316 effect(USE labl);
7317 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_regL_long" %}
7318 ins_cost(250);
7320 ins_encode %{
7321 Register opr1_reg = as_Register($src1$$reg);
7322 Register opr2_reg = as_Register($src2$$reg);
7324 Label* target = $labl$$label;
7325 int flag = $cmp$$cmpcode;
7327 switch(flag) {
7328 case 0x01: //equal
7329 __ beq_long(opr1_reg, opr2_reg, *target);
7330 break;
7332 case 0x02: //not_equal
7333 __ bne_long(opr1_reg, opr2_reg, *target);
7334 break;
7336 case 0x03: //greater
7337 __ slt(AT, opr2_reg, opr1_reg);
7338 __ bne_long(AT, R0, *target);
7339 break;
7341 case 0x04: //greater_equal
7342 __ slt(AT, opr1_reg, opr2_reg);
7343 __ beq_long(AT, R0, *target);
7344 break;
7346 case 0x05: //less
7347 __ slt(AT, opr1_reg, opr2_reg);
7348 __ bne_long(AT, R0, *target);
7349 break;
7351 case 0x06: //less_equal
7352 __ slt(AT, opr2_reg, opr1_reg);
7353 __ beq_long(AT, R0, *target);
7354 break;
7356 default:
7357 Unimplemented();
7358 }
7359 %}
7362 ins_pc_relative(1);
7363 ins_pipe( pipe_alu_branch );
7364 %}
7366 instruct branchConL_regL_immL0_long(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
7367 match( If cmp (CmpL src1 zero) );
7368 effect(USE labl);
7369 format %{ "BR$cmp $src1, zero, $labl #@branchConL_regL_immL0_long" %}
7370 ins_cost(150);
7372 ins_encode %{
7373 Register opr1_reg = as_Register($src1$$reg);
7374 Register opr2_reg = R0;
7376 Label* target = $labl$$label;
7377 int flag = $cmp$$cmpcode;
7379 switch(flag) {
7380 case 0x01: //equal
7381 __ beq_long(opr1_reg, opr2_reg, *target);
7382 break;
7384 case 0x02: //not_equal
7385 __ bne_long(opr1_reg, opr2_reg, *target);
7386 break;
7388 case 0x03: //greater
7389 __ slt(AT, opr2_reg, opr1_reg);
7390 __ bne_long(AT, R0, *target);
7391 break;
7393 case 0x04: //greater_equal
7394 __ slt(AT, opr1_reg, opr2_reg);
7395 __ beq_long(AT, R0, *target);
7396 break;
7398 case 0x05: //less
7399 __ slt(AT, opr1_reg, opr2_reg);
7400 __ bne_long(AT, R0, *target);
7401 break;
7403 case 0x06: //less_equal
7404 __ slt(AT, opr2_reg, opr1_reg);
7405 __ beq_long(AT, R0, *target);
7406 break;
7408 default:
7409 Unimplemented();
7410 }
7411 %}
7414 ins_pc_relative(1);
7415 ins_pipe( pipe_alu_branch );
7416 %}
7418 instruct branchConL_regL_immL_long(cmpOp cmp, mRegL src1, immL src2, label labl) %{
7419 match( If cmp (CmpL src1 src2) );
7420 effect(USE labl);
7421 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_immL_long" %}
7422 ins_cost(180);
7424 ins_encode %{
7425 Register opr1_reg = as_Register($src1$$reg);
7426 Register opr2_reg = AT;
7428 Label* target = $labl$$label;
7429 int flag = $cmp$$cmpcode;
7431 __ set64(opr2_reg, $src2$$constant);
7433 switch(flag) {
7434 case 0x01: //equal
7435 __ beq_long(opr1_reg, opr2_reg, *target);
7436 break;
7438 case 0x02: //not_equal
7439 __ bne_long(opr1_reg, opr2_reg, *target);
7440 break;
7442 case 0x03: //greater
7443 __ slt(AT, opr2_reg, opr1_reg);
7444 __ bne_long(AT, R0, *target);
7445 break;
7447 case 0x04: //greater_equal
7448 __ slt(AT, opr1_reg, opr2_reg);
7449 __ beq_long(AT, R0, *target);
7450 break;
7452 case 0x05: //less
7453 __ slt(AT, opr1_reg, opr2_reg);
7454 __ bne_long(AT, R0, *target);
7455 break;
7457 case 0x06: //less_equal
7458 __ slt(AT, opr2_reg, opr1_reg);
7459 __ beq_long(AT, R0, *target);
7460 break;
7462 default:
7463 Unimplemented();
7464 }
7465 %}
7468 ins_pc_relative(1);
7469 ins_pipe( pipe_alu_branch );
7470 %}
7473 //FIXME
7474 instruct branchConF_reg_reg_long(cmpOp cmp, regF src1, regF src2, label labl) %{
7475 match( If cmp (CmpF src1 src2) );
7476 effect(USE labl);
7477 format %{ "BR$cmp $src1, $src2, $labl #@branchConF_reg_reg_long" %}
7479 ins_encode %{
7480 FloatRegister reg_op1 = $src1$$FloatRegister;
7481 FloatRegister reg_op2 = $src2$$FloatRegister;
7482 Label* L = $labl$$label;
7483 int flag = $cmp$$cmpcode;
7485 switch(flag) {
7486 case 0x01: //equal
7487 __ c_eq_s(reg_op1, reg_op2);
7488 __ bc1t_long(*L);
7489 break;
7490 case 0x02: //not_equal
7491 __ c_eq_s(reg_op1, reg_op2);
7492 __ bc1f_long(*L);
7493 break;
7494 case 0x03: //greater
7495 __ c_ule_s(reg_op1, reg_op2);
7496 __ bc1f_long(*L);
7497 break;
7498 case 0x04: //greater_equal
7499 __ c_ult_s(reg_op1, reg_op2);
7500 __ bc1f_long(*L);
7501 break;
7502 case 0x05: //less
7503 __ c_ult_s(reg_op1, reg_op2);
7504 __ bc1t_long(*L);
7505 break;
7506 case 0x06: //less_equal
7507 __ c_ule_s(reg_op1, reg_op2);
7508 __ bc1t_long(*L);
7509 break;
7510 default:
7511 Unimplemented();
7512 }
7513 %}
7515 ins_pc_relative(1);
7516 ins_pipe(pipe_slow);
7517 %}
7519 instruct branchConD_reg_reg_long(cmpOp cmp, regD src1, regD src2, label labl) %{
7520 match( If cmp (CmpD src1 src2) );
7521 effect(USE labl);
7522 format %{ "BR$cmp $src1, $src2, $labl #@branchConD_reg_reg_long" %}
7524 ins_encode %{
7525 FloatRegister reg_op1 = $src1$$FloatRegister;
7526 FloatRegister reg_op2 = $src2$$FloatRegister;
7527 Label* L = $labl$$label;
7528 int flag = $cmp$$cmpcode;
7530 switch(flag) {
7531 case 0x01: //equal
7532 __ c_eq_d(reg_op1, reg_op2);
7533 __ bc1t_long(*L);
7534 break;
7535 case 0x02: //not_equal
7536 //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.
7537 __ c_eq_d(reg_op1, reg_op2);
7538 __ bc1f_long(*L);
7539 break;
7540 case 0x03: //greater
7541 __ c_ule_d(reg_op1, reg_op2);
7542 __ bc1f_long(*L);
7543 break;
7544 case 0x04: //greater_equal
7545 __ c_ult_d(reg_op1, reg_op2);
7546 __ bc1f_long(*L);
7547 break;
7548 case 0x05: //less
7549 __ c_ult_d(reg_op1, reg_op2);
7550 __ bc1t_long(*L);
7551 break;
7552 case 0x06: //less_equal
7553 __ c_ule_d(reg_op1, reg_op2);
7554 __ bc1t_long(*L);
7555 break;
7556 default:
7557 Unimplemented();
7558 }
7559 %}
7561 ins_pc_relative(1);
7562 ins_pipe(pipe_slow);
7563 %}
7566 // ============================================================================
7567 // Branch Instructions -- short offset versions
7569 // Jump Direct
7570 instruct jmpDir_short(label labl) %{
7571 match(Goto);
7572 effect(USE labl);
7574 ins_cost(300);
7575 format %{ "JMP $labl #@jmpDir_short" %}
7577 ins_encode %{
7578 Label &L = *($labl$$label);
7579 if(&L)
7580 __ b(L);
7581 else
7582 __ b(int(0));
7583 __ nop();
7584 %}
7586 ins_pipe( pipe_jump );
7587 ins_pc_relative(1);
7588 ins_short_branch(1);
7589 %}
7591 // Jump Direct Conditional - Label defines a relative address from Jcc+1
7592 instruct jmpLoopEnd_short(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
7593 match(CountedLoopEnd cop (CmpI src1 src2));
7594 effect(USE labl);
7596 ins_cost(300);
7597 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_short" %}
7598 ins_encode %{
7599 Register op1 = $src1$$Register;
7600 Register op2 = $src2$$Register;
7601 Label &L = *($labl$$label);
7602 int flag = $cop$$cmpcode;
7604 switch(flag) {
7605 case 0x01: //equal
7606 if (&L)
7607 __ beq(op1, op2, L);
7608 else
7609 __ beq(op1, op2, (int)0);
7610 break;
7611 case 0x02: //not_equal
7612 if (&L)
7613 __ bne(op1, op2, L);
7614 else
7615 __ bne(op1, op2, (int)0);
7616 break;
7617 case 0x03: //above
7618 __ slt(AT, op2, op1);
7619 if(&L)
7620 __ bne(AT, R0, L);
7621 else
7622 __ bne(AT, R0, (int)0);
7623 break;
7624 case 0x04: //above_equal
7625 __ slt(AT, op1, op2);
7626 if(&L)
7627 __ beq(AT, R0, L);
7628 else
7629 __ beq(AT, R0, (int)0);
7630 break;
7631 case 0x05: //below
7632 __ slt(AT, op1, op2);
7633 if(&L)
7634 __ bne(AT, R0, L);
7635 else
7636 __ bne(AT, R0, (int)0);
7637 break;
7638 case 0x06: //below_equal
7639 __ slt(AT, op2, op1);
7640 if(&L)
7641 __ beq(AT, R0, L);
7642 else
7643 __ beq(AT, R0, (int)0);
7644 break;
7645 default:
7646 Unimplemented();
7647 }
7648 __ nop();
7649 %}
7650 ins_pipe( pipe_jump );
7651 ins_pc_relative(1);
7652 ins_short_branch(1);
7653 %}
7655 instruct jmpLoopEnd_reg_immI_short(cmpOp cop, mRegI src1, immI src2, label labl) %{
7656 match(CountedLoopEnd cop (CmpI src1 src2));
7657 effect(USE labl);
7659 ins_cost(300);
7660 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_immI_short" %}
7661 ins_encode %{
7662 Register op1 = $src1$$Register;
7663 Register op2 = AT;
7664 Label &L = *($labl$$label);
7665 int flag = $cop$$cmpcode;
7667 __ move(op2, $src2$$constant);
7669 switch(flag) {
7670 case 0x01: //equal
7671 if (&L)
7672 __ beq(op1, op2, L);
7673 else
7674 __ beq(op1, op2, (int)0);
7675 break;
7676 case 0x02: //not_equal
7677 if (&L)
7678 __ bne(op1, op2, L);
7679 else
7680 __ bne(op1, op2, (int)0);
7681 break;
7682 case 0x03: //above
7683 __ slt(AT, op2, op1);
7684 if(&L)
7685 __ bne(AT, R0, L);
7686 else
7687 __ bne(AT, R0, (int)0);
7688 break;
7689 case 0x04: //above_equal
7690 __ slt(AT, op1, op2);
7691 if(&L)
7692 __ beq(AT, R0, L);
7693 else
7694 __ beq(AT, R0, (int)0);
7695 break;
7696 case 0x05: //below
7697 __ slt(AT, op1, op2);
7698 if(&L)
7699 __ bne(AT, R0, L);
7700 else
7701 __ bne(AT, R0, (int)0);
7702 break;
7703 case 0x06: //below_equal
7704 __ slt(AT, op2, op1);
7705 if(&L)
7706 __ beq(AT, R0, L);
7707 else
7708 __ beq(AT, R0, (int)0);
7709 break;
7710 default:
7711 Unimplemented();
7712 }
7713 __ nop();
7714 %}
7715 ins_pipe( pipe_jump );
7716 ins_pc_relative(1);
7717 ins_short_branch(1);
7718 %}
7721 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
7722 instruct jmpCon_flags_short(cmpOp cop, FlagsReg cr, label labl) %{
7723 match(If cop cr);
7724 effect(USE labl);
7726 ins_cost(300);
7727 format %{ "J$cop $labl #mips uses AT as eflag @jmpCon_flags_short" %}
7729 ins_encode %{
7730 Label &L = *($labl$$label);
7731 switch($cop$$cmpcode) {
7732 case 0x01: //equal
7733 if (&L)
7734 __ bne(AT, R0, L);
7735 else
7736 __ bne(AT, R0, (int)0);
7737 break;
7738 case 0x02: //not equal
7739 if (&L)
7740 __ beq(AT, R0, L);
7741 else
7742 __ beq(AT, R0, (int)0);
7743 break;
7744 default:
7745 Unimplemented();
7746 }
7747 __ nop();
7748 %}
7750 ins_pipe( pipe_jump );
7751 ins_pc_relative(1);
7752 ins_short_branch(1);
7753 %}
7755 // Conditional jumps
7756 instruct branchConP_zero_short(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
7757 match(If cmp (CmpP op1 zero));
7758 effect(USE labl);
7760 ins_cost(180);
7761 format %{ "b$cmp $op1, R0, $labl #@branchConP_zero_short" %}
7763 ins_encode %{
7764 Register op1 = $op1$$Register;
7765 Register op2 = R0;
7766 Label &L = *($labl$$label);
7767 int flag = $cmp$$cmpcode;
7769 switch(flag) {
7770 case 0x01: //equal
7771 if (&L)
7772 __ beq(op1, op2, L);
7773 else
7774 __ beq(op1, op2, (int)0);
7775 break;
7776 case 0x02: //not_equal
7777 if (&L)
7778 __ bne(op1, op2, L);
7779 else
7780 __ bne(op1, op2, (int)0);
7781 break;
7782 default:
7783 Unimplemented();
7784 }
7785 __ nop();
7786 %}
7788 ins_pc_relative(1);
7789 ins_pipe( pipe_alu_branch );
7790 ins_short_branch(1);
7791 %}
7793 instruct branchConN2P_zero_short(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
7794 match(If cmp (CmpP (DecodeN op1) zero));
7795 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
7796 effect(USE labl);
7798 ins_cost(180);
7799 format %{ "b$cmp $op1, R0, $labl #@branchConN2P_zero_short" %}
7801 ins_encode %{
7802 Register op1 = $op1$$Register;
7803 Register op2 = R0;
7804 Label &L = *($labl$$label);
7805 int flag = $cmp$$cmpcode;
7807 switch(flag)
7808 {
7809 case 0x01: //equal
7810 if (&L)
7811 __ beq(op1, op2, L);
7812 else
7813 __ beq(op1, op2, (int)0);
7814 break;
7815 case 0x02: //not_equal
7816 if (&L)
7817 __ bne(op1, op2, L);
7818 else
7819 __ bne(op1, op2, (int)0);
7820 break;
7821 default:
7822 Unimplemented();
7823 }
7824 __ nop();
7825 %}
7827 ins_pc_relative(1);
7828 ins_pipe( pipe_alu_branch );
7829 ins_short_branch(1);
7830 %}
7833 instruct branchConP_short(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
7834 match(If cmp (CmpP op1 op2));
7835 // predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
7836 effect(USE labl);
7838 ins_cost(200);
7839 format %{ "b$cmp $op1, $op2, $labl #@branchConP_short" %}
7841 ins_encode %{
7842 Register op1 = $op1$$Register;
7843 Register op2 = $op2$$Register;
7844 Label &L = *($labl$$label);
7845 int flag = $cmp$$cmpcode;
7847 switch(flag) {
7848 case 0x01: //equal
7849 if (&L)
7850 __ beq(op1, op2, L);
7851 else
7852 __ beq(op1, op2, (int)0);
7853 break;
7854 case 0x02: //not_equal
7855 if (&L)
7856 __ bne(op1, op2, L);
7857 else
7858 __ bne(op1, op2, (int)0);
7859 break;
7860 case 0x03: //above
7861 __ sltu(AT, op2, op1);
7862 if(&L)
7863 __ bne(R0, AT, L);
7864 else
7865 __ bne(R0, AT, (int)0);
7866 break;
7867 case 0x04: //above_equal
7868 __ sltu(AT, op1, op2);
7869 if(&L)
7870 __ beq(AT, R0, L);
7871 else
7872 __ beq(AT, R0, (int)0);
7873 break;
7874 case 0x05: //below
7875 __ sltu(AT, op1, op2);
7876 if(&L)
7877 __ bne(R0, AT, L);
7878 else
7879 __ bne(R0, AT, (int)0);
7880 break;
7881 case 0x06: //below_equal
7882 __ sltu(AT, op2, op1);
7883 if(&L)
7884 __ beq(AT, R0, L);
7885 else
7886 __ beq(AT, R0, (int)0);
7887 break;
7888 default:
7889 Unimplemented();
7890 }
7891 __ nop();
7892 %}
7894 ins_pc_relative(1);
7895 ins_pipe( pipe_alu_branch );
7896 ins_short_branch(1);
7897 %}
7899 instruct cmpN_null_branch_short(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
7900 match(If cmp (CmpN op1 null));
7901 effect(USE labl);
7903 ins_cost(180);
7904 format %{ "CMP $op1,0\t! compressed ptr\n\t"
7905 "BP$cmp $labl @ cmpN_null_branch_short" %}
7906 ins_encode %{
7907 Register op1 = $op1$$Register;
7908 Register op2 = R0;
7909 Label &L = *($labl$$label);
7910 int flag = $cmp$$cmpcode;
7912 switch(flag) {
7913 case 0x01: //equal
7914 if (&L)
7915 __ beq(op1, op2, L);
7916 else
7917 __ beq(op1, op2, (int)0);
7918 break;
7919 case 0x02: //not_equal
7920 if (&L)
7921 __ bne(op1, op2, L);
7922 else
7923 __ bne(op1, op2, (int)0);
7924 break;
7925 default:
7926 Unimplemented();
7927 }
7928 __ nop();
7929 %}
7930 //TODO: pipe_branchP or create pipe_branchN LEE
7931 ins_pc_relative(1);
7932 ins_pipe( pipe_alu_branch );
7933 ins_short_branch(1);
7934 %}
7936 instruct cmpN_reg_branch_short(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
7937 match(If cmp (CmpN op1 op2));
7938 effect(USE labl);
7940 ins_cost(180);
7941 format %{ "CMP $op1,$op2\t! compressed ptr\n\t"
7942 "BP$cmp $labl @ cmpN_reg_branch_short" %}
7943 ins_encode %{
7944 Register op1_reg = $op1$$Register;
7945 Register op2_reg = $op2$$Register;
7946 Label &L = *($labl$$label);
7947 int flag = $cmp$$cmpcode;
7949 switch(flag) {
7950 case 0x01: //equal
7951 if (&L)
7952 __ beq(op1_reg, op2_reg, L);
7953 else
7954 __ beq(op1_reg, op2_reg, (int)0);
7955 break;
7956 case 0x02: //not_equal
7957 if (&L)
7958 __ bne(op1_reg, op2_reg, L);
7959 else
7960 __ bne(op1_reg, op2_reg, (int)0);
7961 break;
7962 case 0x03: //above
7963 __ sltu(AT, op2_reg, op1_reg);
7964 if(&L)
7965 __ bne(R0, AT, L);
7966 else
7967 __ bne(R0, AT, (int)0);
7968 break;
7969 case 0x04: //above_equal
7970 __ sltu(AT, op1_reg, op2_reg);
7971 if(&L)
7972 __ beq(AT, R0, L);
7973 else
7974 __ beq(AT, R0, (int)0);
7975 break;
7976 case 0x05: //below
7977 __ sltu(AT, op1_reg, op2_reg);
7978 if(&L)
7979 __ bne(R0, AT, L);
7980 else
7981 __ bne(R0, AT, (int)0);
7982 break;
7983 case 0x06: //below_equal
7984 __ sltu(AT, op2_reg, op1_reg);
7985 if(&L)
7986 __ beq(AT, R0, L);
7987 else
7988 __ beq(AT, R0, (int)0);
7989 break;
7990 default:
7991 Unimplemented();
7992 }
7993 __ nop();
7994 %}
7995 ins_pc_relative(1);
7996 ins_pipe( pipe_alu_branch );
7997 ins_short_branch(1);
7998 %}
8000 instruct branchConIU_reg_reg_short(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
8001 match( If cmp (CmpU src1 src2) );
8002 effect(USE labl);
8003 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_reg_short" %}
8005 ins_encode %{
8006 Register op1 = $src1$$Register;
8007 Register op2 = $src2$$Register;
8008 Label &L = *($labl$$label);
8009 int flag = $cmp$$cmpcode;
8011 switch(flag) {
8012 case 0x01: //equal
8013 if (&L)
8014 __ beq(op1, op2, L);
8015 else
8016 __ beq(op1, op2, (int)0);
8017 break;
8018 case 0x02: //not_equal
8019 if (&L)
8020 __ bne(op1, op2, L);
8021 else
8022 __ bne(op1, op2, (int)0);
8023 break;
8024 case 0x03: //above
8025 __ sltu(AT, op2, op1);
8026 if(&L)
8027 __ bne(AT, R0, L);
8028 else
8029 __ bne(AT, R0, (int)0);
8030 break;
8031 case 0x04: //above_equal
8032 __ sltu(AT, op1, op2);
8033 if(&L)
8034 __ beq(AT, R0, L);
8035 else
8036 __ beq(AT, R0, (int)0);
8037 break;
8038 case 0x05: //below
8039 __ sltu(AT, op1, op2);
8040 if(&L)
8041 __ bne(AT, R0, L);
8042 else
8043 __ bne(AT, R0, (int)0);
8044 break;
8045 case 0x06: //below_equal
8046 __ sltu(AT, op2, op1);
8047 if(&L)
8048 __ beq(AT, R0, L);
8049 else
8050 __ beq(AT, R0, (int)0);
8051 break;
8052 default:
8053 Unimplemented();
8054 }
8055 __ nop();
8056 %}
8058 ins_pc_relative(1);
8059 ins_pipe( pipe_alu_branch );
8060 ins_short_branch(1);
8061 %}
8064 instruct branchConIU_reg_imm_short(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
8065 match( If cmp (CmpU src1 src2) );
8066 effect(USE labl);
8067 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_imm_short" %}
8069 ins_encode %{
8070 Register op1 = $src1$$Register;
8071 int val = $src2$$constant;
8072 Label &L = *($labl$$label);
8073 int flag = $cmp$$cmpcode;
8075 __ move(AT, val);
8076 switch(flag) {
8077 case 0x01: //equal
8078 if (&L)
8079 __ beq(op1, AT, L);
8080 else
8081 __ beq(op1, AT, (int)0);
8082 break;
8083 case 0x02: //not_equal
8084 if (&L)
8085 __ bne(op1, AT, L);
8086 else
8087 __ bne(op1, AT, (int)0);
8088 break;
8089 case 0x03: //above
8090 __ sltu(AT, AT, op1);
8091 if(&L)
8092 __ bne(R0, AT, L);
8093 else
8094 __ bne(R0, AT, (int)0);
8095 break;
8096 case 0x04: //above_equal
8097 __ sltu(AT, op1, AT);
8098 if(&L)
8099 __ beq(AT, R0, L);
8100 else
8101 __ beq(AT, R0, (int)0);
8102 break;
8103 case 0x05: //below
8104 __ sltu(AT, op1, AT);
8105 if(&L)
8106 __ bne(R0, AT, L);
8107 else
8108 __ bne(R0, AT, (int)0);
8109 break;
8110 case 0x06: //below_equal
8111 __ sltu(AT, AT, op1);
8112 if(&L)
8113 __ beq(AT, R0, L);
8114 else
8115 __ beq(AT, R0, (int)0);
8116 break;
8117 default:
8118 Unimplemented();
8119 }
8120 __ nop();
8121 %}
8123 ins_pc_relative(1);
8124 ins_pipe( pipe_alu_branch );
8125 ins_short_branch(1);
8126 %}
8128 instruct branchConI_reg_reg_short(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
8129 match( If cmp (CmpI src1 src2) );
8130 effect(USE labl);
8131 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_reg_short" %}
8133 ins_encode %{
8134 Register op1 = $src1$$Register;
8135 Register op2 = $src2$$Register;
8136 Label &L = *($labl$$label);
8137 int flag = $cmp$$cmpcode;
8139 switch(flag) {
8140 case 0x01: //equal
8141 if (&L)
8142 __ beq(op1, op2, L);
8143 else
8144 __ beq(op1, op2, (int)0);
8145 break;
8146 case 0x02: //not_equal
8147 if (&L)
8148 __ bne(op1, op2, L);
8149 else
8150 __ bne(op1, op2, (int)0);
8151 break;
8152 case 0x03: //above
8153 __ slt(AT, op2, op1);
8154 if(&L)
8155 __ bne(R0, AT, L);
8156 else
8157 __ bne(R0, AT, (int)0);
8158 break;
8159 case 0x04: //above_equal
8160 __ slt(AT, op1, op2);
8161 if(&L)
8162 __ beq(AT, R0, L);
8163 else
8164 __ beq(AT, R0, (int)0);
8165 break;
8166 case 0x05: //below
8167 __ slt(AT, op1, op2);
8168 if(&L)
8169 __ bne(R0, AT, L);
8170 else
8171 __ bne(R0, AT, (int)0);
8172 break;
8173 case 0x06: //below_equal
8174 __ slt(AT, op2, op1);
8175 if(&L)
8176 __ beq(AT, R0, L);
8177 else
8178 __ beq(AT, R0, (int)0);
8179 break;
8180 default:
8181 Unimplemented();
8182 }
8183 __ nop();
8184 %}
8186 ins_pc_relative(1);
8187 ins_pipe( pipe_alu_branch );
8188 ins_short_branch(1);
8189 %}
8191 instruct branchConI_reg_imm0_short(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
8192 match( If cmp (CmpI src1 src2) );
8193 effect(USE labl);
8194 ins_cost(170);
8195 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm0_short" %}
8197 ins_encode %{
8198 Register op1 = $src1$$Register;
8199 Label &L = *($labl$$label);
8200 int flag = $cmp$$cmpcode;
8202 switch(flag) {
8203 case 0x01: //equal
8204 if (&L)
8205 __ beq(op1, R0, L);
8206 else
8207 __ beq(op1, R0, (int)0);
8208 break;
8209 case 0x02: //not_equal
8210 if (&L)
8211 __ bne(op1, R0, L);
8212 else
8213 __ bne(op1, R0, (int)0);
8214 break;
8215 case 0x03: //greater
8216 if(&L)
8217 __ bgtz(op1, L);
8218 else
8219 __ bgtz(op1, (int)0);
8220 break;
8221 case 0x04: //greater_equal
8222 if(&L)
8223 __ bgez(op1, L);
8224 else
8225 __ bgez(op1, (int)0);
8226 break;
8227 case 0x05: //less
8228 if(&L)
8229 __ bltz(op1, L);
8230 else
8231 __ bltz(op1, (int)0);
8232 break;
8233 case 0x06: //less_equal
8234 if(&L)
8235 __ blez(op1, L);
8236 else
8237 __ blez(op1, (int)0);
8238 break;
8239 default:
8240 Unimplemented();
8241 }
8242 __ nop();
8243 %}
8245 ins_pc_relative(1);
8246 ins_pipe( pipe_alu_branch );
8247 ins_short_branch(1);
8248 %}
8251 instruct branchConI_reg_imm_short(cmpOp cmp, mRegI src1, immI src2, label labl) %{
8252 match( If cmp (CmpI src1 src2) );
8253 effect(USE labl);
8254 ins_cost(200);
8255 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm_short" %}
8257 ins_encode %{
8258 Register op1 = $src1$$Register;
8259 int val = $src2$$constant;
8260 Label &L = *($labl$$label);
8261 int flag = $cmp$$cmpcode;
8263 __ move(AT, val);
8264 switch(flag) {
8265 case 0x01: //equal
8266 if (&L)
8267 __ beq(op1, AT, L);
8268 else
8269 __ beq(op1, AT, (int)0);
8270 break;
8271 case 0x02: //not_equal
8272 if (&L)
8273 __ bne(op1, AT, L);
8274 else
8275 __ bne(op1, AT, (int)0);
8276 break;
8277 case 0x03: //greater
8278 __ slt(AT, AT, op1);
8279 if(&L)
8280 __ bne(R0, AT, L);
8281 else
8282 __ bne(R0, AT, (int)0);
8283 break;
8284 case 0x04: //greater_equal
8285 __ slt(AT, op1, AT);
8286 if(&L)
8287 __ beq(AT, R0, L);
8288 else
8289 __ beq(AT, R0, (int)0);
8290 break;
8291 case 0x05: //less
8292 __ slt(AT, op1, AT);
8293 if(&L)
8294 __ bne(R0, AT, L);
8295 else
8296 __ bne(R0, AT, (int)0);
8297 break;
8298 case 0x06: //less_equal
8299 __ slt(AT, AT, op1);
8300 if(&L)
8301 __ beq(AT, R0, L);
8302 else
8303 __ beq(AT, R0, (int)0);
8304 break;
8305 default:
8306 Unimplemented();
8307 }
8308 __ nop();
8309 %}
8311 ins_pc_relative(1);
8312 ins_pipe( pipe_alu_branch );
8313 ins_short_branch(1);
8314 %}
8316 instruct branchConIU_reg_imm0_short(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
8317 match( If cmp (CmpU src1 zero) );
8318 effect(USE labl);
8319 format %{ "BR$cmp $src1, zero, $labl #@branchConIU_reg_imm0_short" %}
8321 ins_encode %{
8322 Register op1 = $src1$$Register;
8323 Label &L = *($labl$$label);
8324 int flag = $cmp$$cmpcode;
8326 switch(flag) {
8327 case 0x01: //equal
8328 if (&L)
8329 __ beq(op1, R0, L);
8330 else
8331 __ beq(op1, R0, (int)0);
8332 break;
8333 case 0x02: //not_equal
8334 if (&L)
8335 __ bne(op1, R0, L);
8336 else
8337 __ bne(op1, R0, (int)0);
8338 break;
8339 case 0x03: //above
8340 if(&L)
8341 __ bne(R0, op1, L);
8342 else
8343 __ bne(R0, op1, (int)0);
8344 break;
8345 case 0x04: //above_equal
8346 if(&L)
8347 __ beq(R0, R0, L);
8348 else
8349 __ beq(R0, R0, (int)0);
8350 break;
8351 case 0x05: //below
8352 return;
8353 break;
8354 case 0x06: //below_equal
8355 if(&L)
8356 __ beq(op1, R0, L);
8357 else
8358 __ beq(op1, R0, (int)0);
8359 break;
8360 default:
8361 Unimplemented();
8362 }
8363 __ nop();
8364 %}
8366 ins_pc_relative(1);
8367 ins_pipe( pipe_alu_branch );
8368 ins_short_branch(1);
8369 %}
8372 instruct branchConIU_reg_immI16_short(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
8373 match( If cmp (CmpU src1 src2) );
8374 effect(USE labl);
8375 ins_cost(180);
8376 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_immI16_short" %}
8378 ins_encode %{
8379 Register op1 = $src1$$Register;
8380 int val = $src2$$constant;
8381 Label &L = *($labl$$label);
8382 int flag = $cmp$$cmpcode;
8384 switch(flag) {
8385 case 0x01: //equal
8386 __ move(AT, val);
8387 if (&L)
8388 __ beq(op1, AT, L);
8389 else
8390 __ beq(op1, AT, (int)0);
8391 break;
8392 case 0x02: //not_equal
8393 __ move(AT, val);
8394 if (&L)
8395 __ bne(op1, AT, L);
8396 else
8397 __ bne(op1, AT, (int)0);
8398 break;
8399 case 0x03: //above
8400 __ move(AT, val);
8401 __ sltu(AT, AT, op1);
8402 if(&L)
8403 __ bne(R0, AT, L);
8404 else
8405 __ bne(R0, AT, (int)0);
8406 break;
8407 case 0x04: //above_equal
8408 __ sltiu(AT, op1, val);
8409 if(&L)
8410 __ beq(AT, R0, L);
8411 else
8412 __ beq(AT, R0, (int)0);
8413 break;
8414 case 0x05: //below
8415 __ sltiu(AT, op1, val);
8416 if(&L)
8417 __ bne(R0, AT, L);
8418 else
8419 __ bne(R0, AT, (int)0);
8420 break;
8421 case 0x06: //below_equal
8422 __ move(AT, val);
8423 __ sltu(AT, AT, op1);
8424 if(&L)
8425 __ beq(AT, R0, L);
8426 else
8427 __ beq(AT, R0, (int)0);
8428 break;
8429 default:
8430 Unimplemented();
8431 }
8432 __ nop();
8433 %}
8435 ins_pc_relative(1);
8436 ins_pipe( pipe_alu_branch );
8437 ins_short_branch(1);
8438 %}
8441 instruct branchConL_regL_regL_short(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
8442 match( If cmp (CmpL src1 src2) );
8443 effect(USE labl);
8444 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_regL_short" %}
8445 ins_cost(250);
8447 ins_encode %{
8448 Register opr1_reg = as_Register($src1$$reg);
8449 Register opr2_reg = as_Register($src2$$reg);
8451 Label &target = *($labl$$label);
8452 int flag = $cmp$$cmpcode;
8454 switch(flag) {
8455 case 0x01: //equal
8456 if (&target)
8457 __ beq(opr1_reg, opr2_reg, target);
8458 else
8459 __ beq(opr1_reg, opr2_reg, (int)0);
8460 __ delayed()->nop();
8461 break;
8463 case 0x02: //not_equal
8464 if(&target)
8465 __ bne(opr1_reg, opr2_reg, target);
8466 else
8467 __ bne(opr1_reg, opr2_reg, (int)0);
8468 __ delayed()->nop();
8469 break;
8471 case 0x03: //greater
8472 __ slt(AT, opr2_reg, opr1_reg);
8473 if(&target)
8474 __ bne(AT, R0, target);
8475 else
8476 __ bne(AT, R0, (int)0);
8477 __ delayed()->nop();
8478 break;
8480 case 0x04: //greater_equal
8481 __ slt(AT, opr1_reg, opr2_reg);
8482 if(&target)
8483 __ beq(AT, R0, target);
8484 else
8485 __ beq(AT, R0, (int)0);
8486 __ delayed()->nop();
8488 break;
8490 case 0x05: //less
8491 __ slt(AT, opr1_reg, opr2_reg);
8492 if(&target)
8493 __ bne(AT, R0, target);
8494 else
8495 __ bne(AT, R0, (int)0);
8496 __ delayed()->nop();
8498 break;
8500 case 0x06: //less_equal
8501 __ slt(AT, opr2_reg, opr1_reg);
8503 if(&target)
8504 __ beq(AT, R0, target);
8505 else
8506 __ beq(AT, R0, (int)0);
8507 __ delayed()->nop();
8509 break;
8511 default:
8512 Unimplemented();
8513 }
8514 %}
8517 ins_pc_relative(1);
8518 ins_pipe( pipe_alu_branch );
8519 ins_short_branch(1);
8520 %}
8523 instruct branchConL_regL_immL0_short(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
8524 match( If cmp (CmpL src1 zero) );
8525 effect(USE labl);
8526 format %{ "BR$cmp $src1, zero, $labl #@branchConL_regL_immL0_short" %}
8527 ins_cost(150);
8529 ins_encode %{
8530 Register opr1_reg = as_Register($src1$$reg);
8531 Label &target = *($labl$$label);
8532 int flag = $cmp$$cmpcode;
8534 switch(flag) {
8535 case 0x01: //equal
8536 if (&target)
8537 __ beq(opr1_reg, R0, target);
8538 else
8539 __ beq(opr1_reg, R0, int(0));
8540 break;
8542 case 0x02: //not_equal
8543 if(&target)
8544 __ bne(opr1_reg, R0, target);
8545 else
8546 __ bne(opr1_reg, R0, (int)0);
8547 break;
8549 case 0x03: //greater
8550 if(&target)
8551 __ bgtz(opr1_reg, target);
8552 else
8553 __ bgtz(opr1_reg, (int)0);
8554 break;
8556 case 0x04: //greater_equal
8557 if(&target)
8558 __ bgez(opr1_reg, target);
8559 else
8560 __ bgez(opr1_reg, (int)0);
8561 break;
8563 case 0x05: //less
8564 __ slt(AT, opr1_reg, R0);
8565 if(&target)
8566 __ bne(AT, R0, target);
8567 else
8568 __ bne(AT, R0, (int)0);
8569 break;
8571 case 0x06: //less_equal
8572 if (&target)
8573 __ blez(opr1_reg, target);
8574 else
8575 __ blez(opr1_reg, int(0));
8576 break;
8578 default:
8579 Unimplemented();
8580 }
8581 __ delayed()->nop();
8582 %}
8585 ins_pc_relative(1);
8586 ins_pipe( pipe_alu_branch );
8587 ins_short_branch(1);
8588 %}
8590 instruct branchConL_regL_immL_short(cmpOp cmp, mRegL src1, immL src2, label labl) %{
8591 match( If cmp (CmpL src1 src2) );
8592 effect(USE labl);
8593 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_immL_short" %}
8594 ins_cost(180);
8596 ins_encode %{
8597 Register opr1_reg = as_Register($src1$$reg);
8598 Register opr2_reg = AT;
8600 Label &target = *($labl$$label);
8601 int flag = $cmp$$cmpcode;
8603 __ set64(opr2_reg, $src2$$constant);
8605 switch(flag) {
8606 case 0x01: //equal
8607 if (&target)
8608 __ beq(opr1_reg, opr2_reg, target);
8609 else
8610 __ beq(opr1_reg, opr2_reg, (int)0);
8611 break;
8613 case 0x02: //not_equal
8614 if(&target)
8615 __ bne(opr1_reg, opr2_reg, target);
8616 else
8617 __ bne(opr1_reg, opr2_reg, (int)0);
8618 break;
8620 case 0x03: //greater
8621 __ slt(AT, opr2_reg, opr1_reg);
8622 if(&target)
8623 __ bne(AT, R0, target);
8624 else
8625 __ bne(AT, R0, (int)0);
8626 break;
8628 case 0x04: //greater_equal
8629 __ slt(AT, opr1_reg, opr2_reg);
8630 if(&target)
8631 __ beq(AT, R0, target);
8632 else
8633 __ beq(AT, R0, (int)0);
8634 break;
8636 case 0x05: //less
8637 __ slt(AT, opr1_reg, opr2_reg);
8638 if(&target)
8639 __ bne(AT, R0, target);
8640 else
8641 __ bne(AT, R0, (int)0);
8642 break;
8644 case 0x06: //less_equal
8645 __ slt(AT, opr2_reg, opr1_reg);
8646 if(&target)
8647 __ beq(AT, R0, target);
8648 else
8649 __ beq(AT, R0, (int)0);
8650 break;
8652 default:
8653 Unimplemented();
8654 }
8655 __ nop();
8656 %}
8659 ins_pc_relative(1);
8660 ins_pipe( pipe_alu_branch );
8661 ins_short_branch(1);
8662 %}
8665 //FIXME
8666 instruct branchConF_reg_reg_short(cmpOp cmp, regF src1, regF src2, label labl) %{
8667 match( If cmp (CmpF src1 src2) );
8668 effect(USE labl);
8669 format %{ "BR$cmp $src1, $src2, $labl #@branchConF_reg_reg_short" %}
8671 ins_encode %{
8672 FloatRegister reg_op1 = $src1$$FloatRegister;
8673 FloatRegister reg_op2 = $src2$$FloatRegister;
8674 Label &L = *($labl$$label);
8675 int flag = $cmp$$cmpcode;
8677 switch(flag) {
8678 case 0x01: //equal
8679 __ c_eq_s(reg_op1, reg_op2);
8680 if (&L)
8681 __ bc1t(L);
8682 else
8683 __ bc1t((int)0);
8684 break;
8685 case 0x02: //not_equal
8686 __ c_eq_s(reg_op1, reg_op2);
8687 if (&L)
8688 __ bc1f(L);
8689 else
8690 __ bc1f((int)0);
8691 break;
8692 case 0x03: //greater
8693 __ c_ule_s(reg_op1, reg_op2);
8694 if(&L)
8695 __ bc1f(L);
8696 else
8697 __ bc1f((int)0);
8698 break;
8699 case 0x04: //greater_equal
8700 __ c_ult_s(reg_op1, reg_op2);
8701 if(&L)
8702 __ bc1f(L);
8703 else
8704 __ bc1f((int)0);
8705 break;
8706 case 0x05: //less
8707 __ c_ult_s(reg_op1, reg_op2);
8708 if(&L)
8709 __ bc1t(L);
8710 else
8711 __ bc1t((int)0);
8712 break;
8713 case 0x06: //less_equal
8714 __ c_ule_s(reg_op1, reg_op2);
8715 if(&L)
8716 __ bc1t(L);
8717 else
8718 __ bc1t((int)0);
8719 break;
8720 default:
8721 Unimplemented();
8722 }
8723 __ nop();
8724 %}
8726 ins_pc_relative(1);
8727 ins_pipe(pipe_slow);
8728 ins_short_branch(1);
8729 %}
8731 instruct branchConD_reg_reg_short(cmpOp cmp, regD src1, regD src2, label labl) %{
8732 match( If cmp (CmpD src1 src2) );
8733 effect(USE labl);
8734 format %{ "BR$cmp $src1, $src2, $labl #@branchConD_reg_reg_short" %}
8736 ins_encode %{
8737 FloatRegister reg_op1 = $src1$$FloatRegister;
8738 FloatRegister reg_op2 = $src2$$FloatRegister;
8739 Label &L = *($labl$$label);
8740 int flag = $cmp$$cmpcode;
8742 switch(flag) {
8743 case 0x01: //equal
8744 __ c_eq_d(reg_op1, reg_op2);
8745 if (&L)
8746 __ bc1t(L);
8747 else
8748 __ bc1t((int)0);
8749 break;
8750 case 0x02: //not_equal
8751 //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.
8752 __ c_eq_d(reg_op1, reg_op2);
8753 if (&L)
8754 __ bc1f(L);
8755 else
8756 __ bc1f((int)0);
8757 break;
8758 case 0x03: //greater
8759 __ c_ule_d(reg_op1, reg_op2);
8760 if(&L)
8761 __ bc1f(L);
8762 else
8763 __ bc1f((int)0);
8764 break;
8765 case 0x04: //greater_equal
8766 __ c_ult_d(reg_op1, reg_op2);
8767 if(&L)
8768 __ bc1f(L);
8769 else
8770 __ bc1f((int)0);
8771 break;
8772 case 0x05: //less
8773 __ c_ult_d(reg_op1, reg_op2);
8774 if(&L)
8775 __ bc1t(L);
8776 else
8777 __ bc1t((int)0);
8778 break;
8779 case 0x06: //less_equal
8780 __ c_ule_d(reg_op1, reg_op2);
8781 if(&L)
8782 __ bc1t(L);
8783 else
8784 __ bc1t((int)0);
8785 break;
8786 default:
8787 Unimplemented();
8788 }
8789 __ nop();
8790 %}
8792 ins_pc_relative(1);
8793 ins_pipe(pipe_slow);
8794 ins_short_branch(1);
8795 %}
8797 // =================== End of branch instructions ==========================
8799 // Call Runtime Instruction
8800 instruct CallRuntimeDirect(method meth) %{
8801 match(CallRuntime );
8802 effect(USE meth);
8804 ins_cost(300);
8805 format %{ "CALL,runtime #@CallRuntimeDirect" %}
8806 ins_encode( Java_To_Runtime( meth ) );
8807 ins_pipe( pipe_slow );
8808 ins_alignment(16);
8809 %}
8813 //------------------------MemBar Instructions-------------------------------
8814 //Memory barrier flavors
8816 instruct membar_acquire() %{
8817 match(MemBarAcquire);
8818 ins_cost(400);
8820 format %{ "MEMBAR-acquire @ membar_acquire" %}
8821 ins_encode %{
8822 __ sync();
8823 %}
8824 ins_pipe(empty);
8825 %}
8827 instruct load_fence() %{
8828 match(LoadFence);
8829 ins_cost(400);
8831 format %{ "MEMBAR @ load_fence" %}
8832 ins_encode %{
8833 __ sync();
8834 %}
8835 ins_pipe(pipe_slow);
8836 %}
8838 instruct membar_acquire_lock()
8839 %{
8840 match(MemBarAcquireLock);
8841 ins_cost(0);
8843 size(0);
8844 format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
8845 ins_encode();
8846 ins_pipe(empty);
8847 %}
8849 instruct membar_release() %{
8850 match(MemBarRelease);
8851 ins_cost(400);
8853 format %{ "MEMBAR-release @ membar_release" %}
8855 ins_encode %{
8856 // Attention: DO NOT DELETE THIS GUY!
8857 __ sync();
8858 %}
8860 ins_pipe(pipe_slow);
8861 %}
8863 instruct store_fence() %{
8864 match(StoreFence);
8865 ins_cost(400);
8867 format %{ "MEMBAR @ store_fence" %}
8869 ins_encode %{
8870 __ sync();
8871 %}
8873 ins_pipe(pipe_slow);
8874 %}
8876 instruct membar_release_lock()
8877 %{
8878 match(MemBarReleaseLock);
8879 ins_cost(0);
8881 size(0);
8882 format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
8883 ins_encode();
8884 ins_pipe(empty);
8885 %}
8888 instruct membar_volatile() %{
8889 match(MemBarVolatile);
8890 ins_cost(400);
8892 format %{ "MEMBAR-volatile" %}
8893 ins_encode %{
8894 if( !os::is_MP() ) return; // Not needed on single CPU
8895 __ sync();
8897 %}
8898 ins_pipe(pipe_slow);
8899 %}
8901 instruct unnecessary_membar_volatile() %{
8902 match(MemBarVolatile);
8903 predicate(Matcher::post_store_load_barrier(n));
8904 ins_cost(0);
8906 size(0);
8907 format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
8908 ins_encode( );
8909 ins_pipe(empty);
8910 %}
8912 instruct membar_storestore() %{
8913 match(MemBarStoreStore);
8915 ins_cost(400);
8916 format %{ "MEMBAR-storestore @ membar_storestore" %}
8917 ins_encode %{
8918 __ sync();
8919 %}
8920 ins_pipe(empty);
8921 %}
8923 //----------Move Instructions--------------------------------------------------
8924 instruct castX2P(mRegP dst, mRegL src) %{
8925 match(Set dst (CastX2P src));
8926 format %{ "castX2P $dst, $src @ castX2P" %}
8927 ins_encode %{
8928 Register src = $src$$Register;
8929 Register dst = $dst$$Register;
8931 if(src != dst)
8932 __ move(dst, src);
8933 %}
8934 ins_cost(10);
8935 ins_pipe( ialu_regI_mov );
8936 %}
8938 instruct castP2X(mRegL dst, mRegP src ) %{
8939 match(Set dst (CastP2X src));
8941 format %{ "mov $dst, $src\t #@castP2X" %}
8942 ins_encode %{
8943 Register src = $src$$Register;
8944 Register dst = $dst$$Register;
8946 if(src != dst)
8947 __ move(dst, src);
8948 %}
8949 ins_pipe( ialu_regI_mov );
8950 %}
8952 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
8953 match(Set dst (MoveF2I src));
8954 effect(DEF dst, USE src);
8955 ins_cost(85);
8956 format %{ "MoveF2I $dst, $src @ MoveF2I_reg_reg" %}
8957 ins_encode %{
8958 Register dst = as_Register($dst$$reg);
8959 FloatRegister src = as_FloatRegister($src$$reg);
8961 __ mfc1(dst, src);
8962 %}
8963 ins_pipe( pipe_slow );
8964 %}
8966 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
8967 match(Set dst (MoveI2F src));
8968 effect(DEF dst, USE src);
8969 ins_cost(85);
8970 format %{ "MoveI2F $dst, $src @ MoveI2F_reg_reg" %}
8971 ins_encode %{
8972 Register src = as_Register($src$$reg);
8973 FloatRegister dst = as_FloatRegister($dst$$reg);
8975 __ mtc1(src, dst);
8976 %}
8977 ins_pipe( pipe_slow );
8978 %}
8980 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
8981 match(Set dst (MoveD2L src));
8982 effect(DEF dst, USE src);
8983 ins_cost(85);
8984 format %{ "MoveD2L $dst, $src @ MoveD2L_reg_reg" %}
8985 ins_encode %{
8986 Register dst = as_Register($dst$$reg);
8987 FloatRegister src = as_FloatRegister($src$$reg);
8989 __ dmfc1(dst, src);
8990 %}
8991 ins_pipe( pipe_slow );
8992 %}
8994 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
8995 match(Set dst (MoveL2D src));
8996 effect(DEF dst, USE src);
8997 ins_cost(85);
8998 format %{ "MoveL2D $dst, $src @ MoveL2D_reg_reg" %}
8999 ins_encode %{
9000 FloatRegister dst = as_FloatRegister($dst$$reg);
9001 Register src = as_Register($src$$reg);
9003 __ dmtc1(src, dst);
9004 %}
9005 ins_pipe( pipe_slow );
9006 %}
9008 //----------Conditional Move---------------------------------------------------
9009 // Conditional move
9010 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9011 match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9012 ins_cost(80);
9013 format %{
9014 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpI_reg_reg\n"
9015 "\tCMOV $dst,$src \t @cmovI_cmpI_reg_reg"
9016 %}
9018 ins_encode %{
9019 Register op1 = $tmp1$$Register;
9020 Register op2 = $tmp2$$Register;
9021 Register dst = $dst$$Register;
9022 Register src = $src$$Register;
9023 int flag = $cop$$cmpcode;
9025 switch(flag) {
9026 case 0x01: //equal
9027 __ subu32(AT, op1, op2);
9028 __ movz(dst, src, AT);
9029 break;
9031 case 0x02: //not_equal
9032 __ subu32(AT, op1, op2);
9033 __ movn(dst, src, AT);
9034 break;
9036 case 0x03: //great
9037 __ slt(AT, op2, op1);
9038 __ movn(dst, src, AT);
9039 break;
9041 case 0x04: //great_equal
9042 __ slt(AT, op1, op2);
9043 __ movz(dst, src, AT);
9044 break;
9046 case 0x05: //less
9047 __ slt(AT, op1, op2);
9048 __ movn(dst, src, AT);
9049 break;
9051 case 0x06: //less_equal
9052 __ slt(AT, op2, op1);
9053 __ movz(dst, src, AT);
9054 break;
9056 default:
9057 Unimplemented();
9058 }
9059 %}
9061 ins_pipe( pipe_slow );
9062 %}
9064 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9065 match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9066 ins_cost(80);
9067 format %{
9068 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
9069 "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
9070 %}
9071 ins_encode %{
9072 Register op1 = $tmp1$$Register;
9073 Register op2 = $tmp2$$Register;
9074 Register dst = $dst$$Register;
9075 Register src = $src$$Register;
9076 int flag = $cop$$cmpcode;
9078 switch(flag) {
9079 case 0x01: //equal
9080 __ subu(AT, op1, op2);
9081 __ movz(dst, src, AT);
9082 break;
9084 case 0x02: //not_equal
9085 __ subu(AT, op1, op2);
9086 __ movn(dst, src, AT);
9087 break;
9089 case 0x03: //above
9090 __ sltu(AT, op2, op1);
9091 __ movn(dst, src, AT);
9092 break;
9094 case 0x04: //above_equal
9095 __ sltu(AT, op1, op2);
9096 __ movz(dst, src, AT);
9097 break;
9099 case 0x05: //below
9100 __ sltu(AT, op1, op2);
9101 __ movn(dst, src, AT);
9102 break;
9104 case 0x06: //below_equal
9105 __ sltu(AT, op2, op1);
9106 __ movz(dst, src, AT);
9107 break;
9109 default:
9110 Unimplemented();
9111 }
9112 %}
9114 ins_pipe( pipe_slow );
9115 %}
9117 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
9118 match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
9119 ins_cost(80);
9120 format %{
9121 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
9122 "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
9123 %}
9124 ins_encode %{
9125 Register op1 = $tmp1$$Register;
9126 Register op2 = $tmp2$$Register;
9127 Register dst = $dst$$Register;
9128 Register src = $src$$Register;
9129 int flag = $cop$$cmpcode;
9131 switch(flag) {
9132 case 0x01: //equal
9133 __ subu32(AT, op1, op2);
9134 __ movz(dst, src, AT);
9135 break;
9137 case 0x02: //not_equal
9138 __ subu32(AT, op1, op2);
9139 __ movn(dst, src, AT);
9140 break;
9142 case 0x03: //above
9143 __ sltu(AT, op2, op1);
9144 __ movn(dst, src, AT);
9145 break;
9147 case 0x04: //above_equal
9148 __ sltu(AT, op1, op2);
9149 __ movz(dst, src, AT);
9150 break;
9152 case 0x05: //below
9153 __ sltu(AT, op1, op2);
9154 __ movn(dst, src, AT);
9155 break;
9157 case 0x06: //below_equal
9158 __ sltu(AT, op2, op1);
9159 __ movz(dst, src, AT);
9160 break;
9162 default:
9163 Unimplemented();
9164 }
9165 %}
9167 ins_pipe( pipe_slow );
9168 %}
9170 instruct cmovP_cmpU_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
9171 match(Set dst (CMoveP (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
9172 ins_cost(80);
9173 format %{
9174 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpU_reg_reg\n\t"
9175 "CMOV $dst,$src\t @cmovP_cmpU_reg_reg"
9176 %}
9177 ins_encode %{
9178 Register op1 = $tmp1$$Register;
9179 Register op2 = $tmp2$$Register;
9180 Register dst = $dst$$Register;
9181 Register src = $src$$Register;
9182 int flag = $cop$$cmpcode;
9184 switch(flag) {
9185 case 0x01: //equal
9186 __ subu32(AT, op1, op2);
9187 __ movz(dst, src, AT);
9188 break;
9190 case 0x02: //not_equal
9191 __ subu32(AT, op1, op2);
9192 __ movn(dst, src, AT);
9193 break;
9195 case 0x03: //above
9196 __ sltu(AT, op2, op1);
9197 __ movn(dst, src, AT);
9198 break;
9200 case 0x04: //above_equal
9201 __ sltu(AT, op1, op2);
9202 __ movz(dst, src, AT);
9203 break;
9205 case 0x05: //below
9206 __ sltu(AT, op1, op2);
9207 __ movn(dst, src, AT);
9208 break;
9210 case 0x06: //below_equal
9211 __ sltu(AT, op2, op1);
9212 __ movz(dst, src, AT);
9213 break;
9215 default:
9216 Unimplemented();
9217 }
9218 %}
9220 ins_pipe( pipe_slow );
9221 %}
9223 instruct cmovP_cmpF_reg_reg(mRegP dst, mRegP src, regF tmp1, regF tmp2, cmpOp cop ) %{
9224 match(Set dst (CMoveP (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
9225 ins_cost(80);
9226 format %{
9227 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpF_reg_reg\n"
9228 "\tCMOV $dst,$src \t @cmovP_cmpF_reg_reg"
9229 %}
9231 ins_encode %{
9232 FloatRegister reg_op1 = $tmp1$$FloatRegister;
9233 FloatRegister reg_op2 = $tmp2$$FloatRegister;
9234 Register dst = $dst$$Register;
9235 Register src = $src$$Register;
9236 int flag = $cop$$cmpcode;
9238 switch(flag) {
9239 case 0x01: //equal
9240 __ c_eq_s(reg_op1, reg_op2);
9241 __ movt(dst, src);
9242 break;
9243 case 0x02: //not_equal
9244 __ c_eq_s(reg_op1, reg_op2);
9245 __ movf(dst, src);
9246 break;
9247 case 0x03: //greater
9248 __ c_ole_s(reg_op1, reg_op2);
9249 __ movf(dst, src);
9250 break;
9251 case 0x04: //greater_equal
9252 __ c_olt_s(reg_op1, reg_op2);
9253 __ movf(dst, src);
9254 break;
9255 case 0x05: //less
9256 __ c_ult_s(reg_op1, reg_op2);
9257 __ movt(dst, src);
9258 break;
9259 case 0x06: //less_equal
9260 __ c_ule_s(reg_op1, reg_op2);
9261 __ movt(dst, src);
9262 break;
9263 default:
9264 Unimplemented();
9265 }
9266 %}
9267 ins_pipe( pipe_slow );
9268 %}
9270 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
9271 match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
9272 ins_cost(80);
9273 format %{
9274 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
9275 "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
9276 %}
9277 ins_encode %{
9278 Register op1 = $tmp1$$Register;
9279 Register op2 = $tmp2$$Register;
9280 Register dst = $dst$$Register;
9281 Register src = $src$$Register;
9282 int flag = $cop$$cmpcode;
9284 switch(flag) {
9285 case 0x01: //equal
9286 __ subu32(AT, op1, op2);
9287 __ movz(dst, src, AT);
9288 break;
9290 case 0x02: //not_equal
9291 __ subu32(AT, op1, op2);
9292 __ movn(dst, src, AT);
9293 break;
9295 case 0x03: //above
9296 __ sltu(AT, op2, op1);
9297 __ movn(dst, src, AT);
9298 break;
9300 case 0x04: //above_equal
9301 __ sltu(AT, op1, op2);
9302 __ movz(dst, src, AT);
9303 break;
9305 case 0x05: //below
9306 __ sltu(AT, op1, op2);
9307 __ movn(dst, src, AT);
9308 break;
9310 case 0x06: //below_equal
9311 __ sltu(AT, op2, op1);
9312 __ movz(dst, src, AT);
9313 break;
9315 default:
9316 Unimplemented();
9317 }
9318 %}
9320 ins_pipe( pipe_slow );
9321 %}
9323 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9324 match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9325 ins_cost(80);
9326 format %{
9327 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
9328 "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
9329 %}
9330 ins_encode %{
9331 Register op1 = $tmp1$$Register;
9332 Register op2 = $tmp2$$Register;
9333 Register dst = $dst$$Register;
9334 Register src = $src$$Register;
9335 int flag = $cop$$cmpcode;
9337 switch(flag) {
9338 case 0x01: //equal
9339 __ subu(AT, op1, op2);
9340 __ movz(dst, src, AT);
9341 break;
9343 case 0x02: //not_equal
9344 __ subu(AT, op1, op2);
9345 __ movn(dst, src, AT);
9346 break;
9348 case 0x03: //above
9349 __ sltu(AT, op2, op1);
9350 __ movn(dst, src, AT);
9351 break;
9353 case 0x04: //above_equal
9354 __ sltu(AT, op1, op2);
9355 __ movz(dst, src, AT);
9356 break;
9358 case 0x05: //below
9359 __ sltu(AT, op1, op2);
9360 __ movn(dst, src, AT);
9361 break;
9363 case 0x06: //below_equal
9364 __ sltu(AT, op2, op1);
9365 __ movz(dst, src, AT);
9366 break;
9368 default:
9369 Unimplemented();
9370 }
9371 %}
9373 ins_pipe( pipe_slow );
9374 %}
9376 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
9377 match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
9378 ins_cost(80);
9379 format %{
9380 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpD_reg_reg\n"
9381 "\tCMOV $dst,$src \t @cmovP_cmpD_reg_reg"
9382 %}
9383 ins_encode %{
9384 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
9385 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
9386 Register dst = as_Register($dst$$reg);
9387 Register src = as_Register($src$$reg);
9389 int flag = $cop$$cmpcode;
9391 switch(flag) {
9392 case 0x01: //equal
9393 __ c_eq_d(reg_op1, reg_op2);
9394 __ movt(dst, src);
9395 break;
9396 case 0x02: //not_equal
9397 __ c_eq_d(reg_op1, reg_op2);
9398 __ movf(dst, src);
9399 break;
9400 case 0x03: //greater
9401 __ c_ole_d(reg_op1, reg_op2);
9402 __ movf(dst, src);
9403 break;
9404 case 0x04: //greater_equal
9405 __ c_olt_d(reg_op1, reg_op2);
9406 __ movf(dst, src);
9407 break;
9408 case 0x05: //less
9409 __ c_ult_d(reg_op1, reg_op2);
9410 __ movt(dst, src);
9411 break;
9412 case 0x06: //less_equal
9413 __ c_ule_d(reg_op1, reg_op2);
9414 __ movt(dst, src);
9415 break;
9416 default:
9417 Unimplemented();
9418 }
9419 %}
9421 ins_pipe( pipe_slow );
9422 %}
9425 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
9426 match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
9427 ins_cost(80);
9428 format %{
9429 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
9430 "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
9431 %}
9432 ins_encode %{
9433 Register op1 = $tmp1$$Register;
9434 Register op2 = $tmp2$$Register;
9435 Register dst = $dst$$Register;
9436 Register src = $src$$Register;
9437 int flag = $cop$$cmpcode;
9439 switch(flag) {
9440 case 0x01: //equal
9441 __ subu32(AT, op1, op2);
9442 __ movz(dst, src, AT);
9443 break;
9445 case 0x02: //not_equal
9446 __ subu32(AT, op1, op2);
9447 __ movn(dst, src, AT);
9448 break;
9450 case 0x03: //above
9451 __ sltu(AT, op2, op1);
9452 __ movn(dst, src, AT);
9453 break;
9455 case 0x04: //above_equal
9456 __ sltu(AT, op1, op2);
9457 __ movz(dst, src, AT);
9458 break;
9460 case 0x05: //below
9461 __ sltu(AT, op1, op2);
9462 __ movn(dst, src, AT);
9463 break;
9465 case 0x06: //below_equal
9466 __ sltu(AT, op2, op1);
9467 __ movz(dst, src, AT);
9468 break;
9470 default:
9471 Unimplemented();
9472 }
9473 %}
9475 ins_pipe( pipe_slow );
9476 %}
9479 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
9480 match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
9481 ins_cost(80);
9482 format %{
9483 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
9484 "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
9485 %}
9486 ins_encode %{
9487 Register op1 = $tmp1$$Register;
9488 Register op2 = $tmp2$$Register;
9489 Register dst = $dst$$Register;
9490 Register src = $src$$Register;
9491 int flag = $cop$$cmpcode;
9493 switch(flag) {
9494 case 0x01: //equal
9495 __ subu(AT, op1, op2);
9496 __ movz(dst, src, AT);
9497 break;
9499 case 0x02: //not_equal
9500 __ subu(AT, op1, op2);
9501 __ movn(dst, src, AT);
9502 break;
9504 case 0x03: //above
9505 __ sltu(AT, op2, op1);
9506 __ movn(dst, src, AT);
9507 break;
9509 case 0x04: //above_equal
9510 __ sltu(AT, op1, op2);
9511 __ movz(dst, src, AT);
9512 break;
9514 case 0x05: //below
9515 __ sltu(AT, op1, op2);
9516 __ movn(dst, src, AT);
9517 break;
9519 case 0x06: //below_equal
9520 __ sltu(AT, op2, op1);
9521 __ movz(dst, src, AT);
9522 break;
9524 default:
9525 Unimplemented();
9526 }
9527 %}
9529 ins_pipe( pipe_slow );
9530 %}
9532 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
9533 match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
9534 ins_cost(80);
9535 format %{
9536 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpL_reg_reg\n"
9537 "\tCMOV $dst,$src \t @cmovI_cmpL_reg_reg"
9538 %}
9539 ins_encode %{
9540 Register opr1 = as_Register($tmp1$$reg);
9541 Register opr2 = as_Register($tmp2$$reg);
9542 Register dst = $dst$$Register;
9543 Register src = $src$$Register;
9544 int flag = $cop$$cmpcode;
9546 switch(flag) {
9547 case 0x01: //equal
9548 __ subu(AT, opr1, opr2);
9549 __ movz(dst, src, AT);
9550 break;
9552 case 0x02: //not_equal
9553 __ subu(AT, opr1, opr2);
9554 __ movn(dst, src, AT);
9555 break;
9557 case 0x03: //greater
9558 __ slt(AT, opr2, opr1);
9559 __ movn(dst, src, AT);
9560 break;
9562 case 0x04: //greater_equal
9563 __ slt(AT, opr1, opr2);
9564 __ movz(dst, src, AT);
9565 break;
9567 case 0x05: //less
9568 __ slt(AT, opr1, opr2);
9569 __ movn(dst, src, AT);
9570 break;
9572 case 0x06: //less_equal
9573 __ slt(AT, opr2, opr1);
9574 __ movz(dst, src, AT);
9575 break;
9577 default:
9578 Unimplemented();
9579 }
9580 %}
9582 ins_pipe( pipe_slow );
9583 %}
9585 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
9586 match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
9587 ins_cost(80);
9588 format %{
9589 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpL_reg_reg\n"
9590 "\tCMOV $dst,$src \t @cmovP_cmpL_reg_reg"
9591 %}
9592 ins_encode %{
9593 Register opr1 = as_Register($tmp1$$reg);
9594 Register opr2 = as_Register($tmp2$$reg);
9595 Register dst = $dst$$Register;
9596 Register src = $src$$Register;
9597 int flag = $cop$$cmpcode;
9599 switch(flag) {
9600 case 0x01: //equal
9601 __ subu(AT, opr1, opr2);
9602 __ movz(dst, src, AT);
9603 break;
9605 case 0x02: //not_equal
9606 __ subu(AT, opr1, opr2);
9607 __ movn(dst, src, AT);
9608 break;
9610 case 0x03: //greater
9611 __ slt(AT, opr2, opr1);
9612 __ movn(dst, src, AT);
9613 break;
9615 case 0x04: //greater_equal
9616 __ slt(AT, opr1, opr2);
9617 __ movz(dst, src, AT);
9618 break;
9620 case 0x05: //less
9621 __ slt(AT, opr1, opr2);
9622 __ movn(dst, src, AT);
9623 break;
9625 case 0x06: //less_equal
9626 __ slt(AT, opr2, opr1);
9627 __ movz(dst, src, AT);
9628 break;
9630 default:
9631 Unimplemented();
9632 }
9633 %}
9635 ins_pipe( pipe_slow );
9636 %}
9638 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
9639 match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
9640 ins_cost(80);
9641 format %{
9642 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpD_reg_reg\n"
9643 "\tCMOV $dst,$src \t @cmovI_cmpD_reg_reg"
9644 %}
9645 ins_encode %{
9646 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
9647 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
9648 Register dst = as_Register($dst$$reg);
9649 Register src = as_Register($src$$reg);
9651 int flag = $cop$$cmpcode;
9653 switch(flag) {
9654 case 0x01: //equal
9655 __ c_eq_d(reg_op1, reg_op2);
9656 __ movt(dst, src);
9657 break;
9658 case 0x02: //not_equal
9659 //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.
9660 __ c_eq_d(reg_op1, reg_op2);
9661 __ movf(dst, src);
9662 break;
9663 case 0x03: //greater
9664 __ c_ole_d(reg_op1, reg_op2);
9665 __ movf(dst, src);
9666 break;
9667 case 0x04: //greater_equal
9668 __ c_olt_d(reg_op1, reg_op2);
9669 __ movf(dst, src);
9670 break;
9671 case 0x05: //less
9672 __ c_ult_d(reg_op1, reg_op2);
9673 __ movt(dst, src);
9674 break;
9675 case 0x06: //less_equal
9676 __ c_ule_d(reg_op1, reg_op2);
9677 __ movt(dst, src);
9678 break;
9679 default:
9680 Unimplemented();
9681 }
9682 %}
9684 ins_pipe( pipe_slow );
9685 %}
9688 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
9689 match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9690 ins_cost(80);
9691 format %{
9692 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
9693 "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
9694 %}
9695 ins_encode %{
9696 Register op1 = $tmp1$$Register;
9697 Register op2 = $tmp2$$Register;
9698 Register dst = $dst$$Register;
9699 Register src = $src$$Register;
9700 int flag = $cop$$cmpcode;
9702 switch(flag) {
9703 case 0x01: //equal
9704 __ subu(AT, op1, op2);
9705 __ movz(dst, src, AT);
9706 break;
9708 case 0x02: //not_equal
9709 __ subu(AT, op1, op2);
9710 __ movn(dst, src, AT);
9711 break;
9713 case 0x03: //above
9714 __ sltu(AT, op2, op1);
9715 __ movn(dst, src, AT);
9716 break;
9718 case 0x04: //above_equal
9719 __ sltu(AT, op1, op2);
9720 __ movz(dst, src, AT);
9721 break;
9723 case 0x05: //below
9724 __ sltu(AT, op1, op2);
9725 __ movn(dst, src, AT);
9726 break;
9728 case 0x06: //below_equal
9729 __ sltu(AT, op2, op1);
9730 __ movz(dst, src, AT);
9731 break;
9733 default:
9734 Unimplemented();
9735 }
9736 %}
9738 ins_pipe( pipe_slow );
9739 %}
9741 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9742 match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9743 ins_cost(80);
9744 format %{
9745 "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
9746 "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
9747 %}
9748 ins_encode %{
9749 Register op1 = $tmp1$$Register;
9750 Register op2 = $tmp2$$Register;
9751 Register dst = $dst$$Register;
9752 Register src = $src$$Register;
9753 int flag = $cop$$cmpcode;
9755 switch(flag) {
9756 case 0x01: //equal
9757 __ subu32(AT, op1, op2);
9758 __ movz(dst, src, AT);
9759 break;
9761 case 0x02: //not_equal
9762 __ subu32(AT, op1, op2);
9763 __ movn(dst, src, AT);
9764 break;
9766 case 0x03: //above
9767 __ slt(AT, op2, op1);
9768 __ movn(dst, src, AT);
9769 break;
9771 case 0x04: //above_equal
9772 __ slt(AT, op1, op2);
9773 __ movz(dst, src, AT);
9774 break;
9776 case 0x05: //below
9777 __ slt(AT, op1, op2);
9778 __ movn(dst, src, AT);
9779 break;
9781 case 0x06: //below_equal
9782 __ slt(AT, op2, op1);
9783 __ movz(dst, src, AT);
9784 break;
9786 default:
9787 Unimplemented();
9788 }
9789 %}
9791 ins_pipe( pipe_slow );
9792 %}
9794 instruct cmovN_cmpL_reg_reg(mRegN dst, mRegN src, mRegL tmp1, mRegL tmp2, cmpOp cop) %{
9795 match(Set dst (CMoveN (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
9796 ins_cost(80);
9797 format %{
9798 "CMP$cop $tmp1, $tmp2\t @cmovN_cmpL_reg_reg\n"
9799 "\tCMOV $dst,$src \t @cmovN_cmpL_reg_reg"
9800 %}
9801 ins_encode %{
9802 Register opr1 = as_Register($tmp1$$reg);
9803 Register opr2 = as_Register($tmp2$$reg);
9804 Register dst = $dst$$Register;
9805 Register src = $src$$Register;
9806 int flag = $cop$$cmpcode;
9808 switch(flag) {
9809 case 0x01: //equal
9810 __ subu(AT, opr1, opr2);
9811 __ movz(dst, src, AT);
9812 break;
9814 case 0x02: //not_equal
9815 __ subu(AT, opr1, opr2);
9816 __ movn(dst, src, AT);
9817 break;
9819 case 0x03: //greater
9820 __ slt(AT, opr2, opr1);
9821 __ movn(dst, src, AT);
9822 break;
9824 case 0x04: //greater_equal
9825 __ slt(AT, opr1, opr2);
9826 __ movz(dst, src, AT);
9827 break;
9829 case 0x05: //less
9830 __ slt(AT, opr1, opr2);
9831 __ movn(dst, src, AT);
9832 break;
9834 case 0x06: //less_equal
9835 __ slt(AT, opr2, opr1);
9836 __ movz(dst, src, AT);
9837 break;
9839 default:
9840 Unimplemented();
9841 }
9842 %}
9844 ins_pipe( pipe_slow );
9845 %}
9847 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9848 match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9849 ins_cost(80);
9850 format %{
9851 "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
9852 "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
9853 %}
9854 ins_encode %{
9855 Register op1 = $tmp1$$Register;
9856 Register op2 = $tmp2$$Register;
9857 Register dst = $dst$$Register;
9858 Register src = $src$$Register;
9859 int flag = $cop$$cmpcode;
9861 switch(flag) {
9862 case 0x01: //equal
9863 __ subu32(AT, op1, op2);
9864 __ movz(dst, src, AT);
9865 break;
9867 case 0x02: //not_equal
9868 __ subu32(AT, op1, op2);
9869 __ movn(dst, src, AT);
9870 break;
9872 case 0x03: //above
9873 __ slt(AT, op2, op1);
9874 __ movn(dst, src, AT);
9875 break;
9877 case 0x04: //above_equal
9878 __ slt(AT, op1, op2);
9879 __ movz(dst, src, AT);
9880 break;
9882 case 0x05: //below
9883 __ slt(AT, op1, op2);
9884 __ movn(dst, src, AT);
9885 break;
9887 case 0x06: //below_equal
9888 __ slt(AT, op2, op1);
9889 __ movz(dst, src, AT);
9890 break;
9892 default:
9893 Unimplemented();
9894 }
9895 %}
9897 ins_pipe( pipe_slow );
9898 %}
9900 instruct cmovL_cmpU_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
9901 match(Set dst (CMoveL (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
9902 ins_cost(80);
9903 format %{
9904 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpU_reg_reg\n\t"
9905 "CMOV $dst,$src\t @cmovL_cmpU_reg_reg"
9906 %}
9907 ins_encode %{
9908 Register op1 = $tmp1$$Register;
9909 Register op2 = $tmp2$$Register;
9910 Register dst = $dst$$Register;
9911 Register src = $src$$Register;
9912 int flag = $cop$$cmpcode;
9914 switch(flag) {
9915 case 0x01: //equal
9916 __ subu32(AT, op1, op2);
9917 __ movz(dst, src, AT);
9918 break;
9920 case 0x02: //not_equal
9921 __ subu32(AT, op1, op2);
9922 __ movn(dst, src, AT);
9923 break;
9925 case 0x03: //above
9926 __ sltu(AT, op2, op1);
9927 __ movn(dst, src, AT);
9928 break;
9930 case 0x04: //above_equal
9931 __ sltu(AT, op1, op2);
9932 __ movz(dst, src, AT);
9933 break;
9935 case 0x05: //below
9936 __ sltu(AT, op1, op2);
9937 __ movn(dst, src, AT);
9938 break;
9940 case 0x06: //below_equal
9941 __ sltu(AT, op2, op1);
9942 __ movz(dst, src, AT);
9943 break;
9945 default:
9946 Unimplemented();
9947 }
9948 %}
9950 ins_pipe( pipe_slow );
9951 %}
9953 instruct cmovL_cmpF_reg_reg(mRegL dst, mRegL src, regF tmp1, regF tmp2, cmpOp cop ) %{
9954 match(Set dst (CMoveL (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
9955 ins_cost(80);
9956 format %{
9957 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpF_reg_reg\n"
9958 "\tCMOV $dst,$src \t @cmovL_cmpF_reg_reg"
9959 %}
9961 ins_encode %{
9962 FloatRegister reg_op1 = $tmp1$$FloatRegister;
9963 FloatRegister reg_op2 = $tmp2$$FloatRegister;
9964 Register dst = $dst$$Register;
9965 Register src = $src$$Register;
9966 int flag = $cop$$cmpcode;
9968 switch(flag) {
9969 case 0x01: //equal
9970 __ c_eq_s(reg_op1, reg_op2);
9971 __ movt(dst, src);
9972 break;
9973 case 0x02: //not_equal
9974 __ c_eq_s(reg_op1, reg_op2);
9975 __ movf(dst, src);
9976 break;
9977 case 0x03: //greater
9978 __ c_ole_s(reg_op1, reg_op2);
9979 __ movf(dst, src);
9980 break;
9981 case 0x04: //greater_equal
9982 __ c_olt_s(reg_op1, reg_op2);
9983 __ movf(dst, src);
9984 break;
9985 case 0x05: //less
9986 __ c_ult_s(reg_op1, reg_op2);
9987 __ movt(dst, src);
9988 break;
9989 case 0x06: //less_equal
9990 __ c_ule_s(reg_op1, reg_op2);
9991 __ movt(dst, src);
9992 break;
9993 default:
9994 Unimplemented();
9995 }
9996 %}
9997 ins_pipe( pipe_slow );
9998 %}
10000 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10001 match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10002 ins_cost(80);
10003 format %{
10004 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpI_reg_reg\n"
10005 "\tCMOV $dst,$src \t @cmovL_cmpI_reg_reg"
10006 %}
10008 ins_encode %{
10009 Register op1 = $tmp1$$Register;
10010 Register op2 = $tmp2$$Register;
10011 Register dst = as_Register($dst$$reg);
10012 Register src = as_Register($src$$reg);
10013 int flag = $cop$$cmpcode;
10015 switch(flag)
10016 {
10017 case 0x01: //equal
10018 __ subu32(AT, op1, op2);
10019 __ movz(dst, src, AT);
10020 break;
10022 case 0x02: //not_equal
10023 __ subu32(AT, op1, op2);
10024 __ movn(dst, src, AT);
10025 break;
10027 case 0x03: //great
10028 __ slt(AT, op2, op1);
10029 __ movn(dst, src, AT);
10030 break;
10032 case 0x04: //great_equal
10033 __ slt(AT, op1, op2);
10034 __ movz(dst, src, AT);
10035 break;
10037 case 0x05: //less
10038 __ slt(AT, op1, op2);
10039 __ movn(dst, src, AT);
10040 break;
10042 case 0x06: //less_equal
10043 __ slt(AT, op2, op1);
10044 __ movz(dst, src, AT);
10045 break;
10047 default:
10048 Unimplemented();
10049 }
10050 %}
10052 ins_pipe( pipe_slow );
10053 %}
10055 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
10056 match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
10057 ins_cost(80);
10058 format %{
10059 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpL_reg_reg\n"
10060 "\tCMOV $dst,$src \t @cmovL_cmpL_reg_reg"
10061 %}
10062 ins_encode %{
10063 Register opr1 = as_Register($tmp1$$reg);
10064 Register opr2 = as_Register($tmp2$$reg);
10065 Register dst = as_Register($dst$$reg);
10066 Register src = as_Register($src$$reg);
10067 int flag = $cop$$cmpcode;
10069 switch(flag) {
10070 case 0x01: //equal
10071 __ subu(AT, opr1, opr2);
10072 __ movz(dst, src, AT);
10073 break;
10075 case 0x02: //not_equal
10076 __ subu(AT, opr1, opr2);
10077 __ movn(dst, src, AT);
10078 break;
10080 case 0x03: //greater
10081 __ slt(AT, opr2, opr1);
10082 __ movn(dst, src, AT);
10083 break;
10085 case 0x04: //greater_equal
10086 __ slt(AT, opr1, opr2);
10087 __ movz(dst, src, AT);
10088 break;
10090 case 0x05: //less
10091 __ slt(AT, opr1, opr2);
10092 __ movn(dst, src, AT);
10093 break;
10095 case 0x06: //less_equal
10096 __ slt(AT, opr2, opr1);
10097 __ movz(dst, src, AT);
10098 break;
10100 default:
10101 Unimplemented();
10102 }
10103 %}
10105 ins_pipe( pipe_slow );
10106 %}
10108 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
10109 match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
10110 ins_cost(80);
10111 format %{
10112 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
10113 "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
10114 %}
10115 ins_encode %{
10116 Register op1 = $tmp1$$Register;
10117 Register op2 = $tmp2$$Register;
10118 Register dst = $dst$$Register;
10119 Register src = $src$$Register;
10120 int flag = $cop$$cmpcode;
10122 switch(flag) {
10123 case 0x01: //equal
10124 __ subu32(AT, op1, op2);
10125 __ movz(dst, src, AT);
10126 break;
10128 case 0x02: //not_equal
10129 __ subu32(AT, op1, op2);
10130 __ movn(dst, src, AT);
10131 break;
10133 case 0x03: //above
10134 __ sltu(AT, op2, op1);
10135 __ movn(dst, src, AT);
10136 break;
10138 case 0x04: //above_equal
10139 __ sltu(AT, op1, op2);
10140 __ movz(dst, src, AT);
10141 break;
10143 case 0x05: //below
10144 __ sltu(AT, op1, op2);
10145 __ movn(dst, src, AT);
10146 break;
10148 case 0x06: //below_equal
10149 __ sltu(AT, op2, op1);
10150 __ movz(dst, src, AT);
10151 break;
10153 default:
10154 Unimplemented();
10155 }
10156 %}
10158 ins_pipe( pipe_slow );
10159 %}
10162 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
10163 match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
10164 ins_cost(80);
10165 format %{
10166 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpD_reg_reg\n"
10167 "\tCMOV $dst,$src \t @cmovL_cmpD_reg_reg"
10168 %}
10169 ins_encode %{
10170 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
10171 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
10172 Register dst = as_Register($dst$$reg);
10173 Register src = as_Register($src$$reg);
10175 int flag = $cop$$cmpcode;
10177 switch(flag) {
10178 case 0x01: //equal
10179 __ c_eq_d(reg_op1, reg_op2);
10180 __ movt(dst, src);
10181 break;
10182 case 0x02: //not_equal
10183 __ c_eq_d(reg_op1, reg_op2);
10184 __ movf(dst, src);
10185 break;
10186 case 0x03: //greater
10187 __ c_ole_d(reg_op1, reg_op2);
10188 __ movf(dst, src);
10189 break;
10190 case 0x04: //greater_equal
10191 __ c_olt_d(reg_op1, reg_op2);
10192 __ movf(dst, src);
10193 break;
10194 case 0x05: //less
10195 __ c_ult_d(reg_op1, reg_op2);
10196 __ movt(dst, src);
10197 break;
10198 case 0x06: //less_equal
10199 __ c_ule_d(reg_op1, reg_op2);
10200 __ movt(dst, src);
10201 break;
10202 default:
10203 Unimplemented();
10204 }
10205 %}
10207 ins_pipe( pipe_slow );
10208 %}
10210 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
10211 match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
10212 ins_cost(200);
10213 format %{
10214 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpD_reg_reg\n"
10215 "\tCMOV $dst,$src \t @cmovD_cmpD_reg_reg"
10216 %}
10217 ins_encode %{
10218 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
10219 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
10220 FloatRegister dst = as_FloatRegister($dst$$reg);
10221 FloatRegister src = as_FloatRegister($src$$reg);
10223 int flag = $cop$$cmpcode;
10225 switch(flag) {
10226 case 0x01: //equal
10227 __ c_eq_d(reg_op1, reg_op2);
10228 __ movt_d(dst, src);
10229 break;
10230 case 0x02: //not_equal
10231 __ c_eq_d(reg_op1, reg_op2);
10232 __ movf_d(dst, src);
10233 break;
10234 case 0x03: //greater
10235 __ c_ole_d(reg_op1, reg_op2);
10236 __ movf_d(dst, src);
10237 break;
10238 case 0x04: //greater_equal
10239 __ c_olt_d(reg_op1, reg_op2);
10240 __ movf_d(dst, src);
10241 break;
10242 case 0x05: //less
10243 __ c_ult_d(reg_op1, reg_op2);
10244 __ movt_d(dst, src);
10245 break;
10246 case 0x06: //less_equal
10247 __ c_ule_d(reg_op1, reg_op2);
10248 __ movt_d(dst, src);
10249 break;
10250 default:
10251 Unimplemented();
10252 }
10253 %}
10255 ins_pipe( pipe_slow );
10256 %}
10258 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10259 match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10260 ins_cost(200);
10261 format %{
10262 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpI_reg_reg\n"
10263 "\tCMOV $dst, $src \t @cmovF_cmpI_reg_reg"
10264 %}
10266 ins_encode %{
10267 Register op1 = $tmp1$$Register;
10268 Register op2 = $tmp2$$Register;
10269 FloatRegister dst = as_FloatRegister($dst$$reg);
10270 FloatRegister src = as_FloatRegister($src$$reg);
10271 int flag = $cop$$cmpcode;
10272 Label L;
10274 switch(flag) {
10275 case 0x01: //equal
10276 __ bne(op1, op2, L);
10277 __ nop();
10278 __ mov_s(dst, src);
10279 __ bind(L);
10280 break;
10281 case 0x02: //not_equal
10282 __ beq(op1, op2, L);
10283 __ nop();
10284 __ mov_s(dst, src);
10285 __ bind(L);
10286 break;
10287 case 0x03: //great
10288 __ slt(AT, op2, op1);
10289 __ beq(AT, R0, L);
10290 __ nop();
10291 __ mov_s(dst, src);
10292 __ bind(L);
10293 break;
10294 case 0x04: //great_equal
10295 __ slt(AT, op1, op2);
10296 __ bne(AT, R0, L);
10297 __ nop();
10298 __ mov_s(dst, src);
10299 __ bind(L);
10300 break;
10301 case 0x05: //less
10302 __ slt(AT, op1, op2);
10303 __ beq(AT, R0, L);
10304 __ nop();
10305 __ mov_s(dst, src);
10306 __ bind(L);
10307 break;
10308 case 0x06: //less_equal
10309 __ slt(AT, op2, op1);
10310 __ bne(AT, R0, L);
10311 __ nop();
10312 __ mov_s(dst, src);
10313 __ bind(L);
10314 break;
10315 default:
10316 Unimplemented();
10317 }
10318 %}
10320 ins_pipe( pipe_slow );
10321 %}
10323 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
10324 match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
10325 ins_cost(200);
10326 format %{
10327 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpI_reg_reg\n"
10328 "\tCMOV $dst, $src \t @cmovD_cmpI_reg_reg"
10329 %}
10331 ins_encode %{
10332 Register op1 = $tmp1$$Register;
10333 Register op2 = $tmp2$$Register;
10334 FloatRegister dst = as_FloatRegister($dst$$reg);
10335 FloatRegister src = as_FloatRegister($src$$reg);
10336 int flag = $cop$$cmpcode;
10337 Label L;
10339 switch(flag) {
10340 case 0x01: //equal
10341 __ bne(op1, op2, L);
10342 __ nop();
10343 __ mov_d(dst, src);
10344 __ bind(L);
10345 break;
10346 case 0x02: //not_equal
10347 __ beq(op1, op2, L);
10348 __ nop();
10349 __ mov_d(dst, src);
10350 __ bind(L);
10351 break;
10352 case 0x03: //great
10353 __ slt(AT, op2, op1);
10354 __ beq(AT, R0, L);
10355 __ nop();
10356 __ mov_d(dst, src);
10357 __ bind(L);
10358 break;
10359 case 0x04: //great_equal
10360 __ slt(AT, op1, op2);
10361 __ bne(AT, R0, L);
10362 __ nop();
10363 __ mov_d(dst, src);
10364 __ bind(L);
10365 break;
10366 case 0x05: //less
10367 __ slt(AT, op1, op2);
10368 __ beq(AT, R0, L);
10369 __ nop();
10370 __ mov_d(dst, src);
10371 __ bind(L);
10372 break;
10373 case 0x06: //less_equal
10374 __ slt(AT, op2, op1);
10375 __ bne(AT, R0, L);
10376 __ nop();
10377 __ mov_d(dst, src);
10378 __ bind(L);
10379 break;
10380 default:
10381 Unimplemented();
10382 }
10383 %}
10385 ins_pipe( pipe_slow );
10386 %}
10388 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
10389 match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
10390 ins_cost(200);
10391 format %{
10392 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpP_reg_reg\n"
10393 "\tCMOV $dst, $src \t @cmovD_cmpP_reg_reg"
10394 %}
10396 ins_encode %{
10397 Register op1 = $tmp1$$Register;
10398 Register op2 = $tmp2$$Register;
10399 FloatRegister dst = as_FloatRegister($dst$$reg);
10400 FloatRegister src = as_FloatRegister($src$$reg);
10401 int flag = $cop$$cmpcode;
10402 Label L;
10404 switch(flag) {
10405 case 0x01: //equal
10406 __ bne(op1, op2, L);
10407 __ nop();
10408 __ mov_d(dst, src);
10409 __ bind(L);
10410 break;
10411 case 0x02: //not_equal
10412 __ beq(op1, op2, L);
10413 __ nop();
10414 __ mov_d(dst, src);
10415 __ bind(L);
10416 break;
10417 case 0x03: //great
10418 __ slt(AT, op2, op1);
10419 __ beq(AT, R0, L);
10420 __ nop();
10421 __ mov_d(dst, src);
10422 __ bind(L);
10423 break;
10424 case 0x04: //great_equal
10425 __ slt(AT, op1, op2);
10426 __ bne(AT, R0, L);
10427 __ nop();
10428 __ mov_d(dst, src);
10429 __ bind(L);
10430 break;
10431 case 0x05: //less
10432 __ slt(AT, op1, op2);
10433 __ beq(AT, R0, L);
10434 __ nop();
10435 __ mov_d(dst, src);
10436 __ bind(L);
10437 break;
10438 case 0x06: //less_equal
10439 __ slt(AT, op2, op1);
10440 __ bne(AT, R0, L);
10441 __ nop();
10442 __ mov_d(dst, src);
10443 __ bind(L);
10444 break;
10445 default:
10446 Unimplemented();
10447 }
10448 %}
10450 ins_pipe( pipe_slow );
10451 %}
10453 //FIXME
10454 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
10455 match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
10456 ins_cost(80);
10457 format %{
10458 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpF_reg_reg\n"
10459 "\tCMOV $dst,$src \t @cmovI_cmpF_reg_reg"
10460 %}
10462 ins_encode %{
10463 FloatRegister reg_op1 = $tmp1$$FloatRegister;
10464 FloatRegister reg_op2 = $tmp2$$FloatRegister;
10465 Register dst = $dst$$Register;
10466 Register src = $src$$Register;
10467 int flag = $cop$$cmpcode;
10469 switch(flag) {
10470 case 0x01: //equal
10471 __ c_eq_s(reg_op1, reg_op2);
10472 __ movt(dst, src);
10473 break;
10474 case 0x02: //not_equal
10475 __ c_eq_s(reg_op1, reg_op2);
10476 __ movf(dst, src);
10477 break;
10478 case 0x03: //greater
10479 __ c_ole_s(reg_op1, reg_op2);
10480 __ movf(dst, src);
10481 break;
10482 case 0x04: //greater_equal
10483 __ c_olt_s(reg_op1, reg_op2);
10484 __ movf(dst, src);
10485 break;
10486 case 0x05: //less
10487 __ c_ult_s(reg_op1, reg_op2);
10488 __ movt(dst, src);
10489 break;
10490 case 0x06: //less_equal
10491 __ c_ule_s(reg_op1, reg_op2);
10492 __ movt(dst, src);
10493 break;
10494 default:
10495 Unimplemented();
10496 }
10497 %}
10498 ins_pipe( pipe_slow );
10499 %}
10501 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
10502 match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
10503 ins_cost(200);
10504 format %{
10505 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpF_reg_reg\n"
10506 "\tCMOV $dst,$src \t @cmovF_cmpF_reg_reg"
10507 %}
10509 ins_encode %{
10510 FloatRegister reg_op1 = $tmp1$$FloatRegister;
10511 FloatRegister reg_op2 = $tmp2$$FloatRegister;
10512 FloatRegister dst = $dst$$FloatRegister;
10513 FloatRegister src = $src$$FloatRegister;
10514 int flag = $cop$$cmpcode;
10516 switch(flag) {
10517 case 0x01: //equal
10518 __ c_eq_s(reg_op1, reg_op2);
10519 __ movt_s(dst, src);
10520 break;
10521 case 0x02: //not_equal
10522 __ c_eq_s(reg_op1, reg_op2);
10523 __ movf_s(dst, src);
10524 break;
10525 case 0x03: //greater
10526 __ c_ole_s(reg_op1, reg_op2);
10527 __ movf_s(dst, src);
10528 break;
10529 case 0x04: //greater_equal
10530 __ c_olt_s(reg_op1, reg_op2);
10531 __ movf_s(dst, src);
10532 break;
10533 case 0x05: //less
10534 __ c_ult_s(reg_op1, reg_op2);
10535 __ movt_s(dst, src);
10536 break;
10537 case 0x06: //less_equal
10538 __ c_ule_s(reg_op1, reg_op2);
10539 __ movt_s(dst, src);
10540 break;
10541 default:
10542 Unimplemented();
10543 }
10544 %}
10545 ins_pipe( pipe_slow );
10546 %}
10548 // Manifest a CmpL result in an integer register. Very painful.
10549 // This is the test to avoid.
10550 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
10551 match(Set dst (CmpL3 src1 src2));
10552 ins_cost(1000);
10553 format %{ "cmpL3 $dst, $src1, $src2 @ cmpL3_reg_reg" %}
10554 ins_encode %{
10555 Register opr1 = as_Register($src1$$reg);
10556 Register opr2 = as_Register($src2$$reg);
10557 Register dst = as_Register($dst$$reg);
10559 Label Done;
10561 __ subu(AT, opr1, opr2);
10562 __ bltz(AT, Done);
10563 __ delayed()->daddiu(dst, R0, -1);
10565 __ move(dst, 1);
10566 __ movz(dst, R0, AT);
10568 __ bind(Done);
10569 %}
10570 ins_pipe( pipe_slow );
10571 %}
10573 //
10574 // less_rsult = -1
10575 // greater_result = 1
10576 // equal_result = 0
10577 // nan_result = -1
10578 //
10579 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
10580 match(Set dst (CmpF3 src1 src2));
10581 ins_cost(1000);
10582 format %{ "cmpF3 $dst, $src1, $src2 @ cmpF3_reg_reg" %}
10583 ins_encode %{
10584 FloatRegister src1 = as_FloatRegister($src1$$reg);
10585 FloatRegister src2 = as_FloatRegister($src2$$reg);
10586 Register dst = as_Register($dst$$reg);
10588 Label Done;
10590 __ c_ult_s(src1, src2);
10591 __ bc1t(Done);
10592 __ delayed()->daddiu(dst, R0, -1);
10594 __ c_eq_s(src1, src2);
10595 __ move(dst, 1);
10596 __ movt(dst, R0);
10598 __ bind(Done);
10599 %}
10600 ins_pipe( pipe_slow );
10601 %}
10603 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
10604 match(Set dst (CmpD3 src1 src2));
10605 ins_cost(1000);
10606 format %{ "cmpD3 $dst, $src1, $src2 @ cmpD3_reg_reg" %}
10607 ins_encode %{
10608 FloatRegister src1 = as_FloatRegister($src1$$reg);
10609 FloatRegister src2 = as_FloatRegister($src2$$reg);
10610 Register dst = as_Register($dst$$reg);
10612 Label Done;
10614 __ c_ult_d(src1, src2);
10615 __ bc1t(Done);
10616 __ delayed()->daddiu(dst, R0, -1);
10618 __ c_eq_d(src1, src2);
10619 __ move(dst, 1);
10620 __ movt(dst, R0);
10622 __ bind(Done);
10623 %}
10624 ins_pipe( pipe_slow );
10625 %}
10627 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
10628 match(Set dummy (ClearArray cnt base));
10629 format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
10630 ins_encode %{
10631 //Assume cnt is the number of bytes in an array to be cleared,
10632 //and base points to the starting address of the array.
10633 Register base = $base$$Register;
10634 Register num = $cnt$$Register;
10635 Label Loop, done;
10637 __ beq(num, R0, done);
10638 __ delayed()->daddu(AT, base, R0);
10640 __ move(T9, num); /* T9 = words */
10642 __ bind(Loop);
10643 __ sd(R0, AT, 0);
10644 __ daddi(T9, T9, -1);
10645 __ bne(T9, R0, Loop);
10646 __ delayed()->daddi(AT, AT, wordSize);
10648 __ bind(done);
10649 %}
10650 ins_pipe( pipe_slow );
10651 %}
10653 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2, mA7RegI cnt2, no_Ax_mRegI result) %{
10654 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
10655 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
10657 format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
10658 ins_encode %{
10659 // Get the first character position in both strings
10660 // [8] char array, [12] offset, [16] count
10661 Register str1 = $str1$$Register;
10662 Register str2 = $str2$$Register;
10663 Register cnt1 = $cnt1$$Register;
10664 Register cnt2 = $cnt2$$Register;
10665 Register result = $result$$Register;
10667 Label L, Loop, haveResult, done;
10669 // compute the and difference of lengths (in result)
10670 __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
10672 // compute the shorter length (in cnt1)
10673 __ slt(AT, cnt2, cnt1);
10674 __ movn(cnt1, cnt2, AT);
10676 // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
10677 __ bind(Loop); // Loop begin
10678 __ beq(cnt1, R0, done);
10679 __ delayed()->lhu(AT, str1, 0);;
10681 // compare current character
10682 __ lhu(cnt2, str2, 0);
10683 __ bne(AT, cnt2, haveResult);
10684 __ delayed()->addi(str1, str1, 2);
10685 __ addi(str2, str2, 2);
10686 __ b(Loop);
10687 __ delayed()->addi(cnt1, cnt1, -1); // Loop end
10689 __ bind(haveResult);
10690 __ subu(result, AT, cnt2);
10692 __ bind(done);
10693 %}
10695 ins_pipe( pipe_slow );
10696 %}
10698 // intrinsic optimization
10699 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
10700 match(Set result (StrEquals (Binary str1 str2) cnt));
10701 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
10703 format %{ "String Equal $str1, $str2, len:$cnt tmp:$temp -> $result @ string_equals" %}
10704 ins_encode %{
10705 // Get the first character position in both strings
10706 // [8] char array, [12] offset, [16] count
10707 Register str1 = $str1$$Register;
10708 Register str2 = $str2$$Register;
10709 Register cnt = $cnt$$Register;
10710 Register tmp = $temp$$Register;
10711 Register result = $result$$Register;
10713 Label Loop, done;
10716 __ beq(str1, str2, done); // same char[] ?
10717 __ daddiu(result, R0, 1);
10719 __ bind(Loop); // Loop begin
10720 __ beq(cnt, R0, done);
10721 __ daddiu(result, R0, 1); // count == 0
10723 // compare current character
10724 __ lhu(AT, str1, 0);;
10725 __ lhu(tmp, str2, 0);
10726 __ bne(AT, tmp, done);
10727 __ delayed()->daddi(result, R0, 0);
10728 __ addi(str1, str1, 2);
10729 __ addi(str2, str2, 2);
10730 __ b(Loop);
10731 __ delayed()->addi(cnt, cnt, -1); // Loop end
10733 __ bind(done);
10734 %}
10736 ins_pipe( pipe_slow );
10737 %}
10739 //----------Arithmetic Instructions-------------------------------------------
10740 //----------Addition Instructions---------------------------------------------
10741 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10742 match(Set dst (AddI src1 src2));
10744 format %{ "add $dst, $src1, $src2 #@addI_Reg_Reg" %}
10745 ins_encode %{
10746 Register dst = $dst$$Register;
10747 Register src1 = $src1$$Register;
10748 Register src2 = $src2$$Register;
10749 __ addu32(dst, src1, src2);
10750 %}
10751 ins_pipe( ialu_regI_regI );
10752 %}
10754 instruct addI_Reg_imm(mRegI dst, mRegI src1, immI src2) %{
10755 match(Set dst (AddI src1 src2));
10757 format %{ "add $dst, $src1, $src2 #@addI_Reg_imm" %}
10758 ins_encode %{
10759 Register dst = $dst$$Register;
10760 Register src1 = $src1$$Register;
10761 int imm = $src2$$constant;
10763 if(Assembler::is_simm16(imm)) {
10764 __ addiu32(dst, src1, imm);
10765 } else {
10766 __ move(AT, imm);
10767 __ addu32(dst, src1, AT);
10768 }
10769 %}
10770 ins_pipe( ialu_regI_regI );
10771 %}
10773 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
10774 match(Set dst (AddP src1 src2));
10776 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg" %}
10778 ins_encode %{
10779 Register dst = $dst$$Register;
10780 Register src1 = $src1$$Register;
10781 Register src2 = $src2$$Register;
10782 __ daddu(dst, src1, src2);
10783 %}
10785 ins_pipe( ialu_regI_regI );
10786 %}
10788 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
10789 match(Set dst (AddP src1 (ConvI2L src2)));
10791 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
10793 ins_encode %{
10794 Register dst = $dst$$Register;
10795 Register src1 = $src1$$Register;
10796 Register src2 = $src2$$Register;
10797 __ daddu(dst, src1, src2);
10798 %}
10800 ins_pipe( ialu_regI_regI );
10801 %}
10803 instruct addP_reg_imm(mRegP dst, mRegP src1, immL src2) %{
10804 match(Set dst (AddP src1 src2));
10806 format %{ "daddi $dst, $src1, $src2 #@addP_reg_imm" %}
10807 ins_encode %{
10808 Register src1 = $src1$$Register;
10809 long src2 = $src2$$constant;
10810 Register dst = $dst$$Register;
10812 if(Assembler::is_simm16(src2)) {
10813 __ daddiu(dst, src1, src2);
10814 } else {
10815 __ set64(AT, src2);
10816 __ daddu(dst, src1, AT);
10817 }
10818 %}
10819 ins_pipe( ialu_regI_imm16 );
10820 %}
10822 // Add Long Register with Register
10823 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10824 match(Set dst (AddL src1 src2));
10825 ins_cost(200);
10826 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
10828 ins_encode %{
10829 Register dst_reg = as_Register($dst$$reg);
10830 Register src1_reg = as_Register($src1$$reg);
10831 Register src2_reg = as_Register($src2$$reg);
10833 __ daddu(dst_reg, src1_reg, src2_reg);
10834 %}
10836 ins_pipe( ialu_regL_regL );
10837 %}
10839 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
10840 %{
10841 match(Set dst (AddL src1 src2));
10843 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_imm " %}
10844 ins_encode %{
10845 Register dst_reg = as_Register($dst$$reg);
10846 Register src1_reg = as_Register($src1$$reg);
10847 int src2_imm = $src2$$constant;
10849 __ daddiu(dst_reg, src1_reg, src2_imm);
10850 %}
10852 ins_pipe( ialu_regL_regL );
10853 %}
10855 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
10856 %{
10857 match(Set dst (AddL (ConvI2L src1) src2));
10859 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_imm " %}
10860 ins_encode %{
10861 Register dst_reg = as_Register($dst$$reg);
10862 Register src1_reg = as_Register($src1$$reg);
10863 int src2_imm = $src2$$constant;
10865 __ daddiu(dst_reg, src1_reg, src2_imm);
10866 %}
10868 ins_pipe( ialu_regL_regL );
10869 %}
10871 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
10872 match(Set dst (AddL (ConvI2L src1) src2));
10873 ins_cost(200);
10874 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
10876 ins_encode %{
10877 Register dst_reg = as_Register($dst$$reg);
10878 Register src1_reg = as_Register($src1$$reg);
10879 Register src2_reg = as_Register($src2$$reg);
10881 __ daddu(dst_reg, src1_reg, src2_reg);
10882 %}
10884 ins_pipe( ialu_regL_regL );
10885 %}
10887 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
10888 match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
10889 ins_cost(200);
10890 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
10892 ins_encode %{
10893 Register dst_reg = as_Register($dst$$reg);
10894 Register src1_reg = as_Register($src1$$reg);
10895 Register src2_reg = as_Register($src2$$reg);
10897 __ daddu(dst_reg, src1_reg, src2_reg);
10898 %}
10900 ins_pipe( ialu_regL_regL );
10901 %}
10903 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
10904 match(Set dst (AddL src1 (ConvI2L src2)));
10905 ins_cost(200);
10906 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
10908 ins_encode %{
10909 Register dst_reg = as_Register($dst$$reg);
10910 Register src1_reg = as_Register($src1$$reg);
10911 Register src2_reg = as_Register($src2$$reg);
10913 __ daddu(dst_reg, src1_reg, src2_reg);
10914 %}
10916 ins_pipe( ialu_regL_regL );
10917 %}
10919 //----------Subtraction Instructions-------------------------------------------
10920 // Integer Subtraction Instructions
10921 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10922 match(Set dst (SubI src1 src2));
10923 ins_cost(100);
10925 format %{ "sub $dst, $src1, $src2 #@subI_Reg_Reg" %}
10926 ins_encode %{
10927 Register dst = $dst$$Register;
10928 Register src1 = $src1$$Register;
10929 Register src2 = $src2$$Register;
10930 __ subu32(dst, src1, src2);
10931 %}
10932 ins_pipe( ialu_regI_regI );
10933 %}
10935 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1, immI16_sub src2) %{
10936 match(Set dst (SubI src1 src2));
10937 ins_cost(80);
10939 format %{ "sub $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
10940 ins_encode %{
10941 Register dst = $dst$$Register;
10942 Register src1 = $src1$$Register;
10943 __ addiu32(dst, src1, -1 * $src2$$constant);
10944 %}
10945 ins_pipe( ialu_regI_regI );
10946 %}
10948 instruct negI_Reg(mRegI dst, immI0 zero, mRegI src) %{
10949 match(Set dst (SubI zero src));
10950 ins_cost(80);
10952 format %{ "neg $dst, $src #@negI_Reg" %}
10953 ins_encode %{
10954 Register dst = $dst$$Register;
10955 Register src = $src$$Register;
10956 __ subu32(dst, R0, src);
10957 %}
10958 ins_pipe( ialu_regI_regI );
10959 %}
10961 instruct negL_Reg(mRegL dst, immL0 zero, mRegL src) %{
10962 match(Set dst (SubL zero src));
10963 ins_cost(80);
10965 format %{ "neg $dst, $src #@negL_Reg" %}
10966 ins_encode %{
10967 Register dst = $dst$$Register;
10968 Register src = $src$$Register;
10969 __ subu(dst, R0, src);
10970 %}
10971 ins_pipe( ialu_regI_regI );
10972 %}
10974 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1, immL16_sub src2) %{
10975 match(Set dst (SubL src1 src2));
10976 ins_cost(80);
10978 format %{ "sub $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
10979 ins_encode %{
10980 Register dst = $dst$$Register;
10981 Register src1 = $src1$$Register;
10982 __ daddiu(dst, src1, -1 * $src2$$constant);
10983 %}
10984 ins_pipe( ialu_regI_regI );
10985 %}
10987 // Subtract Long Register with Register.
10988 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10989 match(Set dst (SubL src1 src2));
10990 ins_cost(100);
10991 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_Reg" %}
10992 ins_encode %{
10993 Register dst = as_Register($dst$$reg);
10994 Register src1 = as_Register($src1$$reg);
10995 Register src2 = as_Register($src2$$reg);
10997 __ subu(dst, src1, src2);
10998 %}
10999 ins_pipe( ialu_regL_regL );
11000 %}
11002 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
11003 match(Set dst (SubL src1 (ConvI2L src2)));
11004 ins_cost(100);
11005 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
11006 ins_encode %{
11007 Register dst = as_Register($dst$$reg);
11008 Register src1 = as_Register($src1$$reg);
11009 Register src2 = as_Register($src2$$reg);
11011 __ subu(dst, src1, src2);
11012 %}
11013 ins_pipe( ialu_regL_regL );
11014 %}
11016 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
11017 match(Set dst (SubL (ConvI2L src1) src2));
11018 ins_cost(200);
11019 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
11020 ins_encode %{
11021 Register dst = as_Register($dst$$reg);
11022 Register src1 = as_Register($src1$$reg);
11023 Register src2 = as_Register($src2$$reg);
11025 __ subu(dst, src1, src2);
11026 %}
11027 ins_pipe( ialu_regL_regL );
11028 %}
11030 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
11031 match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
11032 ins_cost(200);
11033 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
11034 ins_encode %{
11035 Register dst = as_Register($dst$$reg);
11036 Register src1 = as_Register($src1$$reg);
11037 Register src2 = as_Register($src2$$reg);
11039 __ subu(dst, src1, src2);
11040 %}
11041 ins_pipe( ialu_regL_regL );
11042 %}
11044 // Integer MOD with Register
11045 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11046 match(Set dst (ModI src1 src2));
11047 ins_cost(300);
11048 format %{ "modi $dst, $src1, $src2 @ modI_Reg_Reg" %}
11049 ins_encode %{
11050 Register dst = $dst$$Register;
11051 Register src1 = $src1$$Register;
11052 Register src2 = $src2$$Register;
11054 //if (UseLoongsonISA) {
11055 if (0) {
11056 // 2016.08.10
11057 // Experiments show that gsmod is slower that div+mfhi.
11058 // So I just disable it here.
11059 __ gsmod(dst, src1, src2);
11060 } else {
11061 __ div(src1, src2);
11062 __ mfhi(dst);
11063 }
11064 %}
11066 //ins_pipe( ialu_mod );
11067 ins_pipe( ialu_regI_regI );
11068 %}
11070 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11071 match(Set dst (ModL src1 src2));
11072 format %{ "modL $dst, $src1, $src2 @modL_reg_reg" %}
11074 ins_encode %{
11075 Register dst = as_Register($dst$$reg);
11076 Register op1 = as_Register($src1$$reg);
11077 Register op2 = as_Register($src2$$reg);
11079 if (UseLoongsonISA) {
11080 __ gsdmod(dst, op1, op2);
11081 } else {
11082 __ ddiv(op1, op2);
11083 __ mfhi(dst);
11084 }
11085 %}
11086 ins_pipe( pipe_slow );
11087 %}
11089 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11090 match(Set dst (MulI src1 src2));
11092 ins_cost(300);
11093 format %{ "mul $dst, $src1, $src2 @ mulI_Reg_Reg" %}
11094 ins_encode %{
11095 Register src1 = $src1$$Register;
11096 Register src2 = $src2$$Register;
11097 Register dst = $dst$$Register;
11099 __ mul(dst, src1, src2);
11100 %}
11101 ins_pipe( ialu_mult );
11102 %}
11104 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
11105 match(Set dst (AddI (MulI src1 src2) src3));
11107 ins_cost(999);
11108 format %{ "madd $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
11109 ins_encode %{
11110 Register src1 = $src1$$Register;
11111 Register src2 = $src2$$Register;
11112 Register src3 = $src3$$Register;
11113 Register dst = $dst$$Register;
11115 __ mtlo(src3);
11116 __ madd(src1, src2);
11117 __ mflo(dst);
11118 %}
11119 ins_pipe( ialu_mult );
11120 %}
11122 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11123 match(Set dst (DivI src1 src2));
11125 ins_cost(300);
11126 format %{ "div $dst, $src1, $src2 @ divI_Reg_Reg" %}
11127 ins_encode %{
11128 Register src1 = $src1$$Register;
11129 Register src2 = $src2$$Register;
11130 Register dst = $dst$$Register;
11132 /* 2012/4/21 Jin: In MIPS, div does not cause exception.
11133 We must trap an exception manually. */
11134 __ teq(R0, src2, 0x7);
11136 if (UseLoongsonISA) {
11137 __ gsdiv(dst, src1, src2);
11138 } else {
11139 __ div(src1, src2);
11141 __ nop();
11142 __ nop();
11143 __ mflo(dst);
11144 }
11145 %}
11146 ins_pipe( ialu_mod );
11147 %}
11149 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
11150 match(Set dst (DivF src1 src2));
11152 ins_cost(300);
11153 format %{ "divF $dst, $src1, $src2 @ divF_Reg_Reg" %}
11154 ins_encode %{
11155 FloatRegister src1 = $src1$$FloatRegister;
11156 FloatRegister src2 = $src2$$FloatRegister;
11157 FloatRegister dst = $dst$$FloatRegister;
11159 /* Here do we need to trap an exception manually ? */
11160 __ div_s(dst, src1, src2);
11161 %}
11162 ins_pipe( pipe_slow );
11163 %}
11165 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
11166 match(Set dst (DivD src1 src2));
11168 ins_cost(300);
11169 format %{ "divD $dst, $src1, $src2 @ divD_Reg_Reg" %}
11170 ins_encode %{
11171 FloatRegister src1 = $src1$$FloatRegister;
11172 FloatRegister src2 = $src2$$FloatRegister;
11173 FloatRegister dst = $dst$$FloatRegister;
11175 /* Here do we need to trap an exception manually ? */
11176 __ div_d(dst, src1, src2);
11177 %}
11178 ins_pipe( pipe_slow );
11179 %}
11181 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11182 match(Set dst (MulL src1 src2));
11183 format %{ "mulL $dst, $src1, $src2 @mulL_reg_reg" %}
11184 ins_encode %{
11185 Register dst = as_Register($dst$$reg);
11186 Register op1 = as_Register($src1$$reg);
11187 Register op2 = as_Register($src2$$reg);
11189 if (UseLoongsonISA) {
11190 __ gsdmult(dst, op1, op2);
11191 } else {
11192 __ dmult(op1, op2);
11193 __ mflo(dst);
11194 }
11195 %}
11196 ins_pipe( pipe_slow );
11197 %}
11199 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
11200 match(Set dst (MulL src1 (ConvI2L src2)));
11201 format %{ "mulL $dst, $src1, $src2 @mulL_reg_regI2L" %}
11202 ins_encode %{
11203 Register dst = as_Register($dst$$reg);
11204 Register op1 = as_Register($src1$$reg);
11205 Register op2 = as_Register($src2$$reg);
11207 if (UseLoongsonISA) {
11208 __ gsdmult(dst, op1, op2);
11209 } else {
11210 __ dmult(op1, op2);
11211 __ mflo(dst);
11212 }
11213 %}
11214 ins_pipe( pipe_slow );
11215 %}
11217 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
11218 match(Set dst (DivL src1 src2));
11219 format %{ "divL $dst, $src1, $src2 @divL_reg_reg" %}
11221 ins_encode %{
11222 Register dst = as_Register($dst$$reg);
11223 Register op1 = as_Register($src1$$reg);
11224 Register op2 = as_Register($src2$$reg);
11226 if (UseLoongsonISA) {
11227 __ gsddiv(dst, op1, op2);
11228 } else {
11229 __ ddiv(op1, op2);
11230 __ mflo(dst);
11231 }
11232 %}
11233 ins_pipe( pipe_slow );
11234 %}
11236 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
11237 match(Set dst (AddF src1 src2));
11238 format %{ "AddF $dst, $src1, $src2 @addF_reg_reg" %}
11239 ins_encode %{
11240 FloatRegister src1 = as_FloatRegister($src1$$reg);
11241 FloatRegister src2 = as_FloatRegister($src2$$reg);
11242 FloatRegister dst = as_FloatRegister($dst$$reg);
11244 __ add_s(dst, src1, src2);
11245 %}
11246 ins_pipe( fpu_regF_regF );
11247 %}
11249 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
11250 match(Set dst (SubF src1 src2));
11251 format %{ "SubF $dst, $src1, $src2 @subF_reg_reg" %}
11252 ins_encode %{
11253 FloatRegister src1 = as_FloatRegister($src1$$reg);
11254 FloatRegister src2 = as_FloatRegister($src2$$reg);
11255 FloatRegister dst = as_FloatRegister($dst$$reg);
11257 __ sub_s(dst, src1, src2);
11258 %}
11259 ins_pipe( fpu_regF_regF );
11260 %}
11261 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
11262 match(Set dst (AddD src1 src2));
11263 format %{ "AddD $dst, $src1, $src2 @addD_reg_reg" %}
11264 ins_encode %{
11265 FloatRegister src1 = as_FloatRegister($src1$$reg);
11266 FloatRegister src2 = as_FloatRegister($src2$$reg);
11267 FloatRegister dst = as_FloatRegister($dst$$reg);
11269 __ add_d(dst, src1, src2);
11270 %}
11271 ins_pipe( fpu_regF_regF );
11272 %}
11274 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
11275 match(Set dst (SubD src1 src2));
11276 format %{ "SubD $dst, $src1, $src2 @subD_reg_reg" %}
11277 ins_encode %{
11278 FloatRegister src1 = as_FloatRegister($src1$$reg);
11279 FloatRegister src2 = as_FloatRegister($src2$$reg);
11280 FloatRegister dst = as_FloatRegister($dst$$reg);
11282 __ sub_d(dst, src1, src2);
11283 %}
11284 ins_pipe( fpu_regF_regF );
11285 %}
11287 instruct negF_reg(regF dst, regF src) %{
11288 match(Set dst (NegF src));
11289 format %{ "negF $dst, $src @negF_reg" %}
11290 ins_encode %{
11291 FloatRegister src = as_FloatRegister($src$$reg);
11292 FloatRegister dst = as_FloatRegister($dst$$reg);
11294 __ neg_s(dst, src);
11295 %}
11296 ins_pipe( fpu_regF_regF );
11297 %}
11299 instruct negD_reg(regD dst, regD src) %{
11300 match(Set dst (NegD src));
11301 format %{ "negD $dst, $src @negD_reg" %}
11302 ins_encode %{
11303 FloatRegister src = as_FloatRegister($src$$reg);
11304 FloatRegister dst = as_FloatRegister($dst$$reg);
11306 __ neg_d(dst, src);
11307 %}
11308 ins_pipe( fpu_regF_regF );
11309 %}
11312 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
11313 match(Set dst (MulF src1 src2));
11314 format %{ "MULF $dst, $src1, $src2 @mulF_reg_reg" %}
11315 ins_encode %{
11316 FloatRegister src1 = $src1$$FloatRegister;
11317 FloatRegister src2 = $src2$$FloatRegister;
11318 FloatRegister dst = $dst$$FloatRegister;
11320 __ mul_s(dst, src1, src2);
11321 %}
11322 ins_pipe( fpu_regF_regF );
11323 %}
11325 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
11326 match(Set dst (AddF (MulF src1 src2) src3));
11327 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
11328 ins_cost(44444);
11329 format %{ "maddF $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
11330 ins_encode %{
11331 FloatRegister src1 = $src1$$FloatRegister;
11332 FloatRegister src2 = $src2$$FloatRegister;
11333 FloatRegister src3 = $src3$$FloatRegister;
11334 FloatRegister dst = $dst$$FloatRegister;
11336 __ madd_s(dst, src1, src2, src3);
11337 %}
11338 ins_pipe( fpu_regF_regF );
11339 %}
11341 // Mul two double precision floating piont number
11342 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
11343 match(Set dst (MulD src1 src2));
11344 format %{ "MULD $dst, $src1, $src2 @mulD_reg_reg" %}
11345 ins_encode %{
11346 FloatRegister src1 = $src1$$FloatRegister;
11347 FloatRegister src2 = $src2$$FloatRegister;
11348 FloatRegister dst = $dst$$FloatRegister;
11350 __ mul_d(dst, src1, src2);
11351 %}
11352 ins_pipe( fpu_regF_regF );
11353 %}
11355 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
11356 match(Set dst (AddD (MulD src1 src2) src3));
11357 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
11358 ins_cost(44444);
11359 format %{ "maddD $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
11360 ins_encode %{
11361 FloatRegister src1 = $src1$$FloatRegister;
11362 FloatRegister src2 = $src2$$FloatRegister;
11363 FloatRegister src3 = $src3$$FloatRegister;
11364 FloatRegister dst = $dst$$FloatRegister;
11366 __ madd_d(dst, src1, src2, src3);
11367 %}
11368 ins_pipe( fpu_regF_regF );
11369 %}
11371 instruct absF_reg(regF dst, regF src) %{
11372 match(Set dst (AbsF src));
11373 ins_cost(100);
11374 format %{ "absF $dst, $src @absF_reg" %}
11375 ins_encode %{
11376 FloatRegister src = as_FloatRegister($src$$reg);
11377 FloatRegister dst = as_FloatRegister($dst$$reg);
11379 __ abs_s(dst, src);
11380 %}
11381 ins_pipe( fpu_regF_regF );
11382 %}
11385 // intrinsics for math_native.
11386 // AbsD SqrtD CosD SinD TanD LogD Log10D
11388 instruct absD_reg(regD dst, regD src) %{
11389 match(Set dst (AbsD src));
11390 ins_cost(100);
11391 format %{ "absD $dst, $src @absD_reg" %}
11392 ins_encode %{
11393 FloatRegister src = as_FloatRegister($src$$reg);
11394 FloatRegister dst = as_FloatRegister($dst$$reg);
11396 __ abs_d(dst, src);
11397 %}
11398 ins_pipe( fpu_regF_regF );
11399 %}
11401 instruct sqrtD_reg(regD dst, regD src) %{
11402 match(Set dst (SqrtD src));
11403 ins_cost(100);
11404 format %{ "SqrtD $dst, $src @sqrtD_reg" %}
11405 ins_encode %{
11406 FloatRegister src = as_FloatRegister($src$$reg);
11407 FloatRegister dst = as_FloatRegister($dst$$reg);
11409 __ sqrt_d(dst, src);
11410 %}
11411 ins_pipe( fpu_regF_regF );
11412 %}
11414 instruct sqrtF_reg(regF dst, regF src) %{
11415 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
11416 ins_cost(100);
11417 format %{ "SqrtF $dst, $src @sqrtF_reg" %}
11418 ins_encode %{
11419 FloatRegister src = as_FloatRegister($src$$reg);
11420 FloatRegister dst = as_FloatRegister($dst$$reg);
11422 __ sqrt_s(dst, src);
11423 %}
11424 ins_pipe( fpu_regF_regF );
11425 %}
11426 //----------------------------------Logical Instructions----------------------
11427 //__________________________________Integer Logical Instructions-------------
11429 //And Instuctions
11430 // And Register with Immediate
11431 instruct andI_Reg_immI(mRegI dst, mRegI src1, immI src2) %{
11432 match(Set dst (AndI src1 src2));
11434 format %{ "and $dst, $src1, $src2 #@andI_Reg_immI" %}
11435 ins_encode %{
11436 Register dst = $dst$$Register;
11437 Register src = $src1$$Register;
11438 int val = $src2$$constant;
11440 __ move(AT, val);
11441 __ andr(dst, src, AT);
11442 %}
11443 ins_pipe( ialu_regI_regI );
11444 %}
11446 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
11447 match(Set dst (AndI src1 src2));
11448 ins_cost(60);
11450 format %{ "and $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
11451 ins_encode %{
11452 Register dst = $dst$$Register;
11453 Register src = $src1$$Register;
11454 int val = $src2$$constant;
11456 __ andi(dst, src, val);
11457 %}
11458 ins_pipe( ialu_regI_regI );
11459 %}
11461 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1, immI_nonneg_mask mask) %{
11462 match(Set dst (AndI src1 mask));
11463 ins_cost(60);
11465 format %{ "and $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
11466 ins_encode %{
11467 Register dst = $dst$$Register;
11468 Register src = $src1$$Register;
11469 int size = Assembler::is_int_mask($mask$$constant);
11471 __ ext(dst, src, 0, size);
11472 %}
11473 ins_pipe( ialu_regI_regI );
11474 %}
11476 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1, immL_nonneg_mask mask) %{
11477 match(Set dst (AndL src1 mask));
11478 ins_cost(60);
11480 format %{ "and $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
11481 ins_encode %{
11482 Register dst = $dst$$Register;
11483 Register src = $src1$$Register;
11484 int size = Assembler::is_jlong_mask($mask$$constant);
11486 __ dext(dst, src, 0, size);
11487 %}
11488 ins_pipe( ialu_regI_regI );
11489 %}
11491 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
11492 match(Set dst (XorI src1 src2));
11493 ins_cost(60);
11495 format %{ "xori $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
11496 ins_encode %{
11497 Register dst = $dst$$Register;
11498 Register src = $src1$$Register;
11499 int val = $src2$$constant;
11501 __ xori(dst, src, val);
11502 %}
11503 ins_pipe( ialu_regI_regI );
11504 %}
11506 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1, immI_M1 M1) %{
11507 match(Set dst (XorI src1 M1));
11508 predicate(UseLoongsonISA && Use3A2000);
11509 ins_cost(60);
11511 format %{ "xor $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
11512 ins_encode %{
11513 Register dst = $dst$$Register;
11514 Register src = $src1$$Register;
11516 __ gsorn(dst, R0, src);
11517 %}
11518 ins_pipe( ialu_regI_regI );
11519 %}
11521 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1, immI_M1 M1) %{
11522 match(Set dst (XorI (ConvL2I src1) M1));
11523 predicate(UseLoongsonISA && Use3A2000);
11524 ins_cost(60);
11526 format %{ "xor $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
11527 ins_encode %{
11528 Register dst = $dst$$Register;
11529 Register src = $src1$$Register;
11531 __ gsorn(dst, R0, src);
11532 %}
11533 ins_pipe( ialu_regI_regI );
11534 %}
11536 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
11537 match(Set dst (XorL src1 src2));
11538 ins_cost(60);
11540 format %{ "xori $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
11541 ins_encode %{
11542 Register dst = $dst$$Register;
11543 Register src = $src1$$Register;
11544 int val = $src2$$constant;
11546 __ xori(dst, src, val);
11547 %}
11548 ins_pipe( ialu_regI_regI );
11549 %}
11551 /*
11552 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1, immL_M1 M1) %{
11553 match(Set dst (XorL src1 M1));
11554 predicate(UseLoongsonISA);
11555 ins_cost(60);
11557 format %{ "xor $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
11558 ins_encode %{
11559 Register dst = $dst$$Register;
11560 Register src = $src1$$Register;
11562 __ gsorn(dst, R0, src);
11563 %}
11564 ins_pipe( ialu_regI_regI );
11565 %}
11566 */
11568 instruct lbu_and_lmask(mRegI dst, memory mem, immI_255 mask) %{
11569 match(Set dst (AndI mask (LoadB mem)));
11570 ins_cost(60);
11572 format %{ "lhu $dst, $mem #@lbu_and_lmask" %}
11573 ins_encode(load_UB_enc(dst, mem));
11574 ins_pipe( ialu_loadI );
11575 %}
11577 instruct lbu_and_rmask(mRegI dst, memory mem, immI_255 mask) %{
11578 match(Set dst (AndI (LoadB mem) mask));
11579 ins_cost(60);
11581 format %{ "lhu $dst, $mem #@lbu_and_rmask" %}
11582 ins_encode(load_UB_enc(dst, mem));
11583 ins_pipe( ialu_loadI );
11584 %}
11586 instruct andI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11587 match(Set dst (AndI src1 src2));
11589 format %{ "and $dst, $src1, $src2 #@andI_Reg_Reg" %}
11590 ins_encode %{
11591 Register dst = $dst$$Register;
11592 Register src1 = $src1$$Register;
11593 Register src2 = $src2$$Register;
11594 __ andr(dst, src1, src2);
11595 %}
11596 ins_pipe( ialu_regI_regI );
11597 %}
11599 instruct andnI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11600 match(Set dst (AndI src1 (XorI src2 M1)));
11601 predicate(UseLoongsonISA && Use3A2000);
11603 format %{ "andn $dst, $src1, $src2 #@andnI_Reg_nReg" %}
11604 ins_encode %{
11605 Register dst = $dst$$Register;
11606 Register src1 = $src1$$Register;
11607 Register src2 = $src2$$Register;
11609 __ gsandn(dst, src1, src2);
11610 %}
11611 ins_pipe( ialu_regI_regI );
11612 %}
11614 instruct ornI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11615 match(Set dst (OrI src1 (XorI src2 M1)));
11616 predicate(UseLoongsonISA && Use3A2000);
11618 format %{ "orn $dst, $src1, $src2 #@ornI_Reg_nReg" %}
11619 ins_encode %{
11620 Register dst = $dst$$Register;
11621 Register src1 = $src1$$Register;
11622 Register src2 = $src2$$Register;
11624 __ gsorn(dst, src1, src2);
11625 %}
11626 ins_pipe( ialu_regI_regI );
11627 %}
11629 instruct andnI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11630 match(Set dst (AndI (XorI src1 M1) src2));
11631 predicate(UseLoongsonISA && Use3A2000);
11633 format %{ "andn $dst, $src2, $src1 #@andnI_nReg_Reg" %}
11634 ins_encode %{
11635 Register dst = $dst$$Register;
11636 Register src1 = $src1$$Register;
11637 Register src2 = $src2$$Register;
11639 __ gsandn(dst, src2, src1);
11640 %}
11641 ins_pipe( ialu_regI_regI );
11642 %}
11644 instruct ornI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
11645 match(Set dst (OrI (XorI src1 M1) src2));
11646 predicate(UseLoongsonISA && Use3A2000);
11648 format %{ "orn $dst, $src2, $src1 #@ornI_nReg_Reg" %}
11649 ins_encode %{
11650 Register dst = $dst$$Register;
11651 Register src1 = $src1$$Register;
11652 Register src2 = $src2$$Register;
11654 __ gsorn(dst, src2, src1);
11655 %}
11656 ins_pipe( ialu_regI_regI );
11657 %}
11659 // And Long Register with Register
11660 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11661 match(Set dst (AndL src1 src2));
11662 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
11663 ins_encode %{
11664 Register dst_reg = as_Register($dst$$reg);
11665 Register src1_reg = as_Register($src1$$reg);
11666 Register src2_reg = as_Register($src2$$reg);
11668 __ andr(dst_reg, src1_reg, src2_reg);
11669 %}
11670 ins_pipe( ialu_regL_regL );
11671 %}
11673 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
11674 match(Set dst (AndL src1 (ConvI2L src2)));
11675 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
11676 ins_encode %{
11677 Register dst_reg = as_Register($dst$$reg);
11678 Register src1_reg = as_Register($src1$$reg);
11679 Register src2_reg = as_Register($src2$$reg);
11681 __ andr(dst_reg, src1_reg, src2_reg);
11682 %}
11683 ins_pipe( ialu_regL_regL );
11684 %}
11686 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
11687 match(Set dst (AndL src1 src2));
11688 ins_cost(60);
11690 format %{ "and $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
11691 ins_encode %{
11692 Register dst = $dst$$Register;
11693 Register src = $src1$$Register;
11694 long val = $src2$$constant;
11696 __ andi(dst, src, val);
11697 %}
11698 ins_pipe( ialu_regI_regI );
11699 %}
11701 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1, immL_0_65535 src2) %{
11702 match(Set dst (ConvL2I (AndL src1 src2)));
11703 ins_cost(60);
11705 format %{ "and $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
11706 ins_encode %{
11707 Register dst = $dst$$Register;
11708 Register src = $src1$$Register;
11709 long val = $src2$$constant;
11711 __ andi(dst, src, val);
11712 %}
11713 ins_pipe( ialu_regI_regI );
11714 %}
11716 /*
11717 instruct andnL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11718 match(Set dst (AndL src1 (XorL src2 M1)));
11719 predicate(UseLoongsonISA);
11721 format %{ "andn $dst, $src1, $src2 #@andnL_Reg_nReg" %}
11722 ins_encode %{
11723 Register dst = $dst$$Register;
11724 Register src1 = $src1$$Register;
11725 Register src2 = $src2$$Register;
11727 __ gsandn(dst, src1, src2);
11728 %}
11729 ins_pipe( ialu_regI_regI );
11730 %}
11731 */
11733 /*
11734 instruct ornL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11735 match(Set dst (OrL src1 (XorL src2 M1)));
11736 predicate(UseLoongsonISA);
11738 format %{ "orn $dst, $src1, $src2 #@ornL_Reg_nReg" %}
11739 ins_encode %{
11740 Register dst = $dst$$Register;
11741 Register src1 = $src1$$Register;
11742 Register src2 = $src2$$Register;
11744 __ gsorn(dst, src1, src2);
11745 %}
11746 ins_pipe( ialu_regI_regI );
11747 %}
11748 */
11750 /*
11751 instruct andnL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11752 match(Set dst (AndL (XorL src1 M1) src2));
11753 predicate(UseLoongsonISA);
11755 format %{ "andn $dst, $src2, $src1 #@andnL_nReg_Reg" %}
11756 ins_encode %{
11757 Register dst = $dst$$Register;
11758 Register src1 = $src1$$Register;
11759 Register src2 = $src2$$Register;
11761 __ gsandn(dst, src2, src1);
11762 %}
11763 ins_pipe( ialu_regI_regI );
11764 %}
11765 */
11767 /*
11768 instruct ornL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
11769 match(Set dst (OrL (XorL src1 M1) src2));
11770 predicate(UseLoongsonISA);
11772 format %{ "orn $dst, $src2, $src1 #@ornL_nReg_Reg" %}
11773 ins_encode %{
11774 Register dst = $dst$$Register;
11775 Register src1 = $src1$$Register;
11776 Register src2 = $src2$$Register;
11778 __ gsorn(dst, src2, src1);
11779 %}
11780 ins_pipe( ialu_regI_regI );
11781 %}
11782 */
11784 instruct andL_Reg_immL_M8(mRegL dst, immL_M8 M8) %{
11785 match(Set dst (AndL dst M8));
11786 ins_cost(60);
11788 format %{ "and $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
11789 ins_encode %{
11790 Register dst = $dst$$Register;
11792 __ dins(dst, R0, 0, 3);
11793 %}
11794 ins_pipe( ialu_regI_regI );
11795 %}
11797 instruct andL_Reg_immL_M5(mRegL dst, immL_M5 M5) %{
11798 match(Set dst (AndL dst M5));
11799 ins_cost(60);
11801 format %{ "and $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
11802 ins_encode %{
11803 Register dst = $dst$$Register;
11805 __ dins(dst, R0, 2, 1);
11806 %}
11807 ins_pipe( ialu_regI_regI );
11808 %}
11810 instruct andL_Reg_immL_M7(mRegL dst, immL_M7 M7) %{
11811 match(Set dst (AndL dst M7));
11812 ins_cost(60);
11814 format %{ "and $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
11815 ins_encode %{
11816 Register dst = $dst$$Register;
11818 __ dins(dst, R0, 1, 2);
11819 %}
11820 ins_pipe( ialu_regI_regI );
11821 %}
11823 instruct andL_Reg_immL_M4(mRegL dst, immL_M4 M4) %{
11824 match(Set dst (AndL dst M4));
11825 ins_cost(60);
11827 format %{ "and $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
11828 ins_encode %{
11829 Register dst = $dst$$Register;
11831 __ dins(dst, R0, 0, 2);
11832 %}
11833 ins_pipe( ialu_regI_regI );
11834 %}
11836 instruct andL_Reg_immL_M121(mRegL dst, immL_M121 M121) %{
11837 match(Set dst (AndL dst M121));
11838 ins_cost(60);
11840 format %{ "and $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
11841 ins_encode %{
11842 Register dst = $dst$$Register;
11844 __ dins(dst, R0, 3, 4);
11845 %}
11846 ins_pipe( ialu_regI_regI );
11847 %}
11849 // Or Long Register with Register
11850 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11851 match(Set dst (OrL src1 src2));
11852 format %{ "OR $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
11853 ins_encode %{
11854 Register dst_reg = $dst$$Register;
11855 Register src1_reg = $src1$$Register;
11856 Register src2_reg = $src2$$Register;
11858 __ orr(dst_reg, src1_reg, src2_reg);
11859 %}
11860 ins_pipe( ialu_regL_regL );
11861 %}
11863 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
11864 match(Set dst (OrL (CastP2X src1) src2));
11865 format %{ "OR $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
11866 ins_encode %{
11867 Register dst_reg = $dst$$Register;
11868 Register src1_reg = $src1$$Register;
11869 Register src2_reg = $src2$$Register;
11871 __ orr(dst_reg, src1_reg, src2_reg);
11872 %}
11873 ins_pipe( ialu_regL_regL );
11874 %}
11876 // Xor Long Register with Register
11877 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
11878 match(Set dst (XorL src1 src2));
11879 format %{ "XOR $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
11880 ins_encode %{
11881 Register dst_reg = as_Register($dst$$reg);
11882 Register src1_reg = as_Register($src1$$reg);
11883 Register src2_reg = as_Register($src2$$reg);
11885 __ xorr(dst_reg, src1_reg, src2_reg);
11886 %}
11887 ins_pipe( ialu_regL_regL );
11888 %}
11890 // Shift Left by 8-bit immediate
11891 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
11892 match(Set dst (LShiftI src shift));
11894 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm" %}
11895 ins_encode %{
11896 Register src = $src$$Register;
11897 Register dst = $dst$$Register;
11898 int shamt = $shift$$constant;
11900 __ sll(dst, src, shamt);
11901 %}
11902 ins_pipe( ialu_regI_regI );
11903 %}
11905 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
11906 match(Set dst (LShiftI (ConvL2I src) shift));
11908 format %{ "SHL $dst, $src, $shift #@salL2I_Reg_imm" %}
11909 ins_encode %{
11910 Register src = $src$$Register;
11911 Register dst = $dst$$Register;
11912 int shamt = $shift$$constant;
11914 __ sll(dst, src, shamt);
11915 %}
11916 ins_pipe( ialu_regI_regI );
11917 %}
11919 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
11920 match(Set dst (AndI (LShiftI src shift) mask));
11922 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
11923 ins_encode %{
11924 Register src = $src$$Register;
11925 Register dst = $dst$$Register;
11927 __ sll(dst, src, 16);
11928 %}
11929 ins_pipe( ialu_regI_regI );
11930 %}
11932 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
11933 %{
11934 match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
11936 format %{ "andi $dst, $src, 7\t# @land7_2_s" %}
11937 ins_encode %{
11938 Register src = $src$$Register;
11939 Register dst = $dst$$Register;
11941 __ andi(dst, src, 7);
11942 %}
11943 ins_pipe(ialu_regI_regI);
11944 %}
11946 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
11947 %{
11948 match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
11950 format %{ "ori $dst, $src1, $src2\t# @ori2s" %}
11951 ins_encode %{
11952 Register src = $src1$$Register;
11953 int val = $src2$$constant;
11954 Register dst = $dst$$Register;
11956 __ ori(dst, src, val);
11957 %}
11958 ins_pipe(ialu_regI_regI);
11959 %}
11961 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
11962 // This idiom is used by the compiler the i2s bytecode.
11963 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
11964 %{
11965 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
11967 format %{ "i2s $dst, $src\t# @i2s" %}
11968 ins_encode %{
11969 Register src = $src$$Register;
11970 Register dst = $dst$$Register;
11972 __ seh(dst, src);
11973 %}
11974 ins_pipe(ialu_regI_regI);
11975 %}
11977 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
11978 // This idiom is used by the compiler for the i2b bytecode.
11979 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
11980 %{
11981 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
11983 format %{ "i2b $dst, $src\t# @i2b" %}
11984 ins_encode %{
11985 Register src = $src$$Register;
11986 Register dst = $dst$$Register;
11988 __ seb(dst, src);
11989 %}
11990 ins_pipe(ialu_regI_regI);
11991 %}
11994 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
11995 match(Set dst (LShiftI (ConvL2I src) shift));
11997 format %{ "SHL $dst, $src, $shift #@salI_RegL2I_imm" %}
11998 ins_encode %{
11999 Register src = $src$$Register;
12000 Register dst = $dst$$Register;
12001 int shamt = $shift$$constant;
12003 __ sll(dst, src, shamt);
12004 %}
12005 ins_pipe( ialu_regI_regI );
12006 %}
12008 // Shift Left by 8-bit immediate
12009 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12010 match(Set dst (LShiftI src shift));
12012 format %{ "SHL $dst, $src, $shift #@salI_Reg_Reg" %}
12013 ins_encode %{
12014 Register src = $src$$Register;
12015 Register dst = $dst$$Register;
12016 Register shamt = $shift$$Register;
12017 __ sllv(dst, src, shamt);
12018 %}
12019 ins_pipe( ialu_regI_regI );
12020 %}
12023 // Shift Left Long
12024 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
12025 //predicate(UseNewLongLShift);
12026 match(Set dst (LShiftL src shift));
12027 ins_cost(100);
12028 format %{ "salL $dst, $src, $shift @ salL_Reg_imm" %}
12029 ins_encode %{
12030 Register src_reg = as_Register($src$$reg);
12031 Register dst_reg = as_Register($dst$$reg);
12032 int shamt = $shift$$constant;
12034 if (__ is_simm(shamt, 5))
12035 __ dsll(dst_reg, src_reg, shamt);
12036 else {
12037 int sa = Assembler::low(shamt, 6);
12038 if (sa < 32) {
12039 __ dsll(dst_reg, src_reg, sa);
12040 } else {
12041 __ dsll32(dst_reg, src_reg, sa - 32);
12042 }
12043 }
12044 %}
12045 ins_pipe( ialu_regL_regL );
12046 %}
12048 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
12049 //predicate(UseNewLongLShift);
12050 match(Set dst (LShiftL (ConvI2L src) shift));
12051 ins_cost(100);
12052 format %{ "salL $dst, $src, $shift @ salL_RegI2L_imm" %}
12053 ins_encode %{
12054 Register src_reg = as_Register($src$$reg);
12055 Register dst_reg = as_Register($dst$$reg);
12056 int shamt = $shift$$constant;
12058 if (__ is_simm(shamt, 5))
12059 __ dsll(dst_reg, src_reg, shamt);
12060 else {
12061 int sa = Assembler::low(shamt, 6);
12062 if (sa < 32) {
12063 __ dsll(dst_reg, src_reg, sa);
12064 } else {
12065 __ dsll32(dst_reg, src_reg, sa - 32);
12066 }
12067 }
12068 %}
12069 ins_pipe( ialu_regL_regL );
12070 %}
12072 // Shift Left Long
12073 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12074 //predicate(UseNewLongLShift);
12075 match(Set dst (LShiftL src shift));
12076 ins_cost(100);
12077 format %{ "salL $dst, $src, $shift @ salL_Reg_Reg" %}
12078 ins_encode %{
12079 Register src_reg = as_Register($src$$reg);
12080 Register dst_reg = as_Register($dst$$reg);
12082 __ dsllv(dst_reg, src_reg, $shift$$Register);
12083 %}
12084 ins_pipe( ialu_regL_regL );
12085 %}
12087 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
12088 match(Set dst (LShiftL (ConvI2L src) shift));
12089 ins_cost(100);
12090 format %{ "salL $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
12091 ins_encode %{
12092 Register src_reg = as_Register($src$$reg);
12093 Register dst_reg = as_Register($dst$$reg);
12094 int shamt = $shift$$constant;
12096 if (__ is_simm(shamt, 5)) {
12097 __ dsll(dst_reg, src_reg, shamt);
12098 } else {
12099 int sa = Assembler::low(shamt, 6);
12100 if (sa < 32) {
12101 __ dsll(dst_reg, src_reg, sa);
12102 } else {
12103 __ dsll32(dst_reg, src_reg, sa - 32);
12104 }
12105 }
12106 %}
12107 ins_pipe( ialu_regL_regL );
12108 %}
12110 // Shift Right Long
12111 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
12112 match(Set dst (RShiftL src shift));
12113 ins_cost(100);
12114 format %{ "sarL $dst, $src, $shift @ sarL_Reg_imm" %}
12115 ins_encode %{
12116 Register src_reg = as_Register($src$$reg);
12117 Register dst_reg = as_Register($dst$$reg);
12118 int shamt = ($shift$$constant & 0x3f);
12119 if (__ is_simm(shamt, 5))
12120 __ dsra(dst_reg, src_reg, shamt);
12121 else {
12122 int sa = Assembler::low(shamt, 6);
12123 if (sa < 32) {
12124 __ dsra(dst_reg, src_reg, sa);
12125 } else {
12126 __ dsra32(dst_reg, src_reg, sa - 32);
12127 }
12128 }
12129 %}
12130 ins_pipe( ialu_regL_regL );
12131 %}
12133 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
12134 match(Set dst (ConvL2I (RShiftL src shift)));
12135 ins_cost(100);
12136 format %{ "sarL $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
12137 ins_encode %{
12138 Register src_reg = as_Register($src$$reg);
12139 Register dst_reg = as_Register($dst$$reg);
12140 int shamt = $shift$$constant;
12142 __ dsra32(dst_reg, src_reg, shamt - 32);
12143 %}
12144 ins_pipe( ialu_regL_regL );
12145 %}
12147 // Shift Right Long arithmetically
12148 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12149 //predicate(UseNewLongLShift);
12150 match(Set dst (RShiftL src shift));
12151 ins_cost(100);
12152 format %{ "sarL $dst, $src, $shift @ sarL_Reg_Reg" %}
12153 ins_encode %{
12154 Register src_reg = as_Register($src$$reg);
12155 Register dst_reg = as_Register($dst$$reg);
12157 __ dsrav(dst_reg, src_reg, $shift$$Register);
12158 %}
12159 ins_pipe( ialu_regL_regL );
12160 %}
12162 // Shift Right Long logically
12163 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
12164 match(Set dst (URShiftL src shift));
12165 ins_cost(100);
12166 format %{ "slrL $dst, $src, $shift @ slrL_Reg_Reg" %}
12167 ins_encode %{
12168 Register src_reg = as_Register($src$$reg);
12169 Register dst_reg = as_Register($dst$$reg);
12171 __ dsrlv(dst_reg, src_reg, $shift$$Register);
12172 %}
12173 ins_pipe( ialu_regL_regL );
12174 %}
12176 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
12177 match(Set dst (URShiftL src shift));
12178 ins_cost(80);
12179 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
12180 ins_encode %{
12181 Register src_reg = as_Register($src$$reg);
12182 Register dst_reg = as_Register($dst$$reg);
12183 int shamt = $shift$$constant;
12185 __ dsrl(dst_reg, src_reg, shamt);
12186 %}
12187 ins_pipe( ialu_regL_regL );
12188 %}
12190 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
12191 match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
12192 ins_cost(80);
12193 format %{ "dext $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
12194 ins_encode %{
12195 Register src_reg = as_Register($src$$reg);
12196 Register dst_reg = as_Register($dst$$reg);
12197 int shamt = $shift$$constant;
12199 __ dext(dst_reg, src_reg, shamt, 31);
12200 %}
12201 ins_pipe( ialu_regL_regL );
12202 %}
12204 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
12205 match(Set dst (URShiftL (CastP2X src) shift));
12206 ins_cost(80);
12207 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
12208 ins_encode %{
12209 Register src_reg = as_Register($src$$reg);
12210 Register dst_reg = as_Register($dst$$reg);
12211 int shamt = $shift$$constant;
12213 __ dsrl(dst_reg, src_reg, shamt);
12214 %}
12215 ins_pipe( ialu_regL_regL );
12216 %}
12218 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
12219 match(Set dst (URShiftL src shift));
12220 ins_cost(80);
12221 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
12222 ins_encode %{
12223 Register src_reg = as_Register($src$$reg);
12224 Register dst_reg = as_Register($dst$$reg);
12225 int shamt = $shift$$constant;
12227 __ dsrl32(dst_reg, src_reg, shamt - 32);
12228 %}
12229 ins_pipe( ialu_regL_regL );
12230 %}
12232 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
12233 match(Set dst (ConvL2I (URShiftL src shift)));
12234 predicate(n->in(1)->in(2)->get_int() > 32);
12235 ins_cost(80);
12236 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
12237 ins_encode %{
12238 Register src_reg = as_Register($src$$reg);
12239 Register dst_reg = as_Register($dst$$reg);
12240 int shamt = $shift$$constant;
12242 __ dsrl32(dst_reg, src_reg, shamt - 32);
12243 %}
12244 ins_pipe( ialu_regL_regL );
12245 %}
12247 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
12248 match(Set dst (URShiftL (CastP2X src) shift));
12249 ins_cost(80);
12250 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
12251 ins_encode %{
12252 Register src_reg = as_Register($src$$reg);
12253 Register dst_reg = as_Register($dst$$reg);
12254 int shamt = $shift$$constant;
12256 __ dsrl32(dst_reg, src_reg, shamt - 32);
12257 %}
12258 ins_pipe( ialu_regL_regL );
12259 %}
12261 // Xor Instructions
12262 // Xor Register with Register
12263 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
12264 match(Set dst (XorI src1 src2));
12266 format %{ "XOR $dst, $src1, $src2 #@xorI_Reg_Reg" %}
12268 ins_encode %{
12269 Register dst = $dst$$Register;
12270 Register src1 = $src1$$Register;
12271 Register src2 = $src2$$Register;
12272 __ xorr(dst, src1, src2);
12273 __ sll(dst, dst, 0); /* long -> int */
12274 %}
12276 ins_pipe( ialu_regI_regI );
12277 %}
12279 // Or Instructions
12280 // Or Register with Register
12281 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
12282 match(Set dst (OrI src1 src2));
12284 format %{ "OR $dst, $src1, $src2 #@orI_Reg_Reg" %}
12285 ins_encode %{
12286 Register dst = $dst$$Register;
12287 Register src1 = $src1$$Register;
12288 Register src2 = $src2$$Register;
12289 __ orr(dst, src1, src2);
12290 %}
12292 ins_pipe( ialu_regI_regI );
12293 %}
12295 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
12296 match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
12297 predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
12299 format %{ "rotr $dst, $src, 1 ...\n\t"
12300 "srl $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
12301 ins_encode %{
12302 Register dst = $dst$$Register;
12303 Register src = $src$$Register;
12304 int rshift = $rshift$$constant;
12306 __ rotr(dst, src, 1);
12307 if (rshift - 1) {
12308 __ srl(dst, dst, rshift - 1);
12309 }
12310 %}
12312 ins_pipe( ialu_regI_regI );
12313 %}
12315 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
12316 match(Set dst (OrI src1 (CastP2X src2)));
12318 format %{ "OR $dst, $src1, $src2 #@orI_Reg_castP2X" %}
12319 ins_encode %{
12320 Register dst = $dst$$Register;
12321 Register src1 = $src1$$Register;
12322 Register src2 = $src2$$Register;
12323 __ orr(dst, src1, src2);
12324 %}
12326 ins_pipe( ialu_regI_regI );
12327 %}
12329 // Logical Shift Right by 8-bit immediate
12330 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
12331 match(Set dst (URShiftI src shift));
12332 //effect(KILL cr);
12334 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_imm" %}
12335 ins_encode %{
12336 Register src = $src$$Register;
12337 Register dst = $dst$$Register;
12338 int shift = $shift$$constant;
12340 __ srl(dst, src, shift);
12341 %}
12342 ins_pipe( ialu_regI_regI );
12343 %}
12345 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
12346 match(Set dst (AndI (URShiftI src shift) mask));
12348 format %{ "ext $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
12349 ins_encode %{
12350 Register src = $src$$Register;
12351 Register dst = $dst$$Register;
12352 int pos = $shift$$constant;
12353 int size = Assembler::is_int_mask($mask$$constant);
12355 __ ext(dst, src, pos, size);
12356 %}
12357 ins_pipe( ialu_regI_regI );
12358 %}
12360 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
12361 %{
12362 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
12363 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
12365 ins_cost(100);
12366 format %{ "rotr $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
12367 ins_encode %{
12368 Register dst = $dst$$Register;
12369 int sa = $rshift$$constant;
12371 __ rotr(dst, dst, sa);
12372 %}
12373 ins_pipe( ialu_regI_regI );
12374 %}
12376 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
12377 %{
12378 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12379 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
12381 ins_cost(100);
12382 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
12383 ins_encode %{
12384 Register dst = $dst$$Register;
12385 int sa = $rshift$$constant;
12387 __ drotr(dst, dst, sa);
12388 %}
12389 ins_pipe( ialu_regI_regI );
12390 %}
12392 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
12393 %{
12394 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12395 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
12397 ins_cost(100);
12398 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
12399 ins_encode %{
12400 Register dst = $dst$$Register;
12401 int sa = $rshift$$constant;
12403 __ drotr32(dst, dst, sa - 32);
12404 %}
12405 ins_pipe( ialu_regI_regI );
12406 %}
12408 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
12409 %{
12410 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
12411 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
12413 ins_cost(100);
12414 format %{ "rotr $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
12415 ins_encode %{
12416 Register dst = $dst$$Register;
12417 int sa = $rshift$$constant;
12419 __ rotr(dst, dst, sa);
12420 %}
12421 ins_pipe( ialu_regI_regI );
12422 %}
12424 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
12425 %{
12426 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12427 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
12429 ins_cost(100);
12430 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
12431 ins_encode %{
12432 Register dst = $dst$$Register;
12433 int sa = $rshift$$constant;
12435 __ drotr(dst, dst, sa);
12436 %}
12437 ins_pipe( ialu_regI_regI );
12438 %}
12440 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
12441 %{
12442 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
12443 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
12445 ins_cost(100);
12446 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
12447 ins_encode %{
12448 Register dst = $dst$$Register;
12449 int sa = $rshift$$constant;
12451 __ drotr32(dst, dst, sa - 32);
12452 %}
12453 ins_pipe( ialu_regI_regI );
12454 %}
12456 // Logical Shift Right
12457 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12458 match(Set dst (URShiftI src shift));
12460 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_Reg" %}
12461 ins_encode %{
12462 Register src = $src$$Register;
12463 Register dst = $dst$$Register;
12464 Register shift = $shift$$Register;
12465 __ srlv(dst, src, shift);
12466 %}
12467 ins_pipe( ialu_regI_regI );
12468 %}
12471 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
12472 match(Set dst (RShiftI src shift));
12473 // effect(KILL cr);
12475 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_imm" %}
12476 ins_encode %{
12477 Register src = $src$$Register;
12478 Register dst = $dst$$Register;
12479 int shift = $shift$$constant;
12480 __ sra(dst, src, shift);
12481 %}
12482 ins_pipe( ialu_regI_regI );
12483 %}
12485 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
12486 match(Set dst (RShiftI src shift));
12487 // effect(KILL cr);
12489 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_Reg" %}
12490 ins_encode %{
12491 Register src = $src$$Register;
12492 Register dst = $dst$$Register;
12493 Register shift = $shift$$Register;
12494 __ srav(dst, src, shift);
12495 %}
12496 ins_pipe( ialu_regI_regI );
12497 %}
12499 //----------Convert Int to Boolean---------------------------------------------
12501 instruct convI2B(mRegI dst, mRegI src) %{
12502 match(Set dst (Conv2B src));
12504 ins_cost(100);
12505 format %{ "convI2B $dst, $src @ convI2B" %}
12506 ins_encode %{
12507 Register dst = as_Register($dst$$reg);
12508 Register src = as_Register($src$$reg);
12510 if (dst != src) {
12511 __ daddiu(dst, R0, 1);
12512 __ movz(dst, R0, src);
12513 } else {
12514 __ move(AT, src);
12515 __ daddiu(dst, R0, 1);
12516 __ movz(dst, R0, AT);
12517 }
12518 %}
12520 ins_pipe( ialu_regL_regL );
12521 %}
12523 instruct convI2L_reg( mRegL dst, mRegI src) %{
12524 match(Set dst (ConvI2L src));
12526 ins_cost(100);
12527 format %{ "SLL $dst, $src @ convI2L_reg\t" %}
12528 ins_encode %{
12529 Register dst = as_Register($dst$$reg);
12530 Register src = as_Register($src$$reg);
12532 if(dst != src) __ sll(dst, src, 0);
12533 %}
12534 ins_pipe( ialu_regL_regL );
12535 %}
12538 instruct convL2I_reg( mRegI dst, mRegL src ) %{
12539 match(Set dst (ConvL2I src));
12541 format %{ "MOV $dst, $src @ convL2I_reg" %}
12542 ins_encode %{
12543 Register dst = as_Register($dst$$reg);
12544 Register src = as_Register($src$$reg);
12546 __ sll(dst, src, 0);
12547 %}
12549 ins_pipe( ialu_regI_regI );
12550 %}
12552 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
12553 match(Set dst (ConvI2L (ConvL2I src)));
12555 format %{ "sll $dst, $src, 0 @ convL2I2L_reg" %}
12556 ins_encode %{
12557 Register dst = as_Register($dst$$reg);
12558 Register src = as_Register($src$$reg);
12560 __ sll(dst, src, 0);
12561 %}
12563 ins_pipe( ialu_regI_regI );
12564 %}
12566 instruct convL2D_reg( regD dst, mRegL src ) %{
12567 match(Set dst (ConvL2D src));
12568 format %{ "convL2D $dst, $src @ convL2D_reg" %}
12569 ins_encode %{
12570 Register src = as_Register($src$$reg);
12571 FloatRegister dst = as_FloatRegister($dst$$reg);
12573 __ dmtc1(src, dst);
12574 __ cvt_d_l(dst, dst);
12575 %}
12577 ins_pipe( pipe_slow );
12578 %}
12581 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
12582 match(Set dst (ConvD2L src));
12583 ins_cost(150);
12584 format %{ "convD2L $dst, $src @ convD2L_reg_fast" %}
12585 ins_encode %{
12586 Register dst = as_Register($dst$$reg);
12587 FloatRegister src = as_FloatRegister($src$$reg);
12589 Label Done;
12591 __ trunc_l_d(F30, src);
12592 // max_long: 0x7fffffffffffffff
12593 // __ set64(AT, 0x7fffffffffffffff);
12594 __ daddiu(AT, R0, -1);
12595 __ dsrl(AT, AT, 1);
12596 __ dmfc1(dst, F30);
12598 __ bne(dst, AT, Done);
12599 __ delayed()->mtc1(R0, F30);
12601 __ cvt_d_w(F30, F30);
12602 __ c_ult_d(src, F30);
12603 __ bc1f(Done);
12604 __ delayed()->daddiu(T9, R0, -1);
12606 __ c_un_d(src, src); //NaN?
12607 __ subu(dst, T9, AT);
12608 __ movt(dst, R0);
12610 __ bind(Done);
12611 %}
12613 ins_pipe( pipe_slow );
12614 %}
12617 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
12618 match(Set dst (ConvD2L src));
12619 ins_cost(250);
12620 format %{ "convD2L $dst, $src @ convD2L_reg_slow" %}
12621 ins_encode %{
12622 Register dst = as_Register($dst$$reg);
12623 FloatRegister src = as_FloatRegister($src$$reg);
12625 Label L;
12627 __ c_un_d(src, src); //NaN?
12628 __ bc1t(L);
12629 __ delayed();
12630 __ move(dst, R0);
12632 __ trunc_l_d(F30, src);
12633 __ cfc1(AT, 31);
12634 __ li(T9, 0x10000);
12635 __ andr(AT, AT, T9);
12636 __ beq(AT, R0, L);
12637 __ delayed()->dmfc1(dst, F30);
12639 __ mov_d(F12, src);
12640 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
12641 __ move(dst, V0);
12642 __ bind(L);
12643 %}
12645 ins_pipe( pipe_slow );
12646 %}
12649 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
12650 match(Set dst (ConvF2I src));
12651 ins_cost(150);
12652 format %{ "convf2i $dst, $src @ convF2I_reg_fast" %}
12653 ins_encode %{
12654 Register dreg = $dst$$Register;
12655 FloatRegister fval = $src$$FloatRegister;
12656 Label L;
12658 __ trunc_w_s(F30, fval);
12659 __ move(AT, 0x7fffffff);
12660 __ mfc1(dreg, F30);
12661 __ c_un_s(fval, fval); //NaN?
12662 __ movt(dreg, R0);
12664 __ bne(AT, dreg, L);
12665 __ delayed()->lui(T9, 0x8000);
12667 __ mfc1(AT, fval);
12668 __ andr(AT, AT, T9);
12670 __ movn(dreg, T9, AT);
12672 __ bind(L);
12674 %}
12676 ins_pipe( pipe_slow );
12677 %}
12681 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
12682 match(Set dst (ConvF2I src));
12683 ins_cost(250);
12684 format %{ "convf2i $dst, $src @ convF2I_reg_slow" %}
12685 ins_encode %{
12686 Register dreg = $dst$$Register;
12687 FloatRegister fval = $src$$FloatRegister;
12688 Label L;
12690 __ c_un_s(fval, fval); //NaN?
12691 __ bc1t(L);
12692 __ delayed();
12693 __ move(dreg, R0);
12695 __ trunc_w_s(F30, fval);
12697 /* Call SharedRuntime:f2i() to do valid convention */
12698 __ cfc1(AT, 31);
12699 __ li(T9, 0x10000);
12700 __ andr(AT, AT, T9);
12701 __ beq(AT, R0, L);
12702 __ delayed()->mfc1(dreg, F30);
12704 __ mov_s(F12, fval);
12706 /* 2014/01/08 Fu : This bug was found when running ezDS's control-panel.
12707 * J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
12708 *
12709 * An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
12710 * V0 is corrupted during call_VM_leaf(), and should be preserved.
12711 */
12712 __ push(fval);
12713 if(dreg != V0) {
12714 __ push(V0);
12715 }
12716 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
12717 if(dreg != V0) {
12718 __ move(dreg, V0);
12719 __ pop(V0);
12720 }
12721 __ pop(fval);
12722 __ bind(L);
12723 %}
12725 ins_pipe( pipe_slow );
12726 %}
12729 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
12730 match(Set dst (ConvF2L src));
12731 ins_cost(150);
12732 format %{ "convf2l $dst, $src @ convF2L_reg_fast" %}
12733 ins_encode %{
12734 Register dreg = $dst$$Register;
12735 FloatRegister fval = $src$$FloatRegister;
12736 Label L;
12738 __ trunc_l_s(F30, fval);
12739 __ daddiu(AT, R0, -1);
12740 __ dsrl(AT, AT, 1);
12741 __ dmfc1(dreg, F30);
12742 __ c_un_s(fval, fval); //NaN?
12743 __ movt(dreg, R0);
12745 __ bne(AT, dreg, L);
12746 __ delayed()->lui(T9, 0x8000);
12748 __ mfc1(AT, fval);
12749 __ andr(AT, AT, T9);
12751 __ dsll32(T9, T9, 0);
12752 __ movn(dreg, T9, AT);
12754 __ bind(L);
12755 %}
12757 ins_pipe( pipe_slow );
12758 %}
12761 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
12762 match(Set dst (ConvF2L src));
12763 ins_cost(250);
12764 format %{ "convf2l $dst, $src @ convF2L_reg_slow" %}
12765 ins_encode %{
12766 Register dst = as_Register($dst$$reg);
12767 FloatRegister fval = $src$$FloatRegister;
12768 Label L;
12770 __ c_un_s(fval, fval); //NaN?
12771 __ bc1t(L);
12772 __ delayed();
12773 __ move(dst, R0);
12775 __ trunc_l_s(F30, fval);
12776 __ cfc1(AT, 31);
12777 __ li(T9, 0x10000);
12778 __ andr(AT, AT, T9);
12779 __ beq(AT, R0, L);
12780 __ delayed()->dmfc1(dst, F30);
12782 __ mov_s(F12, fval);
12783 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
12784 __ move(dst, V0);
12785 __ bind(L);
12786 %}
12788 ins_pipe( pipe_slow );
12789 %}
12791 instruct convL2F_reg( regF dst, mRegL src ) %{
12792 match(Set dst (ConvL2F src));
12793 format %{ "convl2f $dst, $src @ convL2F_reg" %}
12794 ins_encode %{
12795 FloatRegister dst = $dst$$FloatRegister;
12796 Register src = as_Register($src$$reg);
12797 Label L;
12799 __ dmtc1(src, dst);
12800 __ cvt_s_l(dst, dst);
12801 %}
12803 ins_pipe( pipe_slow );
12804 %}
12806 instruct convI2F_reg( regF dst, mRegI src ) %{
12807 match(Set dst (ConvI2F src));
12808 format %{ "convi2f $dst, $src @ convI2F_reg" %}
12809 ins_encode %{
12810 Register src = $src$$Register;
12811 FloatRegister dst = $dst$$FloatRegister;
12813 __ mtc1(src, dst);
12814 __ cvt_s_w(dst, dst);
12815 %}
12817 ins_pipe( fpu_regF_regF );
12818 %}
12820 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
12821 match(Set dst (CmpLTMask p zero));
12822 ins_cost(100);
12824 format %{ "sra $dst, $p, 31 @ cmpLTMask_immI0" %}
12825 ins_encode %{
12826 Register src = $p$$Register;
12827 Register dst = $dst$$Register;
12829 __ sra(dst, src, 31);
12830 %}
12831 ins_pipe( pipe_slow );
12832 %}
12835 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
12836 match(Set dst (CmpLTMask p q));
12837 ins_cost(400);
12839 format %{ "cmpLTMask $dst, $p, $q @ cmpLTMask" %}
12840 ins_encode %{
12841 Register p = $p$$Register;
12842 Register q = $q$$Register;
12843 Register dst = $dst$$Register;
12845 __ slt(dst, p, q);
12846 __ subu(dst, R0, dst);
12847 %}
12848 ins_pipe( pipe_slow );
12849 %}
12851 instruct convP2B(mRegI dst, mRegP src) %{
12852 match(Set dst (Conv2B src));
12854 ins_cost(100);
12855 format %{ "convP2B $dst, $src @ convP2B" %}
12856 ins_encode %{
12857 Register dst = as_Register($dst$$reg);
12858 Register src = as_Register($src$$reg);
12860 if (dst != src) {
12861 __ daddiu(dst, R0, 1);
12862 __ movz(dst, R0, src);
12863 } else {
12864 __ move(AT, src);
12865 __ daddiu(dst, R0, 1);
12866 __ movz(dst, R0, AT);
12867 }
12868 %}
12870 ins_pipe( ialu_regL_regL );
12871 %}
12874 instruct convI2D_reg_reg(regD dst, mRegI src) %{
12875 match(Set dst (ConvI2D src));
12876 format %{ "conI2D $dst, $src @convI2D_reg" %}
12877 ins_encode %{
12878 Register src = $src$$Register;
12879 FloatRegister dst = $dst$$FloatRegister;
12880 __ mtc1(src, dst);
12881 __ cvt_d_w(dst, dst);
12882 %}
12883 ins_pipe( fpu_regF_regF );
12884 %}
12886 instruct convF2D_reg_reg(regD dst, regF src) %{
12887 match(Set dst (ConvF2D src));
12888 format %{ "convF2D $dst, $src\t# @convF2D_reg_reg" %}
12889 ins_encode %{
12890 FloatRegister dst = $dst$$FloatRegister;
12891 FloatRegister src = $src$$FloatRegister;
12893 __ cvt_d_s(dst, src);
12894 %}
12895 ins_pipe( fpu_regF_regF );
12896 %}
12898 instruct convD2F_reg_reg(regF dst, regD src) %{
12899 match(Set dst (ConvD2F src));
12900 format %{ "convD2F $dst, $src\t# @convD2F_reg_reg" %}
12901 ins_encode %{
12902 FloatRegister dst = $dst$$FloatRegister;
12903 FloatRegister src = $src$$FloatRegister;
12905 __ cvt_s_d(dst, src);
12906 %}
12907 ins_pipe( fpu_regF_regF );
12908 %}
12911 // Convert a double to an int. If the double is a NAN, stuff a zero in instead.
12912 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
12913 match(Set dst (ConvD2I src));
12915 ins_cost(150);
12916 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
12918 ins_encode %{
12919 FloatRegister src = $src$$FloatRegister;
12920 Register dst = $dst$$Register;
12922 Label Done;
12924 __ trunc_w_d(F30, src);
12925 // max_int: 2147483647
12926 __ move(AT, 0x7fffffff);
12927 __ mfc1(dst, F30);
12929 __ bne(dst, AT, Done);
12930 __ delayed()->mtc1(R0, F30);
12932 __ cvt_d_w(F30, F30);
12933 __ c_ult_d(src, F30);
12934 __ bc1f(Done);
12935 __ delayed()->addiu(T9, R0, -1);
12937 __ c_un_d(src, src); //NaN?
12938 __ subu32(dst, T9, AT);
12939 __ movt(dst, R0);
12941 __ bind(Done);
12942 %}
12943 ins_pipe( pipe_slow );
12944 %}
12947 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
12948 match(Set dst (ConvD2I src));
12950 ins_cost(250);
12951 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
12953 ins_encode %{
12954 FloatRegister src = $src$$FloatRegister;
12955 Register dst = $dst$$Register;
12956 Label L;
12958 __ trunc_w_d(F30, src);
12959 __ cfc1(AT, 31);
12960 __ li(T9, 0x10000);
12961 __ andr(AT, AT, T9);
12962 __ beq(AT, R0, L);
12963 __ delayed()->mfc1(dst, F30);
12965 __ mov_d(F12, src);
12966 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
12967 __ move(dst, V0);
12968 __ bind(L);
12970 %}
12971 ins_pipe( pipe_slow );
12972 %}
12974 // Convert oop pointer into compressed form
12975 instruct encodeHeapOop(mRegN dst, mRegP src) %{
12976 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
12977 match(Set dst (EncodeP src));
12978 format %{ "encode_heap_oop $dst,$src" %}
12979 ins_encode %{
12980 Register src = $src$$Register;
12981 Register dst = $dst$$Register;
12983 __ encode_heap_oop(dst, src);
12984 %}
12985 ins_pipe( ialu_regL_regL );
12986 %}
12988 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
12989 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
12990 match(Set dst (EncodeP src));
12991 format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
12992 ins_encode %{
12993 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
12994 %}
12995 ins_pipe( ialu_regL_regL );
12996 %}
12998 instruct decodeHeapOop(mRegP dst, mRegN src) %{
12999 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
13000 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
13001 match(Set dst (DecodeN src));
13002 format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
13003 ins_encode %{
13004 Register s = $src$$Register;
13005 Register d = $dst$$Register;
13007 __ decode_heap_oop(d, s);
13008 %}
13009 ins_pipe( ialu_regL_regL );
13010 %}
13012 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
13013 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
13014 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
13015 match(Set dst (DecodeN src));
13016 format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
13017 ins_encode %{
13018 Register s = $src$$Register;
13019 Register d = $dst$$Register;
13020 if (s != d) {
13021 __ decode_heap_oop_not_null(d, s);
13022 } else {
13023 __ decode_heap_oop_not_null(d);
13024 }
13025 %}
13026 ins_pipe( ialu_regL_regL );
13027 %}
13029 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
13030 match(Set dst (EncodePKlass src));
13031 format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
13032 ins_encode %{
13033 __ encode_klass_not_null($dst$$Register, $src$$Register);
13034 %}
13035 ins_pipe( ialu_regL_regL );
13036 %}
13038 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
13039 match(Set dst (DecodeNKlass src));
13040 format %{ "decode_heap_klass_not_null $dst,$src" %}
13041 ins_encode %{
13042 Register s = $src$$Register;
13043 Register d = $dst$$Register;
13044 if (s != d) {
13045 __ decode_klass_not_null(d, s);
13046 } else {
13047 __ decode_klass_not_null(d);
13048 }
13049 %}
13050 ins_pipe( ialu_regL_regL );
13051 %}
13053 //FIXME
13054 instruct tlsLoadP(mRegP dst) %{
13055 match(Set dst (ThreadLocal));
13057 ins_cost(0);
13058 format %{ " get_thread in $dst #@tlsLoadP" %}
13059 ins_encode %{
13060 Register dst = $dst$$Register;
13061 #ifdef OPT_THREAD
13062 __ move(dst, TREG);
13063 #else
13064 __ get_thread(dst);
13065 #endif
13066 %}
13068 ins_pipe( ialu_loadI );
13069 %}
13072 instruct checkCastPP( mRegP dst ) %{
13073 match(Set dst (CheckCastPP dst));
13075 format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
13076 ins_encode( /*empty encoding*/ );
13077 ins_pipe( empty );
13078 %}
13080 instruct castPP(mRegP dst)
13081 %{
13082 match(Set dst (CastPP dst));
13084 size(0);
13085 format %{ "# castPP of $dst" %}
13086 ins_encode(/* empty encoding */);
13087 ins_pipe(empty);
13088 %}
13090 instruct castII( mRegI dst ) %{
13091 match(Set dst (CastII dst));
13092 format %{ "#castII of $dst empty encoding" %}
13093 ins_encode( /*empty encoding*/ );
13094 ins_cost(0);
13095 ins_pipe( empty );
13096 %}
13098 // Return Instruction
13099 // Remove the return address & jump to it.
13100 instruct Ret() %{
13101 match(Return);
13102 format %{ "RET #@Ret" %}
13104 ins_encode %{
13105 __ jr(RA);
13106 __ nop();
13107 %}
13109 ins_pipe( pipe_jump );
13110 %}
13112 /*
13113 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
13114 instruct jumpXtnd(mRegL switch_val) %{
13115 match(Jump switch_val);
13117 ins_cost(350);
13119 format %{ "load T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
13120 "jr T9\n\t"
13121 "nop" %}
13122 ins_encode %{
13123 Register table_base = $constanttablebase;
13124 int con_offset = $constantoffset;
13125 Register switch_reg = $switch_val$$Register;
13127 if (UseLoongsonISA) {
13128 if (Assembler::is_simm(con_offset, 8)) {
13129 __ gsldx(T9, table_base, switch_reg, con_offset);
13130 } else if (Assembler::is_simm16(con_offset)) {
13131 __ daddu(T9, table_base, switch_reg);
13132 __ ld(T9, T9, con_offset);
13133 } else {
13134 __ move(T9, con_offset);
13135 __ daddu(AT, table_base, switch_reg);
13136 __ gsldx(T9, AT, T9, 0);
13137 }
13138 } else {
13139 if (Assembler::is_simm16(con_offset)) {
13140 __ daddu(T9, table_base, switch_reg);
13141 __ ld(T9, T9, con_offset);
13142 } else {
13143 __ move(T9, con_offset);
13144 __ daddu(AT, table_base, switch_reg);
13145 __ daddu(AT, T9, AT);
13146 __ ld(T9, AT, 0);
13147 }
13148 }
13150 __ jr(T9);
13151 __ nop();
13153 %}
13154 ins_pipe(pipe_jump);
13155 %}
13156 */
13159 // Tail Jump; remove the return address; jump to target.
13160 // TailCall above leaves the return address around.
13161 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
13162 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
13163 // "restore" before this instruction (in Epilogue), we need to materialize it
13164 // in %i0.
13165 //FIXME
13166 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
13167 match( TailJump jump_target ex_oop );
13168 ins_cost(200);
13169 format %{ "Jmp $jump_target ; ex_oop = $ex_oop #@tailjmpInd" %}
13170 ins_encode %{
13171 Register target = $jump_target$$Register;
13173 /* 2012/9/14 Jin: V0, V1 are indicated in:
13174 * [stubGenerator_mips.cpp] generate_forward_exception()
13175 * [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
13176 */
13177 Register oop = $ex_oop$$Register;
13178 Register exception_oop = V0;
13179 Register exception_pc = V1;
13181 __ move(exception_pc, RA);
13182 __ move(exception_oop, oop);
13184 __ jr(target);
13185 __ nop();
13186 %}
13187 ins_pipe( pipe_jump );
13188 %}
13190 // ============================================================================
13191 // Procedure Call/Return Instructions
13192 // Call Java Static Instruction
13193 // Note: If this code changes, the corresponding ret_addr_offset() and
13194 // compute_padding() functions will have to be adjusted.
13195 instruct CallStaticJavaDirect(method meth) %{
13196 match(CallStaticJava);
13197 effect(USE meth);
13199 ins_cost(300);
13200 format %{ "CALL,static #@CallStaticJavaDirect " %}
13201 ins_encode( Java_Static_Call( meth ) );
13202 ins_pipe( pipe_slow );
13203 ins_pc_relative(1);
13204 %}
13206 // Call Java Dynamic Instruction
13207 // Note: If this code changes, the corresponding ret_addr_offset() and
13208 // compute_padding() functions will have to be adjusted.
13209 instruct CallDynamicJavaDirect(method meth) %{
13210 match(CallDynamicJava);
13211 effect(USE meth);
13213 ins_cost(300);
13214 format %{"MOV IC_Klass, (oop)-1\n\t"
13215 "CallDynamic @ CallDynamicJavaDirect" %}
13216 ins_encode( Java_Dynamic_Call( meth ) );
13217 ins_pipe( pipe_slow );
13218 ins_pc_relative(1);
13219 %}
13221 instruct CallLeafNoFPDirect(method meth) %{
13222 match(CallLeafNoFP);
13223 effect(USE meth);
13225 ins_cost(300);
13226 format %{ "CALL_LEAF_NOFP,runtime " %}
13227 ins_encode(Java_To_Runtime(meth));
13228 ins_pipe( pipe_slow );
13229 ins_pc_relative(1);
13230 ins_alignment(16);
13231 %}
13233 // Prefetch instructions.
13235 instruct prefetchrNTA( memory mem ) %{
13236 match(PrefetchRead mem);
13237 ins_cost(125);
13239 format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
13240 ins_encode %{
13241 int base = $mem$$base;
13242 int index = $mem$$index;
13243 int scale = $mem$$scale;
13244 int disp = $mem$$disp;
13246 if( index != 0 ) {
13247 if (scale == 0) {
13248 __ daddu(AT, as_Register(base), as_Register(index));
13249 } else {
13250 __ dsll(AT, as_Register(index), scale);
13251 __ daddu(AT, as_Register(base), AT);
13252 }
13253 } else {
13254 __ move(AT, as_Register(base));
13255 }
13256 if( Assembler::is_simm16(disp) ) {
13257 __ daddiu(AT, as_Register(base), disp);
13258 __ daddiu(AT, AT, disp);
13259 } else {
13260 __ move(T9, disp);
13261 __ daddu(AT, as_Register(base), T9);
13262 }
13263 __ pref(0, AT, 0); //hint: 0:load
13264 %}
13265 ins_pipe(pipe_slow);
13266 %}
13268 instruct prefetchwNTA( memory mem ) %{
13269 match(PrefetchWrite mem);
13270 ins_cost(125);
13271 format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
13272 ins_encode %{
13273 int base = $mem$$base;
13274 int index = $mem$$index;
13275 int scale = $mem$$scale;
13276 int disp = $mem$$disp;
13278 if( index != 0 ) {
13279 if (scale == 0) {
13280 __ daddu(AT, as_Register(base), as_Register(index));
13281 } else {
13282 __ dsll(AT, as_Register(index), scale);
13283 __ daddu(AT, as_Register(base), AT);
13284 }
13285 } else {
13286 __ move(AT, as_Register(base));
13287 }
13288 if( Assembler::is_simm16(disp) ) {
13289 __ daddiu(AT, as_Register(base), disp);
13290 __ daddiu(AT, AT, disp);
13291 } else {
13292 __ move(T9, disp);
13293 __ daddu(AT, as_Register(base), T9);
13294 }
13295 __ pref(1, AT, 0); //hint: 1:store
13296 %}
13297 ins_pipe(pipe_slow);
13298 %}
13300 // Prefetch instructions for allocation.
13302 instruct prefetchAllocNTA( memory mem ) %{
13303 match(PrefetchAllocation mem);
13304 ins_cost(125);
13305 format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
13306 ins_encode %{
13307 int base = $mem$$base;
13308 int index = $mem$$index;
13309 int scale = $mem$$scale;
13310 int disp = $mem$$disp;
13312 Register dst = R0;
13314 if( index != 0 ) {
13315 if( Assembler::is_simm16(disp) ) {
13316 if( UseLoongsonISA ) {
13317 if (scale == 0) {
13318 __ gslbx(dst, as_Register(base), as_Register(index), disp);
13319 } else {
13320 __ dsll(AT, as_Register(index), scale);
13321 __ gslbx(dst, as_Register(base), AT, disp);
13322 }
13323 } else {
13324 if (scale == 0) {
13325 __ addu(AT, as_Register(base), as_Register(index));
13326 } else {
13327 __ dsll(AT, as_Register(index), scale);
13328 __ addu(AT, as_Register(base), AT);
13329 }
13330 __ lb(dst, AT, disp);
13331 }
13332 } else {
13333 if (scale == 0) {
13334 __ addu(AT, as_Register(base), as_Register(index));
13335 } else {
13336 __ dsll(AT, as_Register(index), scale);
13337 __ addu(AT, as_Register(base), AT);
13338 }
13339 __ move(T9, disp);
13340 if( UseLoongsonISA ) {
13341 __ gslbx(dst, AT, T9, 0);
13342 } else {
13343 __ addu(AT, AT, T9);
13344 __ lb(dst, AT, 0);
13345 }
13346 }
13347 } else {
13348 if( Assembler::is_simm16(disp) ) {
13349 __ lb(dst, as_Register(base), disp);
13350 } else {
13351 __ move(T9, disp);
13352 if( UseLoongsonISA ) {
13353 __ gslbx(dst, as_Register(base), T9, 0);
13354 } else {
13355 __ addu(AT, as_Register(base), T9);
13356 __ lb(dst, AT, 0);
13357 }
13358 }
13359 }
13360 %}
13361 ins_pipe(pipe_slow);
13362 %}
13365 // Call runtime without safepoint
13366 instruct CallLeafDirect(method meth) %{
13367 match(CallLeaf);
13368 effect(USE meth);
13370 ins_cost(300);
13371 format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
13372 ins_encode(Java_To_Runtime(meth));
13373 ins_pipe( pipe_slow );
13374 ins_pc_relative(1);
13375 ins_alignment(16);
13376 %}
13378 // Load Char (16bit unsigned)
13379 instruct loadUS(mRegI dst, memory mem) %{
13380 match(Set dst (LoadUS mem));
13382 ins_cost(125);
13383 format %{ "loadUS $dst,$mem @ loadC" %}
13384 ins_encode(load_C_enc(dst, mem));
13385 ins_pipe( ialu_loadI );
13386 %}
13388 instruct loadUS_convI2L(mRegL dst, memory mem) %{
13389 match(Set dst (ConvI2L (LoadUS mem)));
13391 ins_cost(125);
13392 format %{ "loadUS $dst,$mem @ loadUS_convI2L" %}
13393 ins_encode(load_C_enc(dst, mem));
13394 ins_pipe( ialu_loadI );
13395 %}
13397 // Store Char (16bit unsigned)
13398 instruct storeC(memory mem, mRegI src) %{
13399 match(Set mem (StoreC mem src));
13401 ins_cost(125);
13402 format %{ "storeC $src, $mem @ storeC" %}
13403 ins_encode(store_C_reg_enc(mem, src));
13404 ins_pipe( ialu_loadI );
13405 %}
13407 instruct storeC0(memory mem, immI0 zero) %{
13408 match(Set mem (StoreC mem zero));
13410 ins_cost(125);
13411 format %{ "storeC $zero, $mem @ storeC0" %}
13412 ins_encode(store_C0_enc(mem));
13413 ins_pipe( ialu_loadI );
13414 %}
13417 instruct loadConF0(regF dst, immF0 zero) %{
13418 match(Set dst zero);
13419 ins_cost(100);
13421 format %{ "mov $dst, zero @ loadConF0\n"%}
13422 ins_encode %{
13423 FloatRegister dst = $dst$$FloatRegister;
13425 __ mtc1(R0, dst);
13426 %}
13427 ins_pipe( fpu_loadF );
13428 %}
13431 instruct loadConF(regF dst, immF src) %{
13432 match(Set dst src);
13433 ins_cost(125);
13435 format %{ "lwc1 $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
13436 ins_encode %{
13437 int con_offset = $constantoffset($src);
13439 if (Assembler::is_simm16(con_offset)) {
13440 __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
13441 } else {
13442 __ set64(AT, con_offset);
13443 if (UseLoongsonISA) {
13444 __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
13445 } else {
13446 __ daddu(AT, $constanttablebase, AT);
13447 __ lwc1($dst$$FloatRegister, AT, 0);
13448 }
13449 }
13450 %}
13451 ins_pipe( fpu_loadF );
13452 %}
13455 instruct loadConD0(regD dst, immD0 zero) %{
13456 match(Set dst zero);
13457 ins_cost(100);
13459 format %{ "mov $dst, zero @ loadConD0"%}
13460 ins_encode %{
13461 FloatRegister dst = as_FloatRegister($dst$$reg);
13463 __ dmtc1(R0, dst);
13464 %}
13465 ins_pipe( fpu_loadF );
13466 %}
13468 instruct loadConD(regD dst, immD src) %{
13469 match(Set dst src);
13470 ins_cost(125);
13472 format %{ "ldc1 $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
13473 ins_encode %{
13474 int con_offset = $constantoffset($src);
13476 if (Assembler::is_simm16(con_offset)) {
13477 __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
13478 } else {
13479 __ set64(AT, con_offset);
13480 if (UseLoongsonISA) {
13481 __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
13482 } else {
13483 __ daddu(AT, $constanttablebase, AT);
13484 __ ldc1($dst$$FloatRegister, AT, 0);
13485 }
13486 }
13487 %}
13488 ins_pipe( fpu_loadF );
13489 %}
13491 // Store register Float value (it is faster than store from FPU register)
13492 instruct storeF_reg( memory mem, regF src) %{
13493 match(Set mem (StoreF mem src));
13495 ins_cost(50);
13496 format %{ "store $mem, $src\t# store float @ storeF_reg" %}
13497 ins_encode(store_F_reg_enc(mem, src));
13498 ins_pipe( fpu_storeF );
13499 %}
13501 instruct storeF_imm0( memory mem, immF0 zero) %{
13502 match(Set mem (StoreF mem zero));
13504 ins_cost(40);
13505 format %{ "store $mem, zero\t# store float @ storeF_imm0" %}
13506 ins_encode %{
13507 int base = $mem$$base;
13508 int index = $mem$$index;
13509 int scale = $mem$$scale;
13510 int disp = $mem$$disp;
13512 if( index != 0 ) {
13513 if ( UseLoongsonISA ) {
13514 if ( Assembler::is_simm(disp, 8) ) {
13515 if ( scale == 0 ) {
13516 __ gsswx(R0, as_Register(base), as_Register(index), disp);
13517 } else {
13518 __ dsll(T9, as_Register(index), scale);
13519 __ gsswx(R0, as_Register(base), T9, disp);
13520 }
13521 } else if ( Assembler::is_simm16(disp) ) {
13522 if ( scale == 0 ) {
13523 __ daddu(AT, as_Register(base), as_Register(index));
13524 } else {
13525 __ dsll(T9, as_Register(index), scale);
13526 __ daddu(AT, as_Register(base), T9);
13527 }
13528 __ sw(R0, AT, disp);
13529 } else {
13530 if ( scale == 0 ) {
13531 __ move(T9, disp);
13532 __ daddu(AT, as_Register(index), T9);
13533 __ gsswx(R0, as_Register(base), AT, 0);
13534 } else {
13535 __ dsll(T9, as_Register(index), scale);
13536 __ move(AT, disp);
13537 __ daddu(AT, AT, T9);
13538 __ gsswx(R0, as_Register(base), AT, 0);
13539 }
13540 }
13541 } else { //not use loongson isa
13542 if(scale != 0) {
13543 __ dsll(T9, as_Register(index), scale);
13544 __ daddu(AT, as_Register(base), T9);
13545 } else {
13546 __ daddu(AT, as_Register(base), as_Register(index));
13547 }
13548 if( Assembler::is_simm16(disp) ) {
13549 __ sw(R0, AT, disp);
13550 } else {
13551 __ move(T9, disp);
13552 __ daddu(AT, AT, T9);
13553 __ sw(R0, AT, 0);
13554 }
13555 }
13556 } else { //index is 0
13557 if ( UseLoongsonISA ) {
13558 if ( Assembler::is_simm16(disp) ) {
13559 __ sw(R0, as_Register(base), disp);
13560 } else {
13561 __ move(T9, disp);
13562 __ gsswx(R0, as_Register(base), T9, 0);
13563 }
13564 } else {
13565 if( Assembler::is_simm16(disp) ) {
13566 __ sw(R0, as_Register(base), disp);
13567 } else {
13568 __ move(T9, disp);
13569 __ daddu(AT, as_Register(base), T9);
13570 __ sw(R0, AT, 0);
13571 }
13572 }
13573 }
13574 %}
13575 ins_pipe( ialu_storeI );
13576 %}
13578 // Load Double
13579 instruct loadD(regD dst, memory mem) %{
13580 match(Set dst (LoadD mem));
13582 ins_cost(150);
13583 format %{ "loadD $dst, $mem #@loadD" %}
13584 ins_encode(load_D_enc(dst, mem));
13585 ins_pipe( ialu_loadI );
13586 %}
13588 // Load Double - UNaligned
13589 instruct loadD_unaligned(regD dst, memory mem ) %{
13590 match(Set dst (LoadD_unaligned mem));
13591 ins_cost(250);
13592 // FIXME: Jin: Need more effective ldl/ldr
13593 format %{ "loadD_unaligned $dst, $mem #@loadD_unaligned" %}
13594 ins_encode(load_D_enc(dst, mem));
13595 ins_pipe( ialu_loadI );
13596 %}
13598 instruct storeD_reg( memory mem, regD src) %{
13599 match(Set mem (StoreD mem src));
13601 ins_cost(50);
13602 format %{ "store $mem, $src\t# store float @ storeD_reg" %}
13603 ins_encode(store_D_reg_enc(mem, src));
13604 ins_pipe( fpu_storeF );
13605 %}
13607 instruct storeD_imm0( memory mem, immD0 zero) %{
13608 match(Set mem (StoreD mem zero));
13610 ins_cost(40);
13611 format %{ "store $mem, zero\t# store float @ storeD_imm0" %}
13612 ins_encode %{
13613 int base = $mem$$base;
13614 int index = $mem$$index;
13615 int scale = $mem$$scale;
13616 int disp = $mem$$disp;
13618 __ mtc1(R0, F30);
13619 __ cvt_d_w(F30, F30);
13621 if( index != 0 ) {
13622 if ( UseLoongsonISA ) {
13623 if ( Assembler::is_simm(disp, 8) ) {
13624 if (scale == 0) {
13625 __ gssdxc1(F30, as_Register(base), as_Register(index), disp);
13626 } else {
13627 __ dsll(T9, as_Register(index), scale);
13628 __ gssdxc1(F30, as_Register(base), T9, disp);
13629 }
13630 } else if ( Assembler::is_simm16(disp) ) {
13631 if (scale == 0) {
13632 __ daddu(AT, as_Register(base), as_Register(index));
13633 __ sdc1(F30, AT, disp);
13634 } else {
13635 __ dsll(T9, as_Register(index), scale);
13636 __ daddu(AT, as_Register(base), T9);
13637 __ sdc1(F30, AT, disp);
13638 }
13639 } else {
13640 if (scale == 0) {
13641 __ move(T9, disp);
13642 __ daddu(AT, as_Register(index), T9);
13643 __ gssdxc1(F30, as_Register(base), AT, 0);
13644 } else {
13645 __ move(T9, disp);
13646 __ dsll(AT, as_Register(index), scale);
13647 __ daddu(AT, AT, T9);
13648 __ gssdxc1(F30, as_Register(base), AT, 0);
13649 }
13650 }
13651 } else { // not use loongson isa
13652 if(scale != 0) {
13653 __ dsll(T9, as_Register(index), scale);
13654 __ daddu(AT, as_Register(base), T9);
13655 } else {
13656 __ daddu(AT, as_Register(base), as_Register(index));
13657 }
13658 if( Assembler::is_simm16(disp) ) {
13659 __ sdc1(F30, AT, disp);
13660 } else {
13661 __ move(T9, disp);
13662 __ daddu(AT, AT, T9);
13663 __ sdc1(F30, AT, 0);
13664 }
13665 }
13666 } else {// index is 0
13667 if ( UseLoongsonISA ) {
13668 if ( Assembler::is_simm16(disp) ) {
13669 __ sdc1(F30, as_Register(base), disp);
13670 } else {
13671 __ move(T9, disp);
13672 __ gssdxc1(F30, as_Register(base), T9, 0);
13673 }
13674 } else {
13675 if( Assembler::is_simm16(disp) ) {
13676 __ sdc1(F30, as_Register(base), disp);
13677 } else {
13678 __ move(T9, disp);
13679 __ daddu(AT, as_Register(base), T9);
13680 __ sdc1(F30, AT, 0);
13681 }
13682 }
13683 }
13684 %}
13685 ins_pipe( ialu_storeI );
13686 %}
13688 instruct loadSSI(mRegI dst, stackSlotI src)
13689 %{
13690 match(Set dst src);
13692 ins_cost(125);
13693 format %{ "lw $dst, $src\t# int stk @ loadSSI" %}
13694 ins_encode %{
13695 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
13696 __ lw($dst$$Register, SP, $src$$disp);
13697 %}
13698 ins_pipe(ialu_loadI);
13699 %}
13701 instruct storeSSI(stackSlotI dst, mRegI src)
13702 %{
13703 match(Set dst src);
13705 ins_cost(100);
13706 format %{ "sw $dst, $src\t# int stk @ storeSSI" %}
13707 ins_encode %{
13708 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
13709 __ sw($src$$Register, SP, $dst$$disp);
13710 %}
13711 ins_pipe(ialu_storeI);
13712 %}
13714 instruct loadSSL(mRegL dst, stackSlotL src)
13715 %{
13716 match(Set dst src);
13718 ins_cost(125);
13719 format %{ "ld $dst, $src\t# long stk @ loadSSL" %}
13720 ins_encode %{
13721 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
13722 __ ld($dst$$Register, SP, $src$$disp);
13723 %}
13724 ins_pipe(ialu_loadI);
13725 %}
13727 instruct storeSSL(stackSlotL dst, mRegL src)
13728 %{
13729 match(Set dst src);
13731 ins_cost(100);
13732 format %{ "sd $dst, $src\t# long stk @ storeSSL" %}
13733 ins_encode %{
13734 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
13735 __ sd($src$$Register, SP, $dst$$disp);
13736 %}
13737 ins_pipe(ialu_storeI);
13738 %}
13740 instruct loadSSP(mRegP dst, stackSlotP src)
13741 %{
13742 match(Set dst src);
13744 ins_cost(125);
13745 format %{ "ld $dst, $src\t# ptr stk @ loadSSP" %}
13746 ins_encode %{
13747 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
13748 __ ld($dst$$Register, SP, $src$$disp);
13749 %}
13750 ins_pipe(ialu_loadI);
13751 %}
13753 instruct storeSSP(stackSlotP dst, mRegP src)
13754 %{
13755 match(Set dst src);
13757 ins_cost(100);
13758 format %{ "sd $dst, $src\t# ptr stk @ storeSSP" %}
13759 ins_encode %{
13760 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
13761 __ sd($src$$Register, SP, $dst$$disp);
13762 %}
13763 ins_pipe(ialu_storeI);
13764 %}
13766 instruct loadSSF(regF dst, stackSlotF src)
13767 %{
13768 match(Set dst src);
13770 ins_cost(125);
13771 format %{ "lwc1 $dst, $src\t# float stk @ loadSSF" %}
13772 ins_encode %{
13773 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
13774 __ lwc1($dst$$FloatRegister, SP, $src$$disp);
13775 %}
13776 ins_pipe(ialu_loadI);
13777 %}
13779 instruct storeSSF(stackSlotF dst, regF src)
13780 %{
13781 match(Set dst src);
13783 ins_cost(100);
13784 format %{ "swc1 $dst, $src\t# float stk @ storeSSF" %}
13785 ins_encode %{
13786 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
13787 __ swc1($src$$FloatRegister, SP, $dst$$disp);
13788 %}
13789 ins_pipe(fpu_storeF);
13790 %}
13792 // Use the same format since predicate() can not be used here.
13793 instruct loadSSD(regD dst, stackSlotD src)
13794 %{
13795 match(Set dst src);
13797 ins_cost(125);
13798 format %{ "ldc1 $dst, $src\t# double stk @ loadSSD" %}
13799 ins_encode %{
13800 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
13801 __ ldc1($dst$$FloatRegister, SP, $src$$disp);
13802 %}
13803 ins_pipe(ialu_loadI);
13804 %}
13806 instruct storeSSD(stackSlotD dst, regD src)
13807 %{
13808 match(Set dst src);
13810 ins_cost(100);
13811 format %{ "sdc1 $dst, $src\t# double stk @ storeSSD" %}
13812 ins_encode %{
13813 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
13814 __ sdc1($src$$FloatRegister, SP, $dst$$disp);
13815 %}
13816 ins_pipe(fpu_storeF);
13817 %}
13819 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
13820 match( Set cr (FastLock object box) );
13821 effect( TEMP tmp, TEMP scr, USE_KILL box );
13822 ins_cost(300);
13823 format %{ "FASTLOCK $cr <-- $object, $box, $tmp, $scr #@ cmpFastLock" %}
13824 ins_encode %{
13825 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
13826 %}
13828 ins_pipe( pipe_slow );
13829 ins_pc_relative(1);
13830 %}
13832 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
13833 match( Set cr (FastUnlock object box) );
13834 effect( TEMP tmp, USE_KILL box );
13835 ins_cost(300);
13836 format %{ "FASTUNLOCK $cr <-- $object, $box, $tmp #@cmpFastUnlock" %}
13837 ins_encode %{
13838 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
13839 %}
13841 ins_pipe( pipe_slow );
13842 ins_pc_relative(1);
13843 %}
13845 // Store CMS card-mark Immediate
13846 instruct storeImmCM(memory mem, immI8 src) %{
13847 match(Set mem (StoreCM mem src));
13849 ins_cost(150);
13850 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %}
13851 // opcode(0xC6);
13852 ins_encode(store_B_immI_enc_sync(mem, src));
13853 ins_pipe( ialu_storeI );
13854 %}
13856 // Die now
13857 instruct ShouldNotReachHere( )
13858 %{
13859 match(Halt);
13860 ins_cost(300);
13862 // Use the following format syntax
13863 format %{ "ILLTRAP ;#@ShouldNotReachHere" %}
13864 ins_encode %{
13865 // Here we should emit illtrap !
13867 __ stop("in ShoudNotReachHere");
13869 %}
13870 ins_pipe( pipe_jump );
13871 %}
13873 instruct leaP8Narrow(mRegP dst, indOffset8Narrow mem)
13874 %{
13875 predicate(Universe::narrow_oop_shift() == 0);
13876 match(Set dst mem);
13878 ins_cost(110);
13879 format %{ "leaq $dst, $mem\t# ptr off8narrow @ leaP8Narrow" %}
13880 ins_encode %{
13881 Register dst = $dst$$Register;
13882 Register base = as_Register($mem$$base);
13883 int disp = $mem$$disp;
13885 __ daddiu(dst, base, disp);
13886 %}
13887 ins_pipe( ialu_regI_imm16 );
13888 %}
13890 instruct leaPPosIdxScaleOff8(mRegP dst, basePosIndexScaleOffset8 mem)
13891 %{
13892 match(Set dst mem);
13894 ins_cost(110);
13895 format %{ "leaq $dst, $mem\t# @ PosIdxScaleOff8" %}
13896 ins_encode %{
13897 Register dst = $dst$$Register;
13898 Register base = as_Register($mem$$base);
13899 Register index = as_Register($mem$$index);
13900 int scale = $mem$$scale;
13901 int disp = $mem$$disp;
13903 if (scale == 0) {
13904 __ daddu(AT, base, index);
13905 __ daddiu(dst, AT, disp);
13906 } else {
13907 __ dsll(AT, index, scale);
13908 __ daddu(AT, base, AT);
13909 __ daddiu(dst, AT, disp);
13910 }
13911 %}
13913 ins_pipe( ialu_regI_imm16 );
13914 %}
13916 instruct leaPIdxScale(mRegP dst, indIndexScale mem)
13917 %{
13918 match(Set dst mem);
13920 ins_cost(110);
13921 format %{ "leaq $dst, $mem\t# @ leaPIdxScale" %}
13922 ins_encode %{
13923 Register dst = $dst$$Register;
13924 Register base = as_Register($mem$$base);
13925 Register index = as_Register($mem$$index);
13926 int scale = $mem$$scale;
13928 if (scale == 0) {
13929 __ daddu(dst, base, index);
13930 } else {
13931 __ dsll(AT, index, scale);
13932 __ daddu(dst, base, AT);
13933 }
13934 %}
13936 ins_pipe( ialu_regI_imm16 );
13937 %}
13940 // ============================================================================
13941 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
13942 // array for an instance of the superklass. Set a hidden internal cache on a
13943 // hit (cache is checked with exposed code in gen_subtype_check()). Return
13944 // NZ for a miss or zero for a hit. The encoding ALSO sets flags.
13945 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
13946 match(Set result (PartialSubtypeCheck sub super));
13947 effect(KILL tmp);
13948 ins_cost(1100); // slightly larger than the next version
13949 format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
13951 ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
13952 ins_pipe( pipe_slow );
13953 %}
13956 // Conditional-store of an int value.
13957 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
13958 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
13959 match(Set cr (StoreIConditional mem (Binary oldval newval)));
13960 // effect(KILL oldval);
13961 format %{ "CMPXCHG $newval, $mem, $oldval \t# @storeIConditional" %}
13963 ins_encode %{
13964 Register oldval = $oldval$$Register;
13965 Register newval = $newval$$Register;
13966 Address addr(as_Register($mem$$base), $mem$$disp);
13967 Label again, failure;
13969 int index = $mem$$index;
13970 int scale = $mem$$scale;
13971 int disp = $mem$$disp;
13973 guarantee(Assembler::is_simm16(disp), "");
13975 if( index != 0 ) {
13976 __ stop("in storeIConditional: index != 0");
13977 } else {
13978 __ bind(again);
13979 if(UseSyncLevel >= 3000 || UseSyncLevel < 2000) __ sync();
13980 __ ll(AT, addr);
13981 __ bne(AT, oldval, failure);
13982 __ delayed()->addu(AT, R0, R0);
13984 __ addu(AT, newval, R0);
13985 __ sc(AT, addr);
13986 __ beq(AT, R0, again);
13987 __ delayed()->addiu(AT, R0, 0xFF);
13988 __ bind(failure);
13989 __ sync();
13990 }
13991 %}
13993 ins_pipe( long_memory_op );
13994 %}
13996 // Conditional-store of a long value.
13997 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
13998 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
13999 %{
14000 match(Set cr (StoreLConditional mem (Binary oldval newval)));
14001 effect(KILL oldval);
14003 format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
14004 ins_encode%{
14005 Register oldval = $oldval$$Register;
14006 Register newval = $newval$$Register;
14007 Address addr((Register)$mem$$base, $mem$$disp);
14009 int index = $mem$$index;
14010 int scale = $mem$$scale;
14011 int disp = $mem$$disp;
14013 guarantee(Assembler::is_simm16(disp), "");
14015 if( index != 0 ) {
14016 __ stop("in storeIConditional: index != 0");
14017 } else {
14018 __ cmpxchg(newval, addr, oldval);
14019 }
14020 %}
14021 ins_pipe( long_memory_op );
14022 %}
14025 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
14026 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
14027 effect(KILL oldval);
14028 // match(CompareAndSwapI mem_ptr (Binary oldval newval));
14029 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapL\n\t"
14030 "MOV $res, 1 @ compareAndSwapI\n\t"
14031 "BNE AT, R0 @ compareAndSwapI\n\t"
14032 "MOV $res, 0 @ compareAndSwapI\n"
14033 "L:" %}
14034 ins_encode %{
14035 Register newval = $newval$$Register;
14036 Register oldval = $oldval$$Register;
14037 Register res = $res$$Register;
14038 Address addr($mem_ptr$$Register, 0);
14039 Label L;
14041 __ cmpxchg32(newval, addr, oldval);
14042 __ move(res, AT);
14043 %}
14044 ins_pipe( long_memory_op );
14045 %}
14047 instruct compareAndSwapL( mRegI res, mRegP mem_ptr, s2RegL oldval, mRegL newval) %{
14048 predicate(VM_Version::supports_cx8());
14049 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
14050 effect(KILL oldval);
14051 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
14052 "MOV $res, 1 @ compareAndSwapI\n\t"
14053 "BNE AT, R0 @ compareAndSwapI\n\t"
14054 "MOV $res, 0 @ compareAndSwapI\n"
14055 "L:" %}
14056 ins_encode %{
14057 Register newval = $newval$$Register;
14058 Register oldval = $oldval$$Register;
14059 Register res = $res$$Register;
14060 Address addr($mem_ptr$$Register, 0);
14061 Label L;
14063 __ cmpxchg(newval, addr, oldval);
14064 __ move(res, AT);
14065 %}
14066 ins_pipe( long_memory_op );
14067 %}
14069 //FIXME:
14070 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
14071 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
14072 effect(KILL oldval);
14073 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
14074 "MOV $res, AT @ compareAndSwapP\n\t"
14075 "L:" %}
14076 ins_encode %{
14077 Register newval = $newval$$Register;
14078 Register oldval = $oldval$$Register;
14079 Register res = $res$$Register;
14080 Address addr($mem_ptr$$Register, 0);
14081 Label L;
14083 __ cmpxchg(newval, addr, oldval);
14084 __ move(res, AT);
14085 %}
14086 ins_pipe( long_memory_op );
14087 %}
14089 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
14090 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
14091 effect(KILL oldval);
14092 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
14093 "MOV $res, AT @ compareAndSwapN\n\t"
14094 "L:" %}
14095 ins_encode %{
14096 Register newval = $newval$$Register;
14097 Register oldval = $oldval$$Register;
14098 Register res = $res$$Register;
14099 Address addr($mem_ptr$$Register, 0);
14100 Label L;
14102 /* 2013/7/19 Jin: cmpxchg32 is implemented with ll/sc, which will do sign extension.
14103 * Thus, we should extend oldval's sign for correct comparision.
14104 */
14105 __ sll(oldval, oldval, 0);
14107 __ cmpxchg32(newval, addr, oldval);
14108 __ move(res, AT);
14109 %}
14110 ins_pipe( long_memory_op );
14111 %}
14113 //----------Max and Min--------------------------------------------------------
14114 // Min Instructions
14115 ////
14116 // *** Min and Max using the conditional move are slower than the
14117 // *** branch version on a Pentium III.
14118 // // Conditional move for min
14119 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
14120 // effect( USE_DEF op2, USE op1, USE cr );
14121 // format %{ "CMOVlt $op2,$op1\t! min" %}
14122 // opcode(0x4C,0x0F);
14123 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
14124 // ins_pipe( pipe_cmov_reg );
14125 //%}
14126 //
14127 //// Min Register with Register (P6 version)
14128 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
14129 // predicate(VM_Version::supports_cmov() );
14130 // match(Set op2 (MinI op1 op2));
14131 // ins_cost(200);
14132 // expand %{
14133 // eFlagsReg cr;
14134 // compI_eReg(cr,op1,op2);
14135 // cmovI_reg_lt(op2,op1,cr);
14136 // %}
14137 //%}
14139 // Min Register with Register (generic version)
14140 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
14141 match(Set dst (MinI dst src));
14142 //effect(KILL flags);
14143 ins_cost(80);
14145 format %{ "MIN $dst, $src @minI_Reg_Reg" %}
14146 ins_encode %{
14147 Register dst = $dst$$Register;
14148 Register src = $src$$Register;
14150 __ slt(AT, src, dst);
14151 __ movn(dst, src, AT);
14153 %}
14155 ins_pipe( pipe_slow );
14156 %}
14158 // Max Register with Register
14159 // *** Min and Max using the conditional move are slower than the
14160 // *** branch version on a Pentium III.
14161 // // Conditional move for max
14162 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
14163 // effect( USE_DEF op2, USE op1, USE cr );
14164 // format %{ "CMOVgt $op2,$op1\t! max" %}
14165 // opcode(0x4F,0x0F);
14166 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
14167 // ins_pipe( pipe_cmov_reg );
14168 //%}
14169 //
14170 // // Max Register with Register (P6 version)
14171 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
14172 // predicate(VM_Version::supports_cmov() );
14173 // match(Set op2 (MaxI op1 op2));
14174 // ins_cost(200);
14175 // expand %{
14176 // eFlagsReg cr;
14177 // compI_eReg(cr,op1,op2);
14178 // cmovI_reg_gt(op2,op1,cr);
14179 // %}
14180 //%}
14182 // Max Register with Register (generic version)
14183 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
14184 match(Set dst (MaxI dst src));
14185 ins_cost(80);
14187 format %{ "MAX $dst, $src @maxI_Reg_Reg" %}
14189 ins_encode %{
14190 Register dst = $dst$$Register;
14191 Register src = $src$$Register;
14193 __ slt(AT, dst, src);
14194 __ movn(dst, src, AT);
14196 %}
14198 ins_pipe( pipe_slow );
14199 %}
14201 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
14202 match(Set dst (MaxI dst zero));
14203 ins_cost(50);
14205 format %{ "MAX $dst, 0 @maxI_Reg_zero" %}
14207 ins_encode %{
14208 Register dst = $dst$$Register;
14210 __ slt(AT, dst, R0);
14211 __ movn(dst, R0, AT);
14213 %}
14215 ins_pipe( pipe_slow );
14216 %}
14218 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
14219 %{
14220 match(Set dst (AndL src mask));
14222 format %{ "movl $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
14223 ins_encode %{
14224 Register dst = $dst$$Register;
14225 Register src = $src$$Register;
14227 __ dext(dst, src, 0, 32);
14228 %}
14229 ins_pipe(ialu_regI_regI);
14230 %}
14232 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
14233 %{
14234 match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
14236 format %{ "combine_i2l $dst, $src2(H), $src1(L) @ combine_i2l" %}
14237 ins_encode %{
14238 Register dst = $dst$$Register;
14239 Register src1 = $src1$$Register;
14240 Register src2 = $src2$$Register;
14242 if (src1 == dst) {
14243 __ dinsu(dst, src2, 32, 32);
14244 } else if (src2 == dst) {
14245 __ dsll32(dst, dst, 0);
14246 __ dins(dst, src1, 0, 32);
14247 } else {
14248 __ dext(dst, src1, 0, 32);
14249 __ dinsu(dst, src2, 32, 32);
14250 }
14251 %}
14252 ins_pipe(ialu_regI_regI);
14253 %}
14255 // Zero-extend convert int to long
14256 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
14257 %{
14258 match(Set dst (AndL (ConvI2L src) mask));
14260 format %{ "movl $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
14261 ins_encode %{
14262 Register dst = $dst$$Register;
14263 Register src = $src$$Register;
14265 __ dext(dst, src, 0, 32);
14266 %}
14267 ins_pipe(ialu_regI_regI);
14268 %}
14270 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
14271 %{
14272 match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
14274 format %{ "movl $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
14275 ins_encode %{
14276 Register dst = $dst$$Register;
14277 Register src = $src$$Register;
14279 __ dext(dst, src, 0, 32);
14280 %}
14281 ins_pipe(ialu_regI_regI);
14282 %}
14284 // Match loading integer and casting it to unsigned int in long register.
14285 // LoadI + ConvI2L + AndL 0xffffffff.
14286 instruct loadUI2L_rmask(mRegL dst, memory mem, immL_32bits mask) %{
14287 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
14289 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
14290 ins_encode (load_N_enc(dst, mem));
14291 ins_pipe(ialu_loadI);
14292 %}
14294 instruct loadUI2L_lmask(mRegL dst, memory mem, immL_32bits mask) %{
14295 match(Set dst (AndL mask (ConvI2L (LoadI mem))));
14297 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
14298 ins_encode (load_N_enc(dst, mem));
14299 ins_pipe(ialu_loadI);
14300 %}
14303 // ============================================================================
14304 // Safepoint Instruction
14305 instruct safePoint_poll_reg(mRegP poll) %{
14306 match(SafePoint poll);
14307 predicate(false);
14308 effect(USE poll);
14310 ins_cost(125);
14311 format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
14313 ins_encode %{
14314 Register poll_reg = $poll$$Register;
14316 __ block_comment("Safepoint:");
14317 __ relocate(relocInfo::poll_type);
14318 __ lw(AT, poll_reg, 0);
14319 %}
14321 ins_pipe( ialu_storeI );
14322 %}
14324 instruct safePoint_poll() %{
14325 match(SafePoint);
14327 ins_cost(105);
14328 format %{ "poll for GC @ safePoint_poll" %}
14330 ins_encode %{
14331 __ block_comment("Safepoint:");
14332 __ set64(T9, (long)os::get_polling_page());
14333 __ relocate(relocInfo::poll_type);
14334 __ lw(AT, T9, 0);
14335 %}
14337 ins_pipe( ialu_storeI );
14338 %}
14340 //----------Arithmetic Conversion Instructions---------------------------------
14342 instruct roundFloat_nop(regF dst)
14343 %{
14344 match(Set dst (RoundFloat dst));
14346 ins_cost(0);
14347 ins_encode();
14348 ins_pipe(empty);
14349 %}
14351 instruct roundDouble_nop(regD dst)
14352 %{
14353 match(Set dst (RoundDouble dst));
14355 ins_cost(0);
14356 ins_encode();
14357 ins_pipe(empty);
14358 %}
14360 //---------- Zeros Count Instructions ------------------------------------------
14361 // CountLeadingZerosINode CountTrailingZerosINode
14362 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
14363 predicate(UseCountLeadingZerosInstruction);
14364 match(Set dst (CountLeadingZerosI src));
14366 format %{ "clz $dst, $src\t# count leading zeros (int)" %}
14367 ins_encode %{
14368 __ clz($dst$$Register, $src$$Register);
14369 %}
14370 ins_pipe( ialu_regL_regL );
14371 %}
14373 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
14374 predicate(UseCountLeadingZerosInstruction);
14375 match(Set dst (CountLeadingZerosL src));
14377 format %{ "dclz $dst, $src\t# count leading zeros (long)" %}
14378 ins_encode %{
14379 __ dclz($dst$$Register, $src$$Register);
14380 %}
14381 ins_pipe( ialu_regL_regL );
14382 %}
14384 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
14385 predicate(UseCountTrailingZerosInstruction);
14386 match(Set dst (CountTrailingZerosI src));
14388 format %{ "ctz $dst, $src\t# count trailing zeros (int)" %}
14389 ins_encode %{
14390 // ctz and dctz is gs instructions.
14391 __ ctz($dst$$Register, $src$$Register);
14392 %}
14393 ins_pipe( ialu_regL_regL );
14394 %}
14396 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
14397 predicate(UseCountTrailingZerosInstruction);
14398 match(Set dst (CountTrailingZerosL src));
14400 format %{ "dcto $dst, $src\t# count trailing zeros (long)" %}
14401 ins_encode %{
14402 __ dctz($dst$$Register, $src$$Register);
14403 %}
14404 ins_pipe( ialu_regL_regL );
14405 %}
14407 // ====================VECTOR INSTRUCTIONS=====================================
14409 // Load vectors (8 bytes long)
14410 instruct loadV8(vecD dst, memory mem) %{
14411 predicate(n->as_LoadVector()->memory_size() == 8);
14412 match(Set dst (LoadVector mem));
14413 ins_cost(125);
14414 format %{ "load $dst, $mem\t! load vector (8 bytes)" %}
14415 ins_encode(load_D_enc(dst, mem));
14416 ins_pipe( fpu_loadF );
14417 %}
14419 // Store vectors (8 bytes long)
14420 instruct storeV8(memory mem, vecD src) %{
14421 predicate(n->as_StoreVector()->memory_size() == 8);
14422 match(Set mem (StoreVector mem src));
14423 ins_cost(145);
14424 format %{ "store $mem, $src\t! store vector (8 bytes)" %}
14425 ins_encode(store_D_reg_enc(mem, src));
14426 ins_pipe( fpu_storeF );
14427 %}
14429 instruct Repl8B_DSP(vecD dst, mRegI src) %{
14430 predicate(n->as_Vector()->length() == 8 && Use3A2000);
14431 match(Set dst (ReplicateB src));
14432 ins_cost(100);
14433 format %{ "replv_ob AT, $src\n\t"
14434 "dmtc1 AT, $dst\t! replicate8B" %}
14435 ins_encode %{
14436 __ replv_ob(AT, $src$$Register);
14437 __ dmtc1(AT, $dst$$FloatRegister);
14438 %}
14439 ins_pipe( pipe_mtc1 );
14440 %}
14442 instruct Repl8B(vecD dst, mRegI src) %{
14443 predicate(n->as_Vector()->length() == 8);
14444 match(Set dst (ReplicateB src));
14445 ins_cost(140);
14446 format %{ "move AT, $src\n\t"
14447 "dins AT, AT, 8, 8\n\t"
14448 "dins AT, AT, 16, 16\n\t"
14449 "dinsu AT, AT, 32, 32\n\t"
14450 "dmtc1 AT, $dst\t! replicate8B" %}
14451 ins_encode %{
14452 __ move(AT, $src$$Register);
14453 __ dins(AT, AT, 8, 8);
14454 __ dins(AT, AT, 16, 16);
14455 __ dinsu(AT, AT, 32, 32);
14456 __ dmtc1(AT, $dst$$FloatRegister);
14457 %}
14458 ins_pipe( pipe_mtc1 );
14459 %}
14461 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
14462 predicate(n->as_Vector()->length() == 8 && Use3A2000);
14463 match(Set dst (ReplicateB con));
14464 ins_cost(110);
14465 format %{ "repl_ob AT, [$con]\n\t"
14466 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
14467 ins_encode %{
14468 int val = $con$$constant;
14469 __ repl_ob(AT, val);
14470 __ dmtc1(AT, $dst$$FloatRegister);
14471 %}
14472 ins_pipe( pipe_mtc1 );
14473 %}
14475 instruct Repl8B_imm(vecD dst, immI con) %{
14476 predicate(n->as_Vector()->length() == 8);
14477 match(Set dst (ReplicateB con));
14478 ins_cost(150);
14479 format %{ "move AT, [$con]\n\t"
14480 "dins AT, AT, 8, 8\n\t"
14481 "dins AT, AT, 16, 16\n\t"
14482 "dinsu AT, AT, 32, 32\n\t"
14483 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
14484 ins_encode %{
14485 __ move(AT, $con$$constant);
14486 __ dins(AT, AT, 8, 8);
14487 __ dins(AT, AT, 16, 16);
14488 __ dinsu(AT, AT, 32, 32);
14489 __ dmtc1(AT, $dst$$FloatRegister);
14490 %}
14491 ins_pipe( pipe_mtc1 );
14492 %}
14494 instruct Repl8B_zero(vecD dst, immI0 zero) %{
14495 predicate(n->as_Vector()->length() == 8);
14496 match(Set dst (ReplicateB zero));
14497 ins_cost(90);
14498 format %{ "dmtc1 R0, $dst\t! replicate8B zero" %}
14499 ins_encode %{
14500 __ dmtc1(R0, $dst$$FloatRegister);
14501 %}
14502 ins_pipe( pipe_mtc1 );
14503 %}
14505 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
14506 predicate(n->as_Vector()->length() == 8);
14507 match(Set dst (ReplicateB M1));
14508 ins_cost(80);
14509 format %{ "dmtc1 -1, $dst\t! replicate8B -1" %}
14510 ins_encode %{
14511 __ nor(AT, R0, R0);
14512 __ dmtc1(AT, $dst$$FloatRegister);
14513 %}
14514 ins_pipe( pipe_mtc1 );
14515 %}
14517 instruct Repl4S_DSP(vecD dst, mRegI src) %{
14518 predicate(n->as_Vector()->length() == 4 && Use3A2000);
14519 match(Set dst (ReplicateS src));
14520 ins_cost(100);
14521 format %{ "replv_qh AT, $src\n\t"
14522 "dmtc1 AT, $dst\t! replicate4S" %}
14523 ins_encode %{
14524 __ replv_qh(AT, $src$$Register);
14525 __ dmtc1(AT, $dst$$FloatRegister);
14526 %}
14527 ins_pipe( pipe_mtc1 );
14528 %}
14530 instruct Repl4S(vecD dst, mRegI src) %{
14531 predicate(n->as_Vector()->length() == 4);
14532 match(Set dst (ReplicateS src));
14533 ins_cost(120);
14534 format %{ "move AT, $src \n\t"
14535 "dins AT, AT, 16, 16\n\t"
14536 "dinsu AT, AT, 32, 32\n\t"
14537 "dmtc1 AT, $dst\t! replicate4S" %}
14538 ins_encode %{
14539 __ move(AT, $src$$Register);
14540 __ dins(AT, AT, 16, 16);
14541 __ dinsu(AT, AT, 32, 32);
14542 __ dmtc1(AT, $dst$$FloatRegister);
14543 %}
14544 ins_pipe( pipe_mtc1 );
14545 %}
14547 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
14548 predicate(n->as_Vector()->length() == 4 && Use3A2000);
14549 match(Set dst (ReplicateS con));
14550 ins_cost(100);
14551 format %{ "repl_qh AT, [$con]\n\t"
14552 "dmtc1 AT, $dst\t! replicate4S($con)" %}
14553 ins_encode %{
14554 int val = $con$$constant;
14555 if ( Assembler::is_simm(val, 10)) {
14556 //repl_qh supports 10 bits immediate
14557 __ repl_qh(AT, val);
14558 } else {
14559 __ li32(AT, val);
14560 __ replv_qh(AT, AT);
14561 }
14562 __ dmtc1(AT, $dst$$FloatRegister);
14563 %}
14564 ins_pipe( pipe_mtc1 );
14565 %}
14567 instruct Repl4S_imm(vecD dst, immI con) %{
14568 predicate(n->as_Vector()->length() == 4);
14569 match(Set dst (ReplicateS con));
14570 ins_cost(110);
14571 format %{ "move AT, [$con]\n\t"
14572 "dins AT, AT, 16, 16\n\t"
14573 "dinsu AT, AT, 32, 32\n\t"
14574 "dmtc1 AT, $dst\t! replicate4S($con)" %}
14575 ins_encode %{
14576 __ move(AT, $con$$constant);
14577 __ dins(AT, AT, 16, 16);
14578 __ dinsu(AT, AT, 32, 32);
14579 __ dmtc1(AT, $dst$$FloatRegister);
14580 %}
14581 ins_pipe( pipe_mtc1 );
14582 %}
14584 instruct Repl4S_zero(vecD dst, immI0 zero) %{
14585 predicate(n->as_Vector()->length() == 4);
14586 match(Set dst (ReplicateS zero));
14587 format %{ "dmtc1 R0, $dst\t! replicate4S zero" %}
14588 ins_encode %{
14589 __ dmtc1(R0, $dst$$FloatRegister);
14590 %}
14591 ins_pipe( pipe_mtc1 );
14592 %}
14594 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
14595 predicate(n->as_Vector()->length() == 4);
14596 match(Set dst (ReplicateS M1));
14597 format %{ "dmtc1 -1, $dst\t! replicate4S -1" %}
14598 ins_encode %{
14599 __ nor(AT, R0, R0);
14600 __ dmtc1(AT, $dst$$FloatRegister);
14601 %}
14602 ins_pipe( pipe_mtc1 );
14603 %}
14605 // Replicate integer (4 byte) scalar to be vector
14606 instruct Repl2I(vecD dst, mRegI src) %{
14607 predicate(n->as_Vector()->length() == 2);
14608 match(Set dst (ReplicateI src));
14609 format %{ "dins AT, $src, 0, 32\n\t"
14610 "dinsu AT, $src, 32, 32\n\t"
14611 "dmtc1 AT, $dst\t! replicate2I" %}
14612 ins_encode %{
14613 __ dins(AT, $src$$Register, 0, 32);
14614 __ dinsu(AT, $src$$Register, 32, 32);
14615 __ dmtc1(AT, $dst$$FloatRegister);
14616 %}
14617 ins_pipe( pipe_mtc1 );
14618 %}
14620 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
14621 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
14622 predicate(n->as_Vector()->length() == 2);
14623 match(Set dst (ReplicateI con));
14624 effect(KILL tmp);
14625 format %{ "li32 AT, [$con], 32\n\t"
14626 "dinsu AT, AT\n\t"
14627 "dmtc1 AT, $dst\t! replicate2I($con)" %}
14628 ins_encode %{
14629 int val = $con$$constant;
14630 __ li32(AT, val);
14631 __ dinsu(AT, AT, 32, 32);
14632 __ dmtc1(AT, $dst$$FloatRegister);
14633 %}
14634 ins_pipe( pipe_mtc1 );
14635 %}
14637 // Replicate integer (4 byte) scalar zero to be vector
14638 instruct Repl2I_zero(vecD dst, immI0 zero) %{
14639 predicate(n->as_Vector()->length() == 2);
14640 match(Set dst (ReplicateI zero));
14641 format %{ "dmtc1 R0, $dst\t! replicate2I zero" %}
14642 ins_encode %{
14643 __ dmtc1(R0, $dst$$FloatRegister);
14644 %}
14645 ins_pipe( pipe_mtc1 );
14646 %}
14648 // Replicate integer (4 byte) scalar -1 to be vector
14649 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
14650 predicate(n->as_Vector()->length() == 2);
14651 match(Set dst (ReplicateI M1));
14652 format %{ "dmtc1 -1, $dst\t! replicate2I -1, use AT" %}
14653 ins_encode %{
14654 __ nor(AT, R0, R0);
14655 __ dmtc1(AT, $dst$$FloatRegister);
14656 %}
14657 ins_pipe( pipe_mtc1 );
14658 %}
14660 // Replicate float (4 byte) scalar to be vector
14661 instruct Repl2F(vecD dst, regF src) %{
14662 predicate(n->as_Vector()->length() == 2);
14663 match(Set dst (ReplicateF src));
14664 format %{ "cvt.ps $dst, $src, $src\t! replicate2F" %}
14665 ins_encode %{
14666 __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
14667 %}
14668 ins_pipe( pipe_slow );
14669 %}
14671 // Replicate float (4 byte) scalar zero to be vector
14672 instruct Repl2F_zero(vecD dst, immF0 zero) %{
14673 predicate(n->as_Vector()->length() == 2);
14674 match(Set dst (ReplicateF zero));
14675 format %{ "dmtc1 R0, $dst\t! replicate2F zero" %}
14676 ins_encode %{
14677 __ dmtc1(R0, $dst$$FloatRegister);
14678 %}
14679 ins_pipe( pipe_mtc1 );
14680 %}
14683 // ====================VECTOR ARITHMETIC=======================================
14685 // --------------------------------- ADD --------------------------------------
14687 // Floats vector add
14688 // kernel does not have emulation of PS instructions yet, so PS instructions is disabled.
14689 instruct vadd2F(vecD dst, vecD src) %{
14690 predicate(n->as_Vector()->length() == 2);
14691 match(Set dst (AddVF dst src));
14692 format %{ "add.ps $dst,$src\t! add packed2F" %}
14693 ins_encode %{
14694 __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14695 %}
14696 ins_pipe( pipe_slow );
14697 %}
14699 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
14700 predicate(n->as_Vector()->length() == 2);
14701 match(Set dst (AddVF src1 src2));
14702 format %{ "add.ps $dst,$src1,$src2\t! add packed2F" %}
14703 ins_encode %{
14704 __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14705 %}
14706 ins_pipe( fpu_regF_regF );
14707 %}
14709 // --------------------------------- SUB --------------------------------------
14711 // Floats vector sub
14712 instruct vsub2F(vecD dst, vecD src) %{
14713 predicate(n->as_Vector()->length() == 2);
14714 match(Set dst (SubVF dst src));
14715 format %{ "sub.ps $dst,$src\t! sub packed2F" %}
14716 ins_encode %{
14717 __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14718 %}
14719 ins_pipe( fpu_regF_regF );
14720 %}
14722 // --------------------------------- MUL --------------------------------------
14724 // Floats vector mul
14725 instruct vmul2F(vecD dst, vecD src) %{
14726 predicate(n->as_Vector()->length() == 2);
14727 match(Set dst (MulVF dst src));
14728 format %{ "mul.ps $dst, $src\t! mul packed2F" %}
14729 ins_encode %{
14730 __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
14731 %}
14732 ins_pipe( fpu_regF_regF );
14733 %}
14735 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
14736 predicate(n->as_Vector()->length() == 2);
14737 match(Set dst (MulVF src1 src2));
14738 format %{ "mul.ps $dst, $src1, $src2\t! mul packed2F" %}
14739 ins_encode %{
14740 __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14741 %}
14742 ins_pipe( fpu_regF_regF );
14743 %}
14745 // --------------------------------- DIV --------------------------------------
14746 // MIPS do not have div.ps
14748 // --------------------------------- MADD --------------------------------------
14749 // Floats vector madd
14750 //instruct vmadd2F(vecD dst, vecD src1, vecD src2, vecD src3) %{
14751 // predicate(n->as_Vector()->length() == 2);
14752 // match(Set dst (AddVF (MulVF src1 src2) src3));
14753 // ins_cost(50);
14754 // format %{ "madd.ps $dst, $src3, $src1, $src2\t! madd packed2F" %}
14755 // ins_encode %{
14756 // __ madd_ps($dst$$FloatRegister, $src3$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
14757 // %}
14758 // ins_pipe( fpu_regF_regF );
14759 //%}
14762 //----------PEEPHOLE RULES-----------------------------------------------------
14763 // These must follow all instruction definitions as they use the names
14764 // defined in the instructions definitions.
14765 //
14766 // peepmatch ( root_instr_name [preceeding_instruction]* );
14767 //
14768 // peepconstraint %{
14769 // (instruction_number.operand_name relational_op instruction_number.operand_name
14770 // [, ...] );
14771 // // instruction numbers are zero-based using left to right order in peepmatch
14772 //
14773 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
14774 // // provide an instruction_number.operand_name for each operand that appears
14775 // // in the replacement instruction's match rule
14776 //
14777 // ---------VM FLAGS---------------------------------------------------------
14778 //
14779 // All peephole optimizations can be turned off using -XX:-OptoPeephole
14780 //
14781 // Each peephole rule is given an identifying number starting with zero and
14782 // increasing by one in the order seen by the parser. An individual peephole
14783 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
14784 // on the command-line.
14785 //
14786 // ---------CURRENT LIMITATIONS----------------------------------------------
14787 //
14788 // Only match adjacent instructions in same basic block
14789 // Only equality constraints
14790 // Only constraints between operands, not (0.dest_reg == EAX_enc)
14791 // Only one replacement instruction
14792 //
14793 // ---------EXAMPLE----------------------------------------------------------
14794 //
14795 // // pertinent parts of existing instructions in architecture description
14796 // instruct movI(eRegI dst, eRegI src) %{
14797 // match(Set dst (CopyI src));
14798 // %}
14799 //
14800 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
14801 // match(Set dst (AddI dst src));
14802 // effect(KILL cr);
14803 // %}
14804 //
14805 // // Change (inc mov) to lea
14806 // peephole %{
14807 // // increment preceeded by register-register move
14808 // peepmatch ( incI_eReg movI );
14809 // // require that the destination register of the increment
14810 // // match the destination register of the move
14811 // peepconstraint ( 0.dst == 1.dst );
14812 // // construct a replacement instruction that sets
14813 // // the destination to ( move's source register + one )
14814 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14815 // %}
14816 //
14817 // Implementation no longer uses movX instructions since
14818 // machine-independent system no longer uses CopyX nodes.
14819 //
14820 // peephole %{
14821 // peepmatch ( incI_eReg movI );
14822 // peepconstraint ( 0.dst == 1.dst );
14823 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14824 // %}
14825 //
14826 // peephole %{
14827 // peepmatch ( decI_eReg movI );
14828 // peepconstraint ( 0.dst == 1.dst );
14829 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14830 // %}
14831 //
14832 // peephole %{
14833 // peepmatch ( addI_eReg_imm movI );
14834 // peepconstraint ( 0.dst == 1.dst );
14835 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
14836 // %}
14837 //
14838 // peephole %{
14839 // peepmatch ( addP_eReg_imm movP );
14840 // peepconstraint ( 0.dst == 1.dst );
14841 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
14842 // %}
14844 // // Change load of spilled value to only a spill
14845 // instruct storeI(memory mem, eRegI src) %{
14846 // match(Set mem (StoreI mem src));
14847 // %}
14848 //
14849 // instruct loadI(eRegI dst, memory mem) %{
14850 // match(Set dst (LoadI mem));
14851 // %}
14852 //
14853 //peephole %{
14854 // peepmatch ( loadI storeI );
14855 // peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
14856 // peepreplace ( storeI( 1.mem 1.mem 1.src ) );
14857 //%}
14859 //----------SMARTSPILL RULES---------------------------------------------------
14860 // These must follow all instruction definitions as they use the names
14861 // defined in the instructions definitions.