Wed, 07 Feb 2018 15:44:45 +0800
Follows 5e952d5ef68a, the cost of sync is high.
1 //
2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3 // Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
4 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 //
6 // This code is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License version 2 only, as
8 // published by the Free Software Foundation.
9 //
10 // This code is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 // version 2 for more details (a copy is included in the LICENSE file that
14 // accompanied this code).
15 //
16 // You should have received a copy of the GNU General Public License version
17 // 2 along with this work; if not, write to the Free Software Foundation,
18 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 // or visit www.oracle.com if you need additional information or have any
22 // questions.
23 //
24 //
26 // GodSon3 Architecture Description File
28 //----------REGISTER DEFINITION BLOCK------------------------------------------
29 // This information is used by the matcher and the register allocator to
30 // describe individual registers and classes of registers within the target
31 // archtecture.
33 // format:
34 // reg_def name (call convention, c-call convention, ideal type, encoding);
35 // call convention :
36 // NS = No-Save
37 // SOC = Save-On-Call
38 // SOE = Save-On-Entry
39 // AS = Always-Save
40 // ideal type :
41 // see opto/opcodes.hpp for more info
42 // reg_class name (reg, ...);
43 // alloc_class name (reg, ...);
44 register %{
46 // General Registers
47 // Integer Registers
48 reg_def R0 ( NS, NS, Op_RegI, 0, VMRegImpl::Bad());
49 reg_def AT ( NS, NS, Op_RegI, 1, AT->as_VMReg());
50 reg_def AT_H ( NS, NS, Op_RegI, 1, AT->as_VMReg()->next());
51 reg_def V0 (SOC, SOC, Op_RegI, 2, V0->as_VMReg());
52 reg_def V0_H (SOC, SOC, Op_RegI, 2, V0->as_VMReg()->next());
53 reg_def V1 (SOC, SOC, Op_RegI, 3, V1->as_VMReg());
54 reg_def V1_H (SOC, SOC, Op_RegI, 3, V1->as_VMReg()->next());
55 reg_def A0 (SOC, SOC, Op_RegI, 4, A0->as_VMReg());
56 reg_def A0_H (SOC, SOC, Op_RegI, 4, A0->as_VMReg()->next());
57 reg_def A1 (SOC, SOC, Op_RegI, 5, A1->as_VMReg());
58 reg_def A1_H (SOC, SOC, Op_RegI, 5, A1->as_VMReg()->next());
59 reg_def A2 (SOC, SOC, Op_RegI, 6, A2->as_VMReg());
60 reg_def A2_H (SOC, SOC, Op_RegI, 6, A2->as_VMReg()->next());
61 reg_def A3 (SOC, SOC, Op_RegI, 7, A3->as_VMReg());
62 reg_def A3_H (SOC, SOC, Op_RegI, 7, A3->as_VMReg()->next());
63 reg_def A4 (SOC, SOC, Op_RegI, 8, A4->as_VMReg());
64 reg_def A4_H (SOC, SOC, Op_RegI, 8, A4->as_VMReg()->next());
65 reg_def A5 (SOC, SOC, Op_RegI, 9, A5->as_VMReg());
66 reg_def A5_H (SOC, SOC, Op_RegI, 9, A5->as_VMReg()->next());
67 reg_def A6 (SOC, SOC, Op_RegI, 10, A6->as_VMReg());
68 reg_def A6_H (SOC, SOC, Op_RegI, 10, A6->as_VMReg()->next());
69 reg_def A7 (SOC, SOC, Op_RegI, 11, A7->as_VMReg());
70 reg_def A7_H (SOC, SOC, Op_RegI, 11, A7->as_VMReg()->next());
71 reg_def T0 (SOC, SOC, Op_RegI, 12, T0->as_VMReg());
72 reg_def T0_H (SOC, SOC, Op_RegI, 12, T0->as_VMReg()->next());
73 reg_def T1 (SOC, SOC, Op_RegI, 13, T1->as_VMReg());
74 reg_def T1_H (SOC, SOC, Op_RegI, 13, T1->as_VMReg()->next());
75 reg_def T2 (SOC, SOC, Op_RegI, 14, T2->as_VMReg());
76 reg_def T2_H (SOC, SOC, Op_RegI, 14, T2->as_VMReg()->next());
77 reg_def T3 (SOC, SOC, Op_RegI, 15, T3->as_VMReg());
78 reg_def T3_H (SOC, SOC, Op_RegI, 15, T3->as_VMReg()->next());
79 reg_def S0 (SOC, SOE, Op_RegI, 16, S0->as_VMReg());
80 reg_def S0_H (SOC, SOE, Op_RegI, 16, S0->as_VMReg()->next());
81 reg_def S1 (SOC, SOE, Op_RegI, 17, S1->as_VMReg());
82 reg_def S1_H (SOC, SOE, Op_RegI, 17, S1->as_VMReg()->next());
83 reg_def S2 (SOC, SOE, Op_RegI, 18, S2->as_VMReg());
84 reg_def S2_H (SOC, SOE, Op_RegI, 18, S2->as_VMReg()->next());
85 reg_def S3 (SOC, SOE, Op_RegI, 19, S3->as_VMReg());
86 reg_def S3_H (SOC, SOE, Op_RegI, 19, S3->as_VMReg()->next());
87 reg_def S4 (SOC, SOE, Op_RegI, 20, S4->as_VMReg());
88 reg_def S4_H (SOC, SOE, Op_RegI, 20, S4->as_VMReg()->next());
89 reg_def S5 (SOC, SOE, Op_RegI, 21, S5->as_VMReg());
90 reg_def S5_H (SOC, SOE, Op_RegI, 21, S5->as_VMReg()->next());
91 reg_def S6 (SOC, SOE, Op_RegI, 22, S6->as_VMReg());
92 reg_def S6_H (SOC, SOE, Op_RegI, 22, S6->as_VMReg()->next());
93 reg_def S7 (SOC, SOE, Op_RegI, 23, S7->as_VMReg());
94 reg_def S7_H (SOC, SOE, Op_RegI, 23, S7->as_VMReg()->next());
95 reg_def T8 (SOC, SOC, Op_RegI, 24, T8->as_VMReg());
96 reg_def T8_H (SOC, SOC, Op_RegI, 24, T8->as_VMReg()->next());
97 reg_def T9 (SOC, SOC, Op_RegI, 25, T9->as_VMReg());
98 reg_def T9_H (SOC, SOC, Op_RegI, 25, T9->as_VMReg()->next());
100 // Special Registers
101 reg_def K0 ( NS, NS, Op_RegI, 26, K0->as_VMReg());
102 reg_def K1 ( NS, NS, Op_RegI, 27, K1->as_VMReg());
103 reg_def GP ( NS, NS, Op_RegI, 28, GP->as_VMReg());
104 reg_def GP_H ( NS, NS, Op_RegI, 28, GP->as_VMReg()->next());
105 reg_def SP ( NS, NS, Op_RegI, 29, SP->as_VMReg());
106 reg_def SP_H ( NS, NS, Op_RegI, 29, SP->as_VMReg()->next());
107 reg_def FP ( NS, NS, Op_RegI, 30, FP->as_VMReg());
108 reg_def FP_H ( NS, NS, Op_RegI, 30, FP->as_VMReg()->next());
109 reg_def RA ( NS, NS, Op_RegI, 31, RA->as_VMReg());
110 reg_def RA_H ( NS, NS, Op_RegI, 31, RA->as_VMReg()->next());
112 // Floating registers.
113 reg_def F0 ( SOC, SOC, Op_RegF, 0, F0->as_VMReg());
114 reg_def F0_H ( SOC, SOC, Op_RegF, 0, F0->as_VMReg()->next());
115 reg_def F1 ( SOC, SOC, Op_RegF, 1, F1->as_VMReg());
116 reg_def F1_H ( SOC, SOC, Op_RegF, 1, F1->as_VMReg()->next());
117 reg_def F2 ( SOC, SOC, Op_RegF, 2, F2->as_VMReg());
118 reg_def F2_H ( SOC, SOC, Op_RegF, 2, F2->as_VMReg()->next());
119 reg_def F3 ( SOC, SOC, Op_RegF, 3, F3->as_VMReg());
120 reg_def F3_H ( SOC, SOC, Op_RegF, 3, F3->as_VMReg()->next());
121 reg_def F4 ( SOC, SOC, Op_RegF, 4, F4->as_VMReg());
122 reg_def F4_H ( SOC, SOC, Op_RegF, 4, F4->as_VMReg()->next());
123 reg_def F5 ( SOC, SOC, Op_RegF, 5, F5->as_VMReg());
124 reg_def F5_H ( SOC, SOC, Op_RegF, 5, F5->as_VMReg()->next());
125 reg_def F6 ( SOC, SOC, Op_RegF, 6, F6->as_VMReg());
126 reg_def F6_H ( SOC, SOC, Op_RegF, 6, F6->as_VMReg()->next());
127 reg_def F7 ( SOC, SOC, Op_RegF, 7, F7->as_VMReg());
128 reg_def F7_H ( SOC, SOC, Op_RegF, 7, F7->as_VMReg()->next());
129 reg_def F8 ( SOC, SOC, Op_RegF, 8, F8->as_VMReg());
130 reg_def F8_H ( SOC, SOC, Op_RegF, 8, F8->as_VMReg()->next());
131 reg_def F9 ( SOC, SOC, Op_RegF, 9, F9->as_VMReg());
132 reg_def F9_H ( SOC, SOC, Op_RegF, 9, F9->as_VMReg()->next());
133 reg_def F10 ( SOC, SOC, Op_RegF, 10, F10->as_VMReg());
134 reg_def F10_H ( SOC, SOC, Op_RegF, 10, F10->as_VMReg()->next());
135 reg_def F11 ( SOC, SOC, Op_RegF, 11, F11->as_VMReg());
136 reg_def F11_H ( SOC, SOC, Op_RegF, 11, F11->as_VMReg()->next());
137 reg_def F12 ( SOC, SOC, Op_RegF, 12, F12->as_VMReg());
138 reg_def F12_H ( SOC, SOC, Op_RegF, 12, F12->as_VMReg()->next());
139 reg_def F13 ( SOC, SOC, Op_RegF, 13, F13->as_VMReg());
140 reg_def F13_H ( SOC, SOC, Op_RegF, 13, F13->as_VMReg()->next());
141 reg_def F14 ( SOC, SOC, Op_RegF, 14, F14->as_VMReg());
142 reg_def F14_H ( SOC, SOC, Op_RegF, 14, F14->as_VMReg()->next());
143 reg_def F15 ( SOC, SOC, Op_RegF, 15, F15->as_VMReg());
144 reg_def F15_H ( SOC, SOC, Op_RegF, 15, F15->as_VMReg()->next());
145 reg_def F16 ( SOC, SOC, Op_RegF, 16, F16->as_VMReg());
146 reg_def F16_H ( SOC, SOC, Op_RegF, 16, F16->as_VMReg()->next());
147 reg_def F17 ( SOC, SOC, Op_RegF, 17, F17->as_VMReg());
148 reg_def F17_H ( SOC, SOC, Op_RegF, 17, F17->as_VMReg()->next());
149 reg_def F18 ( SOC, SOC, Op_RegF, 18, F18->as_VMReg());
150 reg_def F18_H ( SOC, SOC, Op_RegF, 18, F18->as_VMReg()->next());
151 reg_def F19 ( SOC, SOC, Op_RegF, 19, F19->as_VMReg());
152 reg_def F19_H ( SOC, SOC, Op_RegF, 19, F19->as_VMReg()->next());
153 reg_def F20 ( SOC, SOC, Op_RegF, 20, F20->as_VMReg());
154 reg_def F20_H ( SOC, SOC, Op_RegF, 20, F20->as_VMReg()->next());
155 reg_def F21 ( SOC, SOC, Op_RegF, 21, F21->as_VMReg());
156 reg_def F21_H ( SOC, SOC, Op_RegF, 21, F21->as_VMReg()->next());
157 reg_def F22 ( SOC, SOC, Op_RegF, 22, F22->as_VMReg());
158 reg_def F22_H ( SOC, SOC, Op_RegF, 22, F22->as_VMReg()->next());
159 reg_def F23 ( SOC, SOC, Op_RegF, 23, F23->as_VMReg());
160 reg_def F23_H ( SOC, SOC, Op_RegF, 23, F23->as_VMReg()->next());
161 reg_def F24 ( SOC, SOC, Op_RegF, 24, F24->as_VMReg());
162 reg_def F24_H ( SOC, SOC, Op_RegF, 24, F24->as_VMReg()->next());
163 reg_def F25 ( SOC, SOC, Op_RegF, 25, F25->as_VMReg());
164 reg_def F25_H ( SOC, SOC, Op_RegF, 25, F25->as_VMReg()->next());
165 reg_def F26 ( SOC, SOC, Op_RegF, 26, F26->as_VMReg());
166 reg_def F26_H ( SOC, SOC, Op_RegF, 26, F26->as_VMReg()->next());
167 reg_def F27 ( SOC, SOC, Op_RegF, 27, F27->as_VMReg());
168 reg_def F27_H ( SOC, SOC, Op_RegF, 27, F27->as_VMReg()->next());
169 reg_def F28 ( SOC, SOC, Op_RegF, 28, F28->as_VMReg());
170 reg_def F28_H ( SOC, SOC, Op_RegF, 28, F28->as_VMReg()->next());
171 reg_def F29 ( SOC, SOC, Op_RegF, 29, F29->as_VMReg());
172 reg_def F29_H ( SOC, SOC, Op_RegF, 29, F29->as_VMReg()->next());
173 reg_def F30 ( SOC, SOC, Op_RegF, 30, F30->as_VMReg());
174 reg_def F30_H ( SOC, SOC, Op_RegF, 30, F30->as_VMReg()->next());
175 reg_def F31 ( SOC, SOC, Op_RegF, 31, F31->as_VMReg());
176 reg_def F31_H ( SOC, SOC, Op_RegF, 31, F31->as_VMReg()->next());
179 // ----------------------------
180 // Special Registers
181 // Condition Codes Flag Registers
182 reg_def MIPS_FLAG (SOC, SOC, Op_RegFlags, 1, as_Register(1)->as_VMReg());
183 //S6 is used for get_thread(S6)
184 //S5 is uesd for heapbase of compressed oop
185 alloc_class chunk0(
186 S7, S7_H,
187 S0, S0_H,
188 S1, S1_H,
189 S2, S2_H,
190 S4, S4_H,
191 S5, S5_H,
192 S6, S6_H,
193 S3, S3_H,
194 T2, T2_H,
195 T3, T3_H,
196 T8, T8_H,
197 T9, T9_H,
198 T1, T1_H, // inline_cache_reg
199 V1, V1_H,
200 A7, A7_H,
201 A6, A6_H,
202 A5, A5_H,
203 A4, A4_H,
204 V0, V0_H,
205 A3, A3_H,
206 A2, A2_H,
207 A1, A1_H,
208 A0, A0_H,
209 T0, T0_H,
210 GP, GP_H
211 RA, RA_H,
212 SP, SP_H, // stack_pointer
213 FP, FP_H // frame_pointer
214 );
216 alloc_class chunk1( F0, F0_H,
217 F1, F1_H,
218 F2, F2_H,
219 F3, F3_H,
220 F4, F4_H,
221 F5, F5_H,
222 F6, F6_H,
223 F7, F7_H,
224 F8, F8_H,
225 F9, F9_H,
226 F10, F10_H,
227 F11, F11_H,
228 F20, F20_H,
229 F21, F21_H,
230 F22, F22_H,
231 F23, F23_H,
232 F24, F24_H,
233 F25, F25_H,
234 F26, F26_H,
235 F27, F27_H,
236 F28, F28_H,
237 F19, F19_H,
238 F18, F18_H,
239 F17, F17_H,
240 F16, F16_H,
241 F15, F15_H,
242 F14, F14_H,
243 F13, F13_H,
244 F12, F12_H,
245 F29, F29_H,
246 F30, F30_H,
247 F31, F31_H);
249 alloc_class chunk2(MIPS_FLAG);
251 reg_class s_reg( S0, S1, S2, S3, S4, S5, S6, S7 );
252 reg_class s0_reg( S0 );
253 reg_class s1_reg( S1 );
254 reg_class s2_reg( S2 );
255 reg_class s3_reg( S3 );
256 reg_class s4_reg( S4 );
257 reg_class s5_reg( S5 );
258 reg_class s6_reg( S6 );
259 reg_class s7_reg( S7 );
261 reg_class t_reg( T0, T1, T2, T3, T8, T9 );
262 reg_class t0_reg( T0 );
263 reg_class t1_reg( T1 );
264 reg_class t2_reg( T2 );
265 reg_class t3_reg( T3 );
266 reg_class t8_reg( T8 );
267 reg_class t9_reg( T9 );
269 reg_class a_reg( A0, A1, A2, A3, A4, A5, A6, A7 );
270 reg_class a0_reg( A0 );
271 reg_class a1_reg( A1 );
272 reg_class a2_reg( A2 );
273 reg_class a3_reg( A3 );
274 reg_class a4_reg( A4 );
275 reg_class a5_reg( A5 );
276 reg_class a6_reg( A6 );
277 reg_class a7_reg( A7 );
279 reg_class v0_reg( V0 );
280 reg_class v1_reg( V1 );
282 reg_class sp_reg( SP, SP_H );
283 reg_class fp_reg( FP, FP_H );
285 reg_class mips_flags(MIPS_FLAG);
287 reg_class v0_long_reg( V0, V0_H );
288 reg_class v1_long_reg( V1, V1_H );
289 reg_class a0_long_reg( A0, A0_H );
290 reg_class a1_long_reg( A1, A1_H );
291 reg_class a2_long_reg( A2, A2_H );
292 reg_class a3_long_reg( A3, A3_H );
293 reg_class a4_long_reg( A4, A4_H );
294 reg_class a5_long_reg( A5, A5_H );
295 reg_class a6_long_reg( A6, A6_H );
296 reg_class a7_long_reg( A7, A7_H );
297 reg_class t0_long_reg( T0, T0_H );
298 reg_class t1_long_reg( T1, T1_H );
299 reg_class t2_long_reg( T2, T2_H );
300 reg_class t3_long_reg( T3, T3_H );
301 reg_class t8_long_reg( T8, T8_H );
302 reg_class t9_long_reg( T9, T9_H );
303 reg_class s0_long_reg( S0, S0_H );
304 reg_class s1_long_reg( S1, S1_H );
305 reg_class s2_long_reg( S2, S2_H );
306 reg_class s3_long_reg( S3, S3_H );
307 reg_class s4_long_reg( S4, S4_H );
308 reg_class s5_long_reg( S5, S5_H );
309 reg_class s6_long_reg( S6, S6_H );
310 reg_class s7_long_reg( S7, S7_H );
312 reg_class int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, A7, A6, A5, A4, V0, A3, A2, A1, A0, T0 );
314 reg_class no_Ax_int_reg( S7, S0, S1, S2, S4, S3, T8, T2, T3, T1, V1, V0, T0 );
316 reg_class p_reg(
317 S7, S7_H,
318 S0, S0_H,
319 S1, S1_H,
320 S2, S2_H,
321 S4, S4_H,
322 S3, S3_H,
323 T8, T8_H,
324 T2, T2_H,
325 T3, T3_H,
326 T1, T1_H,
327 A7, A7_H,
328 A6, A6_H,
329 A5, A5_H,
330 A4, A4_H,
331 A3, A3_H,
332 A2, A2_H,
333 A1, A1_H,
334 A0, A0_H,
335 T0, T0_H
336 );
338 reg_class no_T8_p_reg(
339 S7, S7_H,
340 S0, S0_H,
341 S1, S1_H,
342 S2, S2_H,
343 S4, S4_H,
344 S3, S3_H,
345 T2, T2_H,
346 T3, T3_H,
347 T1, T1_H,
348 A7, A7_H,
349 A6, A6_H,
350 A5, A5_H,
351 A4, A4_H,
352 A3, A3_H,
353 A2, A2_H,
354 A1, A1_H,
355 A0, A0_H,
356 T0, T0_H
357 );
359 reg_class long_reg(
360 S7, S7_H,
361 S0, S0_H,
362 S1, S1_H,
363 S2, S2_H,
364 S4, S4_H,
365 S3, S3_H,
366 T8, T8_H,
367 T2, T2_H,
368 T3, T3_H,
369 T1, T1_H,
370 A7, A7_H,
371 A6, A6_H,
372 A5, A5_H,
373 A4, A4_H,
374 A3, A3_H,
375 A2, A2_H,
376 A1, A1_H,
377 A0, A0_H,
378 T0, T0_H
379 );
382 // Floating point registers.
383 // 2012/8/23 Fu: F30/F31 are used as temporary registers in D2I
384 // 2016/12/1 aoqi: F31 are not used as temporary registers in D2I
385 reg_class flt_reg( F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17 F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29, F31);
386 reg_class dbl_reg( F0, F0_H,
387 F1, F1_H,
388 F2, F2_H,
389 F3, F3_H,
390 F4, F4_H,
391 F5, F5_H,
392 F6, F6_H,
393 F7, F7_H,
394 F8, F8_H,
395 F9, F9_H,
396 F10, F10_H,
397 F11, F11_H,
398 F12, F12_H,
399 F13, F13_H,
400 F14, F14_H,
401 F15, F15_H,
402 F16, F16_H,
403 F17, F17_H,
404 F18, F18_H,
405 F19, F19_H,
406 F20, F20_H,
407 F21, F21_H,
408 F22, F22_H,
409 F23, F23_H,
410 F24, F24_H,
411 F25, F25_H,
412 F26, F26_H,
413 F27, F27_H,
414 F28, F28_H,
415 F29, F29_H,
416 F31, F31_H);
418 reg_class flt_arg0( F12 );
419 reg_class dbl_arg0( F12, F12_H );
420 reg_class dbl_arg1( F14, F14_H );
422 %}
424 //----------DEFINITION BLOCK---------------------------------------------------
425 // Define name --> value mappings to inform the ADLC of an integer valued name
426 // Current support includes integer values in the range [0, 0x7FFFFFFF]
427 // Format:
428 // int_def <name> ( <int_value>, <expression>);
429 // Generated Code in ad_<arch>.hpp
430 // #define <name> (<expression>)
431 // // value == <int_value>
432 // Generated code in ad_<arch>.cpp adlc_verification()
433 // assert( <name> == <int_value>, "Expect (<expression>) to equal <int_value>");
434 //
435 definitions %{
436 int_def DEFAULT_COST ( 100, 100);
437 int_def HUGE_COST (1000000, 1000000);
439 // Memory refs are twice as expensive as run-of-the-mill.
440 int_def MEMORY_REF_COST ( 200, DEFAULT_COST * 2);
442 // Branches are even more expensive.
443 int_def BRANCH_COST ( 300, DEFAULT_COST * 3);
444 // we use jr instruction to construct call, so more expensive
445 // by yjl 2/28/2006
446 int_def CALL_COST ( 500, DEFAULT_COST * 5);
447 /*
448 int_def EQUAL ( 1, 1 );
449 int_def NOT_EQUAL ( 2, 2 );
450 int_def GREATER ( 3, 3 );
451 int_def GREATER_EQUAL ( 4, 4 );
452 int_def LESS ( 5, 5 );
453 int_def LESS_EQUAL ( 6, 6 );
454 */
455 %}
459 //----------SOURCE BLOCK-------------------------------------------------------
460 // This is a block of C++ code which provides values, functions, and
461 // definitions necessary in the rest of the architecture description
463 source_hpp %{
464 // Header information of the source block.
465 // Method declarations/definitions which are used outside
466 // the ad-scope can conveniently be defined here.
467 //
468 // To keep related declarations/definitions/uses close together,
469 // we switch between source %{ }% and source_hpp %{ }% freely as needed.
471 class CallStubImpl {
473 //--------------------------------------------------------------
474 //---< Used for optimization in Compile::shorten_branches >---
475 //--------------------------------------------------------------
477 public:
478 // Size of call trampoline stub.
479 static uint size_call_trampoline() {
480 return 0; // no call trampolines on this platform
481 }
483 // number of relocations needed by a call trampoline stub
484 static uint reloc_call_trampoline() {
485 return 0; // no call trampolines on this platform
486 }
487 };
489 class HandlerImpl {
491 public:
493 static int emit_exception_handler(CodeBuffer &cbuf);
494 static int emit_deopt_handler(CodeBuffer& cbuf);
496 static uint size_exception_handler() {
497 // NativeCall instruction size is the same as NativeJump.
498 // exception handler starts out as jump and can be patched to
499 // a call be deoptimization. (4932387)
500 // Note that this value is also credited (in output.cpp) to
501 // the size of the code section.
502 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 =
542 __ start_a_stub(size_exception_handler());
543 if (base == NULL) return 0; // CodeBuffer::expand failed
544 int offset = __ offset();
546 __ block_comment("; emit_exception_handler");
548 cbuf.set_insts_mark();
549 __ relocate(relocInfo::runtime_call_type);
550 __ patchable_jump((address)OptoRuntime::exception_blob()->entry_point());
551 __ align(16);
552 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
553 __ end_a_stub();
554 return offset;
555 }
557 // Emit deopt handler code.
558 int HandlerImpl::emit_deopt_handler(CodeBuffer& cbuf) {
559 // Note that the code buffer's insts_mark is always relative to insts.
560 // That's why we must use the macroassembler to generate a handler.
561 MacroAssembler _masm(&cbuf);
562 address base =
563 __ start_a_stub(size_deopt_handler());
565 // FIXME
566 if (base == NULL) return 0; // CodeBuffer::expand failed
567 int offset = __ offset();
569 __ block_comment("; emit_deopt_handler");
571 cbuf.set_insts_mark();
572 __ relocate(relocInfo::runtime_call_type);
573 __ patchable_call(SharedRuntime::deopt_blob()->unpack());
574 __ align(16);
575 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
576 __ end_a_stub();
577 return offset;
578 }
581 const bool Matcher::match_rule_supported(int opcode) {
582 if (!has_match_rule(opcode))
583 return false;
585 switch (opcode) {
586 //Op_CountLeadingZerosI Op_CountLeadingZerosL can be deleted, all MIPS CPUs support clz & dclz.
587 case Op_CountLeadingZerosI:
588 case Op_CountLeadingZerosL:
589 if (!UseCountLeadingZerosInstruction)
590 return false;
591 break;
592 case Op_CountTrailingZerosI:
593 case Op_CountTrailingZerosL:
594 if (!UseCountTrailingZerosInstruction)
595 return false;
596 break;
597 }
599 return true; // Per default match rules are supported.
600 }
602 //FIXME
603 // emit call stub, compiled java to interpreter
604 void emit_java_to_interp(CodeBuffer &cbuf ) {
605 // Stub is fixed up when the corresponding call is converted from calling
606 // compiled code to calling interpreted code.
607 // mov rbx,0
608 // jmp -1
610 address mark = cbuf.insts_mark(); // get mark within main instrs section
612 // Note that the code buffer's insts_mark is always relative to insts.
613 // That's why we must use the macroassembler to generate a stub.
614 MacroAssembler _masm(&cbuf);
616 address base =
617 __ start_a_stub(Compile::MAX_stubs_size);
618 if (base == NULL) return; // CodeBuffer::expand failed
619 // static stub relocation stores the instruction address of the call
621 __ relocate(static_stub_Relocation::spec(mark), 0);
623 // static stub relocation also tags the methodOop in the code-stream.
624 __ patchable_set48(S3, (long)0);
625 // This is recognized as unresolved by relocs/nativeInst/ic code
627 __ relocate(relocInfo::runtime_call_type);
629 cbuf.set_insts_mark();
630 address call_pc = (address)-1;
631 __ patchable_jump(call_pc);
632 __ align(16);
633 __ end_a_stub();
634 // Update current stubs pointer and restore code_end.
635 }
637 // size of call stub, compiled java to interpretor
638 uint size_java_to_interp() {
639 int size = 4 * 4 + NativeCall::instruction_size; // sizeof(li48) + NativeCall::instruction_size
640 return round_to(size, 16);
641 }
643 // relocation entries for call stub, compiled java to interpreter
644 uint reloc_java_to_interp() {
645 return 16; // in emit_java_to_interp + in Java_Static_Call
646 }
648 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
649 if( Assembler::is_simm16(offset) )
650 return true;
651 else {
652 assert(false, "Not implemented yet !" );
653 Unimplemented();
654 }
655 }
658 // No additional cost for CMOVL.
659 const int Matcher::long_cmove_cost() { return 0; }
661 // No CMOVF/CMOVD with SSE2
662 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
664 // Does the CPU require late expand (see block.cpp for description of late expand)?
665 const bool Matcher::require_postalloc_expand = false;
667 // Should the Matcher clone shifts on addressing modes, expecting them
668 // to be subsumed into complex addressing expressions or compute them
669 // into registers? True for Intel but false for most RISCs
670 const bool Matcher::clone_shift_expressions = false;
672 // Do we need to mask the count passed to shift instructions or does
673 // the cpu only look at the lower 5/6 bits anyway?
674 const bool Matcher::need_masked_shift_count = false;
676 bool Matcher::narrow_oop_use_complex_address() {
677 NOT_LP64(ShouldNotCallThis());
678 assert(UseCompressedOops, "only for compressed oops code");
679 return false;
680 }
682 bool Matcher::narrow_klass_use_complex_address() {
683 NOT_LP64(ShouldNotCallThis());
684 assert(UseCompressedClassPointers, "only for compressed klass code");
685 return false;
686 }
688 // This is UltraSparc specific, true just means we have fast l2f conversion
689 const bool Matcher::convL2FSupported(void) {
690 return true;
691 }
693 // Max vector size in bytes. 0 if not supported.
694 const int Matcher::vector_width_in_bytes(BasicType bt) {
695 if (MaxVectorSize == 0)
696 return 0;
697 assert(MaxVectorSize == 8, "");
698 return 8;
699 }
701 // Vector ideal reg
702 const int Matcher::vector_ideal_reg(int size) {
703 assert(MaxVectorSize == 8, "");
704 switch(size) {
705 case 8: return Op_VecD;
706 }
707 ShouldNotReachHere();
708 return 0;
709 }
711 // Only lowest bits of xmm reg are used for vector shift count.
712 const int Matcher::vector_shift_count_ideal_reg(int size) {
713 fatal("vector shift is not supported");
714 return Node::NotAMachineReg;
715 }
717 // Limits on vector size (number of elements) loaded into vector.
718 const int Matcher::max_vector_size(const BasicType bt) {
719 assert(is_java_primitive(bt), "only primitive type vectors");
720 return vector_width_in_bytes(bt)/type2aelembytes(bt);
721 }
723 const int Matcher::min_vector_size(const BasicType bt) {
724 return max_vector_size(bt); // Same as max.
725 }
727 // MIPS supports misaligned vectors store/load? FIXME
728 const bool Matcher::misaligned_vectors_ok() {
729 return false;
730 //return !AlignVector; // can be changed by flag
731 }
733 // Register for DIVI projection of divmodI
734 RegMask Matcher::divI_proj_mask() {
735 ShouldNotReachHere();
736 return RegMask();
737 }
739 // Register for MODI projection of divmodI
740 RegMask Matcher::modI_proj_mask() {
741 ShouldNotReachHere();
742 return RegMask();
743 }
745 // Register for DIVL projection of divmodL
746 RegMask Matcher::divL_proj_mask() {
747 ShouldNotReachHere();
748 return RegMask();
749 }
751 int Matcher::regnum_to_fpu_offset(int regnum) {
752 return regnum - 32; // The FP registers are in the second chunk
753 }
756 const bool Matcher::isSimpleConstant64(jlong value) {
757 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
758 return true;
759 }
762 // Return whether or not this register is ever used as an argument. This
763 // function is used on startup to build the trampoline stubs in generateOptoStub.
764 // Registers not mentioned will be killed by the VM call in the trampoline, and
765 // arguments in those registers not be available to the callee.
766 bool Matcher::can_be_java_arg( int reg ) {
767 /* Refer to: [sharedRuntime_mips_64.cpp] SharedRuntime::java_calling_convention() */
768 if ( reg == T0_num || reg == T0_H_num
769 || reg == A0_num || reg == A0_H_num
770 || reg == A1_num || reg == A1_H_num
771 || reg == A2_num || reg == A2_H_num
772 || reg == A3_num || reg == A3_H_num
773 || reg == A4_num || reg == A4_H_num
774 || reg == A5_num || reg == A5_H_num
775 || reg == A6_num || reg == A6_H_num
776 || reg == A7_num || reg == A7_H_num )
777 return true;
779 if ( reg == F12_num || reg == F12_H_num
780 || reg == F13_num || reg == F13_H_num
781 || reg == F14_num || reg == F14_H_num
782 || reg == F15_num || reg == F15_H_num
783 || reg == F16_num || reg == F16_H_num
784 || reg == F17_num || reg == F17_H_num
785 || reg == F18_num || reg == F18_H_num
786 || reg == F19_num || reg == F19_H_num )
787 return true;
789 return false;
790 }
792 bool Matcher::is_spillable_arg( int reg ) {
793 return can_be_java_arg(reg);
794 }
796 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
797 return false;
798 }
800 // Register for MODL projection of divmodL
801 RegMask Matcher::modL_proj_mask() {
802 ShouldNotReachHere();
803 return RegMask();
804 }
806 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
807 return FP_REG_mask();
808 }
810 // MIPS doesn't support AES intrinsics
811 const bool Matcher::pass_original_key_for_aes() {
812 return false;
813 }
815 int CallLeafNoFPDirectNode::compute_padding(int current_offset) const {
816 //lui
817 //ori
818 //dsll
819 //ori
821 //jalr
822 //nop
824 return round_to(current_offset, alignment_required()) - current_offset;
825 }
827 int CallLeafDirectNode::compute_padding(int current_offset) const {
828 //lui
829 //ori
830 //dsll
831 //ori
833 //jalr
834 //nop
836 return round_to(current_offset, alignment_required()) - current_offset;
837 }
839 int CallRuntimeDirectNode::compute_padding(int current_offset) const {
840 //lui
841 //ori
842 //dsll
843 //ori
845 //jalr
846 //nop
848 return round_to(current_offset, alignment_required()) - current_offset;
849 }
851 // If CPU can load and store mis-aligned doubles directly then no fixup is
852 // needed. Else we split the double into 2 integer pieces and move it
853 // piece-by-piece. Only happens when passing doubles into C code as the
854 // Java calling convention forces doubles to be aligned.
855 const bool Matcher::misaligned_doubles_ok = false;
856 // Do floats take an entire double register or just half?
857 //const bool Matcher::float_in_double = true;
858 bool Matcher::float_in_double() { return false; }
859 // Threshold size for cleararray.
860 const int Matcher::init_array_short_size = 8 * BytesPerLong;
861 // Do ints take an entire long register or just half?
862 const bool Matcher::int_in_long = true;
863 // Is it better to copy float constants, or load them directly from memory?
864 // Intel can load a float constant from a direct address, requiring no
865 // extra registers. Most RISCs will have to materialize an address into a
866 // register first, so they would do better to copy the constant from stack.
867 const bool Matcher::rematerialize_float_constants = false;
868 // Advertise here if the CPU requires explicit rounding operations
869 // to implement the UseStrictFP mode.
870 const bool Matcher::strict_fp_requires_explicit_rounding = false;
871 // The ecx parameter to rep stos for the ClearArray node is in dwords.
872 const bool Matcher::init_array_count_is_in_bytes = false;
875 // Indicate if the safepoint node needs the polling page as an input.
876 // Since MIPS doesn't have absolute addressing, it needs.
877 bool SafePointNode::needs_polling_address_input() {
878 return false;
879 }
881 // !!!!! Special hack to get all type of calls to specify the byte offset
882 // from the start of the call to the point where the return address
883 // will point.
884 int MachCallStaticJavaNode::ret_addr_offset() {
885 //lui
886 //ori
887 //nop
888 //nop
889 //jalr
890 //nop
891 return 24;
892 }
894 int MachCallDynamicJavaNode::ret_addr_offset() {
895 //lui IC_Klass,
896 //ori IC_Klass,
897 //dsll IC_Klass
898 //ori IC_Klass
900 //lui T9
901 //ori T9
902 //nop
903 //nop
904 //jalr T9
905 //nop
906 return 4 * 4 + 4 * 6;
907 }
909 //=============================================================================
911 // Figure out which register class each belongs in: rc_int, rc_float, rc_stack
912 enum RC { rc_bad, rc_int, rc_float, rc_stack };
913 static enum RC rc_class( OptoReg::Name reg ) {
914 if( !OptoReg::is_valid(reg) ) return rc_bad;
915 if (OptoReg::is_stack(reg)) return rc_stack;
916 VMReg r = OptoReg::as_VMReg(reg);
917 if (r->is_Register()) return rc_int;
918 assert(r->is_FloatRegister(), "must be");
919 return rc_float;
920 }
922 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
923 // Get registers to move
924 OptoReg::Name src_second = ra_->get_reg_second(in(1));
925 OptoReg::Name src_first = ra_->get_reg_first(in(1));
926 OptoReg::Name dst_second = ra_->get_reg_second(this );
927 OptoReg::Name dst_first = ra_->get_reg_first(this );
929 enum RC src_second_rc = rc_class(src_second);
930 enum RC src_first_rc = rc_class(src_first);
931 enum RC dst_second_rc = rc_class(dst_second);
932 enum RC dst_first_rc = rc_class(dst_first);
934 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
936 // Generate spill code!
937 int size = 0;
939 if( src_first == dst_first && src_second == dst_second )
940 return 0; // Self copy, no move
942 if (src_first_rc == rc_stack) {
943 // mem ->
944 if (dst_first_rc == rc_stack) {
945 // mem -> mem
946 assert(src_second != dst_first, "overlap");
947 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
948 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
949 // 64-bit
950 int src_offset = ra_->reg2offset(src_first);
951 int dst_offset = ra_->reg2offset(dst_first);
952 if (cbuf) {
953 MacroAssembler _masm(cbuf);
954 __ ld(AT, Address(SP, src_offset));
955 __ sd(AT, Address(SP, dst_offset));
956 #ifndef PRODUCT
957 } else {
958 if(!do_size){
959 if (size != 0) st->print("\n\t");
960 st->print("ld AT, [SP + #%d]\t# 64-bit mem-mem spill 1\n\t"
961 "sd AT, [SP + #%d]",
962 src_offset, dst_offset);
963 }
964 #endif
965 }
966 size += 8;
967 } else {
968 // 32-bit
969 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
970 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
971 // No pushl/popl, so:
972 int src_offset = ra_->reg2offset(src_first);
973 int dst_offset = ra_->reg2offset(dst_first);
974 if (cbuf) {
975 MacroAssembler _masm(cbuf);
976 __ lw(AT, Address(SP, src_offset));
977 __ sw(AT, Address(SP, dst_offset));
978 #ifndef PRODUCT
979 } else {
980 if(!do_size){
981 if (size != 0) st->print("\n\t");
982 st->print("lw AT, [SP + #%d] spill 2\n\t"
983 "sw AT, [SP + #%d]\n\t",
984 src_offset, dst_offset);
985 }
986 #endif
987 }
988 size += 8;
989 }
990 return size;
991 } else if (dst_first_rc == rc_int) {
992 // mem -> gpr
993 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
994 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
995 // 64-bit
996 int offset = ra_->reg2offset(src_first);
997 if (cbuf) {
998 MacroAssembler _masm(cbuf);
999 __ ld(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1000 #ifndef PRODUCT
1001 } else {
1002 if(!do_size){
1003 if (size != 0) st->print("\n\t");
1004 st->print("ld %s, [SP + #%d]\t# spill 3",
1005 Matcher::regName[dst_first],
1006 offset);
1007 }
1008 #endif
1009 }
1010 size += 4;
1011 } else {
1012 // 32-bit
1013 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1014 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1015 int offset = ra_->reg2offset(src_first);
1016 if (cbuf) {
1017 MacroAssembler _masm(cbuf);
1018 if (this->ideal_reg() == Op_RegI)
1019 __ lw(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1020 else
1021 __ lwu(as_Register(Matcher::_regEncode[dst_first]), Address(SP, offset));
1022 #ifndef PRODUCT
1023 } else {
1024 if(!do_size){
1025 if (size != 0) st->print("\n\t");
1026 if (this->ideal_reg() == Op_RegI)
1027 st->print("lw %s, [SP + #%d]\t# spill 4",
1028 Matcher::regName[dst_first],
1029 offset);
1030 else
1031 st->print("lwu %s, [SP + #%d]\t# spill 5",
1032 Matcher::regName[dst_first],
1033 offset);
1034 }
1035 #endif
1036 }
1037 size += 4;
1038 }
1039 return size;
1040 } else if (dst_first_rc == rc_float) {
1041 // mem-> xmm
1042 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1043 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1044 // 64-bit
1045 int offset = ra_->reg2offset(src_first);
1046 if (cbuf) {
1047 MacroAssembler _masm(cbuf);
1048 __ ldc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1049 #ifndef PRODUCT
1050 } else {
1051 if (!do_size) {
1052 if (size != 0) st->print("\n\t");
1053 st->print("ldc1 %s, [SP + #%d]\t# spill 6",
1054 Matcher::regName[dst_first],
1055 offset);
1056 }
1057 #endif
1058 }
1059 size += 4;
1060 } else {
1061 // 32-bit
1062 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1063 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1064 int offset = ra_->reg2offset(src_first);
1065 if (cbuf) {
1066 MacroAssembler _masm(cbuf);
1067 __ lwc1( as_FloatRegister(Matcher::_regEncode[dst_first]), Address(SP, offset));
1068 #ifndef PRODUCT
1069 } else {
1070 if(!do_size){
1071 if (size != 0) st->print("\n\t");
1072 st->print("lwc1 %s, [SP + #%d]\t# spill 7",
1073 Matcher::regName[dst_first],
1074 offset);
1075 }
1076 #endif
1077 }
1078 size += 4;
1079 }
1080 return size;
1081 }
1082 } else if (src_first_rc == rc_int) {
1083 // gpr ->
1084 if (dst_first_rc == rc_stack) {
1085 // gpr -> mem
1086 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1087 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1088 // 64-bit
1089 int offset = ra_->reg2offset(dst_first);
1090 if (cbuf) {
1091 MacroAssembler _masm(cbuf);
1092 __ sd(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1093 #ifndef PRODUCT
1094 } else {
1095 if(!do_size){
1096 if (size != 0) st->print("\n\t");
1097 st->print("sd %s, [SP + #%d] # spill 8",
1098 Matcher::regName[src_first],
1099 offset);
1100 }
1101 #endif
1102 }
1103 size += 4;
1104 } else {
1105 // 32-bit
1106 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1107 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1108 int offset = ra_->reg2offset(dst_first);
1109 if (cbuf) {
1110 MacroAssembler _masm(cbuf);
1111 __ sw(as_Register(Matcher::_regEncode[src_first]), Address(SP, offset));
1112 #ifndef PRODUCT
1113 } else {
1114 if (!do_size) {
1115 if (size != 0) st->print("\n\t");
1116 st->print("sw %s, [SP + #%d]\t# spill 9",
1117 Matcher::regName[src_first], offset);
1118 }
1119 #endif
1120 }
1121 size += 4;
1122 }
1123 return size;
1124 } else if (dst_first_rc == rc_int) {
1125 // gpr -> gpr
1126 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1127 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1128 // 64-bit
1129 if (cbuf) {
1130 MacroAssembler _masm(cbuf);
1131 __ move(as_Register(Matcher::_regEncode[dst_first]),
1132 as_Register(Matcher::_regEncode[src_first]));
1133 #ifndef PRODUCT
1134 } else {
1135 if(!do_size){
1136 if (size != 0) st->print("\n\t");
1137 st->print("move(64bit) %s <-- %s\t# spill 10",
1138 Matcher::regName[dst_first],
1139 Matcher::regName[src_first]);
1140 }
1141 #endif
1142 }
1143 size += 4;
1144 return size;
1145 } else {
1146 // 32-bit
1147 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1148 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1149 if (cbuf) {
1150 MacroAssembler _masm(cbuf);
1151 if (this->ideal_reg() == Op_RegI)
1152 __ move_u32(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1153 else
1154 __ daddu(as_Register(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]), R0);
1155 #ifndef PRODUCT
1156 } else {
1157 if (!do_size) {
1158 if (size != 0) st->print("\n\t");
1159 st->print("move(32-bit) %s <-- %s\t# spill 11",
1160 Matcher::regName[dst_first],
1161 Matcher::regName[src_first]);
1162 }
1163 #endif
1164 }
1165 size += 4;
1166 return size;
1167 }
1168 } else if (dst_first_rc == rc_float) {
1169 // gpr -> xmm
1170 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1171 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1172 // 64-bit
1173 if (cbuf) {
1174 MacroAssembler _masm(cbuf);
1175 __ dmtc1(as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]));
1176 #ifndef PRODUCT
1177 } else {
1178 if(!do_size){
1179 if (size != 0) st->print("\n\t");
1180 st->print("dmtc1 %s, %s\t# spill 12",
1181 Matcher::regName[dst_first],
1182 Matcher::regName[src_first]);
1183 }
1184 #endif
1185 }
1186 size += 4;
1187 } else {
1188 // 32-bit
1189 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1190 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1191 if (cbuf) {
1192 MacroAssembler _masm(cbuf);
1193 __ mtc1( as_Register(Matcher::_regEncode[src_first]), as_FloatRegister(Matcher::_regEncode[dst_first]) );
1194 #ifndef PRODUCT
1195 } else {
1196 if(!do_size){
1197 if (size != 0) st->print("\n\t");
1198 st->print("mtc1 %s, %s\t# spill 13",
1199 Matcher::regName[dst_first],
1200 Matcher::regName[src_first]);
1201 }
1202 #endif
1203 }
1204 size += 4;
1205 }
1206 return size;
1207 }
1208 } else if (src_first_rc == rc_float) {
1209 // xmm ->
1210 if (dst_first_rc == rc_stack) {
1211 // xmm -> mem
1212 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1213 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1214 // 64-bit
1215 int offset = ra_->reg2offset(dst_first);
1216 if (cbuf) {
1217 MacroAssembler _masm(cbuf);
1218 __ sdc1( as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset) );
1219 #ifndef PRODUCT
1220 } else {
1221 if(!do_size){
1222 if (size != 0) st->print("\n\t");
1223 st->print("sdc1 %s, [SP + #%d]\t# spill 14",
1224 Matcher::regName[src_first],
1225 offset);
1226 }
1227 #endif
1228 }
1229 size += 4;
1230 } else {
1231 // 32-bit
1232 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1233 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1234 int offset = ra_->reg2offset(dst_first);
1235 if (cbuf) {
1236 MacroAssembler _masm(cbuf);
1237 __ swc1(as_FloatRegister(Matcher::_regEncode[src_first]), Address(SP, offset));
1238 #ifndef PRODUCT
1239 } else {
1240 if(!do_size){
1241 if (size != 0) st->print("\n\t");
1242 st->print("swc1 %s, [SP + #%d]\t# spill 15",
1243 Matcher::regName[src_first],
1244 offset);
1245 }
1246 #endif
1247 }
1248 size += 4;
1249 }
1250 return size;
1251 } else if (dst_first_rc == rc_int) {
1252 // xmm -> gpr
1253 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1254 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1255 // 64-bit
1256 if (cbuf) {
1257 MacroAssembler _masm(cbuf);
1258 __ dmfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1259 #ifndef PRODUCT
1260 } else {
1261 if(!do_size){
1262 if (size != 0) st->print("\n\t");
1263 st->print("dmfc1 %s, %s\t# spill 16",
1264 Matcher::regName[dst_first],
1265 Matcher::regName[src_first]);
1266 }
1267 #endif
1268 }
1269 size += 4;
1270 } else {
1271 // 32-bit
1272 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1273 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1274 if (cbuf) {
1275 MacroAssembler _masm(cbuf);
1276 __ mfc1( as_Register(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1277 #ifndef PRODUCT
1278 } else {
1279 if(!do_size){
1280 if (size != 0) st->print("\n\t");
1281 st->print("mfc1 %s, %s\t# spill 17",
1282 Matcher::regName[dst_first],
1283 Matcher::regName[src_first]);
1284 }
1285 #endif
1286 }
1287 size += 4;
1288 }
1289 return size;
1290 } else if (dst_first_rc == rc_float) {
1291 // xmm -> xmm
1292 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1293 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1294 // 64-bit
1295 if (cbuf) {
1296 MacroAssembler _masm(cbuf);
1297 __ mov_d( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1298 #ifndef PRODUCT
1299 } else {
1300 if(!do_size){
1301 if (size != 0) st->print("\n\t");
1302 st->print("mov_d %s <-- %s\t# spill 18",
1303 Matcher::regName[dst_first],
1304 Matcher::regName[src_first]);
1305 }
1306 #endif
1307 }
1308 size += 4;
1309 } else {
1310 // 32-bit
1311 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1312 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1313 if (cbuf) {
1314 MacroAssembler _masm(cbuf);
1315 __ mov_s( as_FloatRegister(Matcher::_regEncode[dst_first]), as_FloatRegister(Matcher::_regEncode[src_first]));
1316 #ifndef PRODUCT
1317 } else {
1318 if(!do_size){
1319 if (size != 0) st->print("\n\t");
1320 st->print("mov_s %s <-- %s\t# spill 19",
1321 Matcher::regName[dst_first],
1322 Matcher::regName[src_first]);
1323 }
1324 #endif
1325 }
1326 size += 4;
1327 }
1328 return size;
1329 }
1330 }
1332 assert(0," foo ");
1333 Unimplemented();
1334 return size;
1336 }
1338 #ifndef PRODUCT
1339 void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1340 implementation( NULL, ra_, false, st );
1341 }
1342 #endif
1344 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1345 implementation( &cbuf, ra_, false, NULL );
1346 }
1348 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1349 return implementation( NULL, ra_, true, NULL );
1350 }
1352 //=============================================================================
1353 #
1355 #ifndef PRODUCT
1356 void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const {
1357 st->print("INT3");
1358 }
1359 #endif
1361 void MachBreakpointNode::emit(CodeBuffer &cbuf, PhaseRegAlloc* ra_) const {
1362 MacroAssembler _masm(&cbuf);
1363 __ int3();
1364 }
1366 uint MachBreakpointNode::size(PhaseRegAlloc* ra_) const {
1367 return MachNode::size(ra_);
1368 }
1371 //=============================================================================
1372 #ifndef PRODUCT
1373 void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1374 Compile *C = ra_->C;
1375 int framesize = C->frame_size_in_bytes();
1377 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1379 st->print("daddiu SP, SP, %d # Rlease stack @ MachEpilogNode",framesize);
1380 st->cr(); st->print("\t");
1381 if (UseLoongsonISA) {
1382 st->print("gslq RA, FP, SP, %d # Restore FP & RA @ MachEpilogNode", -wordSize*2);
1383 } else {
1384 st->print("ld RA, SP, %d # Restore RA @ MachEpilogNode", -wordSize);
1385 st->cr(); st->print("\t");
1386 st->print("ld FP, SP, %d # Restore FP @ MachEpilogNode", -wordSize*2);
1387 }
1389 if( do_polling() && C->is_method_compilation() ) {
1390 st->print("Poll Safepoint # MachEpilogNode");
1391 }
1392 }
1393 #endif
1395 void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1396 Compile *C = ra_->C;
1397 MacroAssembler _masm(&cbuf);
1398 int framesize = C->frame_size_in_bytes();
1400 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1402 __ daddiu(SP, SP, framesize);
1404 if (UseLoongsonISA) {
1405 __ gslq(RA, FP, SP, -wordSize*2);
1406 } else {
1407 __ ld(RA, SP, -wordSize );
1408 __ ld(FP, SP, -wordSize*2 );
1409 }
1411 if( do_polling() && C->is_method_compilation() ) {
1412 __ set64(AT, (long)os::get_polling_page());
1413 __ relocate(relocInfo::poll_return_type);
1414 __ lw(AT, AT, 0);
1415 }
1416 }
1418 uint MachEpilogNode::size(PhaseRegAlloc *ra_) const {
1419 return MachNode::size(ra_); // too many variables; just compute it the hard way fujie debug
1420 }
1422 int MachEpilogNode::reloc() const {
1423 return 0; // a large enough number
1424 }
1426 const Pipeline * MachEpilogNode::pipeline() const {
1427 return MachNode::pipeline_class();
1428 }
1430 int MachEpilogNode::safepoint_offset() const { return 0; }
1432 //=============================================================================
1434 #ifndef PRODUCT
1435 void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1436 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1437 int reg = ra_->get_reg_first(this);
1438 st->print("ADDI %s, SP, %d @BoxLockNode",Matcher::regName[reg],offset);
1439 }
1440 #endif
1443 uint BoxLockNode::size(PhaseRegAlloc *ra_) const {
1444 return 4;
1445 }
1447 void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1448 MacroAssembler _masm(&cbuf);
1449 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1450 int reg = ra_->get_encode(this);
1452 __ addi(as_Register(reg), SP, offset);
1453 }
1456 //static int sizeof_FFree_Float_Stack_All = -1;
1458 int MachCallRuntimeNode::ret_addr_offset() {
1459 //lui
1460 //ori
1461 //dsll
1462 //ori
1463 //jalr
1464 //nop
1465 assert(NativeCall::instruction_size == 24, "in MachCallRuntimeNode::ret_addr_offset()");
1466 return NativeCall::instruction_size;
1467 }
1470 //=============================================================================
1471 #ifndef PRODUCT
1472 void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const {
1473 st->print("NOP \t# %d bytes pad for loops and calls", 4 * _count);
1474 }
1475 #endif
1477 void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const {
1478 MacroAssembler _masm(&cbuf);
1479 int i = 0;
1480 for(i = 0; i < _count; i++)
1481 __ nop();
1482 }
1484 uint MachNopNode::size(PhaseRegAlloc *) const {
1485 return 4 * _count;
1486 }
1487 const Pipeline* MachNopNode::pipeline() const {
1488 return MachNode::pipeline_class();
1489 }
1491 //=============================================================================
1493 //=============================================================================
1494 #ifndef PRODUCT
1495 void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1496 st->print_cr("load_klass(T9, T0)");
1497 st->print_cr("\tbeq(T9, iCache, L)");
1498 st->print_cr("\tnop");
1499 st->print_cr("\tjmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type)");
1500 st->print_cr("\tnop");
1501 st->print_cr("\tnop");
1502 st->print_cr(" L:");
1503 }
1504 #endif
1507 void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1508 MacroAssembler _masm(&cbuf);
1509 #ifdef ASSERT
1510 //uint code_size = cbuf.code_size();
1511 #endif
1512 int ic_reg = Matcher::inline_cache_reg_encode();
1513 Label L;
1514 Register receiver = T0;
1515 Register iCache = as_Register(ic_reg);
1516 __ load_klass(T9, receiver);
1517 __ beq(T9, iCache, L);
1518 __ nop();
1520 __ relocate(relocInfo::runtime_call_type);
1521 __ patchable_jump((address)SharedRuntime::get_ic_miss_stub());
1523 /* WARNING these NOPs are critical so that verified entry point is properly
1524 * 8 bytes aligned for patching by NativeJump::patch_verified_entry() */
1525 __ align(CodeEntryAlignment);
1526 __ bind(L);
1527 }
1529 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
1530 return MachNode::size(ra_);
1531 }
1535 //=============================================================================
1537 const RegMask& MachConstantBaseNode::_out_RegMask = P_REG_mask();
1539 int Compile::ConstantTable::calculate_table_base_offset() const {
1540 return 0; // absolute addressing, no offset
1541 }
1543 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
1544 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
1545 ShouldNotReachHere();
1546 }
1548 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
1549 Compile* C = ra_->C;
1550 Compile::ConstantTable& constant_table = C->constant_table();
1551 MacroAssembler _masm(&cbuf);
1553 Register Rtoc = as_Register(ra_->get_encode(this));
1554 CodeSection* consts_section = __ code()->consts();
1555 int consts_size = consts_section->align_at_start(consts_section->size());
1556 assert(constant_table.size() == consts_size, "must be equal");
1558 if (consts_section->size()) {
1559 // Materialize the constant table base.
1560 address baseaddr = consts_section->start() + -(constant_table.table_base_offset());
1561 // RelocationHolder rspec = internal_word_Relocation::spec(baseaddr);
1562 __ relocate(relocInfo::internal_pc_type);
1563 __ patchable_set48(Rtoc, (long)baseaddr);
1564 }
1565 }
1567 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
1568 // patchable_set48 (4 insts)
1569 return 4 * 4;
1570 }
1572 #ifndef PRODUCT
1573 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
1574 Register r = as_Register(ra_->get_encode(this));
1575 st->print("patchable_set48 %s, &constanttable (constant table base) @ MachConstantBaseNode", r->name());
1576 }
1577 #endif
1580 //=============================================================================
1581 #ifndef PRODUCT
1582 void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
1583 Compile* C = ra_->C;
1585 int framesize = C->frame_size_in_bytes();
1586 int bangsize = C->bang_size_in_bytes();
1587 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1589 // Calls to C2R adapters often do not accept exceptional returns.
1590 // We require that their callers must bang for them. But be careful, because
1591 // some VM calls (such as call site linkage) can use several kilobytes of
1592 // stack. But the stack safety zone should account for that.
1593 // See bugs 4446381, 4468289, 4497237.
1594 if (C->need_stack_bang(bangsize)) {
1595 st->print_cr("# stack bang"); st->print("\t");
1596 }
1597 if (UseLoongsonISA) {
1598 st->print("gssq RA, FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1599 } else {
1600 st->print("sd RA, %d(SP) @ MachPrologNode\n\t", -wordSize);
1601 st->print("sd FP, %d(SP) @ MachPrologNode\n\t", -wordSize*2);
1602 }
1603 st->print("daddiu FP, SP, -%d \n\t", wordSize*2);
1604 st->print("daddiu SP, SP, -%d \t",framesize);
1605 }
1606 #endif
1609 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1610 Compile* C = ra_->C;
1611 MacroAssembler _masm(&cbuf);
1613 int framesize = C->frame_size_in_bytes();
1614 int bangsize = C->bang_size_in_bytes();
1616 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1618 if (C->need_stack_bang(bangsize)) {
1619 __ generate_stack_overflow_check(bangsize);
1620 }
1622 if (UseLoongsonISA) {
1623 __ gssq(RA, FP, SP, -wordSize*2);
1624 } else {
1625 __ sd(RA, SP, -wordSize);
1626 __ sd(FP, SP, -wordSize*2);
1627 }
1628 __ daddiu(FP, SP, -wordSize*2);
1629 __ daddiu(SP, SP, -framesize);
1630 __ nop(); /* 2013.10.22 Jin: Make enough room for patch_verified_entry() */
1631 __ nop();
1633 C->set_frame_complete(cbuf.insts_size());
1634 if (C->has_mach_constant_base_node()) {
1635 // NOTE: We set the table base offset here because users might be
1636 // emitted before MachConstantBaseNode.
1637 Compile::ConstantTable& constant_table = C->constant_table();
1638 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
1639 }
1641 }
1644 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
1645 return MachNode::size(ra_); // too many variables; just compute it the hard way
1646 }
1648 int MachPrologNode::reloc() const {
1649 return 0; // a large enough number
1650 }
1652 %}
1654 //----------ENCODING BLOCK-----------------------------------------------------
1655 // This block specifies the encoding classes used by the compiler to output
1656 // byte streams. Encoding classes generate functions which are called by
1657 // Machine Instruction Nodes in order to generate the bit encoding of the
1658 // instruction. Operands specify their base encoding interface with the
1659 // interface keyword. There are currently supported four interfaces,
1660 // REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an
1661 // operand to generate a function which returns its register number when
1662 // queried. CONST_INTER causes an operand to generate a function which
1663 // returns the value of the constant when queried. MEMORY_INTER causes an
1664 // operand to generate four functions which return the Base Register, the
1665 // Index Register, the Scale Value, and the Offset Value of the operand when
1666 // queried. COND_INTER causes an operand to generate six functions which
1667 // return the encoding code (ie - encoding bits for the instruction)
1668 // associated with each basic boolean condition for a conditional instruction.
1669 // Instructions specify two basic values for encoding. They use the
1670 // ins_encode keyword to specify their encoding class (which must be one of
1671 // the class names specified in the encoding block), and they use the
1672 // opcode keyword to specify, in order, their primary, secondary, and
1673 // tertiary opcode. Only the opcode sections which a particular instruction
1674 // needs for encoding need to be specified.
1675 encode %{
1677 //Load byte signed
1678 enc_class load_B_enc (mRegI dst, memory mem) %{
1679 MacroAssembler _masm(&cbuf);
1680 int dst = $dst$$reg;
1681 int base = $mem$$base;
1682 int index = $mem$$index;
1683 int scale = $mem$$scale;
1684 int disp = $mem$$disp;
1686 if( index != 0 ) {
1687 if( Assembler::is_simm16(disp) ) {
1688 if( UseLoongsonISA ) {
1689 if (scale == 0) {
1690 __ gslbx(as_Register(dst), as_Register(base), as_Register(index), disp);
1691 } else {
1692 __ dsll(AT, as_Register(index), scale);
1693 __ gslbx(as_Register(dst), as_Register(base), AT, disp);
1694 }
1695 } else {
1696 if (scale == 0) {
1697 __ addu(AT, as_Register(base), as_Register(index));
1698 } else {
1699 __ dsll(AT, as_Register(index), scale);
1700 __ addu(AT, as_Register(base), AT);
1701 }
1702 __ lb(as_Register(dst), AT, disp);
1703 }
1704 } else {
1705 if (scale == 0) {
1706 __ addu(AT, as_Register(base), as_Register(index));
1707 } else {
1708 __ dsll(AT, as_Register(index), scale);
1709 __ addu(AT, as_Register(base), AT);
1710 }
1711 __ move(T9, disp);
1712 if( UseLoongsonISA ) {
1713 __ gslbx(as_Register(dst), AT, T9, 0);
1714 } else {
1715 __ addu(AT, AT, T9);
1716 __ lb(as_Register(dst), AT, 0);
1717 }
1718 }
1719 } else {
1720 if( Assembler::is_simm16(disp) ) {
1721 __ lb(as_Register(dst), as_Register(base), disp);
1722 } else {
1723 __ move(T9, disp);
1724 if( UseLoongsonISA ) {
1725 __ gslbx(as_Register(dst), as_Register(base), T9, 0);
1726 } else {
1727 __ addu(AT, as_Register(base), T9);
1728 __ lb(as_Register(dst), AT, 0);
1729 }
1730 }
1731 }
1732 %}
1734 //Load byte unsigned
1735 enc_class load_UB_enc (mRegI dst, memory mem) %{
1736 MacroAssembler _masm(&cbuf);
1737 int dst = $dst$$reg;
1738 int base = $mem$$base;
1739 int index = $mem$$index;
1740 int scale = $mem$$scale;
1741 int disp = $mem$$disp;
1743 if( index != 0 ) {
1744 if (scale == 0) {
1745 __ daddu(AT, as_Register(base), as_Register(index));
1746 } else {
1747 __ dsll(AT, as_Register(index), scale);
1748 __ daddu(AT, as_Register(base), AT);
1749 }
1750 if( Assembler::is_simm16(disp) ) {
1751 __ lbu(as_Register(dst), AT, disp);
1752 } else {
1753 __ move(T9, disp);
1754 __ daddu(AT, AT, T9);
1755 __ lbu(as_Register(dst), AT, 0);
1756 }
1757 } else {
1758 if( Assembler::is_simm16(disp) ) {
1759 __ lbu(as_Register(dst), as_Register(base), disp);
1760 } else {
1761 __ move(T9, disp);
1762 __ daddu(AT, as_Register(base), T9);
1763 __ lbu(as_Register(dst), AT, 0);
1764 }
1765 }
1766 %}
1768 enc_class store_B_reg_enc (memory mem, mRegI src) %{
1769 MacroAssembler _masm(&cbuf);
1770 int src = $src$$reg;
1771 int base = $mem$$base;
1772 int index = $mem$$index;
1773 int scale = $mem$$scale;
1774 int disp = $mem$$disp;
1776 if( index != 0 ) {
1777 if (scale == 0) {
1778 if( Assembler::is_simm(disp, 8) ) {
1779 if (UseLoongsonISA) {
1780 __ gssbx(as_Register(src), as_Register(base), as_Register(index), disp);
1781 } else {
1782 __ addu(AT, as_Register(base), as_Register(index));
1783 __ sb(as_Register(src), AT, disp);
1784 }
1785 } else if( Assembler::is_simm16(disp) ) {
1786 __ addu(AT, as_Register(base), as_Register(index));
1787 __ sb(as_Register(src), AT, disp);
1788 } else {
1789 __ addu(AT, as_Register(base), as_Register(index));
1790 __ move(T9, disp);
1791 if (UseLoongsonISA) {
1792 __ gssbx(as_Register(src), AT, T9, 0);
1793 } else {
1794 __ addu(AT, AT, T9);
1795 __ sb(as_Register(src), AT, 0);
1796 }
1797 }
1798 } else {
1799 __ dsll(AT, as_Register(index), scale);
1800 if( Assembler::is_simm(disp, 8) ) {
1801 if (UseLoongsonISA) {
1802 __ gssbx(as_Register(src), AT, as_Register(base), disp);
1803 } else {
1804 __ addu(AT, as_Register(base), AT);
1805 __ sb(as_Register(src), AT, disp);
1806 }
1807 } else if( Assembler::is_simm16(disp) ) {
1808 __ addu(AT, as_Register(base), AT);
1809 __ sb(as_Register(src), AT, disp);
1810 } else {
1811 __ addu(AT, as_Register(base), AT);
1812 __ move(T9, disp);
1813 if (UseLoongsonISA) {
1814 __ gssbx(as_Register(src), AT, T9, 0);
1815 } else {
1816 __ addu(AT, AT, T9);
1817 __ sb(as_Register(src), AT, 0);
1818 }
1819 }
1820 }
1821 } else {
1822 if( Assembler::is_simm16(disp) ) {
1823 __ sb(as_Register(src), as_Register(base), disp);
1824 } else {
1825 __ move(T9, disp);
1826 if (UseLoongsonISA) {
1827 __ gssbx(as_Register(src), as_Register(base), T9, 0);
1828 } else {
1829 __ addu(AT, as_Register(base), T9);
1830 __ sb(as_Register(src), AT, 0);
1831 }
1832 }
1833 }
1834 %}
1836 enc_class store_B_immI_enc (memory mem, immI8 src) %{
1837 MacroAssembler _masm(&cbuf);
1838 int base = $mem$$base;
1839 int index = $mem$$index;
1840 int scale = $mem$$scale;
1841 int disp = $mem$$disp;
1842 int value = $src$$constant;
1844 if( index != 0 ) {
1845 if (!UseLoongsonISA) {
1846 if (scale == 0) {
1847 __ daddu(AT, as_Register(base), as_Register(index));
1848 } else {
1849 __ dsll(AT, as_Register(index), scale);
1850 __ daddu(AT, as_Register(base), AT);
1851 }
1852 if( Assembler::is_simm16(disp) ) {
1853 if (value == 0) {
1854 __ sb(R0, AT, disp);
1855 } else {
1856 __ move(T9, value);
1857 __ sb(T9, AT, disp);
1858 }
1859 } else {
1860 if (value == 0) {
1861 __ move(T9, disp);
1862 __ daddu(AT, AT, T9);
1863 __ sb(R0, AT, 0);
1864 } else {
1865 __ move(T9, disp);
1866 __ daddu(AT, AT, T9);
1867 __ move(T9, value);
1868 __ sb(T9, AT, 0);
1869 }
1870 }
1871 } else {
1873 if (scale == 0) {
1874 if( Assembler::is_simm(disp, 8) ) {
1875 if (value == 0) {
1876 __ gssbx(R0, as_Register(base), as_Register(index), disp);
1877 } else {
1878 __ move(T9, value);
1879 __ gssbx(T9, as_Register(base), as_Register(index), disp);
1880 }
1881 } else if( Assembler::is_simm16(disp) ) {
1882 __ daddu(AT, as_Register(base), as_Register(index));
1883 if (value == 0) {
1884 __ sb(R0, AT, disp);
1885 } else {
1886 __ move(T9, value);
1887 __ sb(T9, AT, disp);
1888 }
1889 } else {
1890 if (value == 0) {
1891 __ daddu(AT, as_Register(base), as_Register(index));
1892 __ move(T9, disp);
1893 __ gssbx(R0, AT, T9, 0);
1894 } else {
1895 __ move(AT, disp);
1896 __ move(T9, value);
1897 __ daddu(AT, as_Register(base), AT);
1898 __ gssbx(T9, AT, as_Register(index), 0);
1899 }
1900 }
1902 } else {
1904 if( Assembler::is_simm(disp, 8) ) {
1905 __ dsll(AT, as_Register(index), scale);
1906 if (value == 0) {
1907 __ gssbx(R0, as_Register(base), AT, disp);
1908 } else {
1909 __ move(T9, value);
1910 __ gssbx(T9, as_Register(base), AT, disp);
1911 }
1912 } else if( Assembler::is_simm16(disp) ) {
1913 __ dsll(AT, as_Register(index), scale);
1914 __ daddu(AT, as_Register(base), AT);
1915 if (value == 0) {
1916 __ sb(R0, AT, disp);
1917 } else {
1918 __ move(T9, value);
1919 __ sb(T9, AT, disp);
1920 }
1921 } else {
1922 __ dsll(AT, as_Register(index), scale);
1923 if (value == 0) {
1924 __ daddu(AT, as_Register(base), AT);
1925 __ move(T9, disp);
1926 __ gssbx(R0, AT, T9, 0);
1927 } else {
1928 __ move(T9, disp);
1929 __ daddu(AT, AT, T9);
1930 __ move(T9, value);
1931 __ gssbx(T9, as_Register(base), AT, 0);
1932 }
1933 }
1934 }
1935 }
1936 } else {
1937 if( Assembler::is_simm16(disp) ) {
1938 if (value == 0) {
1939 __ sb(R0, as_Register(base), disp);
1940 } else {
1941 __ move(AT, value);
1942 __ sb(AT, as_Register(base), disp);
1943 }
1944 } else {
1945 if (value == 0) {
1946 __ move(T9, disp);
1947 if (UseLoongsonISA) {
1948 __ gssbx(R0, as_Register(base), T9, 0);
1949 } else {
1950 __ daddu(AT, as_Register(base), T9);
1951 __ sb(R0, AT, 0);
1952 }
1953 } else {
1954 __ move(T9, disp);
1955 if (UseLoongsonISA) {
1956 __ move(AT, value);
1957 __ gssbx(AT, as_Register(base), T9, 0);
1958 } else {
1959 __ daddu(AT, as_Register(base), T9);
1960 __ move(T9, value);
1961 __ sb(T9, AT, 0);
1962 }
1963 }
1964 }
1965 }
1966 %}
1969 enc_class store_B_immI_enc_sync (memory mem, immI8 src) %{
1970 MacroAssembler _masm(&cbuf);
1971 int base = $mem$$base;
1972 int index = $mem$$index;
1973 int scale = $mem$$scale;
1974 int disp = $mem$$disp;
1975 int value = $src$$constant;
1977 if( index != 0 ) {
1978 if ( UseLoongsonISA ) {
1979 if ( Assembler::is_simm(disp,8) ) {
1980 if ( scale == 0 ) {
1981 if ( value == 0 ) {
1982 __ gssbx(R0, as_Register(base), as_Register(index), disp);
1983 } else {
1984 __ move(AT, value);
1985 __ gssbx(AT, as_Register(base), as_Register(index), disp);
1986 }
1987 } else {
1988 __ dsll(AT, as_Register(index), scale);
1989 if ( value == 0 ) {
1990 __ gssbx(R0, as_Register(base), AT, disp);
1991 } else {
1992 __ move(T9, value);
1993 __ gssbx(T9, as_Register(base), AT, disp);
1994 }
1995 }
1996 } else if ( Assembler::is_simm16(disp) ) {
1997 if ( scale == 0 ) {
1998 __ daddu(AT, as_Register(base), as_Register(index));
1999 if ( value == 0 ){
2000 __ sb(R0, AT, disp);
2001 } else {
2002 __ move(T9, value);
2003 __ sb(T9, AT, disp);
2004 }
2005 } else {
2006 __ dsll(AT, as_Register(index), scale);
2007 __ daddu(AT, as_Register(base), AT);
2008 if ( value == 0 ) {
2009 __ sb(R0, AT, disp);
2010 } else {
2011 __ move(T9, value);
2012 __ sb(T9, AT, disp);
2013 }
2014 }
2015 } else {
2016 if ( scale == 0 ) {
2017 __ move(AT, disp);
2018 __ daddu(AT, as_Register(index), AT);
2019 if ( value == 0 ) {
2020 __ gssbx(R0, as_Register(base), AT, 0);
2021 } else {
2022 __ move(T9, value);
2023 __ gssbx(T9, as_Register(base), AT, 0);
2024 }
2025 } else {
2026 __ dsll(AT, as_Register(index), scale);
2027 __ move(T9, disp);
2028 __ daddu(AT, AT, T9);
2029 if ( value == 0 ) {
2030 __ gssbx(R0, as_Register(base), AT, 0);
2031 } else {
2032 __ move(T9, value);
2033 __ gssbx(T9, as_Register(base), AT, 0);
2034 }
2035 }
2036 }
2037 } else { //not use loongson isa
2038 if (scale == 0) {
2039 __ daddu(AT, as_Register(base), as_Register(index));
2040 } else {
2041 __ dsll(AT, as_Register(index), scale);
2042 __ daddu(AT, as_Register(base), AT);
2043 }
2044 if( Assembler::is_simm16(disp) ) {
2045 if (value == 0) {
2046 __ sb(R0, AT, disp);
2047 } else {
2048 __ move(T9, value);
2049 __ sb(T9, AT, disp);
2050 }
2051 } else {
2052 if (value == 0) {
2053 __ move(T9, disp);
2054 __ daddu(AT, AT, T9);
2055 __ sb(R0, AT, 0);
2056 } else {
2057 __ move(T9, disp);
2058 __ daddu(AT, AT, T9);
2059 __ move(T9, value);
2060 __ sb(T9, AT, 0);
2061 }
2062 }
2063 }
2064 } else {
2065 if ( UseLoongsonISA ){
2066 if ( Assembler::is_simm16(disp) ){
2067 if ( value == 0 ) {
2068 __ sb(R0, as_Register(base), disp);
2069 } else {
2070 __ move(AT, value);
2071 __ sb(AT, as_Register(base), disp);
2072 }
2073 } else {
2074 __ move(AT, disp);
2075 if ( value == 0 ) {
2076 __ gssbx(R0, as_Register(base), AT, 0);
2077 } else {
2078 __ move(T9, value);
2079 __ gssbx(T9, as_Register(base), AT, 0);
2080 }
2081 }
2082 } else {
2083 if( Assembler::is_simm16(disp) ) {
2084 if (value == 0) {
2085 __ sb(R0, as_Register(base), disp);
2086 } else {
2087 __ move(AT, value);
2088 __ sb(AT, as_Register(base), disp);
2089 }
2090 } else {
2091 if (value == 0) {
2092 __ move(T9, disp);
2093 __ daddu(AT, as_Register(base), T9);
2094 __ sb(R0, AT, 0);
2095 } else {
2096 __ move(T9, disp);
2097 __ daddu(AT, as_Register(base), T9);
2098 __ move(T9, value);
2099 __ sb(T9, AT, 0);
2100 }
2101 }
2102 }
2103 }
2105 __ sync();
2106 %}
2108 // Load Short (16bit signed)
2109 enc_class load_S_enc (mRegI dst, memory mem) %{
2110 MacroAssembler _masm(&cbuf);
2111 int dst = $dst$$reg;
2112 int base = $mem$$base;
2113 int index = $mem$$index;
2114 int scale = $mem$$scale;
2115 int disp = $mem$$disp;
2117 if( index != 0 ) {
2118 if ( UseLoongsonISA ) {
2119 if ( Assembler::is_simm(disp, 8) ) {
2120 if (scale == 0) {
2121 __ gslhx(as_Register(dst), as_Register(base), as_Register(index), disp);
2122 } else {
2123 __ dsll(AT, as_Register(index), scale);
2124 __ gslhx(as_Register(dst), as_Register(base), AT, disp);
2125 }
2126 } else if ( Assembler::is_simm16(disp) ) {
2127 if (scale == 0) {
2128 __ daddu(AT, as_Register(base), as_Register(index));
2129 __ lh(as_Register(dst), AT, disp);
2130 } else {
2131 __ dsll(AT, as_Register(index), scale);
2132 __ daddu(AT, as_Register(base), AT);
2133 __ lh(as_Register(dst), AT, disp);
2134 }
2135 } else {
2136 if (scale == 0) {
2137 __ move(AT, disp);
2138 __ daddu(AT, as_Register(index), AT);
2139 __ gslhx(as_Register(dst), as_Register(base), AT, 0);
2140 } else {
2141 __ dsll(AT, as_Register(index), scale);
2142 __ move(T9, disp);
2143 __ daddu(AT, AT, T9);
2144 __ gslhx(as_Register(dst), as_Register(base), AT, 0);
2145 }
2146 }
2147 } else { // not use loongson isa
2148 if (scale == 0) {
2149 __ daddu(AT, as_Register(base), as_Register(index));
2150 } else {
2151 __ dsll(AT, as_Register(index), scale);
2152 __ daddu(AT, as_Register(base), AT);
2153 }
2154 if( Assembler::is_simm16(disp) ) {
2155 __ lh(as_Register(dst), AT, disp);
2156 } else {
2157 __ move(T9, disp);
2158 __ daddu(AT, AT, T9);
2159 __ lh(as_Register(dst), AT, 0);
2160 }
2161 }
2162 } else { // index is 0
2163 if ( UseLoongsonISA ) {
2164 if ( Assembler::is_simm16(disp) ) {
2165 __ lh(as_Register(dst), as_Register(base), disp);
2166 } else {
2167 __ move(T9, disp);
2168 __ gslhx(as_Register(dst), as_Register(base), T9, 0);
2169 }
2170 } else { //not use loongson isa
2171 if( Assembler::is_simm16(disp) ) {
2172 __ lh(as_Register(dst), as_Register(base), disp);
2173 } else {
2174 __ move(T9, disp);
2175 __ daddu(AT, as_Register(base), T9);
2176 __ lh(as_Register(dst), AT, 0);
2177 }
2178 }
2179 }
2180 %}
2182 // Load Char (16bit unsigned)
2183 enc_class load_C_enc (mRegI dst, memory mem) %{
2184 MacroAssembler _masm(&cbuf);
2185 int dst = $dst$$reg;
2186 int base = $mem$$base;
2187 int index = $mem$$index;
2188 int scale = $mem$$scale;
2189 int disp = $mem$$disp;
2191 if( index != 0 ) {
2192 if (scale == 0) {
2193 __ daddu(AT, as_Register(base), as_Register(index));
2194 } else {
2195 __ dsll(AT, as_Register(index), scale);
2196 __ daddu(AT, as_Register(base), AT);
2197 }
2198 if( Assembler::is_simm16(disp) ) {
2199 __ lhu(as_Register(dst), AT, disp);
2200 } else {
2201 __ move(T9, disp);
2202 __ addu(AT, AT, T9);
2203 __ lhu(as_Register(dst), AT, 0);
2204 }
2205 } else {
2206 if( Assembler::is_simm16(disp) ) {
2207 __ lhu(as_Register(dst), as_Register(base), disp);
2208 } else {
2209 __ move(T9, disp);
2210 __ daddu(AT, as_Register(base), T9);
2211 __ lhu(as_Register(dst), AT, 0);
2212 }
2213 }
2214 %}
2216 // Store Char (16bit unsigned)
2217 enc_class store_C_reg_enc (memory mem, mRegI src) %{
2218 MacroAssembler _masm(&cbuf);
2219 int src = $src$$reg;
2220 int base = $mem$$base;
2221 int index = $mem$$index;
2222 int scale = $mem$$scale;
2223 int disp = $mem$$disp;
2225 if( index != 0 ) {
2226 if( Assembler::is_simm16(disp) ) {
2227 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2228 if (scale == 0) {
2229 __ gsshx(as_Register(src), as_Register(base), as_Register(index), disp);
2230 } else {
2231 __ dsll(AT, as_Register(index), scale);
2232 __ gsshx(as_Register(src), as_Register(base), AT, disp);
2233 }
2234 } else {
2235 if (scale == 0) {
2236 __ addu(AT, as_Register(base), as_Register(index));
2237 } else {
2238 __ dsll(AT, as_Register(index), scale);
2239 __ addu(AT, as_Register(base), AT);
2240 }
2241 __ sh(as_Register(src), AT, disp);
2242 }
2243 } else {
2244 if (scale == 0) {
2245 __ addu(AT, as_Register(base), as_Register(index));
2246 } else {
2247 __ dsll(AT, as_Register(index), scale);
2248 __ addu(AT, as_Register(base), AT);
2249 }
2250 __ move(T9, disp);
2251 if( UseLoongsonISA ) {
2252 __ gsshx(as_Register(src), AT, T9, 0);
2253 } else {
2254 __ addu(AT, AT, T9);
2255 __ sh(as_Register(src), AT, 0);
2256 }
2257 }
2258 } else {
2259 if( Assembler::is_simm16(disp) ) {
2260 __ sh(as_Register(src), as_Register(base), disp);
2261 } else {
2262 __ move(T9, disp);
2263 if( UseLoongsonISA ) {
2264 __ gsshx(as_Register(src), as_Register(base), T9, 0);
2265 } else {
2266 __ addu(AT, as_Register(base), T9);
2267 __ sh(as_Register(src), AT, 0);
2268 }
2269 }
2270 }
2271 %}
2273 enc_class store_C0_enc (memory mem) %{
2274 MacroAssembler _masm(&cbuf);
2275 int base = $mem$$base;
2276 int index = $mem$$index;
2277 int scale = $mem$$scale;
2278 int disp = $mem$$disp;
2280 if( index != 0 ) {
2281 if( Assembler::is_simm16(disp) ) {
2282 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2283 if (scale == 0) {
2284 __ gsshx(R0, as_Register(base), as_Register(index), disp);
2285 } else {
2286 __ dsll(AT, as_Register(index), scale);
2287 __ gsshx(R0, as_Register(base), AT, disp);
2288 }
2289 } else {
2290 if (scale == 0) {
2291 __ addu(AT, as_Register(base), as_Register(index));
2292 } else {
2293 __ dsll(AT, as_Register(index), scale);
2294 __ addu(AT, as_Register(base), AT);
2295 }
2296 __ sh(R0, AT, disp);
2297 }
2298 } else {
2299 if (scale == 0) {
2300 __ addu(AT, as_Register(base), as_Register(index));
2301 } else {
2302 __ dsll(AT, as_Register(index), scale);
2303 __ addu(AT, as_Register(base), AT);
2304 }
2305 __ move(T9, disp);
2306 if( UseLoongsonISA ) {
2307 __ gsshx(R0, AT, T9, 0);
2308 } else {
2309 __ addu(AT, AT, T9);
2310 __ sh(R0, AT, 0);
2311 }
2312 }
2313 } else {
2314 if( Assembler::is_simm16(disp) ) {
2315 __ sh(R0, as_Register(base), disp);
2316 } else {
2317 __ move(T9, disp);
2318 if( UseLoongsonISA ) {
2319 __ gsshx(R0, as_Register(base), T9, 0);
2320 } else {
2321 __ addu(AT, as_Register(base), T9);
2322 __ sh(R0, AT, 0);
2323 }
2324 }
2325 }
2326 %}
2328 enc_class load_I_enc (mRegI dst, memory mem) %{
2329 MacroAssembler _masm(&cbuf);
2330 int dst = $dst$$reg;
2331 int base = $mem$$base;
2332 int index = $mem$$index;
2333 int scale = $mem$$scale;
2334 int disp = $mem$$disp;
2336 if( index != 0 ) {
2337 if( Assembler::is_simm16(disp) ) {
2338 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2339 if (scale == 0) {
2340 __ gslwx(as_Register(dst), as_Register(base), as_Register(index), disp);
2341 } else {
2342 __ dsll(AT, as_Register(index), scale);
2343 __ gslwx(as_Register(dst), as_Register(base), AT, disp);
2344 }
2345 } else {
2346 if (scale == 0) {
2347 __ addu(AT, as_Register(base), as_Register(index));
2348 } else {
2349 __ dsll(AT, as_Register(index), scale);
2350 __ addu(AT, as_Register(base), AT);
2351 }
2352 __ lw(as_Register(dst), AT, disp);
2353 }
2354 } else {
2355 if (scale == 0) {
2356 __ addu(AT, as_Register(base), as_Register(index));
2357 } else {
2358 __ dsll(AT, as_Register(index), scale);
2359 __ addu(AT, as_Register(base), AT);
2360 }
2361 __ move(T9, disp);
2362 if( UseLoongsonISA ) {
2363 __ gslwx(as_Register(dst), AT, T9, 0);
2364 } else {
2365 __ addu(AT, AT, T9);
2366 __ lw(as_Register(dst), AT, 0);
2367 }
2368 }
2369 } else {
2370 if( Assembler::is_simm16(disp) ) {
2371 __ lw(as_Register(dst), as_Register(base), disp);
2372 } else {
2373 __ move(T9, disp);
2374 if( UseLoongsonISA ) {
2375 __ gslwx(as_Register(dst), as_Register(base), T9, 0);
2376 } else {
2377 __ addu(AT, as_Register(base), T9);
2378 __ lw(as_Register(dst), AT, 0);
2379 }
2380 }
2381 }
2382 %}
2384 enc_class store_I_reg_enc (memory mem, mRegI src) %{
2385 MacroAssembler _masm(&cbuf);
2386 int src = $src$$reg;
2387 int base = $mem$$base;
2388 int index = $mem$$index;
2389 int scale = $mem$$scale;
2390 int disp = $mem$$disp;
2392 if( index != 0 ) {
2393 if( Assembler::is_simm16(disp) ) {
2394 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
2395 if (scale == 0) {
2396 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
2397 } else {
2398 __ dsll(AT, as_Register(index), scale);
2399 __ gsswx(as_Register(src), as_Register(base), AT, disp);
2400 }
2401 } else {
2402 if (scale == 0) {
2403 __ addu(AT, as_Register(base), as_Register(index));
2404 } else {
2405 __ dsll(AT, as_Register(index), scale);
2406 __ addu(AT, as_Register(base), AT);
2407 }
2408 __ sw(as_Register(src), AT, disp);
2409 }
2410 } else {
2411 if (scale == 0) {
2412 __ addu(AT, as_Register(base), as_Register(index));
2413 } else {
2414 __ dsll(AT, as_Register(index), scale);
2415 __ addu(AT, as_Register(base), AT);
2416 }
2417 __ move(T9, disp);
2418 if( UseLoongsonISA ) {
2419 __ gsswx(as_Register(src), AT, T9, 0);
2420 } else {
2421 __ addu(AT, AT, T9);
2422 __ sw(as_Register(src), AT, 0);
2423 }
2424 }
2425 } else {
2426 if( Assembler::is_simm16(disp) ) {
2427 __ sw(as_Register(src), as_Register(base), disp);
2428 } else {
2429 __ move(T9, disp);
2430 if( UseLoongsonISA ) {
2431 __ gsswx(as_Register(src), as_Register(base), T9, 0);
2432 } else {
2433 __ addu(AT, as_Register(base), T9);
2434 __ sw(as_Register(src), AT, 0);
2435 }
2436 }
2437 }
2438 %}
2440 enc_class store_I_immI_enc (memory mem, immI src) %{
2441 MacroAssembler _masm(&cbuf);
2442 int base = $mem$$base;
2443 int index = $mem$$index;
2444 int scale = $mem$$scale;
2445 int disp = $mem$$disp;
2446 int value = $src$$constant;
2448 if( index != 0 ) {
2449 if ( UseLoongsonISA ) {
2450 if ( Assembler::is_simm(disp, 8) ) {
2451 if ( scale == 0 ) {
2452 if ( value == 0 ) {
2453 __ gsswx(R0, as_Register(base), as_Register(index), disp);
2454 } else {
2455 __ move(T9, value);
2456 __ gsswx(T9, as_Register(base), as_Register(index), disp);
2457 }
2458 } else {
2459 __ dsll(AT, as_Register(index), scale);
2460 if ( value == 0 ) {
2461 __ gsswx(R0, as_Register(base), AT, disp);
2462 } else {
2463 __ move(T9, value);
2464 __ gsswx(T9, as_Register(base), AT, disp);
2465 }
2466 }
2467 } else if ( Assembler::is_simm16(disp) ) {
2468 if ( scale == 0 ) {
2469 __ daddu(AT, as_Register(base), as_Register(index));
2470 if ( value == 0 ) {
2471 __ sw(R0, AT, disp);
2472 } else {
2473 __ move(T9, value);
2474 __ sw(T9, AT, disp);
2475 }
2476 } else {
2477 __ dsll(AT, as_Register(index), scale);
2478 __ daddu(AT, as_Register(base), AT);
2479 if ( value == 0 ) {
2480 __ sw(R0, AT, disp);
2481 } else {
2482 __ move(T9, value);
2483 __ sw(T9, AT, disp);
2484 }
2485 }
2486 } else {
2487 if ( scale == 0 ) {
2488 __ move(T9, disp);
2489 __ daddu(AT, as_Register(index), T9);
2490 if ( value ==0 ) {
2491 __ gsswx(R0, as_Register(base), AT, 0);
2492 } else {
2493 __ move(T9, value);
2494 __ gsswx(T9, as_Register(base), AT, 0);
2495 }
2496 } else {
2497 __ dsll(AT, as_Register(index), scale);
2498 __ move(T9, disp);
2499 __ daddu(AT, AT, T9);
2500 if ( value == 0 ) {
2501 __ gsswx(R0, as_Register(base), AT, 0);
2502 } else {
2503 __ move(T9, value);
2504 __ gsswx(T9, as_Register(base), AT, 0);
2505 }
2506 }
2507 }
2508 } else { //not use loongson isa
2509 if (scale == 0) {
2510 __ daddu(AT, as_Register(base), as_Register(index));
2511 } else {
2512 __ dsll(AT, as_Register(index), scale);
2513 __ daddu(AT, as_Register(base), AT);
2514 }
2515 if( Assembler::is_simm16(disp) ) {
2516 if (value == 0) {
2517 __ sw(R0, AT, disp);
2518 } else {
2519 __ move(T9, value);
2520 __ sw(T9, AT, disp);
2521 }
2522 } else {
2523 if (value == 0) {
2524 __ move(T9, disp);
2525 __ daddu(AT, AT, T9);
2526 __ sw(R0, AT, 0);
2527 } else {
2528 __ move(T9, disp);
2529 __ daddu(AT, AT, T9);
2530 __ move(T9, value);
2531 __ sw(T9, AT, 0);
2532 }
2533 }
2534 }
2535 } else {
2536 if ( UseLoongsonISA ) {
2537 if ( Assembler::is_simm16(disp) ) {
2538 if ( value == 0 ) {
2539 __ sw(R0, as_Register(base), disp);
2540 } else {
2541 __ move(AT, value);
2542 __ sw(AT, as_Register(base), disp);
2543 }
2544 } else {
2545 __ move(T9, disp);
2546 if ( value == 0 ) {
2547 __ gsswx(R0, as_Register(base), T9, 0);
2548 } else {
2549 __ move(AT, value);
2550 __ gsswx(AT, as_Register(base), T9, 0);
2551 }
2552 }
2553 } else {
2554 if( Assembler::is_simm16(disp) ) {
2555 if (value == 0) {
2556 __ sw(R0, as_Register(base), disp);
2557 } else {
2558 __ move(AT, value);
2559 __ sw(AT, as_Register(base), disp);
2560 }
2561 } else {
2562 if (value == 0) {
2563 __ move(T9, disp);
2564 __ daddu(AT, as_Register(base), T9);
2565 __ sw(R0, AT, 0);
2566 } else {
2567 __ move(T9, disp);
2568 __ daddu(AT, as_Register(base), T9);
2569 __ move(T9, value);
2570 __ sw(T9, AT, 0);
2571 }
2572 }
2573 }
2574 }
2575 %}
2577 enc_class load_N_enc (mRegN dst, memory mem) %{
2578 MacroAssembler _masm(&cbuf);
2579 int dst = $dst$$reg;
2580 int base = $mem$$base;
2581 int index = $mem$$index;
2582 int scale = $mem$$scale;
2583 int disp = $mem$$disp;
2584 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2585 assert(disp_reloc == relocInfo::none, "cannot have disp");
2587 if( index != 0 ) {
2588 if (scale == 0) {
2589 __ daddu(AT, as_Register(base), as_Register(index));
2590 } else {
2591 __ dsll(AT, as_Register(index), scale);
2592 __ daddu(AT, as_Register(base), AT);
2593 }
2594 if( Assembler::is_simm16(disp) ) {
2595 __ lwu(as_Register(dst), AT, disp);
2596 } else {
2597 __ set64(T9, disp);
2598 __ daddu(AT, AT, T9);
2599 __ lwu(as_Register(dst), AT, 0);
2600 }
2601 } else {
2602 if( Assembler::is_simm16(disp) ) {
2603 __ lwu(as_Register(dst), as_Register(base), disp);
2604 } else {
2605 __ set64(T9, disp);
2606 __ daddu(AT, as_Register(base), T9);
2607 __ lwu(as_Register(dst), AT, 0);
2608 }
2609 }
2610 %}
2613 enc_class load_P_enc (mRegP dst, memory mem) %{
2614 MacroAssembler _masm(&cbuf);
2615 int dst = $dst$$reg;
2616 int base = $mem$$base;
2617 int index = $mem$$index;
2618 int scale = $mem$$scale;
2619 int disp = $mem$$disp;
2620 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2621 assert(disp_reloc == relocInfo::none, "cannot have disp");
2623 if( index != 0 ) {
2624 if ( UseLoongsonISA ) {
2625 if ( Assembler::is_simm(disp, 8) ) {
2626 if ( scale != 0 ) {
2627 __ dsll(AT, as_Register(index), scale);
2628 __ gsldx(as_Register(dst), as_Register(base), AT, disp);
2629 } else {
2630 __ gsldx(as_Register(dst), as_Register(base), as_Register(index), disp);
2631 }
2632 } else if ( Assembler::is_simm16(disp) ){
2633 if ( scale != 0 ) {
2634 __ dsll(AT, as_Register(index), scale);
2635 __ daddu(AT, AT, as_Register(base));
2636 } else {
2637 __ daddu(AT, as_Register(index), as_Register(base));
2638 }
2639 __ ld(as_Register(dst), AT, disp);
2640 } else {
2641 if ( scale != 0 ) {
2642 __ dsll(AT, as_Register(index), scale);
2643 __ move(T9, disp);
2644 __ daddu(AT, AT, T9);
2645 } else {
2646 __ move(T9, disp);
2647 __ daddu(AT, as_Register(index), T9);
2648 }
2649 __ gsldx(as_Register(dst), as_Register(base), AT, 0);
2650 }
2651 } else { //not use loongson isa
2652 if (scale == 0) {
2653 __ daddu(AT, as_Register(base), as_Register(index));
2654 } else {
2655 __ dsll(AT, as_Register(index), scale);
2656 __ daddu(AT, as_Register(base), AT);
2657 }
2658 if( Assembler::is_simm16(disp) ) {
2659 __ ld(as_Register(dst), AT, disp);
2660 } else {
2661 __ set64(T9, disp);
2662 __ daddu(AT, AT, T9);
2663 __ ld(as_Register(dst), AT, 0);
2664 }
2665 }
2666 } else {
2667 if ( UseLoongsonISA ) {
2668 if ( Assembler::is_simm16(disp) ){
2669 __ ld(as_Register(dst), as_Register(base), disp);
2670 } else {
2671 __ set64(T9, disp);
2672 __ gsldx(as_Register(dst), as_Register(base), T9, 0);
2673 }
2674 } else { //not use loongson isa
2675 if( Assembler::is_simm16(disp) ) {
2676 __ ld(as_Register(dst), as_Register(base), disp);
2677 } else {
2678 __ set64(T9, disp);
2679 __ daddu(AT, as_Register(base), T9);
2680 __ ld(as_Register(dst), AT, 0);
2681 }
2682 }
2683 }
2684 %}
2686 enc_class store_P_reg_enc (memory mem, mRegP src) %{
2687 MacroAssembler _masm(&cbuf);
2688 int src = $src$$reg;
2689 int base = $mem$$base;
2690 int index = $mem$$index;
2691 int scale = $mem$$scale;
2692 int disp = $mem$$disp;
2694 if( index != 0 ) {
2695 if ( UseLoongsonISA ){
2696 if ( Assembler::is_simm(disp, 8) ) {
2697 if ( scale == 0 ) {
2698 __ gssdx(as_Register(src), as_Register(base), as_Register(index), disp);
2699 } else {
2700 __ dsll(AT, as_Register(index), scale);
2701 __ gssdx(as_Register(src), as_Register(base), AT, disp);
2702 }
2703 } else if ( Assembler::is_simm16(disp) ) {
2704 if ( scale == 0 ) {
2705 __ daddu(AT, as_Register(base), as_Register(index));
2706 } else {
2707 __ dsll(AT, as_Register(index), scale);
2708 __ daddu(AT, as_Register(base), AT);
2709 }
2710 __ sd(as_Register(src), AT, disp);
2711 } else {
2712 if ( scale == 0 ) {
2713 __ move(T9, disp);
2714 __ daddu(AT, as_Register(index), T9);
2715 } else {
2716 __ dsll(AT, as_Register(index), scale);
2717 __ move(T9, disp);
2718 __ daddu(AT, AT, T9);
2719 }
2720 __ gssdx(as_Register(src), as_Register(base), AT, 0);
2721 }
2722 } else { //not use loongson isa
2723 if (scale == 0) {
2724 __ daddu(AT, as_Register(base), as_Register(index));
2725 } else {
2726 __ dsll(AT, as_Register(index), scale);
2727 __ daddu(AT, as_Register(base), AT);
2728 }
2729 if( Assembler::is_simm16(disp) ) {
2730 __ sd(as_Register(src), AT, disp);
2731 } else {
2732 __ move(T9, disp);
2733 __ daddu(AT, AT, T9);
2734 __ sd(as_Register(src), AT, 0);
2735 }
2736 }
2737 } else {
2738 if ( UseLoongsonISA ) {
2739 if ( Assembler::is_simm16(disp) ) {
2740 __ sd(as_Register(src), as_Register(base), disp);
2741 } else {
2742 __ move(T9, disp);
2743 __ gssdx(as_Register(src), as_Register(base), T9, 0);
2744 }
2745 } else {
2746 if( Assembler::is_simm16(disp) ) {
2747 __ sd(as_Register(src), as_Register(base), disp);
2748 } else {
2749 __ move(T9, disp);
2750 __ daddu(AT, as_Register(base), T9);
2751 __ sd(as_Register(src), AT, 0);
2752 }
2753 }
2754 }
2755 %}
2757 enc_class store_N_reg_enc (memory mem, mRegN src) %{
2758 MacroAssembler _masm(&cbuf);
2759 int src = $src$$reg;
2760 int base = $mem$$base;
2761 int index = $mem$$index;
2762 int scale = $mem$$scale;
2763 int disp = $mem$$disp;
2765 if( index != 0 ) {
2766 if ( UseLoongsonISA ){
2767 if ( Assembler::is_simm(disp, 8) ) {
2768 if ( scale == 0 ) {
2769 __ gsswx(as_Register(src), as_Register(base), as_Register(index), disp);
2770 } else {
2771 __ dsll(AT, as_Register(index), scale);
2772 __ gsswx(as_Register(src), as_Register(base), AT, disp);
2773 }
2774 } else if ( Assembler::is_simm16(disp) ) {
2775 if ( scale == 0 ) {
2776 __ daddu(AT, as_Register(base), as_Register(index));
2777 } else {
2778 __ dsll(AT, as_Register(index), scale);
2779 __ daddu(AT, as_Register(base), AT);
2780 }
2781 __ sw(as_Register(src), AT, disp);
2782 } else {
2783 if ( scale == 0 ) {
2784 __ move(T9, disp);
2785 __ daddu(AT, as_Register(index), T9);
2786 } else {
2787 __ dsll(AT, as_Register(index), scale);
2788 __ move(T9, disp);
2789 __ daddu(AT, AT, T9);
2790 }
2791 __ gsswx(as_Register(src), as_Register(base), AT, 0);
2792 }
2793 } else { //not use loongson isa
2794 if (scale == 0) {
2795 __ daddu(AT, as_Register(base), as_Register(index));
2796 } else {
2797 __ dsll(AT, as_Register(index), scale);
2798 __ daddu(AT, as_Register(base), AT);
2799 }
2800 if( Assembler::is_simm16(disp) ) {
2801 __ sw(as_Register(src), AT, disp);
2802 } else {
2803 __ move(T9, disp);
2804 __ daddu(AT, AT, T9);
2805 __ sw(as_Register(src), AT, 0);
2806 }
2807 }
2808 } else {
2809 if ( UseLoongsonISA ) {
2810 if ( Assembler::is_simm16(disp) ) {
2811 __ sw(as_Register(src), as_Register(base), disp);
2812 } else {
2813 __ move(T9, disp);
2814 __ gsswx(as_Register(src), as_Register(base), T9, 0);
2815 }
2816 } else {
2817 if( Assembler::is_simm16(disp) ) {
2818 __ sw(as_Register(src), as_Register(base), disp);
2819 } else {
2820 __ move(T9, disp);
2821 __ daddu(AT, as_Register(base), T9);
2822 __ sw(as_Register(src), AT, 0);
2823 }
2824 }
2825 }
2826 %}
2828 enc_class store_P_immP0_enc (memory mem) %{
2829 MacroAssembler _masm(&cbuf);
2830 int base = $mem$$base;
2831 int index = $mem$$index;
2832 int scale = $mem$$scale;
2833 int disp = $mem$$disp;
2835 if( index != 0 ) {
2836 if (scale == 0) {
2837 if( Assembler::is_simm16(disp) ) {
2838 if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
2839 __ gssdx(R0, as_Register(base), as_Register(index), disp);
2840 } else {
2841 __ daddu(AT, as_Register(base), as_Register(index));
2842 __ sd(R0, AT, disp);
2843 }
2844 } else {
2845 __ daddu(AT, as_Register(base), as_Register(index));
2846 __ move(T9, disp);
2847 if(UseLoongsonISA) {
2848 __ gssdx(R0, AT, T9, 0);
2849 } else {
2850 __ daddu(AT, AT, T9);
2851 __ sd(R0, AT, 0);
2852 }
2853 }
2854 } else {
2855 __ dsll(AT, as_Register(index), scale);
2856 if( Assembler::is_simm16(disp) ) {
2857 if (UseLoongsonISA && Assembler::is_simm(disp, 8)) {
2858 __ gssdx(R0, as_Register(base), AT, disp);
2859 } else {
2860 __ daddu(AT, as_Register(base), AT);
2861 __ sd(R0, AT, disp);
2862 }
2863 } else {
2864 __ daddu(AT, as_Register(base), AT);
2865 __ move(T9, disp);
2866 if (UseLoongsonISA) {
2867 __ gssdx(R0, AT, T9, 0);
2868 } else {
2869 __ daddu(AT, AT, T9);
2870 __ sd(R0, AT, 0);
2871 }
2872 }
2873 }
2874 } else {
2875 if( Assembler::is_simm16(disp) ) {
2876 __ sd(R0, as_Register(base), disp);
2877 } else {
2878 __ move(T9, disp);
2879 if (UseLoongsonISA) {
2880 __ gssdx(R0, as_Register(base), T9, 0);
2881 } else {
2882 __ daddu(AT, as_Register(base), T9);
2883 __ sd(R0, AT, 0);
2884 }
2885 }
2886 }
2887 %}
2889 enc_class storeImmN0_enc(memory mem, ImmN0 src) %{
2890 MacroAssembler _masm(&cbuf);
2891 int base = $mem$$base;
2892 int index = $mem$$index;
2893 int scale = $mem$$scale;
2894 int disp = $mem$$disp;
2896 if(index!=0){
2897 if (scale == 0) {
2898 __ daddu(AT, as_Register(base), as_Register(index));
2899 } else {
2900 __ dsll(AT, as_Register(index), scale);
2901 __ daddu(AT, as_Register(base), AT);
2902 }
2904 if( Assembler::is_simm16(disp) ) {
2905 __ sw(R0, AT, disp);
2906 } else {
2907 __ move(T9, disp);
2908 __ daddu(AT, AT, T9);
2909 __ sw(R0, AT, 0);
2910 }
2911 } else {
2912 if( Assembler::is_simm16(disp) ) {
2913 __ sw(R0, as_Register(base), disp);
2914 } else {
2915 __ move(T9, disp);
2916 __ daddu(AT, as_Register(base), T9);
2917 __ sw(R0, AT, 0);
2918 }
2919 }
2920 %}
2922 enc_class load_L_enc (mRegL dst, memory mem) %{
2923 MacroAssembler _masm(&cbuf);
2924 int base = $mem$$base;
2925 int index = $mem$$index;
2926 int scale = $mem$$scale;
2927 int disp = $mem$$disp;
2928 Register dst_reg = as_Register($dst$$reg);
2930 // For implicit null check
2931 __ lb(AT, as_Register(base), 0);
2933 if( index != 0 ) {
2934 if (scale == 0) {
2935 __ daddu(AT, as_Register(base), as_Register(index));
2936 } else {
2937 __ dsll(AT, as_Register(index), scale);
2938 __ daddu(AT, as_Register(base), AT);
2939 }
2940 if( Assembler::is_simm16(disp) ) {
2941 __ ld(dst_reg, AT, disp);
2942 } else {
2943 __ move(T9, disp);
2944 __ daddu(AT, AT, T9);
2945 __ ld(dst_reg, AT, 0);
2946 }
2947 } else {
2948 if( Assembler::is_simm16(disp) ) {
2949 __ ld(dst_reg, as_Register(base), disp);
2950 } else {
2951 __ move(T9, disp);
2952 __ daddu(AT, as_Register(base), T9);
2953 __ ld(dst_reg, AT, 0);
2954 }
2955 }
2956 %}
2958 enc_class store_L_reg_enc (memory mem, mRegL src) %{
2959 MacroAssembler _masm(&cbuf);
2960 int base = $mem$$base;
2961 int index = $mem$$index;
2962 int scale = $mem$$scale;
2963 int disp = $mem$$disp;
2964 Register src_reg = as_Register($src$$reg);
2966 if( index != 0 ) {
2967 if (scale == 0) {
2968 __ daddu(AT, as_Register(base), as_Register(index));
2969 } else {
2970 __ dsll(AT, as_Register(index), scale);
2971 __ daddu(AT, as_Register(base), AT);
2972 }
2973 if( Assembler::is_simm16(disp) ) {
2974 __ sd(src_reg, AT, disp);
2975 } else {
2976 __ move(T9, disp);
2977 __ daddu(AT, AT, T9);
2978 __ sd(src_reg, AT, 0);
2979 }
2980 } else {
2981 if( Assembler::is_simm16(disp) ) {
2982 __ sd(src_reg, as_Register(base), disp);
2983 } else {
2984 __ move(T9, disp);
2985 __ daddu(AT, as_Register(base), T9);
2986 __ sd(src_reg, AT, 0);
2987 }
2988 }
2989 %}
2991 enc_class store_L_immL0_enc (memory mem, immL0 src) %{
2992 MacroAssembler _masm(&cbuf);
2993 int base = $mem$$base;
2994 int index = $mem$$index;
2995 int scale = $mem$$scale;
2996 int disp = $mem$$disp;
2998 if( index != 0 ) {
2999 // For implicit null check
3000 __ lb(AT, as_Register(base), 0);
3002 if (scale == 0) {
3003 __ daddu(AT, as_Register(base), as_Register(index));
3004 } else {
3005 __ dsll(AT, as_Register(index), scale);
3006 __ daddu(AT, as_Register(base), AT);
3007 }
3008 if( Assembler::is_simm16(disp) ) {
3009 __ sd(R0, AT, disp);
3010 } else {
3011 __ move(T9, disp);
3012 __ addu(AT, AT, T9);
3013 __ sd(R0, AT, 0);
3014 }
3015 } else {
3016 if( Assembler::is_simm16(disp) ) {
3017 __ sd(R0, as_Register(base), disp);
3018 } else {
3019 __ move(T9, disp);
3020 __ addu(AT, as_Register(base), T9);
3021 __ sd(R0, AT, 0);
3022 }
3023 }
3024 %}
3026 enc_class store_L_immL_enc (memory mem, immL src) %{
3027 MacroAssembler _masm(&cbuf);
3028 int base = $mem$$base;
3029 int index = $mem$$index;
3030 int scale = $mem$$scale;
3031 int disp = $mem$$disp;
3032 long imm = $src$$constant;
3034 if( index != 0 ) {
3035 if (scale == 0) {
3036 __ daddu(AT, as_Register(base), as_Register(index));
3037 } else {
3038 __ dsll(AT, as_Register(index), scale);
3039 __ daddu(AT, as_Register(base), AT);
3040 }
3041 if( Assembler::is_simm16(disp) ) {
3042 __ set64(T9, imm);
3043 __ sd(T9, AT, disp);
3044 } else {
3045 __ move(T9, disp);
3046 __ addu(AT, AT, T9);
3047 __ set64(T9, imm);
3048 __ sd(T9, AT, 0);
3049 }
3050 } else {
3051 if( Assembler::is_simm16(disp) ) {
3052 __ move(AT, as_Register(base));
3053 __ set64(T9, imm);
3054 __ sd(T9, AT, disp);
3055 } else {
3056 __ move(T9, disp);
3057 __ addu(AT, as_Register(base), T9);
3058 __ set64(T9, imm);
3059 __ sd(T9, AT, 0);
3060 }
3061 }
3062 %}
3064 enc_class load_F_enc (regF dst, memory mem) %{
3065 MacroAssembler _masm(&cbuf);
3066 int base = $mem$$base;
3067 int index = $mem$$index;
3068 int scale = $mem$$scale;
3069 int disp = $mem$$disp;
3070 FloatRegister dst = $dst$$FloatRegister;
3072 if( index != 0 ) {
3073 if( Assembler::is_simm16(disp) ) {
3074 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3075 if (scale == 0) {
3076 __ gslwxc1(dst, as_Register(base), as_Register(index), disp);
3077 } else {
3078 __ dsll(AT, as_Register(index), scale);
3079 __ gslwxc1(dst, as_Register(base), AT, disp);
3080 }
3081 } else {
3082 if (scale == 0) {
3083 __ daddu(AT, as_Register(base), as_Register(index));
3084 } else {
3085 __ dsll(AT, as_Register(index), scale);
3086 __ daddu(AT, as_Register(base), AT);
3087 }
3088 __ lwc1(dst, AT, disp);
3089 }
3090 } else {
3091 if (scale == 0) {
3092 __ daddu(AT, as_Register(base), as_Register(index));
3093 } else {
3094 __ dsll(AT, as_Register(index), scale);
3095 __ daddu(AT, as_Register(base), AT);
3096 }
3097 __ move(T9, disp);
3098 if( UseLoongsonISA ) {
3099 __ gslwxc1(dst, AT, T9, 0);
3100 } else {
3101 __ daddu(AT, AT, T9);
3102 __ lwc1(dst, AT, 0);
3103 }
3104 }
3105 } else {
3106 if( Assembler::is_simm16(disp) ) {
3107 __ lwc1(dst, as_Register(base), disp);
3108 } else {
3109 __ move(T9, disp);
3110 if( UseLoongsonISA ) {
3111 __ gslwxc1(dst, as_Register(base), T9, 0);
3112 } else {
3113 __ daddu(AT, as_Register(base), T9);
3114 __ lwc1(dst, AT, 0);
3115 }
3116 }
3117 }
3118 %}
3120 enc_class store_F_reg_enc (memory mem, regF src) %{
3121 MacroAssembler _masm(&cbuf);
3122 int base = $mem$$base;
3123 int index = $mem$$index;
3124 int scale = $mem$$scale;
3125 int disp = $mem$$disp;
3126 FloatRegister src = $src$$FloatRegister;
3128 if( index != 0 ) {
3129 if( Assembler::is_simm16(disp) ) {
3130 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3131 if (scale == 0) {
3132 __ gsswxc1(src, as_Register(base), as_Register(index), disp);
3133 } else {
3134 __ dsll(AT, as_Register(index), scale);
3135 __ gsswxc1(src, as_Register(base), AT, disp);
3136 }
3137 } else {
3138 if (scale == 0) {
3139 __ daddu(AT, as_Register(base), as_Register(index));
3140 } else {
3141 __ dsll(AT, as_Register(index), scale);
3142 __ daddu(AT, as_Register(base), AT);
3143 }
3144 __ swc1(src, AT, disp);
3145 }
3146 } else {
3147 if (scale == 0) {
3148 __ daddu(AT, as_Register(base), as_Register(index));
3149 } else {
3150 __ dsll(AT, as_Register(index), scale);
3151 __ daddu(AT, as_Register(base), AT);
3152 }
3153 __ move(T9, disp);
3154 if( UseLoongsonISA ) {
3155 __ gsswxc1(src, AT, T9, 0);
3156 } else {
3157 __ daddu(AT, AT, T9);
3158 __ swc1(src, AT, 0);
3159 }
3160 }
3161 } else {
3162 if( Assembler::is_simm16(disp) ) {
3163 __ swc1(src, as_Register(base), disp);
3164 } else {
3165 __ move(T9, disp);
3166 if( UseLoongsonISA ) {
3167 __ gsswxc1(src, as_Register(base), T9, 0);
3168 } else {
3169 __ daddu(AT, as_Register(base), T9);
3170 __ swc1(src, AT, 0);
3171 }
3172 }
3173 }
3174 %}
3176 enc_class load_D_enc (regD dst, memory mem) %{
3177 MacroAssembler _masm(&cbuf);
3178 int base = $mem$$base;
3179 int index = $mem$$index;
3180 int scale = $mem$$scale;
3181 int disp = $mem$$disp;
3182 FloatRegister dst_reg = as_FloatRegister($dst$$reg);
3184 if( index != 0 ) {
3185 if( Assembler::is_simm16(disp) ) {
3186 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3187 if (scale == 0) {
3188 __ gsldxc1(dst_reg, as_Register(base), as_Register(index), disp);
3189 } else {
3190 __ dsll(AT, as_Register(index), scale);
3191 __ gsldxc1(dst_reg, as_Register(base), AT, disp);
3192 }
3193 } else {
3194 if (scale == 0) {
3195 __ daddu(AT, as_Register(base), as_Register(index));
3196 } else {
3197 __ dsll(AT, as_Register(index), scale);
3198 __ daddu(AT, as_Register(base), AT);
3199 }
3200 __ ldc1(dst_reg, AT, disp);
3201 }
3202 } else {
3203 if (scale == 0) {
3204 __ daddu(AT, as_Register(base), as_Register(index));
3205 } else {
3206 __ dsll(AT, as_Register(index), scale);
3207 __ daddu(AT, as_Register(base), AT);
3208 }
3209 __ move(T9, disp);
3210 if( UseLoongsonISA ) {
3211 __ gsldxc1(dst_reg, AT, T9, 0);
3212 } else {
3213 __ addu(AT, AT, T9);
3214 __ ldc1(dst_reg, AT, 0);
3215 }
3216 }
3217 } else {
3218 if( Assembler::is_simm16(disp) ) {
3219 __ ldc1(dst_reg, as_Register(base), disp);
3220 } else {
3221 __ move(T9, disp);
3222 if( UseLoongsonISA ) {
3223 __ gsldxc1(dst_reg, as_Register(base), T9, 0);
3224 } else {
3225 __ addu(AT, as_Register(base), T9);
3226 __ ldc1(dst_reg, AT, 0);
3227 }
3228 }
3229 }
3230 %}
3232 enc_class store_D_reg_enc (memory mem, regD src) %{
3233 MacroAssembler _masm(&cbuf);
3234 int base = $mem$$base;
3235 int index = $mem$$index;
3236 int scale = $mem$$scale;
3237 int disp = $mem$$disp;
3238 FloatRegister src_reg = as_FloatRegister($src$$reg);
3240 if( index != 0 ) {
3241 if( Assembler::is_simm16(disp) ) {
3242 if( UseLoongsonISA && Assembler::is_simm(disp, 8) ) {
3243 if (scale == 0) {
3244 __ gssdxc1(src_reg, as_Register(base), as_Register(index), disp);
3245 } else {
3246 __ dsll(AT, as_Register(index), scale);
3247 __ gssdxc1(src_reg, as_Register(base), AT, disp);
3248 }
3249 } else {
3250 if (scale == 0) {
3251 __ daddu(AT, as_Register(base), as_Register(index));
3252 } else {
3253 __ dsll(AT, as_Register(index), scale);
3254 __ daddu(AT, as_Register(base), AT);
3255 }
3256 __ sdc1(src_reg, AT, disp);
3257 }
3258 } else {
3259 if (scale == 0) {
3260 __ daddu(AT, as_Register(base), as_Register(index));
3261 } else {
3262 __ dsll(AT, as_Register(index), scale);
3263 __ daddu(AT, as_Register(base), AT);
3264 }
3265 __ move(T9, disp);
3266 if( UseLoongsonISA ) {
3267 __ gssdxc1(src_reg, AT, T9, 0);
3268 } else {
3269 __ addu(AT, AT, T9);
3270 __ sdc1(src_reg, AT, 0);
3271 }
3272 }
3273 } else {
3274 if( Assembler::is_simm16(disp) ) {
3275 __ sdc1(src_reg, as_Register(base), disp);
3276 } else {
3277 __ move(T9, disp);
3278 if( UseLoongsonISA ) {
3279 __ gssdxc1(src_reg, as_Register(base), T9, 0);
3280 } else {
3281 __ addu(AT, as_Register(base), T9);
3282 __ sdc1(src_reg, AT, 0);
3283 }
3284 }
3285 }
3286 %}
3288 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf
3289 MacroAssembler _masm(&cbuf);
3290 // This is the instruction starting address for relocation info.
3291 __ block_comment("Java_To_Runtime");
3292 cbuf.set_insts_mark();
3293 __ relocate(relocInfo::runtime_call_type);
3295 __ patchable_call((address)$meth$$method);
3296 %}
3298 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL
3299 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine
3300 // who we intended to call.
3301 MacroAssembler _masm(&cbuf);
3302 cbuf.set_insts_mark();
3304 if ( !_method ) {
3305 __ relocate(relocInfo::runtime_call_type);
3306 } else if(_optimized_virtual) {
3307 __ relocate(relocInfo::opt_virtual_call_type);
3308 } else {
3309 __ relocate(relocInfo::static_call_type);
3310 }
3312 __ patchable_call((address)($meth$$method));
3313 if( _method ) { // Emit stub for static call
3314 emit_java_to_interp(cbuf);
3315 }
3316 %}
3319 /*
3320 * [Ref: LIR_Assembler::ic_call() ]
3321 */
3322 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL
3323 MacroAssembler _masm(&cbuf);
3324 __ block_comment("Java_Dynamic_Call");
3325 __ ic_call((address)$meth$$method);
3326 %}
3329 enc_class Set_Flags_After_Fast_Lock_Unlock(FlagsReg cr) %{
3330 Register flags = $cr$$Register;
3331 Label L;
3333 MacroAssembler _masm(&cbuf);
3335 __ addu(flags, R0, R0);
3336 __ beq(AT, R0, L);
3337 __ delayed()->nop();
3338 __ move(flags, 0xFFFFFFFF);
3339 __ bind(L);
3340 %}
3342 enc_class enc_PartialSubtypeCheck(mRegP result, mRegP sub, mRegP super, mRegI tmp) %{
3343 Register result = $result$$Register;
3344 Register sub = $sub$$Register;
3345 Register super = $super$$Register;
3346 Register length = $tmp$$Register;
3347 Register tmp = T9;
3348 Label miss;
3350 /* 2012/9/28 Jin: result may be the same as sub
3351 * 47c B40: # B21 B41 <- B20 Freq: 0.155379
3352 * 47c partialSubtypeCheck result=S1, sub=S1, super=S3, length=S0
3353 * 4bc mov S2, NULL #@loadConP
3354 * 4c0 beq S1, S2, B21 #@branchConP P=0.999999 C=-1.000000
3355 */
3356 MacroAssembler _masm(&cbuf);
3357 Label done;
3358 __ check_klass_subtype_slow_path(sub, super, length, tmp,
3359 NULL, &miss,
3360 /*set_cond_codes:*/ true);
3361 /* 2013/7/22 Jin: Refer to X86_64's RDI */
3362 __ move(result, 0);
3363 __ b(done);
3364 __ nop();
3366 __ bind(miss);
3367 __ move(result, 1);
3368 __ bind(done);
3369 %}
3371 %}
3374 //---------MIPS FRAME--------------------------------------------------------------
3375 // Definition of frame structure and management information.
3376 //
3377 // S T A C K L A Y O U T Allocators stack-slot number
3378 // | (to get allocators register number
3379 // G Owned by | | v add SharedInfo::stack0)
3380 // r CALLER | |
3381 // o | +--------+ pad to even-align allocators stack-slot
3382 // w V | pad0 | numbers; owned by CALLER
3383 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
3384 // h ^ | in | 5
3385 // | | args | 4 Holes in incoming args owned by SELF
3386 // | | old | | 3
3387 // | | SP-+--------+----> Matcher::_old_SP, even aligned
3388 // v | | ret | 3 return address
3389 // Owned by +--------+
3390 // Self | pad2 | 2 pad to align old SP
3391 // | +--------+ 1
3392 // | | locks | 0
3393 // | +--------+----> SharedInfo::stack0, even aligned
3394 // | | pad1 | 11 pad to align new SP
3395 // | +--------+
3396 // | | | 10
3397 // | | spills | 9 spills
3398 // V | | 8 (pad0 slot for callee)
3399 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
3400 // ^ | out | 7
3401 // | | args | 6 Holes in outgoing args owned by CALLEE
3402 // Owned by new | |
3403 // Callee SP-+--------+----> Matcher::_new_SP, even aligned
3404 // | |
3405 //
3406 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
3407 // known from SELF's arguments and the Java calling convention.
3408 // Region 6-7 is determined per call site.
3409 // Note 2: If the calling convention leaves holes in the incoming argument
3410 // area, those holes are owned by SELF. Holes in the outgoing area
3411 // are owned by the CALLEE. Holes should not be nessecary in the
3412 // incoming area, as the Java calling convention is completely under
3413 // the control of the AD file. Doubles can be sorted and packed to
3414 // avoid holes. Holes in the outgoing arguments may be nessecary for
3415 // varargs C calling conventions.
3416 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
3417 // even aligned with pad0 as needed.
3418 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
3419 // region 6-11 is even aligned; it may be padded out more so that
3420 // the region from SP to FP meets the minimum stack alignment.
3421 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3422 // alignment. Region 11, pad1, may be dynamically extended so that
3423 // SP meets the minimum alignment.
3426 frame %{
3428 stack_direction(TOWARDS_LOW);
3430 // These two registers define part of the calling convention
3431 // between compiled code and the interpreter.
3432 // SEE StartI2CNode::calling_convention & StartC2INode::calling_convention & StartOSRNode::calling_convention
3433 // for more information. by yjl 3/16/2006
3435 inline_cache_reg(T1); // Inline Cache Register
3436 interpreter_method_oop_reg(S3); // Method Oop Register when calling interpreter
3438 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
3439 cisc_spilling_operand_name(indOffset32);
3441 // Number of stack slots consumed by locking an object
3442 // generate Compile::sync_stack_slots
3443 #ifdef _LP64
3444 sync_stack_slots(2);
3445 #else
3446 sync_stack_slots(1);
3447 #endif
3449 frame_pointer(SP);
3451 // Interpreter stores its frame pointer in a register which is
3452 // stored to the stack by I2CAdaptors.
3453 // I2CAdaptors convert from interpreted java to compiled java.
3455 interpreter_frame_pointer(FP);
3457 // generate Matcher::stack_alignment
3458 stack_alignment(StackAlignmentInBytes); //wordSize = sizeof(char*);
3460 // Number of stack slots between incoming argument block and the start of
3461 // a new frame. The PROLOG must add this many slots to the stack. The
3462 // EPILOG must remove this many slots. Intel needs one slot for
3463 // return address.
3464 // generate Matcher::in_preserve_stack_slots
3465 //in_preserve_stack_slots(VerifyStackAtCalls + 2); //Now VerifyStackAtCalls is defined as false ! Leave one stack slot for ra and fp
3466 in_preserve_stack_slots(4); //Now VerifyStackAtCalls is defined as false ! Leave two stack slots for ra and fp
3468 // Number of outgoing stack slots killed above the out_preserve_stack_slots
3469 // for calls to C. Supports the var-args backing area for register parms.
3470 varargs_C_out_slots_killed(0);
3472 // The after-PROLOG location of the return address. Location of
3473 // return address specifies a type (REG or STACK) and a number
3474 // representing the register number (i.e. - use a register name) or
3475 // stack slot.
3476 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3477 // Otherwise, it is above the locks and verification slot and alignment word
3478 //return_addr(STACK -1+ round_to(1+VerifyStackAtCalls+Compile::current()->sync()*Compile::current()->sync_stack_slots(),WordsPerLong));
3479 return_addr(REG RA);
3481 // Body of function which returns an integer array locating
3482 // arguments either in registers or in stack slots. Passed an array
3483 // of ideal registers called "sig" and a "length" count. Stack-slot
3484 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3485 // arguments for a CALLEE. Incoming stack arguments are
3486 // automatically biased by the preserve_stack_slots field above.
3489 // will generated to Matcher::calling_convention(OptoRegPair *sig, uint length, bool is_outgoing)
3490 // StartNode::calling_convention call this. by yjl 3/16/2006
3491 calling_convention %{
3492 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3493 %}
3498 // Body of function which returns an integer array locating
3499 // arguments either in registers or in stack slots. Passed an array
3500 // of ideal registers called "sig" and a "length" count. Stack-slot
3501 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3502 // arguments for a CALLEE. Incoming stack arguments are
3503 // automatically biased by the preserve_stack_slots field above.
3506 // SEE CallRuntimeNode::calling_convention for more information. by yjl 3/16/2006
3507 c_calling_convention %{
3508 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
3509 %}
3512 // Location of C & interpreter return values
3513 // register(s) contain(s) return value for Op_StartI2C and Op_StartOSR.
3514 // SEE Matcher::match. by yjl 3/16/2006
3515 c_return_value %{
3516 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3517 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
3518 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
3519 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num };
3520 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3521 %}
3523 // Location of return values
3524 // register(s) contain(s) return value for Op_StartC2I and Op_Start.
3525 // SEE Matcher::match. by yjl 3/16/2006
3527 return_value %{
3528 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3529 /* -- , -- , Op_RegN, Op_RegI, Op_RegP, Op_RegF, Op_RegD, Op_RegL */
3530 static int lo[Op_RegL+1] = { 0, 0, V0_num, V0_num, V0_num, F0_num, F0_num, V0_num };
3531 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, V0_H_num, OptoReg::Bad, F0_H_num, V0_H_num};
3532 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3533 %}
3535 %}
3537 //----------ATTRIBUTES---------------------------------------------------------
3538 //----------Operand Attributes-------------------------------------------------
3539 op_attrib op_cost(0); // Required cost attribute
3541 //----------Instruction Attributes---------------------------------------------
3542 ins_attrib ins_cost(100); // Required cost attribute
3543 ins_attrib ins_size(32); // Required size attribute (in bits)
3544 ins_attrib ins_pc_relative(0); // Required PC Relative flag
3545 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
3546 // non-matching short branch variant of some
3547 // long branch?
3548 ins_attrib ins_alignment(4); // Required alignment attribute (must be a power of 2)
3549 // specifies the alignment that some part of the instruction (not
3550 // necessarily the start) requires. If > 1, a compute_padding()
3551 // function must be provided for the instruction
3553 //----------OPERANDS-----------------------------------------------------------
3554 // Operand definitions must precede instruction definitions for correct parsing
3555 // in the ADLC because operands constitute user defined types which are used in
3556 // instruction definitions.
3558 // Vectors
3559 operand vecD() %{
3560 constraint(ALLOC_IN_RC(dbl_reg));
3561 match(VecD);
3563 format %{ %}
3564 interface(REG_INTER);
3565 %}
3567 // Flags register, used as output of compare instructions
3568 operand FlagsReg() %{
3569 constraint(ALLOC_IN_RC(mips_flags));
3570 match(RegFlags);
3572 format %{ "EFLAGS" %}
3573 interface(REG_INTER);
3574 %}
3576 //----------Simple Operands----------------------------------------------------
3577 //TODO: Should we need to define some more special immediate number ?
3578 // Immediate Operands
3579 // Integer Immediate
3580 operand immI() %{
3581 match(ConI);
3582 //TODO: should not match immI8 here LEE
3583 match(immI8);
3585 op_cost(20);
3586 format %{ %}
3587 interface(CONST_INTER);
3588 %}
3590 // Long Immediate 8-bit
3591 operand immL8()
3592 %{
3593 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3594 match(ConL);
3596 op_cost(5);
3597 format %{ %}
3598 interface(CONST_INTER);
3599 %}
3601 // Constant for test vs zero
3602 operand immI0() %{
3603 predicate(n->get_int() == 0);
3604 match(ConI);
3606 op_cost(0);
3607 format %{ %}
3608 interface(CONST_INTER);
3609 %}
3611 // Constant for increment
3612 operand immI1() %{
3613 predicate(n->get_int() == 1);
3614 match(ConI);
3616 op_cost(0);
3617 format %{ %}
3618 interface(CONST_INTER);
3619 %}
3621 // Constant for decrement
3622 operand immI_M1() %{
3623 predicate(n->get_int() == -1);
3624 match(ConI);
3626 op_cost(0);
3627 format %{ %}
3628 interface(CONST_INTER);
3629 %}
3631 operand immI_MaxI() %{
3632 predicate(n->get_int() == 2147483647);
3633 match(ConI);
3635 op_cost(0);
3636 format %{ %}
3637 interface(CONST_INTER);
3638 %}
3640 // Valid scale values for addressing modes
3641 operand immI2() %{
3642 predicate(0 <= n->get_int() && (n->get_int() <= 3));
3643 match(ConI);
3645 format %{ %}
3646 interface(CONST_INTER);
3647 %}
3649 operand immI8() %{
3650 predicate((-128 <= n->get_int()) && (n->get_int() <= 127));
3651 match(ConI);
3653 op_cost(5);
3654 format %{ %}
3655 interface(CONST_INTER);
3656 %}
3658 operand immI16() %{
3659 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
3660 match(ConI);
3662 op_cost(10);
3663 format %{ %}
3664 interface(CONST_INTER);
3665 %}
3667 // Constant for long shifts
3668 operand immI_32() %{
3669 predicate( n->get_int() == 32 );
3670 match(ConI);
3672 op_cost(0);
3673 format %{ %}
3674 interface(CONST_INTER);
3675 %}
3677 operand immI_63() %{
3678 predicate( n->get_int() == 63 );
3679 match(ConI);
3681 op_cost(0);
3682 format %{ %}
3683 interface(CONST_INTER);
3684 %}
3686 operand immI_0_31() %{
3687 predicate( n->get_int() >= 0 && n->get_int() <= 31 );
3688 match(ConI);
3690 op_cost(0);
3691 format %{ %}
3692 interface(CONST_INTER);
3693 %}
3695 // Operand for non-negtive integer mask
3696 operand immI_nonneg_mask() %{
3697 predicate( (n->get_int() >= 0) && (Assembler::is_int_mask(n->get_int()) != -1) );
3698 match(ConI);
3700 op_cost(0);
3701 format %{ %}
3702 interface(CONST_INTER);
3703 %}
3705 operand immI_32_63() %{
3706 predicate( n->get_int() >= 32 && n->get_int() <= 63 );
3707 match(ConI);
3708 op_cost(0);
3710 format %{ %}
3711 interface(CONST_INTER);
3712 %}
3714 operand immI16_sub() %{
3715 predicate((-32767 <= n->get_int()) && (n->get_int() <= 32768));
3716 match(ConI);
3718 op_cost(10);
3719 format %{ %}
3720 interface(CONST_INTER);
3721 %}
3723 operand immI_0_32767() %{
3724 predicate( n->get_int() >= 0 && n->get_int() <= 32767 );
3725 match(ConI);
3726 op_cost(0);
3728 format %{ %}
3729 interface(CONST_INTER);
3730 %}
3732 operand immI_0_65535() %{
3733 predicate( n->get_int() >= 0 && n->get_int() <= 65535 );
3734 match(ConI);
3735 op_cost(0);
3737 format %{ %}
3738 interface(CONST_INTER);
3739 %}
3741 operand immI_1() %{
3742 predicate( n->get_int() == 1 );
3743 match(ConI);
3745 op_cost(0);
3746 format %{ %}
3747 interface(CONST_INTER);
3748 %}
3750 operand immI_2() %{
3751 predicate( n->get_int() == 2 );
3752 match(ConI);
3754 op_cost(0);
3755 format %{ %}
3756 interface(CONST_INTER);
3757 %}
3759 operand immI_3() %{
3760 predicate( n->get_int() == 3 );
3761 match(ConI);
3763 op_cost(0);
3764 format %{ %}
3765 interface(CONST_INTER);
3766 %}
3768 operand immI_7() %{
3769 predicate( n->get_int() == 7 );
3770 match(ConI);
3772 format %{ %}
3773 interface(CONST_INTER);
3774 %}
3776 // Immediates for special shifts (sign extend)
3778 // Constants for increment
3779 operand immI_16() %{
3780 predicate( n->get_int() == 16 );
3781 match(ConI);
3783 format %{ %}
3784 interface(CONST_INTER);
3785 %}
3787 operand immI_24() %{
3788 predicate( n->get_int() == 24 );
3789 match(ConI);
3791 format %{ %}
3792 interface(CONST_INTER);
3793 %}
3795 // Constant for byte-wide masking
3796 operand immI_255() %{
3797 predicate( n->get_int() == 255 );
3798 match(ConI);
3800 op_cost(0);
3801 format %{ %}
3802 interface(CONST_INTER);
3803 %}
3805 operand immI_65535() %{
3806 predicate( n->get_int() == 65535 );
3807 match(ConI);
3809 op_cost(5);
3810 format %{ %}
3811 interface(CONST_INTER);
3812 %}
3814 operand immI_65536() %{
3815 predicate( n->get_int() == 65536 );
3816 match(ConI);
3818 op_cost(5);
3819 format %{ %}
3820 interface(CONST_INTER);
3821 %}
3823 operand immI_M65536() %{
3824 predicate( n->get_int() == -65536 );
3825 match(ConI);
3827 op_cost(5);
3828 format %{ %}
3829 interface(CONST_INTER);
3830 %}
3832 // Pointer Immediate
3833 operand immP() %{
3834 match(ConP);
3836 op_cost(10);
3837 format %{ %}
3838 interface(CONST_INTER);
3839 %}
3841 // NULL Pointer Immediate
3842 operand immP0() %{
3843 predicate( n->get_ptr() == 0 );
3844 match(ConP);
3845 op_cost(0);
3847 format %{ %}
3848 interface(CONST_INTER);
3849 %}
3851 // Pointer Immediate: 64-bit
3852 operand immP_set() %{
3853 match(ConP);
3855 op_cost(5);
3856 // formats are generated automatically for constants and base registers
3857 format %{ %}
3858 interface(CONST_INTER);
3859 %}
3861 // Pointer Immediate: 64-bit
3862 operand immP_load() %{
3863 predicate(n->bottom_type()->isa_oop_ptr() || (MacroAssembler::insts_for_set64(n->get_ptr()) > 3));
3864 match(ConP);
3866 op_cost(5);
3867 // formats are generated automatically for constants and base registers
3868 format %{ %}
3869 interface(CONST_INTER);
3870 %}
3872 // Pointer Immediate: 64-bit
3873 operand immP_no_oop_cheap() %{
3874 predicate(!n->bottom_type()->isa_oop_ptr() && (MacroAssembler::insts_for_set64(n->get_ptr()) <= 3));
3875 match(ConP);
3877 op_cost(5);
3878 // formats are generated automatically for constants and base registers
3879 format %{ %}
3880 interface(CONST_INTER);
3881 %}
3883 // Pointer for polling page
3884 operand immP_poll() %{
3885 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
3886 match(ConP);
3887 op_cost(5);
3889 format %{ %}
3890 interface(CONST_INTER);
3891 %}
3893 // Pointer Immediate
3894 operand immN() %{
3895 match(ConN);
3897 op_cost(10);
3898 format %{ %}
3899 interface(CONST_INTER);
3900 %}
3902 operand immNKlass() %{
3903 match(ConNKlass);
3905 op_cost(10);
3906 format %{ %}
3907 interface(CONST_INTER);
3908 %}
3910 // NULL Pointer Immediate
3911 operand immN0() %{
3912 predicate(n->get_narrowcon() == 0);
3913 match(ConN);
3915 op_cost(5);
3916 format %{ %}
3917 interface(CONST_INTER);
3918 %}
3920 // Long Immediate
3921 operand immL() %{
3922 match(ConL);
3924 op_cost(20);
3925 format %{ %}
3926 interface(CONST_INTER);
3927 %}
3929 // Long Immediate zero
3930 operand immL0() %{
3931 predicate( n->get_long() == 0L );
3932 match(ConL);
3933 op_cost(0);
3935 format %{ %}
3936 interface(CONST_INTER);
3937 %}
3939 operand immL7() %{
3940 predicate( n->get_long() == 7L );
3941 match(ConL);
3942 op_cost(0);
3944 format %{ %}
3945 interface(CONST_INTER);
3946 %}
3948 operand immL_M1() %{
3949 predicate( n->get_long() == -1L );
3950 match(ConL);
3951 op_cost(0);
3953 format %{ %}
3954 interface(CONST_INTER);
3955 %}
3957 // bit 0..2 zero
3958 operand immL_M8() %{
3959 predicate( n->get_long() == -8L );
3960 match(ConL);
3961 op_cost(0);
3963 format %{ %}
3964 interface(CONST_INTER);
3965 %}
3967 // bit 2 zero
3968 operand immL_M5() %{
3969 predicate( n->get_long() == -5L );
3970 match(ConL);
3971 op_cost(0);
3973 format %{ %}
3974 interface(CONST_INTER);
3975 %}
3977 // bit 1..2 zero
3978 operand immL_M7() %{
3979 predicate( n->get_long() == -7L );
3980 match(ConL);
3981 op_cost(0);
3983 format %{ %}
3984 interface(CONST_INTER);
3985 %}
3987 // bit 0..1 zero
3988 operand immL_M4() %{
3989 predicate( n->get_long() == -4L );
3990 match(ConL);
3991 op_cost(0);
3993 format %{ %}
3994 interface(CONST_INTER);
3995 %}
3997 // bit 3..6 zero
3998 operand immL_M121() %{
3999 predicate( n->get_long() == -121L );
4000 match(ConL);
4001 op_cost(0);
4003 format %{ %}
4004 interface(CONST_INTER);
4005 %}
4007 // Long immediate from 0 to 127.
4008 // Used for a shorter form of long mul by 10.
4009 operand immL_127() %{
4010 predicate((0 <= n->get_long()) && (n->get_long() <= 127));
4011 match(ConL);
4012 op_cost(0);
4014 format %{ %}
4015 interface(CONST_INTER);
4016 %}
4018 // Operand for non-negtive long mask
4019 operand immL_nonneg_mask() %{
4020 predicate( (n->get_long() >= 0) && (Assembler::is_jlong_mask(n->get_long()) != -1) );
4021 match(ConL);
4023 op_cost(0);
4024 format %{ %}
4025 interface(CONST_INTER);
4026 %}
4028 operand immL_0_65535() %{
4029 predicate( n->get_long() >= 0 && n->get_long() <= 65535 );
4030 match(ConL);
4031 op_cost(0);
4033 format %{ %}
4034 interface(CONST_INTER);
4035 %}
4037 // Long Immediate: cheap (materialize in <= 3 instructions)
4038 operand immL_cheap() %{
4039 predicate(MacroAssembler::insts_for_set64(n->get_long()) <= 3);
4040 match(ConL);
4041 op_cost(0);
4043 format %{ %}
4044 interface(CONST_INTER);
4045 %}
4047 // Long Immediate: expensive (materialize in > 3 instructions)
4048 operand immL_expensive() %{
4049 predicate(MacroAssembler::insts_for_set64(n->get_long()) > 3);
4050 match(ConL);
4051 op_cost(0);
4053 format %{ %}
4054 interface(CONST_INTER);
4055 %}
4057 operand immL16() %{
4058 predicate((-32768 <= n->get_long()) && (n->get_long() <= 32767));
4059 match(ConL);
4061 op_cost(10);
4062 format %{ %}
4063 interface(CONST_INTER);
4064 %}
4066 operand immL16_sub() %{
4067 predicate((-32767 <= n->get_long()) && (n->get_long() <= 32768));
4068 match(ConL);
4070 op_cost(10);
4071 format %{ %}
4072 interface(CONST_INTER);
4073 %}
4075 // Long Immediate: low 32-bit mask
4076 operand immL_32bits() %{
4077 predicate(n->get_long() == 0xFFFFFFFFL);
4078 match(ConL);
4079 op_cost(20);
4081 format %{ %}
4082 interface(CONST_INTER);
4083 %}
4085 // Long Immediate 32-bit signed
4086 operand immL32()
4087 %{
4088 predicate(n->get_long() == (int) (n->get_long()));
4089 match(ConL);
4091 op_cost(15);
4092 format %{ %}
4093 interface(CONST_INTER);
4094 %}
4097 //single-precision floating-point zero
4098 operand immF0() %{
4099 predicate(jint_cast(n->getf()) == 0);
4100 match(ConF);
4102 op_cost(5);
4103 format %{ %}
4104 interface(CONST_INTER);
4105 %}
4107 //single-precision floating-point immediate
4108 operand immF() %{
4109 match(ConF);
4111 op_cost(20);
4112 format %{ %}
4113 interface(CONST_INTER);
4114 %}
4116 //double-precision floating-point zero
4117 operand immD0() %{
4118 predicate(jlong_cast(n->getd()) == 0);
4119 match(ConD);
4121 op_cost(5);
4122 format %{ %}
4123 interface(CONST_INTER);
4124 %}
4126 //double-precision floating-point immediate
4127 operand immD() %{
4128 match(ConD);
4130 op_cost(20);
4131 format %{ %}
4132 interface(CONST_INTER);
4133 %}
4135 // Register Operands
4136 // Integer Register
4137 operand mRegI() %{
4138 constraint(ALLOC_IN_RC(int_reg));
4139 match(RegI);
4141 format %{ %}
4142 interface(REG_INTER);
4143 %}
4145 operand no_Ax_mRegI() %{
4146 constraint(ALLOC_IN_RC(no_Ax_int_reg));
4147 match(RegI);
4148 match(mRegI);
4150 format %{ %}
4151 interface(REG_INTER);
4152 %}
4154 operand mS0RegI() %{
4155 constraint(ALLOC_IN_RC(s0_reg));
4156 match(RegI);
4157 match(mRegI);
4159 format %{ "S0" %}
4160 interface(REG_INTER);
4161 %}
4163 operand mS1RegI() %{
4164 constraint(ALLOC_IN_RC(s1_reg));
4165 match(RegI);
4166 match(mRegI);
4168 format %{ "S1" %}
4169 interface(REG_INTER);
4170 %}
4172 operand mS2RegI() %{
4173 constraint(ALLOC_IN_RC(s2_reg));
4174 match(RegI);
4175 match(mRegI);
4177 format %{ "S2" %}
4178 interface(REG_INTER);
4179 %}
4181 operand mS3RegI() %{
4182 constraint(ALLOC_IN_RC(s3_reg));
4183 match(RegI);
4184 match(mRegI);
4186 format %{ "S3" %}
4187 interface(REG_INTER);
4188 %}
4190 operand mS4RegI() %{
4191 constraint(ALLOC_IN_RC(s4_reg));
4192 match(RegI);
4193 match(mRegI);
4195 format %{ "S4" %}
4196 interface(REG_INTER);
4197 %}
4199 operand mS5RegI() %{
4200 constraint(ALLOC_IN_RC(s5_reg));
4201 match(RegI);
4202 match(mRegI);
4204 format %{ "S5" %}
4205 interface(REG_INTER);
4206 %}
4208 operand mS6RegI() %{
4209 constraint(ALLOC_IN_RC(s6_reg));
4210 match(RegI);
4211 match(mRegI);
4213 format %{ "S6" %}
4214 interface(REG_INTER);
4215 %}
4217 operand mS7RegI() %{
4218 constraint(ALLOC_IN_RC(s7_reg));
4219 match(RegI);
4220 match(mRegI);
4222 format %{ "S7" %}
4223 interface(REG_INTER);
4224 %}
4227 operand mT0RegI() %{
4228 constraint(ALLOC_IN_RC(t0_reg));
4229 match(RegI);
4230 match(mRegI);
4232 format %{ "T0" %}
4233 interface(REG_INTER);
4234 %}
4236 operand mT1RegI() %{
4237 constraint(ALLOC_IN_RC(t1_reg));
4238 match(RegI);
4239 match(mRegI);
4241 format %{ "T1" %}
4242 interface(REG_INTER);
4243 %}
4245 operand mT2RegI() %{
4246 constraint(ALLOC_IN_RC(t2_reg));
4247 match(RegI);
4248 match(mRegI);
4250 format %{ "T2" %}
4251 interface(REG_INTER);
4252 %}
4254 operand mT3RegI() %{
4255 constraint(ALLOC_IN_RC(t3_reg));
4256 match(RegI);
4257 match(mRegI);
4259 format %{ "T3" %}
4260 interface(REG_INTER);
4261 %}
4263 operand mT8RegI() %{
4264 constraint(ALLOC_IN_RC(t8_reg));
4265 match(RegI);
4266 match(mRegI);
4268 format %{ "T8" %}
4269 interface(REG_INTER);
4270 %}
4272 operand mT9RegI() %{
4273 constraint(ALLOC_IN_RC(t9_reg));
4274 match(RegI);
4275 match(mRegI);
4277 format %{ "T9" %}
4278 interface(REG_INTER);
4279 %}
4281 operand mA0RegI() %{
4282 constraint(ALLOC_IN_RC(a0_reg));
4283 match(RegI);
4284 match(mRegI);
4286 format %{ "A0" %}
4287 interface(REG_INTER);
4288 %}
4290 operand mA1RegI() %{
4291 constraint(ALLOC_IN_RC(a1_reg));
4292 match(RegI);
4293 match(mRegI);
4295 format %{ "A1" %}
4296 interface(REG_INTER);
4297 %}
4299 operand mA2RegI() %{
4300 constraint(ALLOC_IN_RC(a2_reg));
4301 match(RegI);
4302 match(mRegI);
4304 format %{ "A2" %}
4305 interface(REG_INTER);
4306 %}
4308 operand mA3RegI() %{
4309 constraint(ALLOC_IN_RC(a3_reg));
4310 match(RegI);
4311 match(mRegI);
4313 format %{ "A3" %}
4314 interface(REG_INTER);
4315 %}
4317 operand mA4RegI() %{
4318 constraint(ALLOC_IN_RC(a4_reg));
4319 match(RegI);
4320 match(mRegI);
4322 format %{ "A4" %}
4323 interface(REG_INTER);
4324 %}
4326 operand mA5RegI() %{
4327 constraint(ALLOC_IN_RC(a5_reg));
4328 match(RegI);
4329 match(mRegI);
4331 format %{ "A5" %}
4332 interface(REG_INTER);
4333 %}
4335 operand mA6RegI() %{
4336 constraint(ALLOC_IN_RC(a6_reg));
4337 match(RegI);
4338 match(mRegI);
4340 format %{ "A6" %}
4341 interface(REG_INTER);
4342 %}
4344 operand mA7RegI() %{
4345 constraint(ALLOC_IN_RC(a7_reg));
4346 match(RegI);
4347 match(mRegI);
4349 format %{ "A7" %}
4350 interface(REG_INTER);
4351 %}
4353 operand mV0RegI() %{
4354 constraint(ALLOC_IN_RC(v0_reg));
4355 match(RegI);
4356 match(mRegI);
4358 format %{ "V0" %}
4359 interface(REG_INTER);
4360 %}
4362 operand mV1RegI() %{
4363 constraint(ALLOC_IN_RC(v1_reg));
4364 match(RegI);
4365 match(mRegI);
4367 format %{ "V1" %}
4368 interface(REG_INTER);
4369 %}
4371 operand mRegN() %{
4372 constraint(ALLOC_IN_RC(int_reg));
4373 match(RegN);
4375 format %{ %}
4376 interface(REG_INTER);
4377 %}
4379 operand t0_RegN() %{
4380 constraint(ALLOC_IN_RC(t0_reg));
4381 match(RegN);
4382 match(mRegN);
4384 format %{ %}
4385 interface(REG_INTER);
4386 %}
4388 operand t1_RegN() %{
4389 constraint(ALLOC_IN_RC(t1_reg));
4390 match(RegN);
4391 match(mRegN);
4393 format %{ %}
4394 interface(REG_INTER);
4395 %}
4397 operand t2_RegN() %{
4398 constraint(ALLOC_IN_RC(t2_reg));
4399 match(RegN);
4400 match(mRegN);
4402 format %{ %}
4403 interface(REG_INTER);
4404 %}
4406 operand t3_RegN() %{
4407 constraint(ALLOC_IN_RC(t3_reg));
4408 match(RegN);
4409 match(mRegN);
4411 format %{ %}
4412 interface(REG_INTER);
4413 %}
4415 operand t8_RegN() %{
4416 constraint(ALLOC_IN_RC(t8_reg));
4417 match(RegN);
4418 match(mRegN);
4420 format %{ %}
4421 interface(REG_INTER);
4422 %}
4424 operand t9_RegN() %{
4425 constraint(ALLOC_IN_RC(t9_reg));
4426 match(RegN);
4427 match(mRegN);
4429 format %{ %}
4430 interface(REG_INTER);
4431 %}
4433 operand a0_RegN() %{
4434 constraint(ALLOC_IN_RC(a0_reg));
4435 match(RegN);
4436 match(mRegN);
4438 format %{ %}
4439 interface(REG_INTER);
4440 %}
4442 operand a1_RegN() %{
4443 constraint(ALLOC_IN_RC(a1_reg));
4444 match(RegN);
4445 match(mRegN);
4447 format %{ %}
4448 interface(REG_INTER);
4449 %}
4451 operand a2_RegN() %{
4452 constraint(ALLOC_IN_RC(a2_reg));
4453 match(RegN);
4454 match(mRegN);
4456 format %{ %}
4457 interface(REG_INTER);
4458 %}
4460 operand a3_RegN() %{
4461 constraint(ALLOC_IN_RC(a3_reg));
4462 match(RegN);
4463 match(mRegN);
4465 format %{ %}
4466 interface(REG_INTER);
4467 %}
4469 operand a4_RegN() %{
4470 constraint(ALLOC_IN_RC(a4_reg));
4471 match(RegN);
4472 match(mRegN);
4474 format %{ %}
4475 interface(REG_INTER);
4476 %}
4478 operand a5_RegN() %{
4479 constraint(ALLOC_IN_RC(a5_reg));
4480 match(RegN);
4481 match(mRegN);
4483 format %{ %}
4484 interface(REG_INTER);
4485 %}
4487 operand a6_RegN() %{
4488 constraint(ALLOC_IN_RC(a6_reg));
4489 match(RegN);
4490 match(mRegN);
4492 format %{ %}
4493 interface(REG_INTER);
4494 %}
4496 operand a7_RegN() %{
4497 constraint(ALLOC_IN_RC(a7_reg));
4498 match(RegN);
4499 match(mRegN);
4501 format %{ %}
4502 interface(REG_INTER);
4503 %}
4505 operand s0_RegN() %{
4506 constraint(ALLOC_IN_RC(s0_reg));
4507 match(RegN);
4508 match(mRegN);
4510 format %{ %}
4511 interface(REG_INTER);
4512 %}
4514 operand s1_RegN() %{
4515 constraint(ALLOC_IN_RC(s1_reg));
4516 match(RegN);
4517 match(mRegN);
4519 format %{ %}
4520 interface(REG_INTER);
4521 %}
4523 operand s2_RegN() %{
4524 constraint(ALLOC_IN_RC(s2_reg));
4525 match(RegN);
4526 match(mRegN);
4528 format %{ %}
4529 interface(REG_INTER);
4530 %}
4532 operand s3_RegN() %{
4533 constraint(ALLOC_IN_RC(s3_reg));
4534 match(RegN);
4535 match(mRegN);
4537 format %{ %}
4538 interface(REG_INTER);
4539 %}
4541 operand s4_RegN() %{
4542 constraint(ALLOC_IN_RC(s4_reg));
4543 match(RegN);
4544 match(mRegN);
4546 format %{ %}
4547 interface(REG_INTER);
4548 %}
4550 operand s5_RegN() %{
4551 constraint(ALLOC_IN_RC(s5_reg));
4552 match(RegN);
4553 match(mRegN);
4555 format %{ %}
4556 interface(REG_INTER);
4557 %}
4559 operand s6_RegN() %{
4560 constraint(ALLOC_IN_RC(s6_reg));
4561 match(RegN);
4562 match(mRegN);
4564 format %{ %}
4565 interface(REG_INTER);
4566 %}
4568 operand s7_RegN() %{
4569 constraint(ALLOC_IN_RC(s7_reg));
4570 match(RegN);
4571 match(mRegN);
4573 format %{ %}
4574 interface(REG_INTER);
4575 %}
4577 operand v0_RegN() %{
4578 constraint(ALLOC_IN_RC(v0_reg));
4579 match(RegN);
4580 match(mRegN);
4582 format %{ %}
4583 interface(REG_INTER);
4584 %}
4586 operand v1_RegN() %{
4587 constraint(ALLOC_IN_RC(v1_reg));
4588 match(RegN);
4589 match(mRegN);
4591 format %{ %}
4592 interface(REG_INTER);
4593 %}
4595 // Pointer Register
4596 operand mRegP() %{
4597 constraint(ALLOC_IN_RC(p_reg));
4598 match(RegP);
4600 format %{ %}
4601 interface(REG_INTER);
4602 %}
4604 operand no_T8_mRegP() %{
4605 constraint(ALLOC_IN_RC(no_T8_p_reg));
4606 match(RegP);
4607 match(mRegP);
4609 format %{ %}
4610 interface(REG_INTER);
4611 %}
4613 operand s0_RegP()
4614 %{
4615 constraint(ALLOC_IN_RC(s0_long_reg));
4616 match(RegP);
4617 match(mRegP);
4618 match(no_T8_mRegP);
4620 format %{ %}
4621 interface(REG_INTER);
4622 %}
4624 operand s1_RegP()
4625 %{
4626 constraint(ALLOC_IN_RC(s1_long_reg));
4627 match(RegP);
4628 match(mRegP);
4629 match(no_T8_mRegP);
4631 format %{ %}
4632 interface(REG_INTER);
4633 %}
4635 operand s2_RegP()
4636 %{
4637 constraint(ALLOC_IN_RC(s2_long_reg));
4638 match(RegP);
4639 match(mRegP);
4640 match(no_T8_mRegP);
4642 format %{ %}
4643 interface(REG_INTER);
4644 %}
4646 operand s3_RegP()
4647 %{
4648 constraint(ALLOC_IN_RC(s3_long_reg));
4649 match(RegP);
4650 match(mRegP);
4651 match(no_T8_mRegP);
4653 format %{ %}
4654 interface(REG_INTER);
4655 %}
4657 operand s4_RegP()
4658 %{
4659 constraint(ALLOC_IN_RC(s4_long_reg));
4660 match(RegP);
4661 match(mRegP);
4662 match(no_T8_mRegP);
4664 format %{ %}
4665 interface(REG_INTER);
4666 %}
4668 operand s5_RegP()
4669 %{
4670 constraint(ALLOC_IN_RC(s5_long_reg));
4671 match(RegP);
4672 match(mRegP);
4673 match(no_T8_mRegP);
4675 format %{ %}
4676 interface(REG_INTER);
4677 %}
4679 operand s6_RegP()
4680 %{
4681 constraint(ALLOC_IN_RC(s6_long_reg));
4682 match(RegP);
4683 match(mRegP);
4684 match(no_T8_mRegP);
4686 format %{ %}
4687 interface(REG_INTER);
4688 %}
4690 operand s7_RegP()
4691 %{
4692 constraint(ALLOC_IN_RC(s7_long_reg));
4693 match(RegP);
4694 match(mRegP);
4695 match(no_T8_mRegP);
4697 format %{ %}
4698 interface(REG_INTER);
4699 %}
4701 operand t0_RegP()
4702 %{
4703 constraint(ALLOC_IN_RC(t0_long_reg));
4704 match(RegP);
4705 match(mRegP);
4706 match(no_T8_mRegP);
4708 format %{ %}
4709 interface(REG_INTER);
4710 %}
4712 operand t1_RegP()
4713 %{
4714 constraint(ALLOC_IN_RC(t1_long_reg));
4715 match(RegP);
4716 match(mRegP);
4717 match(no_T8_mRegP);
4719 format %{ %}
4720 interface(REG_INTER);
4721 %}
4723 operand t2_RegP()
4724 %{
4725 constraint(ALLOC_IN_RC(t2_long_reg));
4726 match(RegP);
4727 match(mRegP);
4728 match(no_T8_mRegP);
4730 format %{ %}
4731 interface(REG_INTER);
4732 %}
4734 operand t3_RegP()
4735 %{
4736 constraint(ALLOC_IN_RC(t3_long_reg));
4737 match(RegP);
4738 match(mRegP);
4739 match(no_T8_mRegP);
4741 format %{ %}
4742 interface(REG_INTER);
4743 %}
4745 operand t8_RegP()
4746 %{
4747 constraint(ALLOC_IN_RC(t8_long_reg));
4748 match(RegP);
4749 match(mRegP);
4751 format %{ %}
4752 interface(REG_INTER);
4753 %}
4755 operand t9_RegP()
4756 %{
4757 constraint(ALLOC_IN_RC(t9_long_reg));
4758 match(RegP);
4759 match(mRegP);
4760 match(no_T8_mRegP);
4762 format %{ %}
4763 interface(REG_INTER);
4764 %}
4766 operand a0_RegP()
4767 %{
4768 constraint(ALLOC_IN_RC(a0_long_reg));
4769 match(RegP);
4770 match(mRegP);
4771 match(no_T8_mRegP);
4773 format %{ %}
4774 interface(REG_INTER);
4775 %}
4777 operand a1_RegP()
4778 %{
4779 constraint(ALLOC_IN_RC(a1_long_reg));
4780 match(RegP);
4781 match(mRegP);
4782 match(no_T8_mRegP);
4784 format %{ %}
4785 interface(REG_INTER);
4786 %}
4788 operand a2_RegP()
4789 %{
4790 constraint(ALLOC_IN_RC(a2_long_reg));
4791 match(RegP);
4792 match(mRegP);
4793 match(no_T8_mRegP);
4795 format %{ %}
4796 interface(REG_INTER);
4797 %}
4799 operand a3_RegP()
4800 %{
4801 constraint(ALLOC_IN_RC(a3_long_reg));
4802 match(RegP);
4803 match(mRegP);
4804 match(no_T8_mRegP);
4806 format %{ %}
4807 interface(REG_INTER);
4808 %}
4810 operand a4_RegP()
4811 %{
4812 constraint(ALLOC_IN_RC(a4_long_reg));
4813 match(RegP);
4814 match(mRegP);
4815 match(no_T8_mRegP);
4817 format %{ %}
4818 interface(REG_INTER);
4819 %}
4822 operand a5_RegP()
4823 %{
4824 constraint(ALLOC_IN_RC(a5_long_reg));
4825 match(RegP);
4826 match(mRegP);
4827 match(no_T8_mRegP);
4829 format %{ %}
4830 interface(REG_INTER);
4831 %}
4833 operand a6_RegP()
4834 %{
4835 constraint(ALLOC_IN_RC(a6_long_reg));
4836 match(RegP);
4837 match(mRegP);
4838 match(no_T8_mRegP);
4840 format %{ %}
4841 interface(REG_INTER);
4842 %}
4844 operand a7_RegP()
4845 %{
4846 constraint(ALLOC_IN_RC(a7_long_reg));
4847 match(RegP);
4848 match(mRegP);
4849 match(no_T8_mRegP);
4851 format %{ %}
4852 interface(REG_INTER);
4853 %}
4855 operand v0_RegP()
4856 %{
4857 constraint(ALLOC_IN_RC(v0_long_reg));
4858 match(RegP);
4859 match(mRegP);
4860 match(no_T8_mRegP);
4862 format %{ %}
4863 interface(REG_INTER);
4864 %}
4866 operand v1_RegP()
4867 %{
4868 constraint(ALLOC_IN_RC(v1_long_reg));
4869 match(RegP);
4870 match(mRegP);
4871 match(no_T8_mRegP);
4873 format %{ %}
4874 interface(REG_INTER);
4875 %}
4877 /*
4878 operand mSPRegP(mRegP reg) %{
4879 constraint(ALLOC_IN_RC(sp_reg));
4880 match(reg);
4882 format %{ "SP" %}
4883 interface(REG_INTER);
4884 %}
4886 operand mFPRegP(mRegP reg) %{
4887 constraint(ALLOC_IN_RC(fp_reg));
4888 match(reg);
4890 format %{ "FP" %}
4891 interface(REG_INTER);
4892 %}
4893 */
4895 operand mRegL() %{
4896 constraint(ALLOC_IN_RC(long_reg));
4897 match(RegL);
4899 format %{ %}
4900 interface(REG_INTER);
4901 %}
4903 operand v0RegL() %{
4904 constraint(ALLOC_IN_RC(v0_long_reg));
4905 match(RegL);
4906 match(mRegL);
4908 format %{ %}
4909 interface(REG_INTER);
4910 %}
4912 operand v1RegL() %{
4913 constraint(ALLOC_IN_RC(v1_long_reg));
4914 match(RegL);
4915 match(mRegL);
4917 format %{ %}
4918 interface(REG_INTER);
4919 %}
4921 operand a0RegL() %{
4922 constraint(ALLOC_IN_RC(a0_long_reg));
4923 match(RegL);
4924 match(mRegL);
4926 format %{ "A0" %}
4927 interface(REG_INTER);
4928 %}
4930 operand a1RegL() %{
4931 constraint(ALLOC_IN_RC(a1_long_reg));
4932 match(RegL);
4933 match(mRegL);
4935 format %{ %}
4936 interface(REG_INTER);
4937 %}
4939 operand a2RegL() %{
4940 constraint(ALLOC_IN_RC(a2_long_reg));
4941 match(RegL);
4942 match(mRegL);
4944 format %{ %}
4945 interface(REG_INTER);
4946 %}
4948 operand a3RegL() %{
4949 constraint(ALLOC_IN_RC(a3_long_reg));
4950 match(RegL);
4951 match(mRegL);
4953 format %{ %}
4954 interface(REG_INTER);
4955 %}
4957 operand t0RegL() %{
4958 constraint(ALLOC_IN_RC(t0_long_reg));
4959 match(RegL);
4960 match(mRegL);
4962 format %{ %}
4963 interface(REG_INTER);
4964 %}
4966 operand t1RegL() %{
4967 constraint(ALLOC_IN_RC(t1_long_reg));
4968 match(RegL);
4969 match(mRegL);
4971 format %{ %}
4972 interface(REG_INTER);
4973 %}
4975 operand t2RegL() %{
4976 constraint(ALLOC_IN_RC(t2_long_reg));
4977 match(RegL);
4978 match(mRegL);
4980 format %{ %}
4981 interface(REG_INTER);
4982 %}
4984 operand t3RegL() %{
4985 constraint(ALLOC_IN_RC(t3_long_reg));
4986 match(RegL);
4987 match(mRegL);
4989 format %{ %}
4990 interface(REG_INTER);
4991 %}
4993 operand t8RegL() %{
4994 constraint(ALLOC_IN_RC(t8_long_reg));
4995 match(RegL);
4996 match(mRegL);
4998 format %{ %}
4999 interface(REG_INTER);
5000 %}
5002 operand a4RegL() %{
5003 constraint(ALLOC_IN_RC(a4_long_reg));
5004 match(RegL);
5005 match(mRegL);
5007 format %{ %}
5008 interface(REG_INTER);
5009 %}
5011 operand a5RegL() %{
5012 constraint(ALLOC_IN_RC(a5_long_reg));
5013 match(RegL);
5014 match(mRegL);
5016 format %{ %}
5017 interface(REG_INTER);
5018 %}
5020 operand a6RegL() %{
5021 constraint(ALLOC_IN_RC(a6_long_reg));
5022 match(RegL);
5023 match(mRegL);
5025 format %{ %}
5026 interface(REG_INTER);
5027 %}
5029 operand a7RegL() %{
5030 constraint(ALLOC_IN_RC(a7_long_reg));
5031 match(RegL);
5032 match(mRegL);
5034 format %{ %}
5035 interface(REG_INTER);
5036 %}
5038 operand s0RegL() %{
5039 constraint(ALLOC_IN_RC(s0_long_reg));
5040 match(RegL);
5041 match(mRegL);
5043 format %{ %}
5044 interface(REG_INTER);
5045 %}
5047 operand s1RegL() %{
5048 constraint(ALLOC_IN_RC(s1_long_reg));
5049 match(RegL);
5050 match(mRegL);
5052 format %{ %}
5053 interface(REG_INTER);
5054 %}
5056 operand s2RegL() %{
5057 constraint(ALLOC_IN_RC(s2_long_reg));
5058 match(RegL);
5059 match(mRegL);
5061 format %{ %}
5062 interface(REG_INTER);
5063 %}
5065 operand s3RegL() %{
5066 constraint(ALLOC_IN_RC(s3_long_reg));
5067 match(RegL);
5068 match(mRegL);
5070 format %{ %}
5071 interface(REG_INTER);
5072 %}
5074 operand s4RegL() %{
5075 constraint(ALLOC_IN_RC(s4_long_reg));
5076 match(RegL);
5077 match(mRegL);
5079 format %{ %}
5080 interface(REG_INTER);
5081 %}
5083 operand s7RegL() %{
5084 constraint(ALLOC_IN_RC(s7_long_reg));
5085 match(RegL);
5086 match(mRegL);
5088 format %{ %}
5089 interface(REG_INTER);
5090 %}
5092 // Floating register operands
5093 operand regF() %{
5094 constraint(ALLOC_IN_RC(flt_reg));
5095 match(RegF);
5097 format %{ %}
5098 interface(REG_INTER);
5099 %}
5101 //Double Precision Floating register operands
5102 operand regD() %{
5103 constraint(ALLOC_IN_RC(dbl_reg));
5104 match(RegD);
5106 format %{ %}
5107 interface(REG_INTER);
5108 %}
5110 //----------Memory Operands----------------------------------------------------
5111 // Indirect Memory Operand
5112 operand indirect(mRegP reg) %{
5113 constraint(ALLOC_IN_RC(p_reg));
5114 match(reg);
5116 format %{ "[$reg] @ indirect" %}
5117 interface(MEMORY_INTER) %{
5118 base($reg);
5119 index(0x0); /* NO_INDEX */
5120 scale(0x0);
5121 disp(0x0);
5122 %}
5123 %}
5125 // Indirect Memory Plus Short Offset Operand
5126 operand indOffset8(mRegP reg, immL8 off)
5127 %{
5128 constraint(ALLOC_IN_RC(p_reg));
5129 match(AddP reg off);
5131 op_cost(10);
5132 format %{ "[$reg + $off (8-bit)] @ indOffset8" %}
5133 interface(MEMORY_INTER) %{
5134 base($reg);
5135 index(0x0); /* NO_INDEX */
5136 scale(0x0);
5137 disp($off);
5138 %}
5139 %}
5141 // Indirect Memory Times Scale Plus Index Register
5142 operand indIndexScale(mRegP reg, mRegL lreg, immI2 scale)
5143 %{
5144 constraint(ALLOC_IN_RC(p_reg));
5145 match(AddP reg (LShiftL lreg scale));
5147 op_cost(10);
5148 format %{"[$reg + $lreg << $scale] @ indIndexScale" %}
5149 interface(MEMORY_INTER) %{
5150 base($reg);
5151 index($lreg);
5152 scale($scale);
5153 disp(0x0);
5154 %}
5155 %}
5158 // [base + index + offset]
5159 operand baseIndexOffset8(mRegP base, mRegL index, immL8 off)
5160 %{
5161 constraint(ALLOC_IN_RC(p_reg));
5162 op_cost(5);
5163 match(AddP (AddP base index) off);
5165 format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8" %}
5166 interface(MEMORY_INTER) %{
5167 base($base);
5168 index($index);
5169 scale(0x0);
5170 disp($off);
5171 %}
5172 %}
5174 // [base + index + offset]
5175 operand baseIndexOffset8_convI2L(mRegP base, mRegI index, immL8 off)
5176 %{
5177 constraint(ALLOC_IN_RC(p_reg));
5178 op_cost(5);
5179 match(AddP (AddP base (ConvI2L index)) off);
5181 format %{ "[$base + $index + $off (8-bit)] @ baseIndexOffset8_convI2L" %}
5182 interface(MEMORY_INTER) %{
5183 base($base);
5184 index($index);
5185 scale(0x0);
5186 disp($off);
5187 %}
5188 %}
5190 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5191 operand indIndexScaleOffset8(mRegP reg, immL8 off, mRegL lreg, immI2 scale)
5192 %{
5193 constraint(ALLOC_IN_RC(p_reg));
5194 match(AddP (AddP reg (LShiftL lreg scale)) off);
5196 op_cost(10);
5197 format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffset8" %}
5198 interface(MEMORY_INTER) %{
5199 base($reg);
5200 index($lreg);
5201 scale($scale);
5202 disp($off);
5203 %}
5204 %}
5206 operand indIndexScaleOffset8_convI2L(mRegP reg, immL8 off, mRegI ireg, immI2 scale)
5207 %{
5208 constraint(ALLOC_IN_RC(p_reg));
5209 match(AddP (AddP reg (LShiftL (ConvI2L ireg) scale)) off);
5211 op_cost(10);
5212 format %{"[$reg + $off + $ireg << $scale] @ indIndexScaleOffset8_convI2L" %}
5213 interface(MEMORY_INTER) %{
5214 base($reg);
5215 index($ireg);
5216 scale($scale);
5217 disp($off);
5218 %}
5219 %}
5221 // [base + index<<scale + offset]
5222 operand basePosIndexScaleOffset8(mRegP base, mRegI index, immL8 off, immI_0_31 scale)
5223 %{
5224 constraint(ALLOC_IN_RC(p_reg));
5225 //predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5226 op_cost(10);
5227 match(AddP (AddP base (LShiftL (ConvI2L index) scale)) off);
5229 format %{ "[$base + $index << $scale + $off (8-bit)] @ basePosIndexScaleOffset8" %}
5230 interface(MEMORY_INTER) %{
5231 base($base);
5232 index($index);
5233 scale($scale);
5234 disp($off);
5235 %}
5236 %}
5238 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
5239 operand indIndexScaleOffsetNarrow(mRegN reg, immL8 off, mRegL lreg, immI2 scale)
5240 %{
5241 predicate(Universe::narrow_oop_shift() == 0);
5242 constraint(ALLOC_IN_RC(p_reg));
5243 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
5245 op_cost(10);
5246 format %{"[$reg + $off + $lreg << $scale] @ indIndexScaleOffsetNarrow" %}
5247 interface(MEMORY_INTER) %{
5248 base($reg);
5249 index($lreg);
5250 scale($scale);
5251 disp($off);
5252 %}
5253 %}
5255 // [base + index<<scale + offset] for compressd Oops
5256 operand indPosIndexI2LScaleOffset8Narrow(mRegN base, mRegI index, immL8 off, immI_0_31 scale)
5257 %{
5258 constraint(ALLOC_IN_RC(p_reg));
5259 //predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
5260 predicate(Universe::narrow_oop_shift() == 0);
5261 op_cost(10);
5262 match(AddP (AddP (DecodeN base) (LShiftL (ConvI2L index) scale)) off);
5264 format %{ "[$base + $index << $scale + $off (8-bit)] @ indPosIndexI2LScaleOffset8Narrow" %}
5265 interface(MEMORY_INTER) %{
5266 base($base);
5267 index($index);
5268 scale($scale);
5269 disp($off);
5270 %}
5271 %}
5273 //FIXME: I think it's better to limit the immI to be 16-bit at most!
5274 // Indirect Memory Plus Long Offset Operand
5275 operand indOffset32(mRegP reg, immL32 off) %{
5276 constraint(ALLOC_IN_RC(p_reg));
5277 op_cost(20);
5278 match(AddP reg off);
5280 format %{ "[$reg + $off (32-bit)] @ indOffset32" %}
5281 interface(MEMORY_INTER) %{
5282 base($reg);
5283 index(0x0); /* NO_INDEX */
5284 scale(0x0);
5285 disp($off);
5286 %}
5287 %}
5289 // Indirect Memory Plus Index Register
5290 operand indIndex(mRegP addr, mRegL index) %{
5291 constraint(ALLOC_IN_RC(p_reg));
5292 match(AddP addr index);
5294 op_cost(20);
5295 format %{"[$addr + $index] @ indIndex" %}
5296 interface(MEMORY_INTER) %{
5297 base($addr);
5298 index($index);
5299 scale(0x0);
5300 disp(0x0);
5301 %}
5302 %}
5304 operand indirectNarrowKlass(mRegN reg)
5305 %{
5306 predicate(Universe::narrow_klass_shift() == 0);
5307 constraint(ALLOC_IN_RC(p_reg));
5308 op_cost(10);
5309 match(DecodeNKlass reg);
5311 format %{ "[$reg] @ indirectNarrowKlass" %}
5312 interface(MEMORY_INTER) %{
5313 base($reg);
5314 index(0x0);
5315 scale(0x0);
5316 disp(0x0);
5317 %}
5318 %}
5320 operand indOffset8NarrowKlass(mRegN reg, immL8 off)
5321 %{
5322 predicate(Universe::narrow_klass_shift() == 0);
5323 constraint(ALLOC_IN_RC(p_reg));
5324 op_cost(10);
5325 match(AddP (DecodeNKlass reg) off);
5327 format %{ "[$reg + $off (8-bit)] @ indOffset8NarrowKlass" %}
5328 interface(MEMORY_INTER) %{
5329 base($reg);
5330 index(0x0);
5331 scale(0x0);
5332 disp($off);
5333 %}
5334 %}
5336 operand indOffset32NarrowKlass(mRegN reg, immL32 off)
5337 %{
5338 predicate(Universe::narrow_klass_shift() == 0);
5339 constraint(ALLOC_IN_RC(p_reg));
5340 op_cost(10);
5341 match(AddP (DecodeNKlass reg) off);
5343 format %{ "[$reg + $off (32-bit)] @ indOffset32NarrowKlass" %}
5344 interface(MEMORY_INTER) %{
5345 base($reg);
5346 index(0x0);
5347 scale(0x0);
5348 disp($off);
5349 %}
5350 %}
5352 operand indIndexOffsetNarrowKlass(mRegN reg, mRegL lreg, immL32 off)
5353 %{
5354 predicate(Universe::narrow_klass_shift() == 0);
5355 constraint(ALLOC_IN_RC(p_reg));
5356 match(AddP (AddP (DecodeNKlass reg) lreg) off);
5358 op_cost(10);
5359 format %{"[$reg + $off + $lreg] @ indIndexOffsetNarrowKlass" %}
5360 interface(MEMORY_INTER) %{
5361 base($reg);
5362 index($lreg);
5363 scale(0x0);
5364 disp($off);
5365 %}
5366 %}
5368 operand indIndexNarrowKlass(mRegN reg, mRegL lreg)
5369 %{
5370 predicate(Universe::narrow_klass_shift() == 0);
5371 constraint(ALLOC_IN_RC(p_reg));
5372 match(AddP (DecodeNKlass reg) lreg);
5374 op_cost(10);
5375 format %{"[$reg + $lreg] @ indIndexNarrowKlass" %}
5376 interface(MEMORY_INTER) %{
5377 base($reg);
5378 index($lreg);
5379 scale(0x0);
5380 disp(0x0);
5381 %}
5382 %}
5384 // Indirect Memory Operand
5385 operand indirectNarrow(mRegN reg)
5386 %{
5387 predicate(Universe::narrow_oop_shift() == 0);
5388 constraint(ALLOC_IN_RC(p_reg));
5389 op_cost(10);
5390 match(DecodeN reg);
5392 format %{ "[$reg] @ indirectNarrow" %}
5393 interface(MEMORY_INTER) %{
5394 base($reg);
5395 index(0x0);
5396 scale(0x0);
5397 disp(0x0);
5398 %}
5399 %}
5401 // Indirect Memory Plus Short Offset Operand
5402 operand indOffset8Narrow(mRegN reg, immL8 off)
5403 %{
5404 predicate(Universe::narrow_oop_shift() == 0);
5405 constraint(ALLOC_IN_RC(p_reg));
5406 op_cost(10);
5407 match(AddP (DecodeN reg) off);
5409 format %{ "[$reg + $off (8-bit)] @ indOffset8Narrow" %}
5410 interface(MEMORY_INTER) %{
5411 base($reg);
5412 index(0x0);
5413 scale(0x0);
5414 disp($off);
5415 %}
5416 %}
5418 // Indirect Memory Plus Index Register Plus Offset Operand
5419 operand indIndexOffset8Narrow(mRegN reg, mRegL lreg, immL8 off)
5420 %{
5421 predicate(Universe::narrow_oop_shift() == 0);
5422 constraint(ALLOC_IN_RC(p_reg));
5423 match(AddP (AddP (DecodeN reg) lreg) off);
5425 op_cost(10);
5426 format %{"[$reg + $off + $lreg] @ indIndexOffset8Narrow" %}
5427 interface(MEMORY_INTER) %{
5428 base($reg);
5429 index($lreg);
5430 scale(0x0);
5431 disp($off);
5432 %}
5433 %}
5435 //----------Load Long Memory Operands------------------------------------------
5436 // The load-long idiom will use it's address expression again after loading
5437 // the first word of the long. If the load-long destination overlaps with
5438 // registers used in the addressing expression, the 2nd half will be loaded
5439 // from a clobbered address. Fix this by requiring that load-long use
5440 // address registers that do not overlap with the load-long target.
5442 // load-long support
5443 operand load_long_RegP() %{
5444 constraint(ALLOC_IN_RC(p_reg));
5445 match(RegP);
5446 match(mRegP);
5447 op_cost(100);
5448 format %{ %}
5449 interface(REG_INTER);
5450 %}
5452 // Indirect Memory Operand Long
5453 operand load_long_indirect(load_long_RegP reg) %{
5454 constraint(ALLOC_IN_RC(p_reg));
5455 match(reg);
5457 format %{ "[$reg]" %}
5458 interface(MEMORY_INTER) %{
5459 base($reg);
5460 index(0x0);
5461 scale(0x0);
5462 disp(0x0);
5463 %}
5464 %}
5466 // Indirect Memory Plus Long Offset Operand
5467 operand load_long_indOffset32(load_long_RegP reg, immL32 off) %{
5468 match(AddP reg off);
5470 format %{ "[$reg + $off]" %}
5471 interface(MEMORY_INTER) %{
5472 base($reg);
5473 index(0x0);
5474 scale(0x0);
5475 disp($off);
5476 %}
5477 %}
5479 //----------Conditional Branch Operands----------------------------------------
5480 // Comparison Op - This is the operation of the comparison, and is limited to
5481 // the following set of codes:
5482 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
5483 //
5484 // Other attributes of the comparison, such as unsignedness, are specified
5485 // by the comparison instruction that sets a condition code flags register.
5486 // That result is represented by a flags operand whose subtype is appropriate
5487 // to the unsignedness (etc.) of the comparison.
5488 //
5489 // Later, the instruction which matches both the Comparison Op (a Bool) and
5490 // the flags (produced by the Cmp) specifies the coding of the comparison op
5491 // by matching a specific subtype of Bool operand below, such as cmpOpU.
5493 // Comparision Code
5494 operand cmpOp() %{
5495 match(Bool);
5497 format %{ "" %}
5498 interface(COND_INTER) %{
5499 equal(0x01);
5500 not_equal(0x02);
5501 greater(0x03);
5502 greater_equal(0x04);
5503 less(0x05);
5504 less_equal(0x06);
5505 overflow(0x7);
5506 no_overflow(0x8);
5507 %}
5508 %}
5511 // Comparision Code
5512 // Comparison Code, unsigned compare. Used by FP also, with
5513 // C2 (unordered) turned into GT or LT already. The other bits
5514 // C0 and C3 are turned into Carry & Zero flags.
5515 operand cmpOpU() %{
5516 match(Bool);
5518 format %{ "" %}
5519 interface(COND_INTER) %{
5520 equal(0x01);
5521 not_equal(0x02);
5522 greater(0x03);
5523 greater_equal(0x04);
5524 less(0x05);
5525 less_equal(0x06);
5526 overflow(0x7);
5527 no_overflow(0x8);
5528 %}
5529 %}
5532 //----------Special Memory Operands--------------------------------------------
5533 // Stack Slot Operand - This operand is used for loading and storing temporary
5534 // values on the stack where a match requires a value to
5535 // flow through memory.
5536 operand stackSlotP(sRegP reg) %{
5537 constraint(ALLOC_IN_RC(stack_slots));
5538 // No match rule because this operand is only generated in matching
5539 op_cost(50);
5540 format %{ "[$reg]" %}
5541 interface(MEMORY_INTER) %{
5542 base(0x1d); // SP
5543 index(0x0); // No Index
5544 scale(0x0); // No Scale
5545 disp($reg); // Stack Offset
5546 %}
5547 %}
5549 operand stackSlotI(sRegI reg) %{
5550 constraint(ALLOC_IN_RC(stack_slots));
5551 // No match rule because this operand is only generated in matching
5552 op_cost(50);
5553 format %{ "[$reg]" %}
5554 interface(MEMORY_INTER) %{
5555 base(0x1d); // SP
5556 index(0x0); // No Index
5557 scale(0x0); // No Scale
5558 disp($reg); // Stack Offset
5559 %}
5560 %}
5562 operand stackSlotF(sRegF reg) %{
5563 constraint(ALLOC_IN_RC(stack_slots));
5564 // No match rule because this operand is only generated in matching
5565 op_cost(50);
5566 format %{ "[$reg]" %}
5567 interface(MEMORY_INTER) %{
5568 base(0x1d); // SP
5569 index(0x0); // No Index
5570 scale(0x0); // No Scale
5571 disp($reg); // Stack Offset
5572 %}
5573 %}
5575 operand stackSlotD(sRegD reg) %{
5576 constraint(ALLOC_IN_RC(stack_slots));
5577 // No match rule because this operand is only generated in matching
5578 op_cost(50);
5579 format %{ "[$reg]" %}
5580 interface(MEMORY_INTER) %{
5581 base(0x1d); // SP
5582 index(0x0); // No Index
5583 scale(0x0); // No Scale
5584 disp($reg); // Stack Offset
5585 %}
5586 %}
5588 operand stackSlotL(sRegL reg) %{
5589 constraint(ALLOC_IN_RC(stack_slots));
5590 // No match rule because this operand is only generated in matching
5591 op_cost(50);
5592 format %{ "[$reg]" %}
5593 interface(MEMORY_INTER) %{
5594 base(0x1d); // SP
5595 index(0x0); // No Index
5596 scale(0x0); // No Scale
5597 disp($reg); // Stack Offset
5598 %}
5599 %}
5602 //------------------------OPERAND CLASSES--------------------------------------
5603 //opclass memory( direct, indirect, indOffset16, indOffset32, indOffset32X, indIndexOffset );
5604 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);
5607 //----------PIPELINE-----------------------------------------------------------
5608 // Rules which define the behavior of the target architectures pipeline.
5610 pipeline %{
5612 //----------ATTRIBUTES---------------------------------------------------------
5613 attributes %{
5614 fixed_size_instructions; // Fixed size instructions
5615 branch_has_delay_slot; // branch have delay slot in gs2
5616 max_instructions_per_bundle = 1; // 1 instruction per bundle
5617 max_bundles_per_cycle = 4; // Up to 4 bundles per cycle
5618 bundle_unit_size=4;
5619 instruction_unit_size = 4; // An instruction is 4 bytes long
5620 instruction_fetch_unit_size = 16; // The processor fetches one line
5621 instruction_fetch_units = 1; // of 16 bytes
5623 // List of nop instructions
5624 nops( MachNop );
5625 %}
5627 //----------RESOURCES----------------------------------------------------------
5628 // Resources are the functional units available to the machine
5630 resources(D1, D2, D3, D4, DECODE = D1 | D2 | D3| D4, ALU1, ALU2, ALU = ALU1 | ALU2, FPU1, FPU2, FPU = FPU1 | FPU2, MEM, BR);
5632 //----------PIPELINE DESCRIPTION-----------------------------------------------
5633 // Pipeline Description specifies the stages in the machine's pipeline
5635 // IF: fetch
5636 // ID: decode
5637 // RD: read
5638 // CA: caculate
5639 // WB: write back
5640 // CM: commit
5642 pipe_desc(IF, ID, RD, CA, WB, CM);
5645 //----------PIPELINE CLASSES---------------------------------------------------
5646 // Pipeline Classes describe the stages in which input and output are
5647 // referenced by the hardware pipeline.
5649 //No.1 Integer ALU reg-reg operation : dst <-- reg1 op reg2
5650 pipe_class ialu_regI_regI(mRegI dst, mRegI src1, mRegI src2) %{
5651 single_instruction;
5652 src1 : RD(read);
5653 src2 : RD(read);
5654 dst : WB(write)+1;
5655 DECODE : ID;
5656 ALU : CA;
5657 %}
5659 //No.19 Integer mult operation : dst <-- reg1 mult reg2
5660 pipe_class ialu_mult(mRegI dst, mRegI src1, mRegI src2) %{
5661 src1 : RD(read);
5662 src2 : RD(read);
5663 dst : WB(write)+5;
5664 DECODE : ID;
5665 ALU2 : CA;
5666 %}
5668 pipe_class mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
5669 src1 : RD(read);
5670 src2 : RD(read);
5671 dst : WB(write)+10;
5672 DECODE : ID;
5673 ALU2 : CA;
5674 %}
5676 //No.19 Integer div operation : dst <-- reg1 div reg2
5677 pipe_class ialu_div(mRegI dst, mRegI src1, mRegI src2) %{
5678 src1 : RD(read);
5679 src2 : RD(read);
5680 dst : WB(write)+10;
5681 DECODE : ID;
5682 ALU2 : CA;
5683 %}
5685 //No.19 Integer mod operation : dst <-- reg1 mod reg2
5686 pipe_class ialu_mod(mRegI dst, mRegI src1, mRegI src2) %{
5687 instruction_count(2);
5688 src1 : RD(read);
5689 src2 : RD(read);
5690 dst : WB(write)+10;
5691 DECODE : ID;
5692 ALU2 : CA;
5693 %}
5695 //No.15 Long ALU reg-reg operation : dst <-- reg1 op reg2
5696 pipe_class ialu_regL_regL(mRegL dst, mRegL src1, mRegL src2) %{
5697 instruction_count(2);
5698 src1 : RD(read);
5699 src2 : RD(read);
5700 dst : WB(write);
5701 DECODE : ID;
5702 ALU : CA;
5703 %}
5705 //No.18 Long ALU reg-imm16 operation : dst <-- reg1 op imm16
5706 pipe_class ialu_regL_imm16(mRegL dst, mRegL src) %{
5707 instruction_count(2);
5708 src : RD(read);
5709 dst : WB(write);
5710 DECODE : ID;
5711 ALU : CA;
5712 %}
5714 //no.16 load Long from memory :
5715 pipe_class ialu_loadL(mRegL dst, memory mem) %{
5716 instruction_count(2);
5717 mem : RD(read);
5718 dst : WB(write)+5;
5719 DECODE : ID;
5720 MEM : RD;
5721 %}
5723 //No.17 Store Long to Memory :
5724 pipe_class ialu_storeL(mRegL src, memory mem) %{
5725 instruction_count(2);
5726 mem : RD(read);
5727 src : RD(read);
5728 DECODE : ID;
5729 MEM : RD;
5730 %}
5732 //No.2 Integer ALU reg-imm16 operation : dst <-- reg1 op imm16
5733 pipe_class ialu_regI_imm16(mRegI dst, mRegI src) %{
5734 single_instruction;
5735 src : RD(read);
5736 dst : WB(write);
5737 DECODE : ID;
5738 ALU : CA;
5739 %}
5741 //No.3 Integer move operation : dst <-- reg
5742 pipe_class ialu_regI_mov(mRegI dst, mRegI src) %{
5743 src : RD(read);
5744 dst : WB(write);
5745 DECODE : ID;
5746 ALU : CA;
5747 %}
5749 //No.4 No instructions : do nothing
5750 pipe_class empty( ) %{
5751 instruction_count(0);
5752 %}
5754 //No.5 UnConditional branch :
5755 pipe_class pipe_jump( label labl ) %{
5756 multiple_bundles;
5757 DECODE : ID;
5758 BR : RD;
5759 %}
5761 //No.6 ALU Conditional branch :
5762 pipe_class pipe_alu_branch(mRegI src1, mRegI src2, label labl ) %{
5763 multiple_bundles;
5764 src1 : RD(read);
5765 src2 : RD(read);
5766 DECODE : ID;
5767 BR : RD;
5768 %}
5770 //no.7 load integer from memory :
5771 pipe_class ialu_loadI(mRegI dst, memory mem) %{
5772 mem : RD(read);
5773 dst : WB(write)+3;
5774 DECODE : ID;
5775 MEM : RD;
5776 %}
5778 //No.8 Store Integer to Memory :
5779 pipe_class ialu_storeI(mRegI src, memory mem) %{
5780 mem : RD(read);
5781 src : RD(read);
5782 DECODE : ID;
5783 MEM : RD;
5784 %}
5787 //No.10 Floating FPU reg-reg operation : dst <-- reg1 op reg2
5788 pipe_class fpu_regF_regF(regF dst, regF src1, regF src2) %{
5789 src1 : RD(read);
5790 src2 : RD(read);
5791 dst : WB(write);
5792 DECODE : ID;
5793 FPU : CA;
5794 %}
5796 //No.22 Floating div operation : dst <-- reg1 div reg2
5797 pipe_class fpu_div(regF dst, regF src1, regF src2) %{
5798 src1 : RD(read);
5799 src2 : RD(read);
5800 dst : WB(write);
5801 DECODE : ID;
5802 FPU2 : CA;
5803 %}
5805 pipe_class fcvt_I2D(regD dst, mRegI src) %{
5806 src : RD(read);
5807 dst : WB(write);
5808 DECODE : ID;
5809 FPU1 : CA;
5810 %}
5812 pipe_class fcvt_D2I(mRegI dst, regD src) %{
5813 src : RD(read);
5814 dst : WB(write);
5815 DECODE : ID;
5816 FPU1 : CA;
5817 %}
5819 pipe_class pipe_mfc1(mRegI dst, regD src) %{
5820 src : RD(read);
5821 dst : WB(write);
5822 DECODE : ID;
5823 MEM : RD;
5824 %}
5826 pipe_class pipe_mtc1(regD dst, mRegI src) %{
5827 src : RD(read);
5828 dst : WB(write);
5829 DECODE : ID;
5830 MEM : RD(5);
5831 %}
5833 //No.23 Floating sqrt operation : dst <-- reg1 sqrt reg2
5834 pipe_class fpu_sqrt(regF dst, regF src1, regF src2) %{
5835 multiple_bundles;
5836 src1 : RD(read);
5837 src2 : RD(read);
5838 dst : WB(write);
5839 DECODE : ID;
5840 FPU2 : CA;
5841 %}
5843 //No.11 Load Floating from Memory :
5844 pipe_class fpu_loadF(regF dst, memory mem) %{
5845 instruction_count(1);
5846 mem : RD(read);
5847 dst : WB(write)+3;
5848 DECODE : ID;
5849 MEM : RD;
5850 %}
5852 //No.12 Store Floating to Memory :
5853 pipe_class fpu_storeF(regF src, memory mem) %{
5854 instruction_count(1);
5855 mem : RD(read);
5856 src : RD(read);
5857 DECODE : ID;
5858 MEM : RD;
5859 %}
5861 //No.13 FPU Conditional branch :
5862 pipe_class pipe_fpu_branch(regF src1, regF src2, label labl ) %{
5863 multiple_bundles;
5864 src1 : RD(read);
5865 src2 : RD(read);
5866 DECODE : ID;
5867 BR : RD;
5868 %}
5870 //No.14 Floating FPU reg operation : dst <-- op reg
5871 pipe_class fpu1_regF(regF dst, regF src) %{
5872 src : RD(read);
5873 dst : WB(write);
5874 DECODE : ID;
5875 FPU : CA;
5876 %}
5878 pipe_class long_memory_op() %{
5879 instruction_count(10); multiple_bundles; force_serialization;
5880 fixed_latency(30);
5881 %}
5883 pipe_class simple_call() %{
5884 instruction_count(10); multiple_bundles; force_serialization;
5885 fixed_latency(200);
5886 BR : RD;
5887 %}
5889 pipe_class call() %{
5890 instruction_count(10); multiple_bundles; force_serialization;
5891 fixed_latency(200);
5892 %}
5894 //FIXME:
5895 //No.9 Piple slow : for multi-instructions
5896 pipe_class pipe_slow( ) %{
5897 instruction_count(20);
5898 force_serialization;
5899 multiple_bundles;
5900 fixed_latency(50);
5901 %}
5903 %}
5907 //----------INSTRUCTIONS-------------------------------------------------------
5908 //
5909 // match -- States which machine-independent subtree may be replaced
5910 // by this instruction.
5911 // ins_cost -- The estimated cost of this instruction is used by instruction
5912 // selection to identify a minimum cost tree of machine
5913 // instructions that matches a tree of machine-independent
5914 // instructions.
5915 // format -- A string providing the disassembly for this instruction.
5916 // The value of an instruction's operand may be inserted
5917 // by referring to it with a '$' prefix.
5918 // opcode -- Three instruction opcodes may be provided. These are referred
5919 // to within an encode class as $primary, $secondary, and $tertiary
5920 // respectively. The primary opcode is commonly used to
5921 // indicate the type of machine instruction, while secondary
5922 // and tertiary are often used for prefix options or addressing
5923 // modes.
5924 // ins_encode -- A list of encode classes with parameters. The encode class
5925 // name must have been defined in an 'enc_class' specification
5926 // in the encode section of the architecture description.
5929 // Load Integer
5930 instruct loadI(mRegI dst, memory mem) %{
5931 match(Set dst (LoadI mem));
5933 ins_cost(125);
5934 format %{ "lw $dst, $mem #@loadI" %}
5935 ins_encode (load_I_enc(dst, mem));
5936 ins_pipe( ialu_loadI );
5937 %}
5939 instruct loadI_convI2L(mRegL dst, memory mem) %{
5940 match(Set dst (ConvI2L (LoadI mem)));
5942 ins_cost(125);
5943 format %{ "lw $dst, $mem #@loadI_convI2L" %}
5944 ins_encode (load_I_enc(dst, mem));
5945 ins_pipe( ialu_loadI );
5946 %}
5948 // Load Integer (32 bit signed) to Byte (8 bit signed)
5949 instruct loadI2B(mRegI dst, memory mem, immI_24 twentyfour) %{
5950 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
5952 ins_cost(125);
5953 format %{ "lb $dst, $mem\t# int -> byte #@loadI2B" %}
5954 ins_encode(load_B_enc(dst, mem));
5955 ins_pipe(ialu_loadI);
5956 %}
5958 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
5959 instruct loadI2UB(mRegI dst, memory mem, immI_255 mask) %{
5960 match(Set dst (AndI (LoadI mem) mask));
5962 ins_cost(125);
5963 format %{ "lbu $dst, $mem\t# int -> ubyte #@loadI2UB" %}
5964 ins_encode(load_UB_enc(dst, mem));
5965 ins_pipe(ialu_loadI);
5966 %}
5968 // Load Integer (32 bit signed) to Short (16 bit signed)
5969 instruct loadI2S(mRegI dst, memory mem, immI_16 sixteen) %{
5970 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
5972 ins_cost(125);
5973 format %{ "lh $dst, $mem\t# int -> short #@loadI2S" %}
5974 ins_encode(load_S_enc(dst, mem));
5975 ins_pipe(ialu_loadI);
5976 %}
5978 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
5979 instruct loadI2US(mRegI dst, memory mem, immI_65535 mask) %{
5980 match(Set dst (AndI (LoadI mem) mask));
5982 ins_cost(125);
5983 format %{ "lhu $dst, $mem\t# int -> ushort/char #@loadI2US" %}
5984 ins_encode(load_C_enc(dst, mem));
5985 ins_pipe(ialu_loadI);
5986 %}
5988 // Load Long.
5989 instruct loadL(mRegL dst, memory mem) %{
5990 // predicate(!((LoadLNode*)n)->require_atomic_access());
5991 match(Set dst (LoadL mem));
5993 ins_cost(250);
5994 format %{ "ld $dst, $mem #@loadL" %}
5995 ins_encode(load_L_enc(dst, mem));
5996 ins_pipe( ialu_loadL );
5997 %}
5999 // Load Long - UNaligned
6000 instruct loadL_unaligned(mRegL dst, memory mem) %{
6001 match(Set dst (LoadL_unaligned mem));
6003 // FIXME: Jin: Need more effective ldl/ldr
6004 ins_cost(450);
6005 format %{ "ld $dst, $mem #@loadL_unaligned\n\t" %}
6006 ins_encode(load_L_enc(dst, mem));
6007 ins_pipe( ialu_loadL );
6008 %}
6010 // Store Long
6011 instruct storeL_reg(memory mem, mRegL src) %{
6012 match(Set mem (StoreL mem src));
6014 ins_cost(200);
6015 format %{ "sd $mem, $src #@storeL_reg\n" %}
6016 ins_encode(store_L_reg_enc(mem, src));
6017 ins_pipe( ialu_storeL );
6018 %}
6020 instruct storeL_immL0(memory mem, immL0 zero) %{
6021 match(Set mem (StoreL mem zero));
6023 ins_cost(180);
6024 format %{ "sd zero, $mem #@storeL_immL0" %}
6025 ins_encode(store_L_immL0_enc(mem, zero));
6026 ins_pipe( ialu_storeL );
6027 %}
6029 instruct storeL_imm(memory mem, immL src) %{
6030 match(Set mem (StoreL mem src));
6032 ins_cost(200);
6033 format %{ "sd $src, $mem #@storeL_imm" %}
6034 ins_encode(store_L_immL_enc(mem, src));
6035 ins_pipe( ialu_storeL );
6036 %}
6038 // Load Compressed Pointer
6039 instruct loadN(mRegN dst, memory mem)
6040 %{
6041 match(Set dst (LoadN mem));
6043 ins_cost(125); // XXX
6044 format %{ "lwu $dst, $mem\t# compressed ptr @ loadN" %}
6045 ins_encode (load_N_enc(dst, mem));
6046 ins_pipe( ialu_loadI ); // XXX
6047 %}
6049 instruct loadN2P(mRegP dst, memory mem)
6050 %{
6051 match(Set dst (DecodeN (LoadN mem)));
6052 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6054 ins_cost(125); // XXX
6055 format %{ "lwu $dst, $mem\t# @ loadN2P" %}
6056 ins_encode (load_N_enc(dst, mem));
6057 ins_pipe( ialu_loadI ); // XXX
6058 %}
6060 // Load Pointer
6061 instruct loadP(mRegP dst, memory mem) %{
6062 match(Set dst (LoadP mem));
6064 ins_cost(125);
6065 format %{ "ld $dst, $mem #@loadP" %}
6066 ins_encode (load_P_enc(dst, mem));
6067 ins_pipe( ialu_loadI );
6068 %}
6070 // Load Klass Pointer
6071 instruct loadKlass(mRegP dst, memory mem) %{
6072 match(Set dst (LoadKlass mem));
6074 ins_cost(125);
6075 format %{ "MOV $dst,$mem @ loadKlass" %}
6076 ins_encode (load_P_enc(dst, mem));
6077 ins_pipe( ialu_loadI );
6078 %}
6080 // Load narrow Klass Pointer
6081 instruct loadNKlass(mRegN dst, memory mem)
6082 %{
6083 match(Set dst (LoadNKlass mem));
6085 ins_cost(125); // XXX
6086 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadNKlass" %}
6087 ins_encode (load_N_enc(dst, mem));
6088 ins_pipe( ialu_loadI ); // XXX
6089 %}
6091 instruct loadN2PKlass(mRegP dst, memory mem)
6092 %{
6093 match(Set dst (DecodeNKlass (LoadNKlass mem)));
6094 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
6096 ins_cost(125); // XXX
6097 format %{ "lwu $dst, $mem\t# compressed klass ptr @ loadN2PKlass" %}
6098 ins_encode (load_N_enc(dst, mem));
6099 ins_pipe( ialu_loadI ); // XXX
6100 %}
6102 // Load Constant
6103 instruct loadConI(mRegI dst, immI src) %{
6104 match(Set dst src);
6106 ins_cost(150);
6107 format %{ "mov $dst, $src #@loadConI" %}
6108 ins_encode %{
6109 Register dst = $dst$$Register;
6110 int value = $src$$constant;
6111 __ move(dst, value);
6112 %}
6113 ins_pipe( ialu_regI_regI );
6114 %}
6117 instruct loadConL_set64(mRegL dst, immL src) %{
6118 match(Set dst src);
6119 ins_cost(120);
6120 format %{ "li $dst, $src @ loadConL_set64" %}
6121 ins_encode %{
6122 __ set64($dst$$Register, $src$$constant);
6123 %}
6124 ins_pipe(ialu_regL_regL);
6125 %}
6127 /*
6128 // Load long value from constant table (predicated by immL_expensive).
6129 instruct loadConL_load(mRegL dst, immL_expensive src) %{
6130 match(Set dst src);
6131 ins_cost(150);
6132 format %{ "ld $dst, $constantoffset[$constanttablebase] # load long $src from table @ loadConL_ldx" %}
6133 ins_encode %{
6134 int con_offset = $constantoffset($src);
6136 if (Assembler::is_simm16(con_offset)) {
6137 __ ld($dst$$Register, $constanttablebase, con_offset);
6138 } else {
6139 __ set64(AT, con_offset);
6140 if (UseLoongsonISA) {
6141 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
6142 } else {
6143 __ daddu(AT, $constanttablebase, AT);
6144 __ ld($dst$$Register, AT, 0);
6145 }
6146 }
6147 %}
6148 ins_pipe(ialu_loadI);
6149 %}
6150 */
6152 instruct loadConL16(mRegL dst, immL16 src) %{
6153 match(Set dst src);
6154 ins_cost(105);
6155 format %{ "mov $dst, $src #@loadConL16" %}
6156 ins_encode %{
6157 Register dst_reg = as_Register($dst$$reg);
6158 int value = $src$$constant;
6159 __ daddiu(dst_reg, R0, value);
6160 %}
6161 ins_pipe( ialu_regL_regL );
6162 %}
6165 instruct loadConL0(mRegL dst, immL0 src) %{
6166 match(Set dst src);
6167 ins_cost(100);
6168 format %{ "mov $dst, zero #@loadConL0" %}
6169 ins_encode %{
6170 Register dst_reg = as_Register($dst$$reg);
6171 __ daddu(dst_reg, R0, R0);
6172 %}
6173 ins_pipe( ialu_regL_regL );
6174 %}
6176 // Load Range
6177 instruct loadRange(mRegI dst, memory mem) %{
6178 match(Set dst (LoadRange mem));
6180 ins_cost(125);
6181 format %{ "MOV $dst,$mem @ loadRange" %}
6182 ins_encode(load_I_enc(dst, mem));
6183 ins_pipe( ialu_loadI );
6184 %}
6187 instruct storeP(memory mem, mRegP src ) %{
6188 match(Set mem (StoreP mem src));
6190 ins_cost(125);
6191 format %{ "sd $src, $mem #@storeP" %}
6192 ins_encode(store_P_reg_enc(mem, src));
6193 ins_pipe( ialu_storeI );
6194 %}
6196 // Store NULL Pointer, mark word, or other simple pointer constant.
6197 instruct storeImmP0(memory mem, immP0 zero) %{
6198 match(Set mem (StoreP mem zero));
6200 ins_cost(125);
6201 format %{ "mov $mem, $zero #@storeImmP0" %}
6202 ins_encode(store_P_immP0_enc(mem));
6203 ins_pipe( ialu_storeI );
6204 %}
6206 // Store Byte Immediate
6207 instruct storeImmB(memory mem, immI8 src) %{
6208 match(Set mem (StoreB mem src));
6210 ins_cost(150);
6211 format %{ "movb $mem, $src #@storeImmB" %}
6212 ins_encode(store_B_immI_enc(mem, src));
6213 ins_pipe( ialu_storeI );
6214 %}
6216 // Store Compressed Pointer
6217 instruct storeN(memory mem, mRegN src)
6218 %{
6219 match(Set mem (StoreN mem src));
6221 ins_cost(125); // XXX
6222 format %{ "sw $mem, $src\t# compressed ptr @ storeN" %}
6223 ins_encode(store_N_reg_enc(mem, src));
6224 ins_pipe( ialu_storeI );
6225 %}
6227 instruct storeP2N(memory mem, mRegP src)
6228 %{
6229 match(Set mem (StoreN mem (EncodeP src)));
6230 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6232 ins_cost(125); // XXX
6233 format %{ "sw $mem, $src\t# @ storeP2N" %}
6234 ins_encode(store_N_reg_enc(mem, src));
6235 ins_pipe( ialu_storeI );
6236 %}
6238 instruct storeNKlass(memory mem, mRegN src)
6239 %{
6240 match(Set mem (StoreNKlass mem src));
6242 ins_cost(125); // XXX
6243 format %{ "sw $mem, $src\t# compressed klass ptr @ storeNKlass" %}
6244 ins_encode(store_N_reg_enc(mem, src));
6245 ins_pipe( ialu_storeI );
6246 %}
6248 instruct storeP2NKlass(memory mem, mRegP src)
6249 %{
6250 match(Set mem (StoreNKlass mem (EncodePKlass src)));
6251 predicate(Universe::narrow_klass_base() == NULL && Universe::narrow_klass_shift() == 0);
6253 ins_cost(125); // XXX
6254 format %{ "sw $mem, $src\t# @ storeP2NKlass" %}
6255 ins_encode(store_N_reg_enc(mem, src));
6256 ins_pipe( ialu_storeI );
6257 %}
6259 instruct storeImmN0(memory mem, immN0 zero)
6260 %{
6261 match(Set mem (StoreN mem zero));
6263 ins_cost(125); // XXX
6264 format %{ "storeN0 zero, $mem\t# compressed ptr" %}
6265 ins_encode(storeImmN0_enc(mem, zero));
6266 ins_pipe( ialu_storeI );
6267 %}
6269 // Store Byte
6270 instruct storeB(memory mem, mRegI src) %{
6271 match(Set mem (StoreB mem src));
6273 ins_cost(125);
6274 format %{ "sb $src, $mem #@storeB" %}
6275 ins_encode(store_B_reg_enc(mem, src));
6276 ins_pipe( ialu_storeI );
6277 %}
6279 instruct storeB_convL2I(memory mem, mRegL src) %{
6280 match(Set mem (StoreB mem (ConvL2I src)));
6282 ins_cost(125);
6283 format %{ "sb $src, $mem #@storeB_convL2I" %}
6284 ins_encode(store_B_reg_enc(mem, src));
6285 ins_pipe( ialu_storeI );
6286 %}
6288 // Load Byte (8bit signed)
6289 instruct loadB(mRegI dst, memory mem) %{
6290 match(Set dst (LoadB mem));
6292 ins_cost(125);
6293 format %{ "lb $dst, $mem #@loadB" %}
6294 ins_encode(load_B_enc(dst, mem));
6295 ins_pipe( ialu_loadI );
6296 %}
6298 instruct loadB_convI2L(mRegL dst, memory mem) %{
6299 match(Set dst (ConvI2L (LoadB mem)));
6301 ins_cost(125);
6302 format %{ "lb $dst, $mem #@loadB_convI2L" %}
6303 ins_encode(load_B_enc(dst, mem));
6304 ins_pipe( ialu_loadI );
6305 %}
6307 // Load Byte (8bit UNsigned)
6308 instruct loadUB(mRegI dst, memory mem) %{
6309 match(Set dst (LoadUB mem));
6311 ins_cost(125);
6312 format %{ "lbu $dst, $mem #@loadUB" %}
6313 ins_encode(load_UB_enc(dst, mem));
6314 ins_pipe( ialu_loadI );
6315 %}
6317 instruct loadUB_convI2L(mRegL dst, memory mem) %{
6318 match(Set dst (ConvI2L (LoadUB mem)));
6320 ins_cost(125);
6321 format %{ "lbu $dst, $mem #@loadUB_convI2L" %}
6322 ins_encode(load_UB_enc(dst, mem));
6323 ins_pipe( ialu_loadI );
6324 %}
6326 // Load Short (16bit signed)
6327 instruct loadS(mRegI dst, memory mem) %{
6328 match(Set dst (LoadS mem));
6330 ins_cost(125);
6331 format %{ "lh $dst, $mem #@loadS" %}
6332 ins_encode(load_S_enc(dst, mem));
6333 ins_pipe( ialu_loadI );
6334 %}
6336 // Load Short (16 bit signed) to Byte (8 bit signed)
6337 instruct loadS2B(mRegI dst, memory mem, immI_24 twentyfour) %{
6338 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
6340 ins_cost(125);
6341 format %{ "lb $dst, $mem\t# short -> byte #@loadS2B" %}
6342 ins_encode(load_B_enc(dst, mem));
6343 ins_pipe(ialu_loadI);
6344 %}
6346 instruct loadS_convI2L(mRegL dst, memory mem) %{
6347 match(Set dst (ConvI2L (LoadS mem)));
6349 ins_cost(125);
6350 format %{ "lh $dst, $mem #@loadS_convI2L" %}
6351 ins_encode(load_S_enc(dst, mem));
6352 ins_pipe( ialu_loadI );
6353 %}
6355 // Store Integer Immediate
6356 instruct storeImmI(memory mem, immI src) %{
6357 match(Set mem (StoreI mem src));
6359 ins_cost(150);
6360 format %{ "mov $mem, $src #@storeImmI" %}
6361 ins_encode(store_I_immI_enc(mem, src));
6362 ins_pipe( ialu_storeI );
6363 %}
6365 // Store Integer
6366 instruct storeI(memory mem, mRegI src) %{
6367 match(Set mem (StoreI mem src));
6369 ins_cost(125);
6370 format %{ "sw $mem, $src #@storeI" %}
6371 ins_encode(store_I_reg_enc(mem, src));
6372 ins_pipe( ialu_storeI );
6373 %}
6375 instruct storeI_convL2I(memory mem, mRegL src) %{
6376 match(Set mem (StoreI mem (ConvL2I src)));
6378 ins_cost(125);
6379 format %{ "sw $mem, $src #@storeI_convL2I" %}
6380 ins_encode(store_I_reg_enc(mem, src));
6381 ins_pipe( ialu_storeI );
6382 %}
6384 // Load Float
6385 instruct loadF(regF dst, memory mem) %{
6386 match(Set dst (LoadF mem));
6388 ins_cost(150);
6389 format %{ "loadF $dst, $mem #@loadF" %}
6390 ins_encode(load_F_enc(dst, mem));
6391 ins_pipe( ialu_loadI );
6392 %}
6394 instruct loadConP_general(mRegP dst, immP src) %{
6395 match(Set dst src);
6397 ins_cost(120);
6398 format %{ "li $dst, $src #@loadConP_general" %}
6400 ins_encode %{
6401 Register dst = $dst$$Register;
6402 long* value = (long*)$src$$constant;
6404 if($src->constant_reloc() == relocInfo::metadata_type){
6405 int klass_index = __ oop_recorder()->find_index((Klass*)value);
6406 RelocationHolder rspec = metadata_Relocation::spec(klass_index);
6408 __ relocate(rspec);
6409 __ patchable_set48(dst, (long)value);
6410 }else if($src->constant_reloc() == relocInfo::oop_type){
6411 int oop_index = __ oop_recorder()->find_index((jobject)value);
6412 RelocationHolder rspec = oop_Relocation::spec(oop_index);
6414 __ relocate(rspec);
6415 __ patchable_set48(dst, (long)value);
6416 } else if ($src->constant_reloc() == relocInfo::none) {
6417 __ set64(dst, (long)value);
6418 }
6419 %}
6421 ins_pipe( ialu_regI_regI );
6422 %}
6424 /*
6425 instruct loadConP_load(mRegP dst, immP_load src) %{
6426 match(Set dst src);
6428 ins_cost(100);
6429 format %{ "ld $dst, [$constanttablebase + $constantoffset] load from constant table: ptr=$src @ loadConP_load" %}
6431 ins_encode %{
6433 int con_offset = $constantoffset($src);
6435 if (Assembler::is_simm16(con_offset)) {
6436 __ ld($dst$$Register, $constanttablebase, con_offset);
6437 } else {
6438 __ set64(AT, con_offset);
6439 if (UseLoongsonISA) {
6440 __ gsldx($dst$$Register, $constanttablebase, AT, 0);
6441 } else {
6442 __ daddu(AT, $constanttablebase, AT);
6443 __ ld($dst$$Register, AT, 0);
6444 }
6445 }
6446 %}
6448 ins_pipe(ialu_loadI);
6449 %}
6450 */
6452 instruct loadConP_no_oop_cheap(mRegP dst, immP_no_oop_cheap src) %{
6453 match(Set dst src);
6455 ins_cost(80);
6456 format %{ "li $dst, $src @ loadConP_no_oop_cheap" %}
6458 ins_encode %{
6459 __ set64($dst$$Register, $src$$constant);
6460 %}
6462 ins_pipe(ialu_regI_regI);
6463 %}
6466 instruct loadConP_poll(mRegP dst, immP_poll src) %{
6467 match(Set dst src);
6469 ins_cost(50);
6470 format %{ "li $dst, $src #@loadConP_poll" %}
6472 ins_encode %{
6473 Register dst = $dst$$Register;
6474 intptr_t value = (intptr_t)$src$$constant;
6476 __ set64(dst, (jlong)value);
6477 %}
6479 ins_pipe( ialu_regI_regI );
6480 %}
6482 instruct loadConP0(mRegP dst, immP0 src)
6483 %{
6484 match(Set dst src);
6486 ins_cost(50);
6487 format %{ "mov $dst, R0\t# ptr" %}
6488 ins_encode %{
6489 Register dst_reg = $dst$$Register;
6490 __ daddu(dst_reg, R0, R0);
6491 %}
6492 ins_pipe( ialu_regI_regI );
6493 %}
6495 instruct loadConN0(mRegN dst, immN0 src) %{
6496 match(Set dst src);
6497 format %{ "move $dst, R0\t# compressed NULL ptr" %}
6498 ins_encode %{
6499 __ move($dst$$Register, R0);
6500 %}
6501 ins_pipe( ialu_regI_regI );
6502 %}
6504 instruct loadConN(mRegN dst, immN src) %{
6505 match(Set dst src);
6507 ins_cost(125);
6508 format %{ "li $dst, $src\t# compressed ptr @ loadConN" %}
6509 ins_encode %{
6510 Register dst = $dst$$Register;
6511 __ set_narrow_oop(dst, (jobject)$src$$constant);
6512 %}
6513 ins_pipe( ialu_regI_regI ); // XXX
6514 %}
6516 instruct loadConNKlass(mRegN dst, immNKlass src) %{
6517 match(Set dst src);
6519 ins_cost(125);
6520 format %{ "li $dst, $src\t# compressed klass ptr @ loadConNKlass" %}
6521 ins_encode %{
6522 Register dst = $dst$$Register;
6523 __ set_narrow_klass(dst, (Klass*)$src$$constant);
6524 %}
6525 ins_pipe( ialu_regI_regI ); // XXX
6526 %}
6528 //FIXME
6529 // Tail Call; Jump from runtime stub to Java code.
6530 // Also known as an 'interprocedural jump'.
6531 // Target of jump will eventually return to caller.
6532 // TailJump below removes the return address.
6533 instruct TailCalljmpInd(mRegP jump_target, mRegP method_oop) %{
6534 match(TailCall jump_target method_oop );
6535 ins_cost(300);
6536 format %{ "JMP $jump_target \t# @TailCalljmpInd" %}
6538 ins_encode %{
6539 Register target = $jump_target$$Register;
6540 Register oop = $method_oop$$Register;
6542 /* 2012/10/12 Jin: RA will be used in generate_forward_exception() */
6543 __ push(RA);
6545 __ move(S3, oop);
6546 __ jr(target);
6547 __ nop();
6548 %}
6550 ins_pipe( pipe_jump );
6551 %}
6553 // Create exception oop: created by stack-crawling runtime code.
6554 // Created exception is now available to this handler, and is setup
6555 // just prior to jumping to this handler. No code emitted.
6556 instruct CreateException( a0_RegP ex_oop )
6557 %{
6558 match(Set ex_oop (CreateEx));
6560 // use the following format syntax
6561 format %{ "# exception oop is in A0; no code emitted @CreateException" %}
6562 ins_encode %{
6563 /* Jin: X86 leaves this function empty */
6564 __ block_comment("CreateException is empty in X86/MIPS");
6565 %}
6566 ins_pipe( empty );
6567 // ins_pipe( pipe_jump );
6568 %}
6571 /* 2012/9/14 Jin: The mechanism of exception handling is clear now.
6573 - Common try/catch:
6574 2012/9/14 Jin: [stubGenerator_mips.cpp] generate_forward_exception()
6575 |- V0, V1 are created
6576 |- T9 <= SharedRuntime::exception_handler_for_return_address
6577 `- jr T9
6578 `- the caller's exception_handler
6579 `- jr OptoRuntime::exception_blob
6580 `- here
6581 - Rethrow(e.g. 'unwind'):
6582 * The callee:
6583 |- an exception is triggered during execution
6584 `- exits the callee method through RethrowException node
6585 |- The callee pushes exception_oop(T0) and exception_pc(RA)
6586 `- The callee jumps to OptoRuntime::rethrow_stub()
6587 * In OptoRuntime::rethrow_stub:
6588 |- The VM calls _rethrow_Java to determine the return address in the caller method
6589 `- exits the stub with tailjmpInd
6590 |- pops exception_oop(V0) and exception_pc(V1)
6591 `- jumps to the return address(usually an exception_handler)
6592 * The caller:
6593 `- continues processing the exception_blob with V0/V1
6594 */
6596 /*
6597 Disassembling OptoRuntime::rethrow_stub()
6599 ; locals
6600 0x2d3bf320: addiu sp, sp, 0xfffffff8
6601 0x2d3bf324: sw ra, 0x4(sp)
6602 0x2d3bf328: sw fp, 0x0(sp)
6603 0x2d3bf32c: addu fp, sp, zero
6604 0x2d3bf330: addiu sp, sp, 0xfffffff0
6605 0x2d3bf334: sw ra, 0x8(sp)
6606 0x2d3bf338: sw t0, 0x4(sp)
6607 0x2d3bf33c: sw sp, 0x0(sp)
6609 ; get_thread(S2)
6610 0x2d3bf340: addu s2, sp, zero
6611 0x2d3bf344: srl s2, s2, 12
6612 0x2d3bf348: sll s2, s2, 2
6613 0x2d3bf34c: lui at, 0x2c85
6614 0x2d3bf350: addu at, at, s2
6615 0x2d3bf354: lw s2, 0xffffcc80(at)
6617 0x2d3bf358: lw s0, 0x0(sp)
6618 0x2d3bf35c: sw s0, 0x118(s2) // last_sp -> threa
6619 0x2d3bf360: sw s2, 0xc(sp)
6621 ; OptoRuntime::rethrow_C(oopDesc* exception, JavaThread* thread, address ret_pc)
6622 0x2d3bf364: lw a0, 0x4(sp)
6623 0x2d3bf368: lw a1, 0xc(sp)
6624 0x2d3bf36c: lw a2, 0x8(sp)
6625 ;; Java_To_Runtime
6626 0x2d3bf370: lui t9, 0x2c34
6627 0x2d3bf374: addiu t9, t9, 0xffff8a48
6628 0x2d3bf378: jalr t9
6629 0x2d3bf37c: nop
6631 0x2d3bf380: addu s3, v0, zero ; S3: SharedRuntime::raw_exception_handler_for_return_address()
6633 0x2d3bf384: lw s0, 0xc(sp)
6634 0x2d3bf388: sw zero, 0x118(s0)
6635 0x2d3bf38c: sw zero, 0x11c(s0)
6636 0x2d3bf390: lw s1, 0x144(s0) ; ex_oop: S1
6637 0x2d3bf394: addu s2, s0, zero
6638 0x2d3bf398: sw zero, 0x144(s2)
6639 0x2d3bf39c: lw s0, 0x4(s2)
6640 0x2d3bf3a0: addiu s4, zero, 0x0
6641 0x2d3bf3a4: bne s0, s4, 0x2d3bf3d4
6642 0x2d3bf3a8: nop
6643 0x2d3bf3ac: addiu sp, sp, 0x10
6644 0x2d3bf3b0: addiu sp, sp, 0x8
6645 0x2d3bf3b4: lw ra, 0xfffffffc(sp)
6646 0x2d3bf3b8: lw fp, 0xfffffff8(sp)
6647 0x2d3bf3bc: lui at, 0x2b48
6648 0x2d3bf3c0: lw at, 0x100(at)
6650 ; tailjmpInd: Restores exception_oop & exception_pc
6651 0x2d3bf3c4: addu v1, ra, zero
6652 0x2d3bf3c8: addu v0, s1, zero
6653 0x2d3bf3cc: jr s3
6654 0x2d3bf3d0: nop
6655 ; Exception:
6656 0x2d3bf3d4: lui s1, 0x2cc8 ; generate_forward_exception()
6657 0x2d3bf3d8: addiu s1, s1, 0x40
6658 0x2d3bf3dc: addiu s2, zero, 0x0
6659 0x2d3bf3e0: addiu sp, sp, 0x10
6660 0x2d3bf3e4: addiu sp, sp, 0x8
6661 0x2d3bf3e8: lw ra, 0xfffffffc(sp)
6662 0x2d3bf3ec: lw fp, 0xfffffff8(sp)
6663 0x2d3bf3f0: lui at, 0x2b48
6664 0x2d3bf3f4: lw at, 0x100(at)
6665 ; TailCalljmpInd
6666 __ push(RA); ; to be used in generate_forward_exception()
6667 0x2d3bf3f8: addu t7, s2, zero
6668 0x2d3bf3fc: jr s1
6669 0x2d3bf400: nop
6670 */
6671 // Rethrow exception:
6672 // The exception oop will come in the first argument position.
6673 // Then JUMP (not call) to the rethrow stub code.
6674 instruct RethrowException()
6675 %{
6676 match(Rethrow);
6678 // use the following format syntax
6679 format %{ "JMP rethrow_stub #@RethrowException" %}
6680 ins_encode %{
6681 __ block_comment("@ RethrowException");
6683 cbuf.set_insts_mark();
6684 cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
6686 // call OptoRuntime::rethrow_stub to get the exception handler in parent method
6687 __ patchable_jump((address)OptoRuntime::rethrow_stub());
6688 %}
6689 ins_pipe( pipe_jump );
6690 %}
6692 instruct branchConP_zero(cmpOpU cmp, mRegP op1, immP0 zero, label labl) %{
6693 match(If cmp (CmpP op1 zero));
6694 effect(USE labl);
6696 ins_cost(180);
6697 format %{ "b$cmp $op1, R0, $labl #@branchConP_zero" %}
6699 ins_encode %{
6700 Register op1 = $op1$$Register;
6701 Register op2 = R0;
6702 Label &L = *($labl$$label);
6703 int flag = $cmp$$cmpcode;
6705 switch(flag) {
6706 case 0x01: //equal
6707 if (&L)
6708 __ beq(op1, op2, L);
6709 else
6710 __ beq(op1, op2, (int)0);
6711 break;
6712 case 0x02: //not_equal
6713 if (&L)
6714 __ bne(op1, op2, L);
6715 else
6716 __ bne(op1, op2, (int)0);
6717 break;
6718 default:
6719 Unimplemented();
6720 }
6721 __ nop();
6722 %}
6724 ins_pc_relative(1);
6725 ins_pipe( pipe_alu_branch );
6726 %}
6728 instruct branchConN2P_zero(cmpOpU cmp, mRegN op1, immP0 zero, label labl) %{
6729 match(If cmp (CmpP (DecodeN op1) zero));
6730 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_oop_shift() == 0);
6731 effect(USE labl);
6733 ins_cost(180);
6734 format %{ "b$cmp $op1, R0, $labl #@branchConN2P_zero" %}
6736 ins_encode %{
6737 Register op1 = $op1$$Register;
6738 Register op2 = R0;
6739 Label &L = *($labl$$label);
6740 int flag = $cmp$$cmpcode;
6742 switch(flag)
6743 {
6744 case 0x01: //equal
6745 if (&L)
6746 __ beq(op1, op2, L);
6747 else
6748 __ beq(op1, op2, (int)0);
6749 break;
6750 case 0x02: //not_equal
6751 if (&L)
6752 __ bne(op1, op2, L);
6753 else
6754 __ bne(op1, op2, (int)0);
6755 break;
6756 default:
6757 Unimplemented();
6758 }
6759 __ nop();
6760 %}
6762 ins_pc_relative(1);
6763 ins_pipe( pipe_alu_branch );
6764 %}
6767 instruct branchConP(cmpOpU cmp, mRegP op1, mRegP op2, label labl) %{
6768 match(If cmp (CmpP op1 op2));
6769 // predicate(can_branch_register(_kids[0]->_leaf, _kids[1]->_leaf));
6770 effect(USE labl);
6772 ins_cost(200);
6773 format %{ "b$cmp $op1, $op2, $labl #@branchConP" %}
6775 ins_encode %{
6776 Register op1 = $op1$$Register;
6777 Register op2 = $op2$$Register;
6778 Label &L = *($labl$$label);
6779 int flag = $cmp$$cmpcode;
6781 switch(flag) {
6782 case 0x01: //equal
6783 if (&L)
6784 __ beq(op1, op2, L);
6785 else
6786 __ beq(op1, op2, (int)0);
6787 break;
6788 case 0x02: //not_equal
6789 if (&L)
6790 __ bne(op1, op2, L);
6791 else
6792 __ bne(op1, op2, (int)0);
6793 break;
6794 case 0x03: //above
6795 __ sltu(AT, op2, op1);
6796 if(&L)
6797 __ bne(R0, AT, L);
6798 else
6799 __ bne(R0, AT, (int)0);
6800 break;
6801 case 0x04: //above_equal
6802 __ sltu(AT, op1, op2);
6803 if(&L)
6804 __ beq(AT, R0, L);
6805 else
6806 __ beq(AT, R0, (int)0);
6807 break;
6808 case 0x05: //below
6809 __ sltu(AT, op1, op2);
6810 if(&L)
6811 __ bne(R0, AT, L);
6812 else
6813 __ bne(R0, AT, (int)0);
6814 break;
6815 case 0x06: //below_equal
6816 __ sltu(AT, op2, op1);
6817 if(&L)
6818 __ beq(AT, R0, L);
6819 else
6820 __ beq(AT, R0, (int)0);
6821 break;
6822 default:
6823 Unimplemented();
6824 }
6825 __ nop();
6826 %}
6828 ins_pc_relative(1);
6829 ins_pipe( pipe_alu_branch );
6830 %}
6832 instruct cmpN_null_branch(cmpOp cmp, mRegN op1, immN0 null, label labl) %{
6833 match(If cmp (CmpN op1 null));
6834 effect(USE labl);
6836 ins_cost(180);
6837 format %{ "CMP $op1,0\t! compressed ptr\n\t"
6838 "BP$cmp $labl @ cmpN_null_branch" %}
6839 ins_encode %{
6840 Register op1 = $op1$$Register;
6841 Register op2 = R0;
6842 Label &L = *($labl$$label);
6843 int flag = $cmp$$cmpcode;
6845 switch(flag) {
6846 case 0x01: //equal
6847 if (&L)
6848 __ beq(op1, op2, L);
6849 else
6850 __ beq(op1, op2, (int)0);
6851 break;
6852 case 0x02: //not_equal
6853 if (&L)
6854 __ bne(op1, op2, L);
6855 else
6856 __ bne(op1, op2, (int)0);
6857 break;
6858 default:
6859 Unimplemented();
6860 }
6861 __ nop();
6862 %}
6863 //TODO: pipe_branchP or create pipe_branchN LEE
6864 ins_pc_relative(1);
6865 ins_pipe( pipe_alu_branch );
6866 %}
6868 instruct cmpN_reg_branch(cmpOp cmp, mRegN op1, mRegN op2, label labl) %{
6869 match(If cmp (CmpN op1 op2));
6870 effect(USE labl);
6872 ins_cost(180);
6873 format %{ "CMP $op1,$op2\t! compressed ptr\n\t"
6874 "BP$cmp $labl" %}
6875 ins_encode %{
6876 Register op1_reg = $op1$$Register;
6877 Register op2_reg = $op2$$Register;
6878 Label &L = *($labl$$label);
6879 int flag = $cmp$$cmpcode;
6881 switch(flag) {
6882 case 0x01: //equal
6883 if (&L)
6884 __ beq(op1_reg, op2_reg, L);
6885 else
6886 __ beq(op1_reg, op2_reg, (int)0);
6887 break;
6888 case 0x02: //not_equal
6889 if (&L)
6890 __ bne(op1_reg, op2_reg, L);
6891 else
6892 __ bne(op1_reg, op2_reg, (int)0);
6893 break;
6894 case 0x03: //above
6895 __ sltu(AT, op2_reg, op1_reg);
6896 if(&L)
6897 __ bne(R0, AT, L);
6898 else
6899 __ bne(R0, AT, (int)0);
6900 break;
6901 case 0x04: //above_equal
6902 __ sltu(AT, op1_reg, op2_reg);
6903 if(&L)
6904 __ beq(AT, R0, L);
6905 else
6906 __ beq(AT, R0, (int)0);
6907 break;
6908 case 0x05: //below
6909 __ sltu(AT, op1_reg, op2_reg);
6910 if(&L)
6911 __ bne(R0, AT, L);
6912 else
6913 __ bne(R0, AT, (int)0);
6914 break;
6915 case 0x06: //below_equal
6916 __ sltu(AT, op2_reg, op1_reg);
6917 if(&L)
6918 __ beq(AT, R0, L);
6919 else
6920 __ beq(AT, R0, (int)0);
6921 break;
6922 default:
6923 Unimplemented();
6924 }
6925 __ nop();
6926 %}
6927 ins_pc_relative(1);
6928 ins_pipe( pipe_alu_branch );
6929 %}
6931 instruct branchConIU_reg_reg(cmpOpU cmp, mRegI src1, mRegI src2, label labl) %{
6932 match( If cmp (CmpU src1 src2) );
6933 effect(USE labl);
6934 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_reg" %}
6936 ins_encode %{
6937 Register op1 = $src1$$Register;
6938 Register op2 = $src2$$Register;
6939 Label &L = *($labl$$label);
6940 int flag = $cmp$$cmpcode;
6942 switch(flag) {
6943 case 0x01: //equal
6944 if (&L)
6945 __ beq(op1, op2, L);
6946 else
6947 __ beq(op1, op2, (int)0);
6948 break;
6949 case 0x02: //not_equal
6950 if (&L)
6951 __ bne(op1, op2, L);
6952 else
6953 __ bne(op1, op2, (int)0);
6954 break;
6955 case 0x03: //above
6956 __ sltu(AT, op2, op1);
6957 if(&L)
6958 __ bne(AT, R0, L);
6959 else
6960 __ bne(AT, R0, (int)0);
6961 break;
6962 case 0x04: //above_equal
6963 __ sltu(AT, op1, op2);
6964 if(&L)
6965 __ beq(AT, R0, L);
6966 else
6967 __ beq(AT, R0, (int)0);
6968 break;
6969 case 0x05: //below
6970 __ sltu(AT, op1, op2);
6971 if(&L)
6972 __ bne(AT, R0, L);
6973 else
6974 __ bne(AT, R0, (int)0);
6975 break;
6976 case 0x06: //below_equal
6977 __ sltu(AT, op2, op1);
6978 if(&L)
6979 __ beq(AT, R0, L);
6980 else
6981 __ beq(AT, R0, (int)0);
6982 break;
6983 default:
6984 Unimplemented();
6985 }
6986 __ nop();
6987 %}
6989 ins_pc_relative(1);
6990 ins_pipe( pipe_alu_branch );
6991 %}
6994 instruct branchConIU_reg_imm(cmpOpU cmp, mRegI src1, immI src2, label labl) %{
6995 match( If cmp (CmpU src1 src2) );
6996 effect(USE labl);
6997 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_imm" %}
6999 ins_encode %{
7000 Register op1 = $src1$$Register;
7001 int val = $src2$$constant;
7002 Label &L = *($labl$$label);
7003 int flag = $cmp$$cmpcode;
7005 __ move(AT, val);
7006 switch(flag) {
7007 case 0x01: //equal
7008 if (&L)
7009 __ beq(op1, AT, L);
7010 else
7011 __ beq(op1, AT, (int)0);
7012 break;
7013 case 0x02: //not_equal
7014 if (&L)
7015 __ bne(op1, AT, L);
7016 else
7017 __ bne(op1, AT, (int)0);
7018 break;
7019 case 0x03: //above
7020 __ sltu(AT, AT, op1);
7021 if(&L)
7022 __ bne(R0, AT, L);
7023 else
7024 __ bne(R0, AT, (int)0);
7025 break;
7026 case 0x04: //above_equal
7027 __ sltu(AT, op1, AT);
7028 if(&L)
7029 __ beq(AT, R0, L);
7030 else
7031 __ beq(AT, R0, (int)0);
7032 break;
7033 case 0x05: //below
7034 __ sltu(AT, op1, AT);
7035 if(&L)
7036 __ bne(R0, AT, L);
7037 else
7038 __ bne(R0, AT, (int)0);
7039 break;
7040 case 0x06: //below_equal
7041 __ sltu(AT, AT, op1);
7042 if(&L)
7043 __ beq(AT, R0, L);
7044 else
7045 __ beq(AT, R0, (int)0);
7046 break;
7047 default:
7048 Unimplemented();
7049 }
7050 __ nop();
7051 %}
7053 ins_pc_relative(1);
7054 ins_pipe( pipe_alu_branch );
7055 %}
7057 instruct branchConI_reg_reg(cmpOp cmp, mRegI src1, mRegI src2, label labl) %{
7058 match( If cmp (CmpI src1 src2) );
7059 effect(USE labl);
7060 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_reg" %}
7062 ins_encode %{
7063 Register op1 = $src1$$Register;
7064 Register op2 = $src2$$Register;
7065 Label &L = *($labl$$label);
7066 int flag = $cmp$$cmpcode;
7068 switch(flag) {
7069 case 0x01: //equal
7070 if (&L)
7071 __ beq(op1, op2, L);
7072 else
7073 __ beq(op1, op2, (int)0);
7074 break;
7075 case 0x02: //not_equal
7076 if (&L)
7077 __ bne(op1, op2, L);
7078 else
7079 __ bne(op1, op2, (int)0);
7080 break;
7081 case 0x03: //above
7082 __ slt(AT, op2, op1);
7083 if(&L)
7084 __ bne(R0, AT, L);
7085 else
7086 __ bne(R0, AT, (int)0);
7087 break;
7088 case 0x04: //above_equal
7089 __ slt(AT, op1, op2);
7090 if(&L)
7091 __ beq(AT, R0, L);
7092 else
7093 __ beq(AT, R0, (int)0);
7094 break;
7095 case 0x05: //below
7096 __ slt(AT, op1, op2);
7097 if(&L)
7098 __ bne(R0, AT, L);
7099 else
7100 __ bne(R0, AT, (int)0);
7101 break;
7102 case 0x06: //below_equal
7103 __ slt(AT, op2, op1);
7104 if(&L)
7105 __ beq(AT, R0, L);
7106 else
7107 __ beq(AT, R0, (int)0);
7108 break;
7109 default:
7110 Unimplemented();
7111 }
7112 __ nop();
7113 %}
7115 ins_pc_relative(1);
7116 ins_pipe( pipe_alu_branch );
7117 %}
7119 instruct branchConI_reg_imm0(cmpOp cmp, mRegI src1, immI0 src2, label labl) %{
7120 match( If cmp (CmpI src1 src2) );
7121 effect(USE labl);
7122 ins_cost(170);
7123 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm0" %}
7125 ins_encode %{
7126 Register op1 = $src1$$Register;
7127 Label &L = *($labl$$label);
7128 int flag = $cmp$$cmpcode;
7130 switch(flag) {
7131 case 0x01: //equal
7132 if (&L)
7133 __ beq(op1, R0, L);
7134 else
7135 __ beq(op1, R0, (int)0);
7136 break;
7137 case 0x02: //not_equal
7138 if (&L)
7139 __ bne(op1, R0, L);
7140 else
7141 __ bne(op1, R0, (int)0);
7142 break;
7143 case 0x03: //greater
7144 if(&L)
7145 __ bgtz(op1, L);
7146 else
7147 __ bgtz(op1, (int)0);
7148 break;
7149 case 0x04: //greater_equal
7150 if(&L)
7151 __ bgez(op1, L);
7152 else
7153 __ bgez(op1, (int)0);
7154 break;
7155 case 0x05: //less
7156 if(&L)
7157 __ bltz(op1, L);
7158 else
7159 __ bltz(op1, (int)0);
7160 break;
7161 case 0x06: //less_equal
7162 if(&L)
7163 __ blez(op1, L);
7164 else
7165 __ blez(op1, (int)0);
7166 break;
7167 default:
7168 Unimplemented();
7169 }
7170 __ nop();
7171 %}
7173 ins_pc_relative(1);
7174 ins_pipe( pipe_alu_branch );
7175 %}
7178 instruct branchConI_reg_imm(cmpOp cmp, mRegI src1, immI src2, label labl) %{
7179 match( If cmp (CmpI src1 src2) );
7180 effect(USE labl);
7181 ins_cost(200);
7182 format %{ "BR$cmp $src1, $src2, $labl #@branchConI_reg_imm" %}
7184 ins_encode %{
7185 Register op1 = $src1$$Register;
7186 int val = $src2$$constant;
7187 Label &L = *($labl$$label);
7188 int flag = $cmp$$cmpcode;
7190 __ move(AT, val);
7191 switch(flag) {
7192 case 0x01: //equal
7193 if (&L)
7194 __ beq(op1, AT, L);
7195 else
7196 __ beq(op1, AT, (int)0);
7197 break;
7198 case 0x02: //not_equal
7199 if (&L)
7200 __ bne(op1, AT, L);
7201 else
7202 __ bne(op1, AT, (int)0);
7203 break;
7204 case 0x03: //greater
7205 __ slt(AT, AT, op1);
7206 if(&L)
7207 __ bne(R0, AT, L);
7208 else
7209 __ bne(R0, AT, (int)0);
7210 break;
7211 case 0x04: //greater_equal
7212 __ slt(AT, op1, AT);
7213 if(&L)
7214 __ beq(AT, R0, L);
7215 else
7216 __ beq(AT, R0, (int)0);
7217 break;
7218 case 0x05: //less
7219 __ slt(AT, op1, AT);
7220 if(&L)
7221 __ bne(R0, AT, L);
7222 else
7223 __ bne(R0, AT, (int)0);
7224 break;
7225 case 0x06: //less_equal
7226 __ slt(AT, AT, op1);
7227 if(&L)
7228 __ beq(AT, R0, L);
7229 else
7230 __ beq(AT, R0, (int)0);
7231 break;
7232 default:
7233 Unimplemented();
7234 }
7235 __ nop();
7236 %}
7238 ins_pc_relative(1);
7239 ins_pipe( pipe_alu_branch );
7240 %}
7242 instruct branchConIU_reg_imm0(cmpOpU cmp, mRegI src1, immI0 zero, label labl) %{
7243 match( If cmp (CmpU src1 zero) );
7244 effect(USE labl);
7245 format %{ "BR$cmp $src1, zero, $labl #@branchConIU_reg_imm0" %}
7247 ins_encode %{
7248 Register op1 = $src1$$Register;
7249 Label &L = *($labl$$label);
7250 int flag = $cmp$$cmpcode;
7252 switch(flag) {
7253 case 0x01: //equal
7254 if (&L)
7255 __ beq(op1, R0, L);
7256 else
7257 __ beq(op1, R0, (int)0);
7258 break;
7259 case 0x02: //not_equal
7260 if (&L)
7261 __ bne(op1, R0, L);
7262 else
7263 __ bne(op1, R0, (int)0);
7264 break;
7265 case 0x03: //above
7266 if(&L)
7267 __ bne(R0, op1, L);
7268 else
7269 __ bne(R0, op1, (int)0);
7270 break;
7271 case 0x04: //above_equal
7272 if(&L)
7273 __ beq(R0, R0, L);
7274 else
7275 __ beq(R0, R0, (int)0);
7276 break;
7277 case 0x05: //below
7278 return;
7279 break;
7280 case 0x06: //below_equal
7281 if(&L)
7282 __ beq(op1, R0, L);
7283 else
7284 __ beq(op1, R0, (int)0);
7285 break;
7286 default:
7287 Unimplemented();
7288 }
7289 __ nop();
7290 %}
7292 ins_pc_relative(1);
7293 ins_pipe( pipe_alu_branch );
7294 %}
7297 instruct branchConIU_reg_immI16(cmpOpU cmp, mRegI src1, immI16 src2, label labl) %{
7298 match( If cmp (CmpU src1 src2) );
7299 effect(USE labl);
7300 ins_cost(180);
7301 format %{ "BR$cmp $src1, $src2, $labl #@branchConIU_reg_immI16" %}
7303 ins_encode %{
7304 Register op1 = $src1$$Register;
7305 int val = $src2$$constant;
7306 Label &L = *($labl$$label);
7307 int flag = $cmp$$cmpcode;
7309 switch(flag) {
7310 case 0x01: //equal
7311 __ move(AT, val);
7312 if (&L)
7313 __ beq(op1, AT, L);
7314 else
7315 __ beq(op1, AT, (int)0);
7316 break;
7317 case 0x02: //not_equal
7318 __ move(AT, val);
7319 if (&L)
7320 __ bne(op1, AT, L);
7321 else
7322 __ bne(op1, AT, (int)0);
7323 break;
7324 case 0x03: //above
7325 __ move(AT, val);
7326 __ sltu(AT, AT, op1);
7327 if(&L)
7328 __ bne(R0, AT, L);
7329 else
7330 __ bne(R0, AT, (int)0);
7331 break;
7332 case 0x04: //above_equal
7333 __ sltiu(AT, op1, val);
7334 if(&L)
7335 __ beq(AT, R0, L);
7336 else
7337 __ beq(AT, R0, (int)0);
7338 break;
7339 case 0x05: //below
7340 __ sltiu(AT, op1, val);
7341 if(&L)
7342 __ bne(R0, AT, L);
7343 else
7344 __ bne(R0, AT, (int)0);
7345 break;
7346 case 0x06: //below_equal
7347 __ move(AT, val);
7348 __ sltu(AT, AT, op1);
7349 if(&L)
7350 __ beq(AT, R0, L);
7351 else
7352 __ beq(AT, R0, (int)0);
7353 break;
7354 default:
7355 Unimplemented();
7356 }
7357 __ nop();
7358 %}
7360 ins_pc_relative(1);
7361 ins_pipe( pipe_alu_branch );
7362 %}
7365 instruct branchConL_regL_regL(cmpOp cmp, mRegL src1, mRegL src2, label labl) %{
7366 match( If cmp (CmpL src1 src2) );
7367 effect(USE labl);
7368 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_regL" %}
7369 ins_cost(250);
7371 ins_encode %{
7372 Register opr1_reg = as_Register($src1$$reg);
7373 Register opr2_reg = as_Register($src2$$reg);
7375 Label &target = *($labl$$label);
7376 int flag = $cmp$$cmpcode;
7378 switch(flag) {
7379 case 0x01: //equal
7380 if (&target)
7381 __ beq(opr1_reg, opr2_reg, target);
7382 else
7383 __ beq(opr1_reg, opr2_reg, (int)0);
7384 __ delayed()->nop();
7385 break;
7387 case 0x02: //not_equal
7388 if(&target)
7389 __ bne(opr1_reg, opr2_reg, target);
7390 else
7391 __ bne(opr1_reg, opr2_reg, (int)0);
7392 __ delayed()->nop();
7393 break;
7395 case 0x03: //greater
7396 __ slt(AT, opr2_reg, opr1_reg);
7397 if(&target)
7398 __ bne(AT, R0, target);
7399 else
7400 __ bne(AT, R0, (int)0);
7401 __ delayed()->nop();
7402 break;
7404 case 0x04: //greater_equal
7405 __ slt(AT, opr1_reg, opr2_reg);
7406 if(&target)
7407 __ beq(AT, R0, target);
7408 else
7409 __ beq(AT, R0, (int)0);
7410 __ delayed()->nop();
7412 break;
7414 case 0x05: //less
7415 __ slt(AT, opr1_reg, opr2_reg);
7416 if(&target)
7417 __ bne(AT, R0, target);
7418 else
7419 __ bne(AT, R0, (int)0);
7420 __ delayed()->nop();
7422 break;
7424 case 0x06: //less_equal
7425 __ slt(AT, opr2_reg, opr1_reg);
7427 if(&target)
7428 __ beq(AT, R0, target);
7429 else
7430 __ beq(AT, R0, (int)0);
7431 __ delayed()->nop();
7433 break;
7435 default:
7436 Unimplemented();
7437 }
7438 %}
7441 ins_pc_relative(1);
7442 ins_pipe( pipe_alu_branch );
7443 %}
7446 instruct branchConL_regL_immL0(cmpOp cmp, mRegL src1, immL0 zero, label labl) %{
7447 match( If cmp (CmpL src1 zero) );
7448 effect(USE labl);
7449 format %{ "BR$cmp $src1, zero, $labl #@branchConL_regL_immL0" %}
7450 ins_cost(150);
7452 ins_encode %{
7453 Register opr1_reg = as_Register($src1$$reg);
7454 Label &target = *($labl$$label);
7455 int flag = $cmp$$cmpcode;
7457 switch(flag) {
7458 case 0x01: //equal
7459 if (&target)
7460 __ beq(opr1_reg, R0, target);
7461 else
7462 __ beq(opr1_reg, R0, int(0));
7463 break;
7465 case 0x02: //not_equal
7466 if(&target)
7467 __ bne(opr1_reg, R0, target);
7468 else
7469 __ bne(opr1_reg, R0, (int)0);
7470 break;
7472 case 0x03: //greater
7473 if(&target)
7474 __ bgtz(opr1_reg, target);
7475 else
7476 __ bgtz(opr1_reg, (int)0);
7477 break;
7479 case 0x04: //greater_equal
7480 if(&target)
7481 __ bgez(opr1_reg, target);
7482 else
7483 __ bgez(opr1_reg, (int)0);
7484 break;
7486 case 0x05: //less
7487 __ slt(AT, opr1_reg, R0);
7488 if(&target)
7489 __ bne(AT, R0, target);
7490 else
7491 __ bne(AT, R0, (int)0);
7492 break;
7494 case 0x06: //less_equal
7495 if (&target)
7496 __ blez(opr1_reg, target);
7497 else
7498 __ blez(opr1_reg, int(0));
7499 break;
7501 default:
7502 Unimplemented();
7503 }
7504 __ delayed()->nop();
7505 %}
7508 ins_pc_relative(1);
7509 ins_pipe( pipe_alu_branch );
7510 %}
7512 instruct branchConL_regL_immL(cmpOp cmp, mRegL src1, immL src2, label labl) %{
7513 match( If cmp (CmpL src1 src2) );
7514 effect(USE labl);
7515 format %{ "BR$cmp $src1, $src2, $labl #@branchConL_regL_immL" %}
7516 ins_cost(180);
7518 ins_encode %{
7519 Register opr1_reg = as_Register($src1$$reg);
7520 Register opr2_reg = AT;
7522 Label &target = *($labl$$label);
7523 int flag = $cmp$$cmpcode;
7525 __ set64(opr2_reg, $src2$$constant);
7527 switch(flag) {
7528 case 0x01: //equal
7529 if (&target)
7530 __ beq(opr1_reg, opr2_reg, target);
7531 else
7532 __ beq(opr1_reg, opr2_reg, (int)0);
7533 break;
7535 case 0x02: //not_equal
7536 if(&target)
7537 __ bne(opr1_reg, opr2_reg, target);
7538 else
7539 __ bne(opr1_reg, opr2_reg, (int)0);
7540 break;
7542 case 0x03: //greater
7543 __ slt(AT, opr2_reg, opr1_reg);
7544 if(&target)
7545 __ bne(AT, R0, target);
7546 else
7547 __ bne(AT, R0, (int)0);
7548 break;
7550 case 0x04: //greater_equal
7551 __ slt(AT, opr1_reg, opr2_reg);
7552 if(&target)
7553 __ beq(AT, R0, target);
7554 else
7555 __ beq(AT, R0, (int)0);
7556 break;
7558 case 0x05: //less
7559 __ slt(AT, opr1_reg, opr2_reg);
7560 if(&target)
7561 __ bne(AT, R0, target);
7562 else
7563 __ bne(AT, R0, (int)0);
7564 break;
7566 case 0x06: //less_equal
7567 __ slt(AT, opr2_reg, opr1_reg);
7568 if(&target)
7569 __ beq(AT, R0, target);
7570 else
7571 __ beq(AT, R0, (int)0);
7572 break;
7574 default:
7575 Unimplemented();
7576 }
7577 __ nop();
7578 %}
7581 ins_pc_relative(1);
7582 ins_pipe( pipe_alu_branch );
7583 %}
7586 //FIXME
7587 instruct branchConF_reg_reg(cmpOp cmp, regF src1, regF src2, label labl) %{
7588 match( If cmp (CmpF src1 src2) );
7589 effect(USE labl);
7590 format %{ "BR$cmp $src1, $src2, $labl #@branchConF_reg_reg" %}
7592 ins_encode %{
7593 FloatRegister reg_op1 = $src1$$FloatRegister;
7594 FloatRegister reg_op2 = $src2$$FloatRegister;
7595 Label &L = *($labl$$label);
7596 int flag = $cmp$$cmpcode;
7598 switch(flag) {
7599 case 0x01: //equal
7600 __ c_eq_s(reg_op1, reg_op2);
7601 if (&L)
7602 __ bc1t(L);
7603 else
7604 __ bc1t((int)0);
7605 break;
7606 case 0x02: //not_equal
7607 __ c_eq_s(reg_op1, reg_op2);
7608 if (&L)
7609 __ bc1f(L);
7610 else
7611 __ bc1f((int)0);
7612 break;
7613 case 0x03: //greater
7614 __ c_ule_s(reg_op1, reg_op2);
7615 if(&L)
7616 __ bc1f(L);
7617 else
7618 __ bc1f((int)0);
7619 break;
7620 case 0x04: //greater_equal
7621 __ c_ult_s(reg_op1, reg_op2);
7622 if(&L)
7623 __ bc1f(L);
7624 else
7625 __ bc1f((int)0);
7626 break;
7627 case 0x05: //less
7628 __ c_ult_s(reg_op1, reg_op2);
7629 if(&L)
7630 __ bc1t(L);
7631 else
7632 __ bc1t((int)0);
7633 break;
7634 case 0x06: //less_equal
7635 __ c_ule_s(reg_op1, reg_op2);
7636 if(&L)
7637 __ bc1t(L);
7638 else
7639 __ bc1t((int)0);
7640 break;
7641 default:
7642 Unimplemented();
7643 }
7644 __ nop();
7645 %}
7647 ins_pc_relative(1);
7648 ins_pipe(pipe_slow);
7649 %}
7651 instruct branchConD_reg_reg(cmpOp cmp, regD src1, regD src2, label labl) %{
7652 match( If cmp (CmpD src1 src2) );
7653 effect(USE labl);
7654 format %{ "BR$cmp $src1, $src2, $labl #@branchConD_reg_reg" %}
7656 ins_encode %{
7657 FloatRegister reg_op1 = $src1$$FloatRegister;
7658 FloatRegister reg_op2 = $src2$$FloatRegister;
7659 Label &L = *($labl$$label);
7660 int flag = $cmp$$cmpcode;
7662 switch(flag) {
7663 case 0x01: //equal
7664 __ c_eq_d(reg_op1, reg_op2);
7665 if (&L)
7666 __ bc1t(L);
7667 else
7668 __ bc1t((int)0);
7669 break;
7670 case 0x02: //not_equal
7671 //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.
7672 __ c_eq_d(reg_op1, reg_op2);
7673 if (&L)
7674 __ bc1f(L);
7675 else
7676 __ bc1f((int)0);
7677 break;
7678 case 0x03: //greater
7679 __ c_ule_d(reg_op1, reg_op2);
7680 if(&L)
7681 __ bc1f(L);
7682 else
7683 __ bc1f((int)0);
7684 break;
7685 case 0x04: //greater_equal
7686 __ c_ult_d(reg_op1, reg_op2);
7687 if(&L)
7688 __ bc1f(L);
7689 else
7690 __ bc1f((int)0);
7691 break;
7692 case 0x05: //less
7693 __ c_ult_d(reg_op1, reg_op2);
7694 if(&L)
7695 __ bc1t(L);
7696 else
7697 __ bc1t((int)0);
7698 break;
7699 case 0x06: //less_equal
7700 __ c_ule_d(reg_op1, reg_op2);
7701 if(&L)
7702 __ bc1t(L);
7703 else
7704 __ bc1t((int)0);
7705 break;
7706 default:
7707 Unimplemented();
7708 }
7709 __ nop();
7710 %}
7712 ins_pc_relative(1);
7713 ins_pipe(pipe_slow);
7714 %}
7717 // Call Runtime Instruction
7718 instruct CallRuntimeDirect(method meth) %{
7719 match(CallRuntime );
7720 effect(USE meth);
7722 ins_cost(300);
7723 format %{ "CALL,runtime #@CallRuntimeDirect" %}
7724 ins_encode( Java_To_Runtime( meth ) );
7725 ins_pipe( pipe_slow );
7726 ins_alignment(16);
7727 %}
7731 //------------------------MemBar Instructions-------------------------------
7732 //Memory barrier flavors
7734 instruct membar_acquire() %{
7735 match(MemBarAcquire);
7736 ins_cost(400);
7738 format %{ "MEMBAR-acquire (empty) @ membar_acquire" %}
7739 ins_encode %{
7740 __ sync();
7741 %}
7742 ins_pipe(empty);
7743 %}
7745 instruct load_fence() %{
7746 match(LoadFence);
7747 ins_cost(400);
7749 format %{ "MEMBAR @ load_fence" %}
7750 ins_encode %{
7751 __ sync();
7752 %}
7753 ins_pipe(pipe_slow);
7754 %}
7756 instruct membar_acquire_lock()
7757 %{
7758 match(MemBarAcquireLock);
7759 ins_cost(0);
7761 size(0);
7762 format %{ "MEMBAR-acquire (acquire as part of CAS in prior FastLock so empty encoding) @ membar_acquire_lock" %}
7763 ins_encode();
7764 ins_pipe(empty);
7765 %}
7767 instruct membar_release() %{
7768 match(MemBarRelease);
7769 ins_cost(400);
7771 format %{ "MEMBAR-release @ membar_release" %}
7773 ins_encode %{
7774 // Attention: DO NOT DELETE THIS GUY!
7775 __ sync();
7776 %}
7778 ins_pipe(pipe_slow);
7779 %}
7781 instruct store_fence() %{
7782 match(StoreFence);
7783 ins_cost(400);
7785 format %{ "MEMBAR @ store_fence" %}
7787 ins_encode %{
7788 __ sync();
7789 %}
7791 ins_pipe(pipe_slow);
7792 %}
7794 instruct membar_release_lock()
7795 %{
7796 match(MemBarReleaseLock);
7797 ins_cost(0);
7799 size(0);
7800 format %{ "MEMBAR-release-lock (release in FastUnlock so empty) @ membar_release_lock" %}
7801 ins_encode();
7802 ins_pipe(empty);
7803 %}
7806 instruct membar_volatile() %{
7807 match(MemBarVolatile);
7808 ins_cost(400);
7810 format %{ "MEMBAR-volatile" %}
7811 ins_encode %{
7812 if( !os::is_MP() ) return; // Not needed on single CPU
7813 __ sync();
7815 %}
7816 ins_pipe(pipe_slow);
7817 %}
7819 instruct unnecessary_membar_volatile() %{
7820 match(MemBarVolatile);
7821 predicate(Matcher::post_store_load_barrier(n));
7822 ins_cost(0);
7824 size(0);
7825 format %{ "MEMBAR-volatile (unnecessary so empty encoding) @ unnecessary_membar_volatile" %}
7826 ins_encode( );
7827 ins_pipe(empty);
7828 %}
7830 instruct membar_storestore() %{
7831 match(MemBarStoreStore);
7833 ins_cost(400);
7834 format %{ "MEMBAR-storestore (empty encoding) @ membar_storestore" %}
7835 ins_encode %{
7836 __ sync();
7837 %}
7838 ins_pipe(empty);
7839 %}
7841 //----------Move Instructions--------------------------------------------------
7842 instruct castX2P(mRegP dst, mRegL src) %{
7843 match(Set dst (CastX2P src));
7844 format %{ "castX2P $dst, $src @ castX2P" %}
7845 ins_encode %{
7846 Register src = $src$$Register;
7847 Register dst = $dst$$Register;
7849 if(src != dst)
7850 __ move(dst, src);
7851 %}
7852 ins_cost(10);
7853 ins_pipe( ialu_regI_mov );
7854 %}
7856 instruct castP2X(mRegL dst, mRegP src ) %{
7857 match(Set dst (CastP2X src));
7859 format %{ "mov $dst, $src\t #@castP2X" %}
7860 ins_encode %{
7861 Register src = $src$$Register;
7862 Register dst = $dst$$Register;
7864 if(src != dst)
7865 __ move(dst, src);
7866 %}
7867 ins_pipe( ialu_regI_mov );
7868 %}
7870 instruct MoveF2I_reg_reg(mRegI dst, regF src) %{
7871 match(Set dst (MoveF2I src));
7872 effect(DEF dst, USE src);
7873 ins_cost(85);
7874 format %{ "MoveF2I $dst, $src @ MoveF2I_reg_reg" %}
7875 ins_encode %{
7876 Register dst = as_Register($dst$$reg);
7877 FloatRegister src = as_FloatRegister($src$$reg);
7879 __ mfc1(dst, src);
7880 %}
7881 ins_pipe( pipe_slow );
7882 %}
7884 instruct MoveI2F_reg_reg(regF dst, mRegI src) %{
7885 match(Set dst (MoveI2F src));
7886 effect(DEF dst, USE src);
7887 ins_cost(85);
7888 format %{ "MoveI2F $dst, $src @ MoveI2F_reg_reg" %}
7889 ins_encode %{
7890 Register src = as_Register($src$$reg);
7891 FloatRegister dst = as_FloatRegister($dst$$reg);
7893 __ mtc1(src, dst);
7894 %}
7895 ins_pipe( pipe_slow );
7896 %}
7898 instruct MoveD2L_reg_reg(mRegL dst, regD src) %{
7899 match(Set dst (MoveD2L src));
7900 effect(DEF dst, USE src);
7901 ins_cost(85);
7902 format %{ "MoveD2L $dst, $src @ MoveD2L_reg_reg" %}
7903 ins_encode %{
7904 Register dst = as_Register($dst$$reg);
7905 FloatRegister src = as_FloatRegister($src$$reg);
7907 __ dmfc1(dst, src);
7908 %}
7909 ins_pipe( pipe_slow );
7910 %}
7912 instruct MoveL2D_reg_reg(regD dst, mRegL src) %{
7913 match(Set dst (MoveL2D src));
7914 effect(DEF dst, USE src);
7915 ins_cost(85);
7916 format %{ "MoveL2D $dst, $src @ MoveL2D_reg_reg" %}
7917 ins_encode %{
7918 FloatRegister dst = as_FloatRegister($dst$$reg);
7919 Register src = as_Register($src$$reg);
7921 __ dmtc1(src, dst);
7922 %}
7923 ins_pipe( pipe_slow );
7924 %}
7926 //----------Conditional Move---------------------------------------------------
7927 // Conditional move
7928 instruct cmovI_cmpI_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
7929 match(Set dst (CMoveI (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
7930 ins_cost(80);
7931 format %{
7932 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpI_reg_reg\n"
7933 "\tCMOV $dst,$src \t @cmovI_cmpI_reg_reg"
7934 %}
7936 ins_encode %{
7937 Register op1 = $tmp1$$Register;
7938 Register op2 = $tmp2$$Register;
7939 Register dst = $dst$$Register;
7940 Register src = $src$$Register;
7941 int flag = $cop$$cmpcode;
7943 switch(flag) {
7944 case 0x01: //equal
7945 __ subu32(AT, op1, op2);
7946 __ movz(dst, src, AT);
7947 break;
7949 case 0x02: //not_equal
7950 __ subu32(AT, op1, op2);
7951 __ movn(dst, src, AT);
7952 break;
7954 case 0x03: //great
7955 __ slt(AT, op2, op1);
7956 __ movn(dst, src, AT);
7957 break;
7959 case 0x04: //great_equal
7960 __ slt(AT, op1, op2);
7961 __ movz(dst, src, AT);
7962 break;
7964 case 0x05: //less
7965 __ slt(AT, op1, op2);
7966 __ movn(dst, src, AT);
7967 break;
7969 case 0x06: //less_equal
7970 __ slt(AT, op2, op1);
7971 __ movz(dst, src, AT);
7972 break;
7974 default:
7975 Unimplemented();
7976 }
7977 %}
7979 ins_pipe( pipe_slow );
7980 %}
7982 instruct cmovI_cmpP_reg_reg(mRegI dst, mRegI src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
7983 match(Set dst (CMoveI (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
7984 ins_cost(80);
7985 format %{
7986 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpP_reg_reg\n\t"
7987 "CMOV $dst,$src\t @cmovI_cmpP_reg_reg"
7988 %}
7989 ins_encode %{
7990 Register op1 = $tmp1$$Register;
7991 Register op2 = $tmp2$$Register;
7992 Register dst = $dst$$Register;
7993 Register src = $src$$Register;
7994 int flag = $cop$$cmpcode;
7996 switch(flag) {
7997 case 0x01: //equal
7998 __ subu(AT, op1, op2);
7999 __ movz(dst, src, AT);
8000 break;
8002 case 0x02: //not_equal
8003 __ subu(AT, op1, op2);
8004 __ movn(dst, src, AT);
8005 break;
8007 case 0x03: //above
8008 __ sltu(AT, op2, op1);
8009 __ movn(dst, src, AT);
8010 break;
8012 case 0x04: //above_equal
8013 __ sltu(AT, op1, op2);
8014 __ movz(dst, src, AT);
8015 break;
8017 case 0x05: //below
8018 __ sltu(AT, op1, op2);
8019 __ movn(dst, src, AT);
8020 break;
8022 case 0x06: //below_equal
8023 __ sltu(AT, op2, op1);
8024 __ movz(dst, src, AT);
8025 break;
8027 default:
8028 Unimplemented();
8029 }
8030 %}
8032 ins_pipe( pipe_slow );
8033 %}
8035 instruct cmovI_cmpN_reg_reg(mRegI dst, mRegI src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
8036 match(Set dst (CMoveI (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
8037 ins_cost(80);
8038 format %{
8039 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpN_reg_reg\n\t"
8040 "CMOV $dst,$src\t @cmovI_cmpN_reg_reg"
8041 %}
8042 ins_encode %{
8043 Register op1 = $tmp1$$Register;
8044 Register op2 = $tmp2$$Register;
8045 Register dst = $dst$$Register;
8046 Register src = $src$$Register;
8047 int flag = $cop$$cmpcode;
8049 switch(flag) {
8050 case 0x01: //equal
8051 __ subu32(AT, op1, op2);
8052 __ movz(dst, src, AT);
8053 break;
8055 case 0x02: //not_equal
8056 __ subu32(AT, op1, op2);
8057 __ movn(dst, src, AT);
8058 break;
8060 case 0x03: //above
8061 __ sltu(AT, op2, op1);
8062 __ movn(dst, src, AT);
8063 break;
8065 case 0x04: //above_equal
8066 __ sltu(AT, op1, op2);
8067 __ movz(dst, src, AT);
8068 break;
8070 case 0x05: //below
8071 __ sltu(AT, op1, op2);
8072 __ movn(dst, src, AT);
8073 break;
8075 case 0x06: //below_equal
8076 __ sltu(AT, op2, op1);
8077 __ movz(dst, src, AT);
8078 break;
8080 default:
8081 Unimplemented();
8082 }
8083 %}
8085 ins_pipe( pipe_slow );
8086 %}
8088 instruct cmovP_cmpU_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
8089 match(Set dst (CMoveP (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
8090 ins_cost(80);
8091 format %{
8092 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpU_reg_reg\n\t"
8093 "CMOV $dst,$src\t @cmovP_cmpU_reg_reg"
8094 %}
8095 ins_encode %{
8096 Register op1 = $tmp1$$Register;
8097 Register op2 = $tmp2$$Register;
8098 Register dst = $dst$$Register;
8099 Register src = $src$$Register;
8100 int flag = $cop$$cmpcode;
8102 switch(flag) {
8103 case 0x01: //equal
8104 __ subu32(AT, op1, op2);
8105 __ movz(dst, src, AT);
8106 break;
8108 case 0x02: //not_equal
8109 __ subu32(AT, op1, op2);
8110 __ movn(dst, src, AT);
8111 break;
8113 case 0x03: //above
8114 __ sltu(AT, op2, op1);
8115 __ movn(dst, src, AT);
8116 break;
8118 case 0x04: //above_equal
8119 __ sltu(AT, op1, op2);
8120 __ movz(dst, src, AT);
8121 break;
8123 case 0x05: //below
8124 __ sltu(AT, op1, op2);
8125 __ movn(dst, src, AT);
8126 break;
8128 case 0x06: //below_equal
8129 __ sltu(AT, op2, op1);
8130 __ movz(dst, src, AT);
8131 break;
8133 default:
8134 Unimplemented();
8135 }
8136 %}
8138 ins_pipe( pipe_slow );
8139 %}
8141 instruct cmovP_cmpF_reg_reg(mRegP dst, mRegP src, regF tmp1, regF tmp2, cmpOp cop ) %{
8142 match(Set dst (CMoveP (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
8143 ins_cost(80);
8144 format %{
8145 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpF_reg_reg\n"
8146 "\tCMOV $dst,$src \t @cmovP_cmpF_reg_reg"
8147 %}
8149 ins_encode %{
8150 FloatRegister reg_op1 = $tmp1$$FloatRegister;
8151 FloatRegister reg_op2 = $tmp2$$FloatRegister;
8152 Register dst = $dst$$Register;
8153 Register src = $src$$Register;
8154 int flag = $cop$$cmpcode;
8156 switch(flag) {
8157 case 0x01: //equal
8158 __ c_eq_s(reg_op1, reg_op2);
8159 __ movt(dst, src);
8160 break;
8161 case 0x02: //not_equal
8162 __ c_eq_s(reg_op1, reg_op2);
8163 __ movf(dst, src);
8164 break;
8165 case 0x03: //greater
8166 __ c_ole_s(reg_op1, reg_op2);
8167 __ movf(dst, src);
8168 break;
8169 case 0x04: //greater_equal
8170 __ c_olt_s(reg_op1, reg_op2);
8171 __ movf(dst, src);
8172 break;
8173 case 0x05: //less
8174 __ c_ult_s(reg_op1, reg_op2);
8175 __ movt(dst, src);
8176 break;
8177 case 0x06: //less_equal
8178 __ c_ule_s(reg_op1, reg_op2);
8179 __ movt(dst, src);
8180 break;
8181 default:
8182 Unimplemented();
8183 }
8184 %}
8185 ins_pipe( pipe_slow );
8186 %}
8188 instruct cmovP_cmpN_reg_reg(mRegP dst, mRegP src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
8189 match(Set dst (CMoveP (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
8190 ins_cost(80);
8191 format %{
8192 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpN_reg_reg\n\t"
8193 "CMOV $dst,$src\t @cmovP_cmpN_reg_reg"
8194 %}
8195 ins_encode %{
8196 Register op1 = $tmp1$$Register;
8197 Register op2 = $tmp2$$Register;
8198 Register dst = $dst$$Register;
8199 Register src = $src$$Register;
8200 int flag = $cop$$cmpcode;
8202 switch(flag) {
8203 case 0x01: //equal
8204 __ subu32(AT, op1, op2);
8205 __ movz(dst, src, AT);
8206 break;
8208 case 0x02: //not_equal
8209 __ subu32(AT, op1, op2);
8210 __ movn(dst, src, AT);
8211 break;
8213 case 0x03: //above
8214 __ sltu(AT, op2, op1);
8215 __ movn(dst, src, AT);
8216 break;
8218 case 0x04: //above_equal
8219 __ sltu(AT, op1, op2);
8220 __ movz(dst, src, AT);
8221 break;
8223 case 0x05: //below
8224 __ sltu(AT, op1, op2);
8225 __ movn(dst, src, AT);
8226 break;
8228 case 0x06: //below_equal
8229 __ sltu(AT, op2, op1);
8230 __ movz(dst, src, AT);
8231 break;
8233 default:
8234 Unimplemented();
8235 }
8236 %}
8238 ins_pipe( pipe_slow );
8239 %}
8241 instruct cmovN_cmpP_reg_reg(mRegN dst, mRegN src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
8242 match(Set dst (CMoveN (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
8243 ins_cost(80);
8244 format %{
8245 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpP_reg_reg\n\t"
8246 "CMOV $dst,$src\t @cmovN_cmpP_reg_reg"
8247 %}
8248 ins_encode %{
8249 Register op1 = $tmp1$$Register;
8250 Register op2 = $tmp2$$Register;
8251 Register dst = $dst$$Register;
8252 Register src = $src$$Register;
8253 int flag = $cop$$cmpcode;
8255 switch(flag) {
8256 case 0x01: //equal
8257 __ subu(AT, op1, op2);
8258 __ movz(dst, src, AT);
8259 break;
8261 case 0x02: //not_equal
8262 __ subu(AT, op1, op2);
8263 __ movn(dst, src, AT);
8264 break;
8266 case 0x03: //above
8267 __ sltu(AT, op2, op1);
8268 __ movn(dst, src, AT);
8269 break;
8271 case 0x04: //above_equal
8272 __ sltu(AT, op1, op2);
8273 __ movz(dst, src, AT);
8274 break;
8276 case 0x05: //below
8277 __ sltu(AT, op1, op2);
8278 __ movn(dst, src, AT);
8279 break;
8281 case 0x06: //below_equal
8282 __ sltu(AT, op2, op1);
8283 __ movz(dst, src, AT);
8284 break;
8286 default:
8287 Unimplemented();
8288 }
8289 %}
8291 ins_pipe( pipe_slow );
8292 %}
8294 instruct cmovP_cmpD_reg_reg(mRegP dst, mRegP src, regD tmp1, regD tmp2, cmpOp cop ) %{
8295 match(Set dst (CMoveP (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
8296 ins_cost(80);
8297 format %{
8298 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpD_reg_reg\n"
8299 "\tCMOV $dst,$src \t @cmovP_cmpD_reg_reg"
8300 %}
8301 ins_encode %{
8302 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
8303 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
8304 Register dst = as_Register($dst$$reg);
8305 Register src = as_Register($src$$reg);
8307 int flag = $cop$$cmpcode;
8309 switch(flag) {
8310 case 0x01: //equal
8311 __ c_eq_d(reg_op1, reg_op2);
8312 __ movt(dst, src);
8313 break;
8314 case 0x02: //not_equal
8315 __ c_eq_d(reg_op1, reg_op2);
8316 __ movf(dst, src);
8317 break;
8318 case 0x03: //greater
8319 __ c_ole_d(reg_op1, reg_op2);
8320 __ movf(dst, src);
8321 break;
8322 case 0x04: //greater_equal
8323 __ c_olt_d(reg_op1, reg_op2);
8324 __ movf(dst, src);
8325 break;
8326 case 0x05: //less
8327 __ c_ult_d(reg_op1, reg_op2);
8328 __ movt(dst, src);
8329 break;
8330 case 0x06: //less_equal
8331 __ c_ule_d(reg_op1, reg_op2);
8332 __ movt(dst, src);
8333 break;
8334 default:
8335 Unimplemented();
8336 }
8337 %}
8339 ins_pipe( pipe_slow );
8340 %}
8343 instruct cmovN_cmpN_reg_reg(mRegN dst, mRegN src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
8344 match(Set dst (CMoveN (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
8345 ins_cost(80);
8346 format %{
8347 "CMPU$cop $tmp1,$tmp2\t @cmovN_cmpN_reg_reg\n\t"
8348 "CMOV $dst,$src\t @cmovN_cmpN_reg_reg"
8349 %}
8350 ins_encode %{
8351 Register op1 = $tmp1$$Register;
8352 Register op2 = $tmp2$$Register;
8353 Register dst = $dst$$Register;
8354 Register src = $src$$Register;
8355 int flag = $cop$$cmpcode;
8357 switch(flag) {
8358 case 0x01: //equal
8359 __ subu32(AT, op1, op2);
8360 __ movz(dst, src, AT);
8361 break;
8363 case 0x02: //not_equal
8364 __ subu32(AT, op1, op2);
8365 __ movn(dst, src, AT);
8366 break;
8368 case 0x03: //above
8369 __ sltu(AT, op2, op1);
8370 __ movn(dst, src, AT);
8371 break;
8373 case 0x04: //above_equal
8374 __ sltu(AT, op1, op2);
8375 __ movz(dst, src, AT);
8376 break;
8378 case 0x05: //below
8379 __ sltu(AT, op1, op2);
8380 __ movn(dst, src, AT);
8381 break;
8383 case 0x06: //below_equal
8384 __ sltu(AT, op2, op1);
8385 __ movz(dst, src, AT);
8386 break;
8388 default:
8389 Unimplemented();
8390 }
8391 %}
8393 ins_pipe( pipe_slow );
8394 %}
8397 instruct cmovI_cmpU_reg_reg(mRegI dst, mRegI src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
8398 match(Set dst (CMoveI (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
8399 ins_cost(80);
8400 format %{
8401 "CMPU$cop $tmp1,$tmp2\t @cmovI_cmpU_reg_reg\n\t"
8402 "CMOV $dst,$src\t @cmovI_cmpU_reg_reg"
8403 %}
8404 ins_encode %{
8405 Register op1 = $tmp1$$Register;
8406 Register op2 = $tmp2$$Register;
8407 Register dst = $dst$$Register;
8408 Register src = $src$$Register;
8409 int flag = $cop$$cmpcode;
8411 switch(flag) {
8412 case 0x01: //equal
8413 __ subu(AT, op1, op2);
8414 __ movz(dst, src, AT);
8415 break;
8417 case 0x02: //not_equal
8418 __ subu(AT, op1, op2);
8419 __ movn(dst, src, AT);
8420 break;
8422 case 0x03: //above
8423 __ sltu(AT, op2, op1);
8424 __ movn(dst, src, AT);
8425 break;
8427 case 0x04: //above_equal
8428 __ sltu(AT, op1, op2);
8429 __ movz(dst, src, AT);
8430 break;
8432 case 0x05: //below
8433 __ sltu(AT, op1, op2);
8434 __ movn(dst, src, AT);
8435 break;
8437 case 0x06: //below_equal
8438 __ sltu(AT, op2, op1);
8439 __ movz(dst, src, AT);
8440 break;
8442 default:
8443 Unimplemented();
8444 }
8445 %}
8447 ins_pipe( pipe_slow );
8448 %}
8450 instruct cmovI_cmpL_reg_reg(mRegI dst, mRegI src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
8451 match(Set dst (CMoveI (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
8452 ins_cost(80);
8453 format %{
8454 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpL_reg_reg\n"
8455 "\tCMOV $dst,$src \t @cmovI_cmpL_reg_reg"
8456 %}
8457 ins_encode %{
8458 Register opr1 = as_Register($tmp1$$reg);
8459 Register opr2 = as_Register($tmp2$$reg);
8460 Register dst = $dst$$Register;
8461 Register src = $src$$Register;
8462 int flag = $cop$$cmpcode;
8464 switch(flag) {
8465 case 0x01: //equal
8466 __ subu(AT, opr1, opr2);
8467 __ movz(dst, src, AT);
8468 break;
8470 case 0x02: //not_equal
8471 __ subu(AT, opr1, opr2);
8472 __ movn(dst, src, AT);
8473 break;
8475 case 0x03: //greater
8476 __ slt(AT, opr2, opr1);
8477 __ movn(dst, src, AT);
8478 break;
8480 case 0x04: //greater_equal
8481 __ slt(AT, opr1, opr2);
8482 __ movz(dst, src, AT);
8483 break;
8485 case 0x05: //less
8486 __ slt(AT, opr1, opr2);
8487 __ movn(dst, src, AT);
8488 break;
8490 case 0x06: //less_equal
8491 __ slt(AT, opr2, opr1);
8492 __ movz(dst, src, AT);
8493 break;
8495 default:
8496 Unimplemented();
8497 }
8498 %}
8500 ins_pipe( pipe_slow );
8501 %}
8503 instruct cmovP_cmpL_reg_reg(mRegP dst, mRegP src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
8504 match(Set dst (CMoveP (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
8505 ins_cost(80);
8506 format %{
8507 "CMP$cop $tmp1, $tmp2\t @cmovP_cmpL_reg_reg\n"
8508 "\tCMOV $dst,$src \t @cmovP_cmpL_reg_reg"
8509 %}
8510 ins_encode %{
8511 Register opr1 = as_Register($tmp1$$reg);
8512 Register opr2 = as_Register($tmp2$$reg);
8513 Register dst = $dst$$Register;
8514 Register src = $src$$Register;
8515 int flag = $cop$$cmpcode;
8517 switch(flag) {
8518 case 0x01: //equal
8519 __ subu(AT, opr1, opr2);
8520 __ movz(dst, src, AT);
8521 break;
8523 case 0x02: //not_equal
8524 __ subu(AT, opr1, opr2);
8525 __ movn(dst, src, AT);
8526 break;
8528 case 0x03: //greater
8529 __ slt(AT, opr2, opr1);
8530 __ movn(dst, src, AT);
8531 break;
8533 case 0x04: //greater_equal
8534 __ slt(AT, opr1, opr2);
8535 __ movz(dst, src, AT);
8536 break;
8538 case 0x05: //less
8539 __ slt(AT, opr1, opr2);
8540 __ movn(dst, src, AT);
8541 break;
8543 case 0x06: //less_equal
8544 __ slt(AT, opr2, opr1);
8545 __ movz(dst, src, AT);
8546 break;
8548 default:
8549 Unimplemented();
8550 }
8551 %}
8553 ins_pipe( pipe_slow );
8554 %}
8556 instruct cmovI_cmpD_reg_reg(mRegI dst, mRegI src, regD tmp1, regD tmp2, cmpOp cop ) %{
8557 match(Set dst (CMoveI (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
8558 ins_cost(80);
8559 format %{
8560 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpD_reg_reg\n"
8561 "\tCMOV $dst,$src \t @cmovI_cmpD_reg_reg"
8562 %}
8563 ins_encode %{
8564 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
8565 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
8566 Register dst = as_Register($dst$$reg);
8567 Register src = as_Register($src$$reg);
8569 int flag = $cop$$cmpcode;
8571 switch(flag) {
8572 case 0x01: //equal
8573 __ c_eq_d(reg_op1, reg_op2);
8574 __ movt(dst, src);
8575 break;
8576 case 0x02: //not_equal
8577 //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.
8578 __ c_eq_d(reg_op1, reg_op2);
8579 __ movf(dst, src);
8580 break;
8581 case 0x03: //greater
8582 __ c_ole_d(reg_op1, reg_op2);
8583 __ movf(dst, src);
8584 break;
8585 case 0x04: //greater_equal
8586 __ c_olt_d(reg_op1, reg_op2);
8587 __ movf(dst, src);
8588 break;
8589 case 0x05: //less
8590 __ c_ult_d(reg_op1, reg_op2);
8591 __ movt(dst, src);
8592 break;
8593 case 0x06: //less_equal
8594 __ c_ule_d(reg_op1, reg_op2);
8595 __ movt(dst, src);
8596 break;
8597 default:
8598 Unimplemented();
8599 }
8600 %}
8602 ins_pipe( pipe_slow );
8603 %}
8606 instruct cmovP_cmpP_reg_reg(mRegP dst, mRegP src, mRegP tmp1, mRegP tmp2, cmpOpU cop ) %{
8607 match(Set dst (CMoveP (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
8608 ins_cost(80);
8609 format %{
8610 "CMPU$cop $tmp1,$tmp2\t @cmovP_cmpP_reg_reg\n\t"
8611 "CMOV $dst,$src\t @cmovP_cmpP_reg_reg"
8612 %}
8613 ins_encode %{
8614 Register op1 = $tmp1$$Register;
8615 Register op2 = $tmp2$$Register;
8616 Register dst = $dst$$Register;
8617 Register src = $src$$Register;
8618 int flag = $cop$$cmpcode;
8620 switch(flag) {
8621 case 0x01: //equal
8622 __ subu(AT, op1, op2);
8623 __ movz(dst, src, AT);
8624 break;
8626 case 0x02: //not_equal
8627 __ subu(AT, op1, op2);
8628 __ movn(dst, src, AT);
8629 break;
8631 case 0x03: //above
8632 __ sltu(AT, op2, op1);
8633 __ movn(dst, src, AT);
8634 break;
8636 case 0x04: //above_equal
8637 __ sltu(AT, op1, op2);
8638 __ movz(dst, src, AT);
8639 break;
8641 case 0x05: //below
8642 __ sltu(AT, op1, op2);
8643 __ movn(dst, src, AT);
8644 break;
8646 case 0x06: //below_equal
8647 __ sltu(AT, op2, op1);
8648 __ movz(dst, src, AT);
8649 break;
8651 default:
8652 Unimplemented();
8653 }
8654 %}
8656 ins_pipe( pipe_slow );
8657 %}
8659 instruct cmovP_cmpI_reg_reg(mRegP dst, mRegP src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
8660 match(Set dst (CMoveP (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
8661 ins_cost(80);
8662 format %{
8663 "CMP$cop $tmp1,$tmp2\t @cmovP_cmpI_reg_reg\n\t"
8664 "CMOV $dst,$src\t @cmovP_cmpI_reg_reg"
8665 %}
8666 ins_encode %{
8667 Register op1 = $tmp1$$Register;
8668 Register op2 = $tmp2$$Register;
8669 Register dst = $dst$$Register;
8670 Register src = $src$$Register;
8671 int flag = $cop$$cmpcode;
8673 switch(flag) {
8674 case 0x01: //equal
8675 __ subu32(AT, op1, op2);
8676 __ movz(dst, src, AT);
8677 break;
8679 case 0x02: //not_equal
8680 __ subu32(AT, op1, op2);
8681 __ movn(dst, src, AT);
8682 break;
8684 case 0x03: //above
8685 __ slt(AT, op2, op1);
8686 __ movn(dst, src, AT);
8687 break;
8689 case 0x04: //above_equal
8690 __ slt(AT, op1, op2);
8691 __ movz(dst, src, AT);
8692 break;
8694 case 0x05: //below
8695 __ slt(AT, op1, op2);
8696 __ movn(dst, src, AT);
8697 break;
8699 case 0x06: //below_equal
8700 __ slt(AT, op2, op1);
8701 __ movz(dst, src, AT);
8702 break;
8704 default:
8705 Unimplemented();
8706 }
8707 %}
8709 ins_pipe( pipe_slow );
8710 %}
8712 instruct cmovN_cmpL_reg_reg(mRegN dst, mRegN src, mRegL tmp1, mRegL tmp2, cmpOp cop) %{
8713 match(Set dst (CMoveN (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
8714 ins_cost(80);
8715 format %{
8716 "CMP$cop $tmp1, $tmp2\t @cmovN_cmpL_reg_reg\n"
8717 "\tCMOV $dst,$src \t @cmovN_cmpL_reg_reg"
8718 %}
8719 ins_encode %{
8720 Register opr1 = as_Register($tmp1$$reg);
8721 Register opr2 = as_Register($tmp2$$reg);
8722 Register dst = $dst$$Register;
8723 Register src = $src$$Register;
8724 int flag = $cop$$cmpcode;
8726 switch(flag) {
8727 case 0x01: //equal
8728 __ subu(AT, opr1, opr2);
8729 __ movz(dst, src, AT);
8730 break;
8732 case 0x02: //not_equal
8733 __ subu(AT, opr1, opr2);
8734 __ movn(dst, src, AT);
8735 break;
8737 case 0x03: //greater
8738 __ slt(AT, opr2, opr1);
8739 __ movn(dst, src, AT);
8740 break;
8742 case 0x04: //greater_equal
8743 __ slt(AT, opr1, opr2);
8744 __ movz(dst, src, AT);
8745 break;
8747 case 0x05: //less
8748 __ slt(AT, opr1, opr2);
8749 __ movn(dst, src, AT);
8750 break;
8752 case 0x06: //less_equal
8753 __ slt(AT, opr2, opr1);
8754 __ movz(dst, src, AT);
8755 break;
8757 default:
8758 Unimplemented();
8759 }
8760 %}
8762 ins_pipe( pipe_slow );
8763 %}
8765 instruct cmovN_cmpI_reg_reg(mRegN dst, mRegN src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
8766 match(Set dst (CMoveN (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
8767 ins_cost(80);
8768 format %{
8769 "CMP$cop $tmp1,$tmp2\t @cmovN_cmpI_reg_reg\n\t"
8770 "CMOV $dst,$src\t @cmovN_cmpI_reg_reg"
8771 %}
8772 ins_encode %{
8773 Register op1 = $tmp1$$Register;
8774 Register op2 = $tmp2$$Register;
8775 Register dst = $dst$$Register;
8776 Register src = $src$$Register;
8777 int flag = $cop$$cmpcode;
8779 switch(flag) {
8780 case 0x01: //equal
8781 __ subu32(AT, op1, op2);
8782 __ movz(dst, src, AT);
8783 break;
8785 case 0x02: //not_equal
8786 __ subu32(AT, op1, op2);
8787 __ movn(dst, src, AT);
8788 break;
8790 case 0x03: //above
8791 __ slt(AT, op2, op1);
8792 __ movn(dst, src, AT);
8793 break;
8795 case 0x04: //above_equal
8796 __ slt(AT, op1, op2);
8797 __ movz(dst, src, AT);
8798 break;
8800 case 0x05: //below
8801 __ slt(AT, op1, op2);
8802 __ movn(dst, src, AT);
8803 break;
8805 case 0x06: //below_equal
8806 __ slt(AT, op2, op1);
8807 __ movz(dst, src, AT);
8808 break;
8810 default:
8811 Unimplemented();
8812 }
8813 %}
8815 ins_pipe( pipe_slow );
8816 %}
8818 instruct cmovL_cmpU_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOpU cop ) %{
8819 match(Set dst (CMoveL (Binary cop (CmpU tmp1 tmp2)) (Binary dst src)));
8820 ins_cost(80);
8821 format %{
8822 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpU_reg_reg\n\t"
8823 "CMOV $dst,$src\t @cmovL_cmpU_reg_reg"
8824 %}
8825 ins_encode %{
8826 Register op1 = $tmp1$$Register;
8827 Register op2 = $tmp2$$Register;
8828 Register dst = $dst$$Register;
8829 Register src = $src$$Register;
8830 int flag = $cop$$cmpcode;
8832 switch(flag) {
8833 case 0x01: //equal
8834 __ subu32(AT, op1, op2);
8835 __ movz(dst, src, AT);
8836 break;
8838 case 0x02: //not_equal
8839 __ subu32(AT, op1, op2);
8840 __ movn(dst, src, AT);
8841 break;
8843 case 0x03: //above
8844 __ sltu(AT, op2, op1);
8845 __ movn(dst, src, AT);
8846 break;
8848 case 0x04: //above_equal
8849 __ sltu(AT, op1, op2);
8850 __ movz(dst, src, AT);
8851 break;
8853 case 0x05: //below
8854 __ sltu(AT, op1, op2);
8855 __ movn(dst, src, AT);
8856 break;
8858 case 0x06: //below_equal
8859 __ sltu(AT, op2, op1);
8860 __ movz(dst, src, AT);
8861 break;
8863 default:
8864 Unimplemented();
8865 }
8866 %}
8868 ins_pipe( pipe_slow );
8869 %}
8871 instruct cmovL_cmpF_reg_reg(mRegL dst, mRegL src, regF tmp1, regF tmp2, cmpOp cop ) %{
8872 match(Set dst (CMoveL (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
8873 ins_cost(80);
8874 format %{
8875 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpF_reg_reg\n"
8876 "\tCMOV $dst,$src \t @cmovL_cmpF_reg_reg"
8877 %}
8879 ins_encode %{
8880 FloatRegister reg_op1 = $tmp1$$FloatRegister;
8881 FloatRegister reg_op2 = $tmp2$$FloatRegister;
8882 Register dst = $dst$$Register;
8883 Register src = $src$$Register;
8884 int flag = $cop$$cmpcode;
8886 switch(flag) {
8887 case 0x01: //equal
8888 __ c_eq_s(reg_op1, reg_op2);
8889 __ movt(dst, src);
8890 break;
8891 case 0x02: //not_equal
8892 __ c_eq_s(reg_op1, reg_op2);
8893 __ movf(dst, src);
8894 break;
8895 case 0x03: //greater
8896 __ c_ole_s(reg_op1, reg_op2);
8897 __ movf(dst, src);
8898 break;
8899 case 0x04: //greater_equal
8900 __ c_olt_s(reg_op1, reg_op2);
8901 __ movf(dst, src);
8902 break;
8903 case 0x05: //less
8904 __ c_ult_s(reg_op1, reg_op2);
8905 __ movt(dst, src);
8906 break;
8907 case 0x06: //less_equal
8908 __ c_ule_s(reg_op1, reg_op2);
8909 __ movt(dst, src);
8910 break;
8911 default:
8912 Unimplemented();
8913 }
8914 %}
8915 ins_pipe( pipe_slow );
8916 %}
8918 instruct cmovL_cmpI_reg_reg(mRegL dst, mRegL src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
8919 match(Set dst (CMoveL (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
8920 ins_cost(80);
8921 format %{
8922 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpI_reg_reg\n"
8923 "\tCMOV $dst,$src \t @cmovL_cmpI_reg_reg"
8924 %}
8926 ins_encode %{
8927 Register op1 = $tmp1$$Register;
8928 Register op2 = $tmp2$$Register;
8929 Register dst = as_Register($dst$$reg);
8930 Register src = as_Register($src$$reg);
8931 int flag = $cop$$cmpcode;
8933 switch(flag)
8934 {
8935 case 0x01: //equal
8936 __ subu32(AT, op1, op2);
8937 __ movz(dst, src, AT);
8938 break;
8940 case 0x02: //not_equal
8941 __ subu32(AT, op1, op2);
8942 __ movn(dst, src, AT);
8943 break;
8945 case 0x03: //great
8946 __ slt(AT, op2, op1);
8947 __ movn(dst, src, AT);
8948 break;
8950 case 0x04: //great_equal
8951 __ slt(AT, op1, op2);
8952 __ movz(dst, src, AT);
8953 break;
8955 case 0x05: //less
8956 __ slt(AT, op1, op2);
8957 __ movn(dst, src, AT);
8958 break;
8960 case 0x06: //less_equal
8961 __ slt(AT, op2, op1);
8962 __ movz(dst, src, AT);
8963 break;
8965 default:
8966 Unimplemented();
8967 }
8968 %}
8970 ins_pipe( pipe_slow );
8971 %}
8973 instruct cmovL_cmpL_reg_reg(mRegL dst, mRegL src, mRegL tmp1, mRegL tmp2, cmpOp cop ) %{
8974 match(Set dst (CMoveL (Binary cop (CmpL tmp1 tmp2)) (Binary dst src)));
8975 ins_cost(80);
8976 format %{
8977 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpL_reg_reg\n"
8978 "\tCMOV $dst,$src \t @cmovL_cmpL_reg_reg"
8979 %}
8980 ins_encode %{
8981 Register opr1 = as_Register($tmp1$$reg);
8982 Register opr2 = as_Register($tmp2$$reg);
8983 Register dst = as_Register($dst$$reg);
8984 Register src = as_Register($src$$reg);
8985 int flag = $cop$$cmpcode;
8987 switch(flag) {
8988 case 0x01: //equal
8989 __ subu(AT, opr1, opr2);
8990 __ movz(dst, src, AT);
8991 break;
8993 case 0x02: //not_equal
8994 __ subu(AT, opr1, opr2);
8995 __ movn(dst, src, AT);
8996 break;
8998 case 0x03: //greater
8999 __ slt(AT, opr2, opr1);
9000 __ movn(dst, src, AT);
9001 break;
9003 case 0x04: //greater_equal
9004 __ slt(AT, opr1, opr2);
9005 __ movz(dst, src, AT);
9006 break;
9008 case 0x05: //less
9009 __ slt(AT, opr1, opr2);
9010 __ movn(dst, src, AT);
9011 break;
9013 case 0x06: //less_equal
9014 __ slt(AT, opr2, opr1);
9015 __ movz(dst, src, AT);
9016 break;
9018 default:
9019 Unimplemented();
9020 }
9021 %}
9023 ins_pipe( pipe_slow );
9024 %}
9026 instruct cmovL_cmpN_reg_reg(mRegL dst, mRegL src, mRegN tmp1, mRegN tmp2, cmpOpU cop ) %{
9027 match(Set dst (CMoveL (Binary cop (CmpN tmp1 tmp2)) (Binary dst src)));
9028 ins_cost(80);
9029 format %{
9030 "CMPU$cop $tmp1,$tmp2\t @cmovL_cmpN_reg_reg\n\t"
9031 "CMOV $dst,$src\t @cmovL_cmpN_reg_reg"
9032 %}
9033 ins_encode %{
9034 Register op1 = $tmp1$$Register;
9035 Register op2 = $tmp2$$Register;
9036 Register dst = $dst$$Register;
9037 Register src = $src$$Register;
9038 int flag = $cop$$cmpcode;
9040 switch(flag) {
9041 case 0x01: //equal
9042 __ subu32(AT, op1, op2);
9043 __ movz(dst, src, AT);
9044 break;
9046 case 0x02: //not_equal
9047 __ subu32(AT, op1, op2);
9048 __ movn(dst, src, AT);
9049 break;
9051 case 0x03: //above
9052 __ sltu(AT, op2, op1);
9053 __ movn(dst, src, AT);
9054 break;
9056 case 0x04: //above_equal
9057 __ sltu(AT, op1, op2);
9058 __ movz(dst, src, AT);
9059 break;
9061 case 0x05: //below
9062 __ sltu(AT, op1, op2);
9063 __ movn(dst, src, AT);
9064 break;
9066 case 0x06: //below_equal
9067 __ sltu(AT, op2, op1);
9068 __ movz(dst, src, AT);
9069 break;
9071 default:
9072 Unimplemented();
9073 }
9074 %}
9076 ins_pipe( pipe_slow );
9077 %}
9080 instruct cmovL_cmpD_reg_reg(mRegL dst, mRegL src, regD tmp1, regD tmp2, cmpOp cop ) %{
9081 match(Set dst (CMoveL (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
9082 ins_cost(80);
9083 format %{
9084 "CMP$cop $tmp1, $tmp2\t @cmovL_cmpD_reg_reg\n"
9085 "\tCMOV $dst,$src \t @cmovL_cmpD_reg_reg"
9086 %}
9087 ins_encode %{
9088 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
9089 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
9090 Register dst = as_Register($dst$$reg);
9091 Register src = as_Register($src$$reg);
9093 int flag = $cop$$cmpcode;
9095 switch(flag) {
9096 case 0x01: //equal
9097 __ c_eq_d(reg_op1, reg_op2);
9098 __ movt(dst, src);
9099 break;
9100 case 0x02: //not_equal
9101 __ c_eq_d(reg_op1, reg_op2);
9102 __ movf(dst, src);
9103 break;
9104 case 0x03: //greater
9105 __ c_ole_d(reg_op1, reg_op2);
9106 __ movf(dst, src);
9107 break;
9108 case 0x04: //greater_equal
9109 __ c_olt_d(reg_op1, reg_op2);
9110 __ movf(dst, src);
9111 break;
9112 case 0x05: //less
9113 __ c_ult_d(reg_op1, reg_op2);
9114 __ movt(dst, src);
9115 break;
9116 case 0x06: //less_equal
9117 __ c_ule_d(reg_op1, reg_op2);
9118 __ movt(dst, src);
9119 break;
9120 default:
9121 Unimplemented();
9122 }
9123 %}
9125 ins_pipe( pipe_slow );
9126 %}
9128 instruct cmovD_cmpD_reg_reg(regD dst, regD src, regD tmp1, regD tmp2, cmpOp cop ) %{
9129 match(Set dst (CMoveD (Binary cop (CmpD tmp1 tmp2)) (Binary dst src)));
9130 ins_cost(200);
9131 format %{
9132 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpD_reg_reg\n"
9133 "\tCMOV $dst,$src \t @cmovD_cmpD_reg_reg"
9134 %}
9135 ins_encode %{
9136 FloatRegister reg_op1 = as_FloatRegister($tmp1$$reg);
9137 FloatRegister reg_op2 = as_FloatRegister($tmp2$$reg);
9138 FloatRegister dst = as_FloatRegister($dst$$reg);
9139 FloatRegister src = as_FloatRegister($src$$reg);
9141 int flag = $cop$$cmpcode;
9143 switch(flag) {
9144 case 0x01: //equal
9145 __ c_eq_d(reg_op1, reg_op2);
9146 __ movt_d(dst, src);
9147 break;
9148 case 0x02: //not_equal
9149 __ c_eq_d(reg_op1, reg_op2);
9150 __ movf_d(dst, src);
9151 break;
9152 case 0x03: //greater
9153 __ c_ole_d(reg_op1, reg_op2);
9154 __ movf_d(dst, src);
9155 break;
9156 case 0x04: //greater_equal
9157 __ c_olt_d(reg_op1, reg_op2);
9158 __ movf_d(dst, src);
9159 break;
9160 case 0x05: //less
9161 __ c_ult_d(reg_op1, reg_op2);
9162 __ movt_d(dst, src);
9163 break;
9164 case 0x06: //less_equal
9165 __ c_ule_d(reg_op1, reg_op2);
9166 __ movt_d(dst, src);
9167 break;
9168 default:
9169 Unimplemented();
9170 }
9171 %}
9173 ins_pipe( pipe_slow );
9174 %}
9176 instruct cmovF_cmpI_reg_reg(regF dst, regF src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9177 match(Set dst (CMoveF (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9178 ins_cost(200);
9179 format %{
9180 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpI_reg_reg\n"
9181 "\tCMOV $dst, $src \t @cmovF_cmpI_reg_reg"
9182 %}
9184 ins_encode %{
9185 Register op1 = $tmp1$$Register;
9186 Register op2 = $tmp2$$Register;
9187 FloatRegister dst = as_FloatRegister($dst$$reg);
9188 FloatRegister src = as_FloatRegister($src$$reg);
9189 int flag = $cop$$cmpcode;
9190 Label L;
9192 switch(flag) {
9193 case 0x01: //equal
9194 __ bne(op1, op2, L);
9195 __ nop();
9196 __ mov_s(dst, src);
9197 __ bind(L);
9198 break;
9199 case 0x02: //not_equal
9200 __ beq(op1, op2, L);
9201 __ nop();
9202 __ mov_s(dst, src);
9203 __ bind(L);
9204 break;
9205 case 0x03: //great
9206 __ slt(AT, op2, op1);
9207 __ beq(AT, R0, L);
9208 __ nop();
9209 __ mov_s(dst, src);
9210 __ bind(L);
9211 break;
9212 case 0x04: //great_equal
9213 __ slt(AT, op1, op2);
9214 __ bne(AT, R0, L);
9215 __ nop();
9216 __ mov_s(dst, src);
9217 __ bind(L);
9218 break;
9219 case 0x05: //less
9220 __ slt(AT, op1, op2);
9221 __ beq(AT, R0, L);
9222 __ nop();
9223 __ mov_s(dst, src);
9224 __ bind(L);
9225 break;
9226 case 0x06: //less_equal
9227 __ slt(AT, op2, op1);
9228 __ bne(AT, R0, L);
9229 __ nop();
9230 __ mov_s(dst, src);
9231 __ bind(L);
9232 break;
9233 default:
9234 Unimplemented();
9235 }
9236 %}
9238 ins_pipe( pipe_slow );
9239 %}
9241 instruct cmovD_cmpI_reg_reg(regD dst, regD src, mRegI tmp1, mRegI tmp2, cmpOp cop ) %{
9242 match(Set dst (CMoveD (Binary cop (CmpI tmp1 tmp2)) (Binary dst src)));
9243 ins_cost(200);
9244 format %{
9245 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpI_reg_reg\n"
9246 "\tCMOV $dst, $src \t @cmovD_cmpI_reg_reg"
9247 %}
9249 ins_encode %{
9250 Register op1 = $tmp1$$Register;
9251 Register op2 = $tmp2$$Register;
9252 FloatRegister dst = as_FloatRegister($dst$$reg);
9253 FloatRegister src = as_FloatRegister($src$$reg);
9254 int flag = $cop$$cmpcode;
9255 Label L;
9257 switch(flag) {
9258 case 0x01: //equal
9259 __ bne(op1, op2, L);
9260 __ nop();
9261 __ mov_d(dst, src);
9262 __ bind(L);
9263 break;
9264 case 0x02: //not_equal
9265 __ beq(op1, op2, L);
9266 __ nop();
9267 __ mov_d(dst, src);
9268 __ bind(L);
9269 break;
9270 case 0x03: //great
9271 __ slt(AT, op2, op1);
9272 __ beq(AT, R0, L);
9273 __ nop();
9274 __ mov_d(dst, src);
9275 __ bind(L);
9276 break;
9277 case 0x04: //great_equal
9278 __ slt(AT, op1, op2);
9279 __ bne(AT, R0, L);
9280 __ nop();
9281 __ mov_d(dst, src);
9282 __ bind(L);
9283 break;
9284 case 0x05: //less
9285 __ slt(AT, op1, op2);
9286 __ beq(AT, R0, L);
9287 __ nop();
9288 __ mov_d(dst, src);
9289 __ bind(L);
9290 break;
9291 case 0x06: //less_equal
9292 __ slt(AT, op2, op1);
9293 __ bne(AT, R0, L);
9294 __ nop();
9295 __ mov_d(dst, src);
9296 __ bind(L);
9297 break;
9298 default:
9299 Unimplemented();
9300 }
9301 %}
9303 ins_pipe( pipe_slow );
9304 %}
9306 instruct cmovD_cmpP_reg_reg(regD dst, regD src, mRegP tmp1, mRegP tmp2, cmpOp cop ) %{
9307 match(Set dst (CMoveD (Binary cop (CmpP tmp1 tmp2)) (Binary dst src)));
9308 ins_cost(200);
9309 format %{
9310 "CMP$cop $tmp1, $tmp2\t @cmovD_cmpP_reg_reg\n"
9311 "\tCMOV $dst, $src \t @cmovD_cmpP_reg_reg"
9312 %}
9314 ins_encode %{
9315 Register op1 = $tmp1$$Register;
9316 Register op2 = $tmp2$$Register;
9317 FloatRegister dst = as_FloatRegister($dst$$reg);
9318 FloatRegister src = as_FloatRegister($src$$reg);
9319 int flag = $cop$$cmpcode;
9320 Label L;
9322 switch(flag) {
9323 case 0x01: //equal
9324 __ bne(op1, op2, L);
9325 __ nop();
9326 __ mov_d(dst, src);
9327 __ bind(L);
9328 break;
9329 case 0x02: //not_equal
9330 __ beq(op1, op2, L);
9331 __ nop();
9332 __ mov_d(dst, src);
9333 __ bind(L);
9334 break;
9335 case 0x03: //great
9336 __ slt(AT, op2, op1);
9337 __ beq(AT, R0, L);
9338 __ nop();
9339 __ mov_d(dst, src);
9340 __ bind(L);
9341 break;
9342 case 0x04: //great_equal
9343 __ slt(AT, op1, op2);
9344 __ bne(AT, R0, L);
9345 __ nop();
9346 __ mov_d(dst, src);
9347 __ bind(L);
9348 break;
9349 case 0x05: //less
9350 __ slt(AT, op1, op2);
9351 __ beq(AT, R0, L);
9352 __ nop();
9353 __ mov_d(dst, src);
9354 __ bind(L);
9355 break;
9356 case 0x06: //less_equal
9357 __ slt(AT, op2, op1);
9358 __ bne(AT, R0, L);
9359 __ nop();
9360 __ mov_d(dst, src);
9361 __ bind(L);
9362 break;
9363 default:
9364 Unimplemented();
9365 }
9366 %}
9368 ins_pipe( pipe_slow );
9369 %}
9371 //FIXME
9372 instruct cmovI_cmpF_reg_reg(mRegI dst, mRegI src, regF tmp1, regF tmp2, cmpOp cop ) %{
9373 match(Set dst (CMoveI (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
9374 ins_cost(80);
9375 format %{
9376 "CMP$cop $tmp1, $tmp2\t @cmovI_cmpF_reg_reg\n"
9377 "\tCMOV $dst,$src \t @cmovI_cmpF_reg_reg"
9378 %}
9380 ins_encode %{
9381 FloatRegister reg_op1 = $tmp1$$FloatRegister;
9382 FloatRegister reg_op2 = $tmp2$$FloatRegister;
9383 Register dst = $dst$$Register;
9384 Register src = $src$$Register;
9385 int flag = $cop$$cmpcode;
9387 switch(flag) {
9388 case 0x01: //equal
9389 __ c_eq_s(reg_op1, reg_op2);
9390 __ movt(dst, src);
9391 break;
9392 case 0x02: //not_equal
9393 __ c_eq_s(reg_op1, reg_op2);
9394 __ movf(dst, src);
9395 break;
9396 case 0x03: //greater
9397 __ c_ole_s(reg_op1, reg_op2);
9398 __ movf(dst, src);
9399 break;
9400 case 0x04: //greater_equal
9401 __ c_olt_s(reg_op1, reg_op2);
9402 __ movf(dst, src);
9403 break;
9404 case 0x05: //less
9405 __ c_ult_s(reg_op1, reg_op2);
9406 __ movt(dst, src);
9407 break;
9408 case 0x06: //less_equal
9409 __ c_ule_s(reg_op1, reg_op2);
9410 __ movt(dst, src);
9411 break;
9412 default:
9413 Unimplemented();
9414 }
9415 %}
9416 ins_pipe( pipe_slow );
9417 %}
9419 instruct cmovF_cmpF_reg_reg(regF dst, regF src, regF tmp1, regF tmp2, cmpOp cop ) %{
9420 match(Set dst (CMoveF (Binary cop (CmpF tmp1 tmp2)) (Binary dst src)));
9421 ins_cost(200);
9422 format %{
9423 "CMP$cop $tmp1, $tmp2\t @cmovF_cmpF_reg_reg\n"
9424 "\tCMOV $dst,$src \t @cmovF_cmpF_reg_reg"
9425 %}
9427 ins_encode %{
9428 FloatRegister reg_op1 = $tmp1$$FloatRegister;
9429 FloatRegister reg_op2 = $tmp2$$FloatRegister;
9430 FloatRegister dst = $dst$$FloatRegister;
9431 FloatRegister src = $src$$FloatRegister;
9432 int flag = $cop$$cmpcode;
9434 switch(flag) {
9435 case 0x01: //equal
9436 __ c_eq_s(reg_op1, reg_op2);
9437 __ movt_s(dst, src);
9438 break;
9439 case 0x02: //not_equal
9440 __ c_eq_s(reg_op1, reg_op2);
9441 __ movf_s(dst, src);
9442 break;
9443 case 0x03: //greater
9444 __ c_ole_s(reg_op1, reg_op2);
9445 __ movf_s(dst, src);
9446 break;
9447 case 0x04: //greater_equal
9448 __ c_olt_s(reg_op1, reg_op2);
9449 __ movf_s(dst, src);
9450 break;
9451 case 0x05: //less
9452 __ c_ult_s(reg_op1, reg_op2);
9453 __ movt_s(dst, src);
9454 break;
9455 case 0x06: //less_equal
9456 __ c_ule_s(reg_op1, reg_op2);
9457 __ movt_s(dst, src);
9458 break;
9459 default:
9460 Unimplemented();
9461 }
9462 %}
9463 ins_pipe( pipe_slow );
9464 %}
9466 // Manifest a CmpL result in an integer register. Very painful.
9467 // This is the test to avoid.
9468 instruct cmpL3_reg_reg(mRegI dst, mRegL src1, mRegL src2) %{
9469 match(Set dst (CmpL3 src1 src2));
9470 ins_cost(1000);
9471 format %{ "cmpL3 $dst, $src1, $src2 @ cmpL3_reg_reg" %}
9472 ins_encode %{
9473 Register opr1 = as_Register($src1$$reg);
9474 Register opr2 = as_Register($src2$$reg);
9475 Register dst = as_Register($dst$$reg);
9477 Label Done;
9479 __ subu(AT, opr1, opr2);
9480 __ bltz(AT, Done);
9481 __ delayed()->daddiu(dst, R0, -1);
9483 __ move(dst, 1);
9484 __ movz(dst, R0, AT);
9486 __ bind(Done);
9487 %}
9488 ins_pipe( pipe_slow );
9489 %}
9491 //
9492 // less_rsult = -1
9493 // greater_result = 1
9494 // equal_result = 0
9495 // nan_result = -1
9496 //
9497 instruct cmpF3_reg_reg(mRegI dst, regF src1, regF src2) %{
9498 match(Set dst (CmpF3 src1 src2));
9499 ins_cost(1000);
9500 format %{ "cmpF3 $dst, $src1, $src2 @ cmpF3_reg_reg" %}
9501 ins_encode %{
9502 FloatRegister src1 = as_FloatRegister($src1$$reg);
9503 FloatRegister src2 = as_FloatRegister($src2$$reg);
9504 Register dst = as_Register($dst$$reg);
9506 Label Done;
9508 __ c_ult_s(src1, src2);
9509 __ bc1t(Done);
9510 __ delayed()->daddiu(dst, R0, -1);
9512 __ c_eq_s(src1, src2);
9513 __ move(dst, 1);
9514 __ movt(dst, R0);
9516 __ bind(Done);
9517 %}
9518 ins_pipe( pipe_slow );
9519 %}
9521 instruct cmpD3_reg_reg(mRegI dst, regD src1, regD src2) %{
9522 match(Set dst (CmpD3 src1 src2));
9523 ins_cost(1000);
9524 format %{ "cmpD3 $dst, $src1, $src2 @ cmpD3_reg_reg" %}
9525 ins_encode %{
9526 FloatRegister src1 = as_FloatRegister($src1$$reg);
9527 FloatRegister src2 = as_FloatRegister($src2$$reg);
9528 Register dst = as_Register($dst$$reg);
9530 Label Done;
9532 __ c_ult_d(src1, src2);
9533 __ bc1t(Done);
9534 __ delayed()->daddiu(dst, R0, -1);
9536 __ c_eq_d(src1, src2);
9537 __ move(dst, 1);
9538 __ movt(dst, R0);
9540 __ bind(Done);
9541 %}
9542 ins_pipe( pipe_slow );
9543 %}
9545 instruct clear_array(mRegL cnt, mRegP base, Universe dummy) %{
9546 match(Set dummy (ClearArray cnt base));
9547 format %{ "CLEAR_ARRAY base = $base, cnt = $cnt # Clear doublewords" %}
9548 ins_encode %{
9549 //Assume cnt is the number of bytes in an array to be cleared,
9550 //and base points to the starting address of the array.
9551 Register base = $base$$Register;
9552 Register num = $cnt$$Register;
9553 Label Loop, done;
9555 __ beq(num, R0, done);
9556 __ delayed()->daddu(AT, base, R0);
9558 __ move(T9, num); /* T9 = words */
9560 __ bind(Loop);
9561 __ sd(R0, AT, 0);
9562 __ daddi(T9, T9, -1);
9563 __ bne(T9, R0, Loop);
9564 __ delayed()->daddi(AT, AT, wordSize);
9566 __ bind(done);
9567 %}
9568 ins_pipe( pipe_slow );
9569 %}
9571 instruct string_compare(a4_RegP str1, mA5RegI cnt1, a6_RegP str2, mA7RegI cnt2, no_Ax_mRegI result) %{
9572 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
9573 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2);
9575 format %{ "String Compare $str1[len: $cnt1], $str2[len: $cnt2] -> $result @ string_compare" %}
9576 ins_encode %{
9577 // Get the first character position in both strings
9578 // [8] char array, [12] offset, [16] count
9579 Register str1 = $str1$$Register;
9580 Register str2 = $str2$$Register;
9581 Register cnt1 = $cnt1$$Register;
9582 Register cnt2 = $cnt2$$Register;
9583 Register result = $result$$Register;
9585 Label L, Loop, haveResult, done;
9587 // compute the and difference of lengths (in result)
9588 __ subu(result, cnt1, cnt2); // result holds the difference of two lengths
9590 // compute the shorter length (in cnt1)
9591 __ slt(AT, cnt2, cnt1);
9592 __ movn(cnt1, cnt2, AT);
9594 // Now the shorter length is in cnt1 and cnt2 can be used as a tmp register
9595 __ bind(Loop); // Loop begin
9596 __ beq(cnt1, R0, done);
9597 __ delayed()->lhu(AT, str1, 0);;
9599 // compare current character
9600 __ lhu(cnt2, str2, 0);
9601 __ bne(AT, cnt2, haveResult);
9602 __ delayed()->addi(str1, str1, 2);
9603 __ addi(str2, str2, 2);
9604 __ b(Loop);
9605 __ delayed()->addi(cnt1, cnt1, -1); // Loop end
9607 __ bind(haveResult);
9608 __ subu(result, AT, cnt2);
9610 __ bind(done);
9611 %}
9613 ins_pipe( pipe_slow );
9614 %}
9616 // intrinsic optimization
9617 instruct string_equals(a4_RegP str1, a5_RegP str2, mA6RegI cnt, mA7RegI temp, no_Ax_mRegI result) %{
9618 match(Set result (StrEquals (Binary str1 str2) cnt));
9619 effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL temp);
9621 format %{ "String Equal $str1, $str2, len:$cnt tmp:$temp -> $result @ string_equals" %}
9622 ins_encode %{
9623 // Get the first character position in both strings
9624 // [8] char array, [12] offset, [16] count
9625 Register str1 = $str1$$Register;
9626 Register str2 = $str2$$Register;
9627 Register cnt = $cnt$$Register;
9628 Register tmp = $temp$$Register;
9629 Register result = $result$$Register;
9631 Label Loop, done;
9634 __ beq(str1, str2, done); // same char[] ?
9635 __ daddiu(result, R0, 1);
9637 __ bind(Loop); // Loop begin
9638 __ beq(cnt, R0, done);
9639 __ daddiu(result, R0, 1); // count == 0
9641 // compare current character
9642 __ lhu(AT, str1, 0);;
9643 __ lhu(tmp, str2, 0);
9644 __ bne(AT, tmp, done);
9645 __ delayed()->daddi(result, R0, 0);
9646 __ addi(str1, str1, 2);
9647 __ addi(str2, str2, 2);
9648 __ b(Loop);
9649 __ delayed()->addi(cnt, cnt, -1); // Loop end
9651 __ bind(done);
9652 %}
9654 ins_pipe( pipe_slow );
9655 %}
9657 //----------Arithmetic Instructions-------------------------------------------
9658 //----------Addition Instructions---------------------------------------------
9659 instruct addI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9660 match(Set dst (AddI src1 src2));
9662 format %{ "add $dst, $src1, $src2 #@addI_Reg_Reg" %}
9663 ins_encode %{
9664 Register dst = $dst$$Register;
9665 Register src1 = $src1$$Register;
9666 Register src2 = $src2$$Register;
9667 __ addu32(dst, src1, src2);
9668 %}
9669 ins_pipe( ialu_regI_regI );
9670 %}
9672 instruct addI_Reg_imm(mRegI dst, mRegI src1, immI src2) %{
9673 match(Set dst (AddI src1 src2));
9675 format %{ "add $dst, $src1, $src2 #@addI_Reg_imm" %}
9676 ins_encode %{
9677 Register dst = $dst$$Register;
9678 Register src1 = $src1$$Register;
9679 int imm = $src2$$constant;
9681 if(Assembler::is_simm16(imm)) {
9682 __ addiu32(dst, src1, imm);
9683 } else {
9684 __ move(AT, imm);
9685 __ addu32(dst, src1, AT);
9686 }
9687 %}
9688 ins_pipe( ialu_regI_regI );
9689 %}
9691 instruct addP_reg_reg(mRegP dst, mRegP src1, mRegL src2) %{
9692 match(Set dst (AddP src1 src2));
9694 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg" %}
9696 ins_encode %{
9697 Register dst = $dst$$Register;
9698 Register src1 = $src1$$Register;
9699 Register src2 = $src2$$Register;
9700 __ daddu(dst, src1, src2);
9701 %}
9703 ins_pipe( ialu_regI_regI );
9704 %}
9706 instruct addP_reg_reg_convI2L(mRegP dst, mRegP src1, mRegI src2) %{
9707 match(Set dst (AddP src1 (ConvI2L src2)));
9709 format %{ "dadd $dst, $src1, $src2 #@addP_reg_reg_convI2L" %}
9711 ins_encode %{
9712 Register dst = $dst$$Register;
9713 Register src1 = $src1$$Register;
9714 Register src2 = $src2$$Register;
9715 __ daddu(dst, src1, src2);
9716 %}
9718 ins_pipe( ialu_regI_regI );
9719 %}
9721 instruct addP_reg_imm(mRegP dst, mRegP src1, immL src2) %{
9722 match(Set dst (AddP src1 src2));
9724 format %{ "daddi $dst, $src1, $src2 #@addP_reg_imm" %}
9725 ins_encode %{
9726 Register src1 = $src1$$Register;
9727 long src2 = $src2$$constant;
9728 Register dst = $dst$$Register;
9730 if(Assembler::is_simm16(src2)) {
9731 __ daddiu(dst, src1, src2);
9732 } else {
9733 __ set64(AT, src2);
9734 __ daddu(dst, src1, AT);
9735 }
9736 %}
9737 ins_pipe( ialu_regI_imm16 );
9738 %}
9740 // Add Long Register with Register
9741 instruct addL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
9742 match(Set dst (AddL src1 src2));
9743 ins_cost(200);
9744 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_Reg\t" %}
9746 ins_encode %{
9747 Register dst_reg = as_Register($dst$$reg);
9748 Register src1_reg = as_Register($src1$$reg);
9749 Register src2_reg = as_Register($src2$$reg);
9751 __ daddu(dst_reg, src1_reg, src2_reg);
9752 %}
9754 ins_pipe( ialu_regL_regL );
9755 %}
9757 instruct addL_Reg_imm(mRegL dst, mRegL src1, immL16 src2)
9758 %{
9759 match(Set dst (AddL src1 src2));
9761 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_imm " %}
9762 ins_encode %{
9763 Register dst_reg = as_Register($dst$$reg);
9764 Register src1_reg = as_Register($src1$$reg);
9765 int src2_imm = $src2$$constant;
9767 __ daddiu(dst_reg, src1_reg, src2_imm);
9768 %}
9770 ins_pipe( ialu_regL_regL );
9771 %}
9773 instruct addL_RegI2L_imm(mRegL dst, mRegI src1, immL16 src2)
9774 %{
9775 match(Set dst (AddL (ConvI2L src1) src2));
9777 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_imm " %}
9778 ins_encode %{
9779 Register dst_reg = as_Register($dst$$reg);
9780 Register src1_reg = as_Register($src1$$reg);
9781 int src2_imm = $src2$$constant;
9783 __ daddiu(dst_reg, src1_reg, src2_imm);
9784 %}
9786 ins_pipe( ialu_regL_regL );
9787 %}
9789 instruct addL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
9790 match(Set dst (AddL (ConvI2L src1) src2));
9791 ins_cost(200);
9792 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_Reg\t" %}
9794 ins_encode %{
9795 Register dst_reg = as_Register($dst$$reg);
9796 Register src1_reg = as_Register($src1$$reg);
9797 Register src2_reg = as_Register($src2$$reg);
9799 __ daddu(dst_reg, src1_reg, src2_reg);
9800 %}
9802 ins_pipe( ialu_regL_regL );
9803 %}
9805 instruct addL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
9806 match(Set dst (AddL (ConvI2L src1) (ConvI2L src2)));
9807 ins_cost(200);
9808 format %{ "ADD $dst, $src1, $src2 #@addL_RegI2L_RegI2L\t" %}
9810 ins_encode %{
9811 Register dst_reg = as_Register($dst$$reg);
9812 Register src1_reg = as_Register($src1$$reg);
9813 Register src2_reg = as_Register($src2$$reg);
9815 __ daddu(dst_reg, src1_reg, src2_reg);
9816 %}
9818 ins_pipe( ialu_regL_regL );
9819 %}
9821 instruct addL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
9822 match(Set dst (AddL src1 (ConvI2L src2)));
9823 ins_cost(200);
9824 format %{ "ADD $dst, $src1, $src2 #@addL_Reg_RegI2L\t" %}
9826 ins_encode %{
9827 Register dst_reg = as_Register($dst$$reg);
9828 Register src1_reg = as_Register($src1$$reg);
9829 Register src2_reg = as_Register($src2$$reg);
9831 __ daddu(dst_reg, src1_reg, src2_reg);
9832 %}
9834 ins_pipe( ialu_regL_regL );
9835 %}
9837 //----------Subtraction Instructions-------------------------------------------
9838 // Integer Subtraction Instructions
9839 instruct subI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9840 match(Set dst (SubI src1 src2));
9841 ins_cost(100);
9843 format %{ "sub $dst, $src1, $src2 #@subI_Reg_Reg" %}
9844 ins_encode %{
9845 Register dst = $dst$$Register;
9846 Register src1 = $src1$$Register;
9847 Register src2 = $src2$$Register;
9848 __ subu32(dst, src1, src2);
9849 %}
9850 ins_pipe( ialu_regI_regI );
9851 %}
9853 instruct subI_Reg_immI16_sub(mRegI dst, mRegI src1, immI16_sub src2) %{
9854 match(Set dst (SubI src1 src2));
9855 ins_cost(80);
9857 format %{ "sub $dst, $src1, $src2 #@subI_Reg_immI16_sub" %}
9858 ins_encode %{
9859 Register dst = $dst$$Register;
9860 Register src1 = $src1$$Register;
9861 __ addiu32(dst, src1, -1 * $src2$$constant);
9862 %}
9863 ins_pipe( ialu_regI_regI );
9864 %}
9866 instruct negI_Reg(mRegI dst, immI0 zero, mRegI src) %{
9867 match(Set dst (SubI zero src));
9868 ins_cost(80);
9870 format %{ "neg $dst, $src #@negI_Reg" %}
9871 ins_encode %{
9872 Register dst = $dst$$Register;
9873 Register src = $src$$Register;
9874 __ subu32(dst, R0, src);
9875 %}
9876 ins_pipe( ialu_regI_regI );
9877 %}
9879 instruct negL_Reg(mRegL dst, immL0 zero, mRegL src) %{
9880 match(Set dst (SubL zero src));
9881 ins_cost(80);
9883 format %{ "neg $dst, $src #@negL_Reg" %}
9884 ins_encode %{
9885 Register dst = $dst$$Register;
9886 Register src = $src$$Register;
9887 __ subu(dst, R0, src);
9888 %}
9889 ins_pipe( ialu_regI_regI );
9890 %}
9892 instruct subL_Reg_immL16_sub(mRegL dst, mRegL src1, immL16_sub src2) %{
9893 match(Set dst (SubL src1 src2));
9894 ins_cost(80);
9896 format %{ "sub $dst, $src1, $src2 #@subL_Reg_immL16_sub" %}
9897 ins_encode %{
9898 Register dst = $dst$$Register;
9899 Register src1 = $src1$$Register;
9900 __ daddiu(dst, src1, -1 * $src2$$constant);
9901 %}
9902 ins_pipe( ialu_regI_regI );
9903 %}
9905 // Subtract Long Register with Register.
9906 instruct subL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
9907 match(Set dst (SubL src1 src2));
9908 ins_cost(100);
9909 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_Reg" %}
9910 ins_encode %{
9911 Register dst = as_Register($dst$$reg);
9912 Register src1 = as_Register($src1$$reg);
9913 Register src2 = as_Register($src2$$reg);
9915 __ subu(dst, src1, src2);
9916 %}
9917 ins_pipe( ialu_regL_regL );
9918 %}
9920 instruct subL_Reg_RegI2L(mRegL dst, mRegL src1, mRegI src2) %{
9921 match(Set dst (SubL src1 (ConvI2L src2)));
9922 ins_cost(100);
9923 format %{ "SubL $dst, $src1, $src2 @ subL_Reg_RegI2L" %}
9924 ins_encode %{
9925 Register dst = as_Register($dst$$reg);
9926 Register src1 = as_Register($src1$$reg);
9927 Register src2 = as_Register($src2$$reg);
9929 __ subu(dst, src1, src2);
9930 %}
9931 ins_pipe( ialu_regL_regL );
9932 %}
9934 instruct subL_RegI2L_Reg(mRegL dst, mRegI src1, mRegL src2) %{
9935 match(Set dst (SubL (ConvI2L src1) src2));
9936 ins_cost(200);
9937 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_Reg" %}
9938 ins_encode %{
9939 Register dst = as_Register($dst$$reg);
9940 Register src1 = as_Register($src1$$reg);
9941 Register src2 = as_Register($src2$$reg);
9943 __ subu(dst, src1, src2);
9944 %}
9945 ins_pipe( ialu_regL_regL );
9946 %}
9948 instruct subL_RegI2L_RegI2L(mRegL dst, mRegI src1, mRegI src2) %{
9949 match(Set dst (SubL (ConvI2L src1) (ConvI2L src2)));
9950 ins_cost(200);
9951 format %{ "SubL $dst, $src1, $src2 @ subL_RegI2L_RegI2L" %}
9952 ins_encode %{
9953 Register dst = as_Register($dst$$reg);
9954 Register src1 = as_Register($src1$$reg);
9955 Register src2 = as_Register($src2$$reg);
9957 __ subu(dst, src1, src2);
9958 %}
9959 ins_pipe( ialu_regL_regL );
9960 %}
9962 // Integer MOD with Register
9963 instruct modI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
9964 match(Set dst (ModI src1 src2));
9965 ins_cost(300);
9966 format %{ "modi $dst, $src1, $src2 @ modI_Reg_Reg" %}
9967 ins_encode %{
9968 Register dst = $dst$$Register;
9969 Register src1 = $src1$$Register;
9970 Register src2 = $src2$$Register;
9972 //if (UseLoongsonISA) {
9973 if (0) {
9974 // 2016.08.10
9975 // Experiments show that gsmod is slower that div+mfhi.
9976 // So I just disable it here.
9977 __ gsmod(dst, src1, src2);
9978 } else {
9979 __ div(src1, src2);
9980 __ mfhi(dst);
9981 }
9982 %}
9984 //ins_pipe( ialu_mod );
9985 ins_pipe( ialu_regI_regI );
9986 %}
9988 instruct modL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
9989 match(Set dst (ModL src1 src2));
9990 format %{ "modL $dst, $src1, $src2 @modL_reg_reg" %}
9992 ins_encode %{
9993 Register dst = as_Register($dst$$reg);
9994 Register op1 = as_Register($src1$$reg);
9995 Register op2 = as_Register($src2$$reg);
9997 if (UseLoongsonISA) {
9998 __ gsdmod(dst, op1, op2);
9999 } else {
10000 __ ddiv(op1, op2);
10001 __ mfhi(dst);
10002 }
10003 %}
10004 ins_pipe( pipe_slow );
10005 %}
10007 instruct mulI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10008 match(Set dst (MulI src1 src2));
10010 ins_cost(300);
10011 format %{ "mul $dst, $src1, $src2 @ mulI_Reg_Reg" %}
10012 ins_encode %{
10013 Register src1 = $src1$$Register;
10014 Register src2 = $src2$$Register;
10015 Register dst = $dst$$Register;
10017 __ mul(dst, src1, src2);
10018 %}
10019 ins_pipe( ialu_mult );
10020 %}
10022 instruct maddI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2, mRegI src3) %{
10023 match(Set dst (AddI (MulI src1 src2) src3));
10025 ins_cost(999);
10026 format %{ "madd $dst, $src1 * $src2 + $src3 #@maddI_Reg_Reg" %}
10027 ins_encode %{
10028 Register src1 = $src1$$Register;
10029 Register src2 = $src2$$Register;
10030 Register src3 = $src3$$Register;
10031 Register dst = $dst$$Register;
10033 __ mtlo(src3);
10034 __ madd(src1, src2);
10035 __ mflo(dst);
10036 %}
10037 ins_pipe( ialu_mult );
10038 %}
10040 instruct divI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10041 match(Set dst (DivI src1 src2));
10043 ins_cost(300);
10044 format %{ "div $dst, $src1, $src2 @ divI_Reg_Reg" %}
10045 ins_encode %{
10046 Register src1 = $src1$$Register;
10047 Register src2 = $src2$$Register;
10048 Register dst = $dst$$Register;
10050 /* 2012/4/21 Jin: In MIPS, div does not cause exception.
10051 We must trap an exception manually. */
10052 __ teq(R0, src2, 0x7);
10054 if (UseLoongsonISA) {
10055 __ gsdiv(dst, src1, src2);
10056 } else {
10057 __ div(src1, src2);
10059 __ nop();
10060 __ nop();
10061 __ mflo(dst);
10062 }
10063 %}
10064 ins_pipe( ialu_mod );
10065 %}
10067 instruct divF_Reg_Reg(regF dst, regF src1, regF src2) %{
10068 match(Set dst (DivF src1 src2));
10070 ins_cost(300);
10071 format %{ "divF $dst, $src1, $src2 @ divF_Reg_Reg" %}
10072 ins_encode %{
10073 FloatRegister src1 = $src1$$FloatRegister;
10074 FloatRegister src2 = $src2$$FloatRegister;
10075 FloatRegister dst = $dst$$FloatRegister;
10077 /* Here do we need to trap an exception manually ? */
10078 __ div_s(dst, src1, src2);
10079 %}
10080 ins_pipe( pipe_slow );
10081 %}
10083 instruct divD_Reg_Reg(regD dst, regD src1, regD src2) %{
10084 match(Set dst (DivD src1 src2));
10086 ins_cost(300);
10087 format %{ "divD $dst, $src1, $src2 @ divD_Reg_Reg" %}
10088 ins_encode %{
10089 FloatRegister src1 = $src1$$FloatRegister;
10090 FloatRegister src2 = $src2$$FloatRegister;
10091 FloatRegister dst = $dst$$FloatRegister;
10093 /* Here do we need to trap an exception manually ? */
10094 __ div_d(dst, src1, src2);
10095 %}
10096 ins_pipe( pipe_slow );
10097 %}
10099 instruct mulL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
10100 match(Set dst (MulL src1 src2));
10101 format %{ "mulL $dst, $src1, $src2 @mulL_reg_reg" %}
10102 ins_encode %{
10103 Register dst = as_Register($dst$$reg);
10104 Register op1 = as_Register($src1$$reg);
10105 Register op2 = as_Register($src2$$reg);
10107 if (UseLoongsonISA) {
10108 __ gsdmult(dst, op1, op2);
10109 } else {
10110 __ dmult(op1, op2);
10111 __ mflo(dst);
10112 }
10113 %}
10114 ins_pipe( pipe_slow );
10115 %}
10117 instruct mulL_reg_regI2L(mRegL dst, mRegL src1, mRegI src2) %{
10118 match(Set dst (MulL src1 (ConvI2L src2)));
10119 format %{ "mulL $dst, $src1, $src2 @mulL_reg_regI2L" %}
10120 ins_encode %{
10121 Register dst = as_Register($dst$$reg);
10122 Register op1 = as_Register($src1$$reg);
10123 Register op2 = as_Register($src2$$reg);
10125 if (UseLoongsonISA) {
10126 __ gsdmult(dst, op1, op2);
10127 } else {
10128 __ dmult(op1, op2);
10129 __ mflo(dst);
10130 }
10131 %}
10132 ins_pipe( pipe_slow );
10133 %}
10135 instruct divL_reg_reg(mRegL dst, mRegL src1, mRegL src2) %{
10136 match(Set dst (DivL src1 src2));
10137 format %{ "divL $dst, $src1, $src2 @divL_reg_reg" %}
10139 ins_encode %{
10140 Register dst = as_Register($dst$$reg);
10141 Register op1 = as_Register($src1$$reg);
10142 Register op2 = as_Register($src2$$reg);
10144 if (UseLoongsonISA) {
10145 __ gsddiv(dst, op1, op2);
10146 } else {
10147 __ ddiv(op1, op2);
10148 __ mflo(dst);
10149 }
10150 %}
10151 ins_pipe( pipe_slow );
10152 %}
10154 instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
10155 match(Set dst (AddF src1 src2));
10156 format %{ "AddF $dst, $src1, $src2 @addF_reg_reg" %}
10157 ins_encode %{
10158 FloatRegister src1 = as_FloatRegister($src1$$reg);
10159 FloatRegister src2 = as_FloatRegister($src2$$reg);
10160 FloatRegister dst = as_FloatRegister($dst$$reg);
10162 __ add_s(dst, src1, src2);
10163 %}
10164 ins_pipe( fpu_regF_regF );
10165 %}
10167 instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
10168 match(Set dst (SubF src1 src2));
10169 format %{ "SubF $dst, $src1, $src2 @subF_reg_reg" %}
10170 ins_encode %{
10171 FloatRegister src1 = as_FloatRegister($src1$$reg);
10172 FloatRegister src2 = as_FloatRegister($src2$$reg);
10173 FloatRegister dst = as_FloatRegister($dst$$reg);
10175 __ sub_s(dst, src1, src2);
10176 %}
10177 ins_pipe( fpu_regF_regF );
10178 %}
10179 instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
10180 match(Set dst (AddD src1 src2));
10181 format %{ "AddD $dst, $src1, $src2 @addD_reg_reg" %}
10182 ins_encode %{
10183 FloatRegister src1 = as_FloatRegister($src1$$reg);
10184 FloatRegister src2 = as_FloatRegister($src2$$reg);
10185 FloatRegister dst = as_FloatRegister($dst$$reg);
10187 __ add_d(dst, src1, src2);
10188 %}
10189 ins_pipe( fpu_regF_regF );
10190 %}
10192 instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
10193 match(Set dst (SubD src1 src2));
10194 format %{ "SubD $dst, $src1, $src2 @subD_reg_reg" %}
10195 ins_encode %{
10196 FloatRegister src1 = as_FloatRegister($src1$$reg);
10197 FloatRegister src2 = as_FloatRegister($src2$$reg);
10198 FloatRegister dst = as_FloatRegister($dst$$reg);
10200 __ sub_d(dst, src1, src2);
10201 %}
10202 ins_pipe( fpu_regF_regF );
10203 %}
10205 instruct negF_reg(regF dst, regF src) %{
10206 match(Set dst (NegF src));
10207 format %{ "negF $dst, $src @negF_reg" %}
10208 ins_encode %{
10209 FloatRegister src = as_FloatRegister($src$$reg);
10210 FloatRegister dst = as_FloatRegister($dst$$reg);
10212 __ neg_s(dst, src);
10213 %}
10214 ins_pipe( fpu_regF_regF );
10215 %}
10217 instruct negD_reg(regD dst, regD src) %{
10218 match(Set dst (NegD src));
10219 format %{ "negD $dst, $src @negD_reg" %}
10220 ins_encode %{
10221 FloatRegister src = as_FloatRegister($src$$reg);
10222 FloatRegister dst = as_FloatRegister($dst$$reg);
10224 __ neg_d(dst, src);
10225 %}
10226 ins_pipe( fpu_regF_regF );
10227 %}
10230 instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
10231 match(Set dst (MulF src1 src2));
10232 format %{ "MULF $dst, $src1, $src2 @mulF_reg_reg" %}
10233 ins_encode %{
10234 FloatRegister src1 = $src1$$FloatRegister;
10235 FloatRegister src2 = $src2$$FloatRegister;
10236 FloatRegister dst = $dst$$FloatRegister;
10238 __ mul_s(dst, src1, src2);
10239 %}
10240 ins_pipe( fpu_regF_regF );
10241 %}
10243 instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
10244 match(Set dst (AddF (MulF src1 src2) src3));
10245 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
10246 ins_cost(44444);
10247 format %{ "maddF $dst, $src1, $src2, $src3 @maddF_reg_reg" %}
10248 ins_encode %{
10249 FloatRegister src1 = $src1$$FloatRegister;
10250 FloatRegister src2 = $src2$$FloatRegister;
10251 FloatRegister src3 = $src3$$FloatRegister;
10252 FloatRegister dst = $dst$$FloatRegister;
10254 __ madd_s(dst, src1, src2, src3);
10255 %}
10256 ins_pipe( fpu_regF_regF );
10257 %}
10259 // Mul two double precision floating piont number
10260 instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
10261 match(Set dst (MulD src1 src2));
10262 format %{ "MULD $dst, $src1, $src2 @mulD_reg_reg" %}
10263 ins_encode %{
10264 FloatRegister src1 = $src1$$FloatRegister;
10265 FloatRegister src2 = $src2$$FloatRegister;
10266 FloatRegister dst = $dst$$FloatRegister;
10268 __ mul_d(dst, src1, src2);
10269 %}
10270 ins_pipe( fpu_regF_regF );
10271 %}
10273 instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
10274 match(Set dst (AddD (MulD src1 src2) src3));
10275 // For compatibility reason (e.g. on the Loongson platform), disable this guy.
10276 ins_cost(44444);
10277 format %{ "maddD $dst, $src1, $src2, $src3 @maddD_reg_reg" %}
10278 ins_encode %{
10279 FloatRegister src1 = $src1$$FloatRegister;
10280 FloatRegister src2 = $src2$$FloatRegister;
10281 FloatRegister src3 = $src3$$FloatRegister;
10282 FloatRegister dst = $dst$$FloatRegister;
10284 __ madd_d(dst, src1, src2, src3);
10285 %}
10286 ins_pipe( fpu_regF_regF );
10287 %}
10289 instruct absF_reg(regF dst, regF src) %{
10290 match(Set dst (AbsF src));
10291 ins_cost(100);
10292 format %{ "absF $dst, $src @absF_reg" %}
10293 ins_encode %{
10294 FloatRegister src = as_FloatRegister($src$$reg);
10295 FloatRegister dst = as_FloatRegister($dst$$reg);
10297 __ abs_s(dst, src);
10298 %}
10299 ins_pipe( fpu_regF_regF );
10300 %}
10303 // intrinsics for math_native.
10304 // AbsD SqrtD CosD SinD TanD LogD Log10D
10306 instruct absD_reg(regD dst, regD src) %{
10307 match(Set dst (AbsD src));
10308 ins_cost(100);
10309 format %{ "absD $dst, $src @absD_reg" %}
10310 ins_encode %{
10311 FloatRegister src = as_FloatRegister($src$$reg);
10312 FloatRegister dst = as_FloatRegister($dst$$reg);
10314 __ abs_d(dst, src);
10315 %}
10316 ins_pipe( fpu_regF_regF );
10317 %}
10319 instruct sqrtD_reg(regD dst, regD src) %{
10320 match(Set dst (SqrtD src));
10321 ins_cost(100);
10322 format %{ "SqrtD $dst, $src @sqrtD_reg" %}
10323 ins_encode %{
10324 FloatRegister src = as_FloatRegister($src$$reg);
10325 FloatRegister dst = as_FloatRegister($dst$$reg);
10327 __ sqrt_d(dst, src);
10328 %}
10329 ins_pipe( fpu_regF_regF );
10330 %}
10332 instruct sqrtF_reg(regF dst, regF src) %{
10333 match(Set dst (ConvD2F (SqrtD (ConvF2D src))));
10334 ins_cost(100);
10335 format %{ "SqrtF $dst, $src @sqrtF_reg" %}
10336 ins_encode %{
10337 FloatRegister src = as_FloatRegister($src$$reg);
10338 FloatRegister dst = as_FloatRegister($dst$$reg);
10340 __ sqrt_s(dst, src);
10341 %}
10342 ins_pipe( fpu_regF_regF );
10343 %}
10344 //----------------------------------Logical Instructions----------------------
10345 //__________________________________Integer Logical Instructions-------------
10347 //And Instuctions
10348 // And Register with Immediate
10349 instruct andI_Reg_immI(mRegI dst, mRegI src1, immI src2) %{
10350 match(Set dst (AndI src1 src2));
10352 format %{ "and $dst, $src1, $src2 #@andI_Reg_immI" %}
10353 ins_encode %{
10354 Register dst = $dst$$Register;
10355 Register src = $src1$$Register;
10356 int val = $src2$$constant;
10358 __ move(AT, val);
10359 __ andr(dst, src, AT);
10360 %}
10361 ins_pipe( ialu_regI_regI );
10362 %}
10364 instruct andI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
10365 match(Set dst (AndI src1 src2));
10366 ins_cost(60);
10368 format %{ "and $dst, $src1, $src2 #@andI_Reg_imm_0_65535" %}
10369 ins_encode %{
10370 Register dst = $dst$$Register;
10371 Register src = $src1$$Register;
10372 int val = $src2$$constant;
10374 __ andi(dst, src, val);
10375 %}
10376 ins_pipe( ialu_regI_regI );
10377 %}
10379 instruct andI_Reg_immI_nonneg_mask(mRegI dst, mRegI src1, immI_nonneg_mask mask) %{
10380 match(Set dst (AndI src1 mask));
10381 ins_cost(60);
10383 format %{ "and $dst, $src1, $mask #@andI_Reg_immI_nonneg_mask" %}
10384 ins_encode %{
10385 Register dst = $dst$$Register;
10386 Register src = $src1$$Register;
10387 int size = Assembler::is_int_mask($mask$$constant);
10389 __ ext(dst, src, 0, size);
10390 %}
10391 ins_pipe( ialu_regI_regI );
10392 %}
10394 instruct andL_Reg_immL_nonneg_mask(mRegL dst, mRegL src1, immL_nonneg_mask mask) %{
10395 match(Set dst (AndL src1 mask));
10396 ins_cost(60);
10398 format %{ "and $dst, $src1, $mask #@andL_Reg_immL_nonneg_mask" %}
10399 ins_encode %{
10400 Register dst = $dst$$Register;
10401 Register src = $src1$$Register;
10402 int size = Assembler::is_jlong_mask($mask$$constant);
10404 __ dext(dst, src, 0, size);
10405 %}
10406 ins_pipe( ialu_regI_regI );
10407 %}
10409 instruct xorI_Reg_imm_0_65535(mRegI dst, mRegI src1, immI_0_65535 src2) %{
10410 match(Set dst (XorI src1 src2));
10411 ins_cost(60);
10413 format %{ "xori $dst, $src1, $src2 #@xorI_Reg_imm_0_65535" %}
10414 ins_encode %{
10415 Register dst = $dst$$Register;
10416 Register src = $src1$$Register;
10417 int val = $src2$$constant;
10419 __ xori(dst, src, val);
10420 %}
10421 ins_pipe( ialu_regI_regI );
10422 %}
10424 instruct xorI_Reg_immI_M1(mRegI dst, mRegI src1, immI_M1 M1) %{
10425 match(Set dst (XorI src1 M1));
10426 predicate(UseLoongsonISA && Use3A2000);
10427 ins_cost(60);
10429 format %{ "xor $dst, $src1, $M1 #@xorI_Reg_immI_M1" %}
10430 ins_encode %{
10431 Register dst = $dst$$Register;
10432 Register src = $src1$$Register;
10434 __ gsorn(dst, R0, src);
10435 %}
10436 ins_pipe( ialu_regI_regI );
10437 %}
10439 instruct xorL2I_Reg_immI_M1(mRegI dst, mRegL src1, immI_M1 M1) %{
10440 match(Set dst (XorI (ConvL2I src1) M1));
10441 predicate(UseLoongsonISA && Use3A2000);
10442 ins_cost(60);
10444 format %{ "xor $dst, $src1, $M1 #@xorL2I_Reg_immI_M1" %}
10445 ins_encode %{
10446 Register dst = $dst$$Register;
10447 Register src = $src1$$Register;
10449 __ gsorn(dst, R0, src);
10450 %}
10451 ins_pipe( ialu_regI_regI );
10452 %}
10454 instruct xorL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
10455 match(Set dst (XorL src1 src2));
10456 ins_cost(60);
10458 format %{ "xori $dst, $src1, $src2 #@xorL_Reg_imm_0_65535" %}
10459 ins_encode %{
10460 Register dst = $dst$$Register;
10461 Register src = $src1$$Register;
10462 int val = $src2$$constant;
10464 __ xori(dst, src, val);
10465 %}
10466 ins_pipe( ialu_regI_regI );
10467 %}
10469 /*
10470 instruct xorL_Reg_immL_M1(mRegL dst, mRegL src1, immL_M1 M1) %{
10471 match(Set dst (XorL src1 M1));
10472 predicate(UseLoongsonISA);
10473 ins_cost(60);
10475 format %{ "xor $dst, $src1, $M1 #@xorL_Reg_immL_M1" %}
10476 ins_encode %{
10477 Register dst = $dst$$Register;
10478 Register src = $src1$$Register;
10480 __ gsorn(dst, R0, src);
10481 %}
10482 ins_pipe( ialu_regI_regI );
10483 %}
10484 */
10486 instruct lbu_and_lmask(mRegI dst, memory mem, immI_255 mask) %{
10487 match(Set dst (AndI mask (LoadB mem)));
10488 ins_cost(60);
10490 format %{ "lhu $dst, $mem #@lbu_and_lmask" %}
10491 ins_encode(load_UB_enc(dst, mem));
10492 ins_pipe( ialu_loadI );
10493 %}
10495 instruct lbu_and_rmask(mRegI dst, memory mem, immI_255 mask) %{
10496 match(Set dst (AndI (LoadB mem) mask));
10497 ins_cost(60);
10499 format %{ "lhu $dst, $mem #@lbu_and_rmask" %}
10500 ins_encode(load_UB_enc(dst, mem));
10501 ins_pipe( ialu_loadI );
10502 %}
10504 instruct andI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
10505 match(Set dst (AndI src1 src2));
10507 format %{ "and $dst, $src1, $src2 #@andI_Reg_Reg" %}
10508 ins_encode %{
10509 Register dst = $dst$$Register;
10510 Register src1 = $src1$$Register;
10511 Register src2 = $src2$$Register;
10512 __ andr(dst, src1, src2);
10513 %}
10514 ins_pipe( ialu_regI_regI );
10515 %}
10517 instruct andnI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
10518 match(Set dst (AndI src1 (XorI src2 M1)));
10519 predicate(UseLoongsonISA && Use3A2000);
10521 format %{ "andn $dst, $src1, $src2 #@andnI_Reg_nReg" %}
10522 ins_encode %{
10523 Register dst = $dst$$Register;
10524 Register src1 = $src1$$Register;
10525 Register src2 = $src2$$Register;
10527 __ gsandn(dst, src1, src2);
10528 %}
10529 ins_pipe( ialu_regI_regI );
10530 %}
10532 instruct ornI_Reg_nReg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
10533 match(Set dst (OrI src1 (XorI src2 M1)));
10534 predicate(UseLoongsonISA && Use3A2000);
10536 format %{ "orn $dst, $src1, $src2 #@ornI_Reg_nReg" %}
10537 ins_encode %{
10538 Register dst = $dst$$Register;
10539 Register src1 = $src1$$Register;
10540 Register src2 = $src2$$Register;
10542 __ gsorn(dst, src1, src2);
10543 %}
10544 ins_pipe( ialu_regI_regI );
10545 %}
10547 instruct andnI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
10548 match(Set dst (AndI (XorI src1 M1) src2));
10549 predicate(UseLoongsonISA && Use3A2000);
10551 format %{ "andn $dst, $src2, $src1 #@andnI_nReg_Reg" %}
10552 ins_encode %{
10553 Register dst = $dst$$Register;
10554 Register src1 = $src1$$Register;
10555 Register src2 = $src2$$Register;
10557 __ gsandn(dst, src2, src1);
10558 %}
10559 ins_pipe( ialu_regI_regI );
10560 %}
10562 instruct ornI_nReg_Reg(mRegI dst, mRegI src1, mRegI src2, immI_M1 M1) %{
10563 match(Set dst (OrI (XorI src1 M1) src2));
10564 predicate(UseLoongsonISA && Use3A2000);
10566 format %{ "orn $dst, $src2, $src1 #@ornI_nReg_Reg" %}
10567 ins_encode %{
10568 Register dst = $dst$$Register;
10569 Register src1 = $src1$$Register;
10570 Register src2 = $src2$$Register;
10572 __ gsorn(dst, src2, src1);
10573 %}
10574 ins_pipe( ialu_regI_regI );
10575 %}
10577 // And Long Register with Register
10578 instruct andL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10579 match(Set dst (AndL src1 src2));
10580 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg\n\t" %}
10581 ins_encode %{
10582 Register dst_reg = as_Register($dst$$reg);
10583 Register src1_reg = as_Register($src1$$reg);
10584 Register src2_reg = as_Register($src2$$reg);
10586 __ andr(dst_reg, src1_reg, src2_reg);
10587 %}
10588 ins_pipe( ialu_regL_regL );
10589 %}
10591 instruct andL_Reg_Reg_convI2L(mRegL dst, mRegL src1, mRegI src2) %{
10592 match(Set dst (AndL src1 (ConvI2L src2)));
10593 format %{ "AND $dst, $src1, $src2 @ andL_Reg_Reg_convI2L\n\t" %}
10594 ins_encode %{
10595 Register dst_reg = as_Register($dst$$reg);
10596 Register src1_reg = as_Register($src1$$reg);
10597 Register src2_reg = as_Register($src2$$reg);
10599 __ andr(dst_reg, src1_reg, src2_reg);
10600 %}
10601 ins_pipe( ialu_regL_regL );
10602 %}
10604 instruct andL_Reg_imm_0_65535(mRegL dst, mRegL src1, immL_0_65535 src2) %{
10605 match(Set dst (AndL src1 src2));
10606 ins_cost(60);
10608 format %{ "and $dst, $src1, $src2 #@andL_Reg_imm_0_65535" %}
10609 ins_encode %{
10610 Register dst = $dst$$Register;
10611 Register src = $src1$$Register;
10612 long val = $src2$$constant;
10614 __ andi(dst, src, val);
10615 %}
10616 ins_pipe( ialu_regI_regI );
10617 %}
10619 instruct andL2I_Reg_imm_0_65535(mRegI dst, mRegL src1, immL_0_65535 src2) %{
10620 match(Set dst (ConvL2I (AndL src1 src2)));
10621 ins_cost(60);
10623 format %{ "and $dst, $src1, $src2 #@andL2I_Reg_imm_0_65535" %}
10624 ins_encode %{
10625 Register dst = $dst$$Register;
10626 Register src = $src1$$Register;
10627 long val = $src2$$constant;
10629 __ andi(dst, src, val);
10630 %}
10631 ins_pipe( ialu_regI_regI );
10632 %}
10634 /*
10635 instruct andnL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
10636 match(Set dst (AndL src1 (XorL src2 M1)));
10637 predicate(UseLoongsonISA);
10639 format %{ "andn $dst, $src1, $src2 #@andnL_Reg_nReg" %}
10640 ins_encode %{
10641 Register dst = $dst$$Register;
10642 Register src1 = $src1$$Register;
10643 Register src2 = $src2$$Register;
10645 __ gsandn(dst, src1, src2);
10646 %}
10647 ins_pipe( ialu_regI_regI );
10648 %}
10649 */
10651 /*
10652 instruct ornL_Reg_nReg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
10653 match(Set dst (OrL src1 (XorL src2 M1)));
10654 predicate(UseLoongsonISA);
10656 format %{ "orn $dst, $src1, $src2 #@ornL_Reg_nReg" %}
10657 ins_encode %{
10658 Register dst = $dst$$Register;
10659 Register src1 = $src1$$Register;
10660 Register src2 = $src2$$Register;
10662 __ gsorn(dst, src1, src2);
10663 %}
10664 ins_pipe( ialu_regI_regI );
10665 %}
10666 */
10668 /*
10669 instruct andnL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
10670 match(Set dst (AndL (XorL src1 M1) src2));
10671 predicate(UseLoongsonISA);
10673 format %{ "andn $dst, $src2, $src1 #@andnL_nReg_Reg" %}
10674 ins_encode %{
10675 Register dst = $dst$$Register;
10676 Register src1 = $src1$$Register;
10677 Register src2 = $src2$$Register;
10679 __ gsandn(dst, src2, src1);
10680 %}
10681 ins_pipe( ialu_regI_regI );
10682 %}
10683 */
10685 /*
10686 instruct ornL_nReg_Reg(mRegL dst, mRegL src1, mRegL src2, immL_M1 M1) %{
10687 match(Set dst (OrL (XorL src1 M1) src2));
10688 predicate(UseLoongsonISA);
10690 format %{ "orn $dst, $src2, $src1 #@ornL_nReg_Reg" %}
10691 ins_encode %{
10692 Register dst = $dst$$Register;
10693 Register src1 = $src1$$Register;
10694 Register src2 = $src2$$Register;
10696 __ gsorn(dst, src2, src1);
10697 %}
10698 ins_pipe( ialu_regI_regI );
10699 %}
10700 */
10702 instruct andL_Reg_immL_M8(mRegL dst, immL_M8 M8) %{
10703 match(Set dst (AndL dst M8));
10704 ins_cost(60);
10706 format %{ "and $dst, $dst, $M8 #@andL_Reg_immL_M8" %}
10707 ins_encode %{
10708 Register dst = $dst$$Register;
10710 __ dins(dst, R0, 0, 3);
10711 %}
10712 ins_pipe( ialu_regI_regI );
10713 %}
10715 instruct andL_Reg_immL_M5(mRegL dst, immL_M5 M5) %{
10716 match(Set dst (AndL dst M5));
10717 ins_cost(60);
10719 format %{ "and $dst, $dst, $M5 #@andL_Reg_immL_M5" %}
10720 ins_encode %{
10721 Register dst = $dst$$Register;
10723 __ dins(dst, R0, 2, 1);
10724 %}
10725 ins_pipe( ialu_regI_regI );
10726 %}
10728 instruct andL_Reg_immL_M7(mRegL dst, immL_M7 M7) %{
10729 match(Set dst (AndL dst M7));
10730 ins_cost(60);
10732 format %{ "and $dst, $dst, $M7 #@andL_Reg_immL_M7" %}
10733 ins_encode %{
10734 Register dst = $dst$$Register;
10736 __ dins(dst, R0, 1, 2);
10737 %}
10738 ins_pipe( ialu_regI_regI );
10739 %}
10741 instruct andL_Reg_immL_M4(mRegL dst, immL_M4 M4) %{
10742 match(Set dst (AndL dst M4));
10743 ins_cost(60);
10745 format %{ "and $dst, $dst, $M4 #@andL_Reg_immL_M4" %}
10746 ins_encode %{
10747 Register dst = $dst$$Register;
10749 __ dins(dst, R0, 0, 2);
10750 %}
10751 ins_pipe( ialu_regI_regI );
10752 %}
10754 instruct andL_Reg_immL_M121(mRegL dst, immL_M121 M121) %{
10755 match(Set dst (AndL dst M121));
10756 ins_cost(60);
10758 format %{ "and $dst, $dst, $M121 #@andL_Reg_immL_M121" %}
10759 ins_encode %{
10760 Register dst = $dst$$Register;
10762 __ dins(dst, R0, 3, 4);
10763 %}
10764 ins_pipe( ialu_regI_regI );
10765 %}
10767 // Or Long Register with Register
10768 instruct orL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10769 match(Set dst (OrL src1 src2));
10770 format %{ "OR $dst, $src1, $src2 @ orL_Reg_Reg\t" %}
10771 ins_encode %{
10772 Register dst_reg = $dst$$Register;
10773 Register src1_reg = $src1$$Register;
10774 Register src2_reg = $src2$$Register;
10776 __ orr(dst_reg, src1_reg, src2_reg);
10777 %}
10778 ins_pipe( ialu_regL_regL );
10779 %}
10781 instruct orL_Reg_P2XReg(mRegL dst, mRegP src1, mRegL src2) %{
10782 match(Set dst (OrL (CastP2X src1) src2));
10783 format %{ "OR $dst, $src1, $src2 @ orL_Reg_P2XReg\t" %}
10784 ins_encode %{
10785 Register dst_reg = $dst$$Register;
10786 Register src1_reg = $src1$$Register;
10787 Register src2_reg = $src2$$Register;
10789 __ orr(dst_reg, src1_reg, src2_reg);
10790 %}
10791 ins_pipe( ialu_regL_regL );
10792 %}
10794 // Xor Long Register with Register
10795 instruct xorL_Reg_Reg(mRegL dst, mRegL src1, mRegL src2) %{
10796 match(Set dst (XorL src1 src2));
10797 format %{ "XOR $dst, $src1, $src2 @ xorL_Reg_Reg\t" %}
10798 ins_encode %{
10799 Register dst_reg = as_Register($dst$$reg);
10800 Register src1_reg = as_Register($src1$$reg);
10801 Register src2_reg = as_Register($src2$$reg);
10803 __ xorr(dst_reg, src1_reg, src2_reg);
10804 %}
10805 ins_pipe( ialu_regL_regL );
10806 %}
10808 // Shift Left by 8-bit immediate
10809 instruct salI_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
10810 match(Set dst (LShiftI src shift));
10812 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm" %}
10813 ins_encode %{
10814 Register src = $src$$Register;
10815 Register dst = $dst$$Register;
10816 int shamt = $shift$$constant;
10818 __ sll(dst, src, shamt);
10819 %}
10820 ins_pipe( ialu_regI_regI );
10821 %}
10823 instruct salL2I_Reg_imm(mRegI dst, mRegL src, immI8 shift) %{
10824 match(Set dst (LShiftI (ConvL2I src) shift));
10826 format %{ "SHL $dst, $src, $shift #@salL2I_Reg_imm" %}
10827 ins_encode %{
10828 Register src = $src$$Register;
10829 Register dst = $dst$$Register;
10830 int shamt = $shift$$constant;
10832 __ sll(dst, src, shamt);
10833 %}
10834 ins_pipe( ialu_regI_regI );
10835 %}
10837 instruct salI_Reg_imm_and_M65536(mRegI dst, mRegI src, immI_16 shift, immI_M65536 mask) %{
10838 match(Set dst (AndI (LShiftI src shift) mask));
10840 format %{ "SHL $dst, $src, $shift #@salI_Reg_imm_and_M65536" %}
10841 ins_encode %{
10842 Register src = $src$$Register;
10843 Register dst = $dst$$Register;
10845 __ sll(dst, src, 16);
10846 %}
10847 ins_pipe( ialu_regI_regI );
10848 %}
10850 instruct land7_2_s(mRegI dst, mRegL src, immL7 seven, immI_16 sixteen)
10851 %{
10852 match(Set dst (RShiftI (LShiftI (ConvL2I (AndL src seven)) sixteen) sixteen));
10854 format %{ "andi $dst, $src, 7\t# @land7_2_s" %}
10855 ins_encode %{
10856 Register src = $src$$Register;
10857 Register dst = $dst$$Register;
10859 __ andi(dst, src, 7);
10860 %}
10861 ins_pipe(ialu_regI_regI);
10862 %}
10864 instruct ori2s(mRegI dst, mRegI src1, immI_0_32767 src2, immI_16 sixteen)
10865 %{
10866 match(Set dst (RShiftI (LShiftI (OrI src1 src2) sixteen) sixteen));
10868 format %{ "ori $dst, $src1, $src2\t# @ori2s" %}
10869 ins_encode %{
10870 Register src = $src1$$Register;
10871 int val = $src2$$constant;
10872 Register dst = $dst$$Register;
10874 __ ori(dst, src, val);
10875 %}
10876 ins_pipe(ialu_regI_regI);
10877 %}
10879 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
10880 // This idiom is used by the compiler the i2s bytecode.
10881 instruct i2s(mRegI dst, mRegI src, immI_16 sixteen)
10882 %{
10883 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
10885 format %{ "i2s $dst, $src\t# @i2s" %}
10886 ins_encode %{
10887 Register src = $src$$Register;
10888 Register dst = $dst$$Register;
10890 __ seh(dst, src);
10891 %}
10892 ins_pipe(ialu_regI_regI);
10893 %}
10895 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
10896 // This idiom is used by the compiler for the i2b bytecode.
10897 instruct i2b(mRegI dst, mRegI src, immI_24 twentyfour)
10898 %{
10899 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
10901 format %{ "i2b $dst, $src\t# @i2b" %}
10902 ins_encode %{
10903 Register src = $src$$Register;
10904 Register dst = $dst$$Register;
10906 __ seb(dst, src);
10907 %}
10908 ins_pipe(ialu_regI_regI);
10909 %}
10912 instruct salI_RegL2I_imm(mRegI dst, mRegL src, immI8 shift) %{
10913 match(Set dst (LShiftI (ConvL2I src) shift));
10915 format %{ "SHL $dst, $src, $shift #@salI_RegL2I_imm" %}
10916 ins_encode %{
10917 Register src = $src$$Register;
10918 Register dst = $dst$$Register;
10919 int shamt = $shift$$constant;
10921 __ sll(dst, src, shamt);
10922 %}
10923 ins_pipe( ialu_regI_regI );
10924 %}
10926 // Shift Left by 8-bit immediate
10927 instruct salI_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
10928 match(Set dst (LShiftI src shift));
10930 format %{ "SHL $dst, $src, $shift #@salI_Reg_Reg" %}
10931 ins_encode %{
10932 Register src = $src$$Register;
10933 Register dst = $dst$$Register;
10934 Register shamt = $shift$$Register;
10935 __ sllv(dst, src, shamt);
10936 %}
10937 ins_pipe( ialu_regI_regI );
10938 %}
10941 // Shift Left Long
10942 instruct salL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
10943 //predicate(UseNewLongLShift);
10944 match(Set dst (LShiftL src shift));
10945 ins_cost(100);
10946 format %{ "salL $dst, $src, $shift @ salL_Reg_imm" %}
10947 ins_encode %{
10948 Register src_reg = as_Register($src$$reg);
10949 Register dst_reg = as_Register($dst$$reg);
10950 int shamt = $shift$$constant;
10952 if (__ is_simm(shamt, 5))
10953 __ dsll(dst_reg, src_reg, shamt);
10954 else {
10955 int sa = Assembler::low(shamt, 6);
10956 if (sa < 32) {
10957 __ dsll(dst_reg, src_reg, sa);
10958 } else {
10959 __ dsll32(dst_reg, src_reg, sa - 32);
10960 }
10961 }
10962 %}
10963 ins_pipe( ialu_regL_regL );
10964 %}
10966 instruct salL_RegI2L_imm(mRegL dst, mRegI src, immI8 shift) %{
10967 //predicate(UseNewLongLShift);
10968 match(Set dst (LShiftL (ConvI2L src) shift));
10969 ins_cost(100);
10970 format %{ "salL $dst, $src, $shift @ salL_RegI2L_imm" %}
10971 ins_encode %{
10972 Register src_reg = as_Register($src$$reg);
10973 Register dst_reg = as_Register($dst$$reg);
10974 int shamt = $shift$$constant;
10976 if (__ is_simm(shamt, 5))
10977 __ dsll(dst_reg, src_reg, shamt);
10978 else {
10979 int sa = Assembler::low(shamt, 6);
10980 if (sa < 32) {
10981 __ dsll(dst_reg, src_reg, sa);
10982 } else {
10983 __ dsll32(dst_reg, src_reg, sa - 32);
10984 }
10985 }
10986 %}
10987 ins_pipe( ialu_regL_regL );
10988 %}
10990 // Shift Left Long
10991 instruct salL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
10992 //predicate(UseNewLongLShift);
10993 match(Set dst (LShiftL src shift));
10994 ins_cost(100);
10995 format %{ "salL $dst, $src, $shift @ salL_Reg_Reg" %}
10996 ins_encode %{
10997 Register src_reg = as_Register($src$$reg);
10998 Register dst_reg = as_Register($dst$$reg);
11000 __ dsllv(dst_reg, src_reg, $shift$$Register);
11001 %}
11002 ins_pipe( ialu_regL_regL );
11003 %}
11005 instruct salL_convI2L_Reg_imm(mRegL dst, mRegI src, immI8 shift) %{
11006 match(Set dst (LShiftL (ConvI2L src) shift));
11007 ins_cost(100);
11008 format %{ "salL $dst, $src, $shift @ salL_convI2L_Reg_imm" %}
11009 ins_encode %{
11010 Register src_reg = as_Register($src$$reg);
11011 Register dst_reg = as_Register($dst$$reg);
11012 int shamt = $shift$$constant;
11014 if (__ is_simm(shamt, 5)) {
11015 __ dsll(dst_reg, src_reg, shamt);
11016 } else {
11017 int sa = Assembler::low(shamt, 6);
11018 if (sa < 32) {
11019 __ dsll(dst_reg, src_reg, sa);
11020 } else {
11021 __ dsll32(dst_reg, src_reg, sa - 32);
11022 }
11023 }
11024 %}
11025 ins_pipe( ialu_regL_regL );
11026 %}
11028 // Shift Right Long
11029 instruct sarL_Reg_imm(mRegL dst, mRegL src, immI8 shift) %{
11030 match(Set dst (RShiftL src shift));
11031 ins_cost(100);
11032 format %{ "sarL $dst, $src, $shift @ sarL_Reg_imm" %}
11033 ins_encode %{
11034 Register src_reg = as_Register($src$$reg);
11035 Register dst_reg = as_Register($dst$$reg);
11036 int shamt = ($shift$$constant & 0x3f);
11037 if (__ is_simm(shamt, 5))
11038 __ dsra(dst_reg, src_reg, shamt);
11039 else {
11040 int sa = Assembler::low(shamt, 6);
11041 if (sa < 32) {
11042 __ dsra(dst_reg, src_reg, sa);
11043 } else {
11044 __ dsra32(dst_reg, src_reg, sa - 32);
11045 }
11046 }
11047 %}
11048 ins_pipe( ialu_regL_regL );
11049 %}
11051 instruct sarL2I_Reg_immI_32_63(mRegI dst, mRegL src, immI_32_63 shift) %{
11052 match(Set dst (ConvL2I (RShiftL src shift)));
11053 ins_cost(100);
11054 format %{ "sarL $dst, $src, $shift @ sarL2I_Reg_immI_32_63" %}
11055 ins_encode %{
11056 Register src_reg = as_Register($src$$reg);
11057 Register dst_reg = as_Register($dst$$reg);
11058 int shamt = $shift$$constant;
11060 __ dsra32(dst_reg, src_reg, shamt - 32);
11061 %}
11062 ins_pipe( ialu_regL_regL );
11063 %}
11065 // Shift Right Long arithmetically
11066 instruct sarL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
11067 //predicate(UseNewLongLShift);
11068 match(Set dst (RShiftL src shift));
11069 ins_cost(100);
11070 format %{ "sarL $dst, $src, $shift @ sarL_Reg_Reg" %}
11071 ins_encode %{
11072 Register src_reg = as_Register($src$$reg);
11073 Register dst_reg = as_Register($dst$$reg);
11075 __ dsrav(dst_reg, src_reg, $shift$$Register);
11076 %}
11077 ins_pipe( ialu_regL_regL );
11078 %}
11080 // Shift Right Long logically
11081 instruct slrL_Reg_Reg(mRegL dst, mRegL src, mRegI shift) %{
11082 match(Set dst (URShiftL src shift));
11083 ins_cost(100);
11084 format %{ "slrL $dst, $src, $shift @ slrL_Reg_Reg" %}
11085 ins_encode %{
11086 Register src_reg = as_Register($src$$reg);
11087 Register dst_reg = as_Register($dst$$reg);
11089 __ dsrlv(dst_reg, src_reg, $shift$$Register);
11090 %}
11091 ins_pipe( ialu_regL_regL );
11092 %}
11094 instruct slrL_Reg_immI_0_31(mRegL dst, mRegL src, immI_0_31 shift) %{
11095 match(Set dst (URShiftL src shift));
11096 ins_cost(80);
11097 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_0_31" %}
11098 ins_encode %{
11099 Register src_reg = as_Register($src$$reg);
11100 Register dst_reg = as_Register($dst$$reg);
11101 int shamt = $shift$$constant;
11103 __ dsrl(dst_reg, src_reg, shamt);
11104 %}
11105 ins_pipe( ialu_regL_regL );
11106 %}
11108 instruct slrL_Reg_immI_0_31_and_max_int(mRegI dst, mRegL src, immI_0_31 shift, immI_MaxI max_int) %{
11109 match(Set dst (AndI (ConvL2I (URShiftL src shift)) max_int));
11110 ins_cost(80);
11111 format %{ "dext $dst, $src, $shift, 31 @ slrL_Reg_immI_0_31_and_max_int" %}
11112 ins_encode %{
11113 Register src_reg = as_Register($src$$reg);
11114 Register dst_reg = as_Register($dst$$reg);
11115 int shamt = $shift$$constant;
11117 __ dext(dst_reg, src_reg, shamt, 31);
11118 %}
11119 ins_pipe( ialu_regL_regL );
11120 %}
11122 instruct slrL_P2XReg_immI_0_31(mRegL dst, mRegP src, immI_0_31 shift) %{
11123 match(Set dst (URShiftL (CastP2X src) shift));
11124 ins_cost(80);
11125 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_0_31" %}
11126 ins_encode %{
11127 Register src_reg = as_Register($src$$reg);
11128 Register dst_reg = as_Register($dst$$reg);
11129 int shamt = $shift$$constant;
11131 __ dsrl(dst_reg, src_reg, shamt);
11132 %}
11133 ins_pipe( ialu_regL_regL );
11134 %}
11136 instruct slrL_Reg_immI_32_63(mRegL dst, mRegL src, immI_32_63 shift) %{
11137 match(Set dst (URShiftL src shift));
11138 ins_cost(80);
11139 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_32_63" %}
11140 ins_encode %{
11141 Register src_reg = as_Register($src$$reg);
11142 Register dst_reg = as_Register($dst$$reg);
11143 int shamt = $shift$$constant;
11145 __ dsrl32(dst_reg, src_reg, shamt - 32);
11146 %}
11147 ins_pipe( ialu_regL_regL );
11148 %}
11150 instruct slrL_Reg_immI_convL2I(mRegI dst, mRegL src, immI_32_63 shift) %{
11151 match(Set dst (ConvL2I (URShiftL src shift)));
11152 predicate(n->in(1)->in(2)->get_int() > 32);
11153 ins_cost(80);
11154 format %{ "slrL $dst, $src, $shift @ slrL_Reg_immI_convL2I" %}
11155 ins_encode %{
11156 Register src_reg = as_Register($src$$reg);
11157 Register dst_reg = as_Register($dst$$reg);
11158 int shamt = $shift$$constant;
11160 __ dsrl32(dst_reg, src_reg, shamt - 32);
11161 %}
11162 ins_pipe( ialu_regL_regL );
11163 %}
11165 instruct slrL_P2XReg_immI_32_63(mRegL dst, mRegP src, immI_32_63 shift) %{
11166 match(Set dst (URShiftL (CastP2X src) shift));
11167 ins_cost(80);
11168 format %{ "slrL $dst, $src, $shift @ slrL_P2XReg_immI_32_63" %}
11169 ins_encode %{
11170 Register src_reg = as_Register($src$$reg);
11171 Register dst_reg = as_Register($dst$$reg);
11172 int shamt = $shift$$constant;
11174 __ dsrl32(dst_reg, src_reg, shamt - 32);
11175 %}
11176 ins_pipe( ialu_regL_regL );
11177 %}
11179 // Xor Instructions
11180 // Xor Register with Register
11181 instruct xorI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11182 match(Set dst (XorI src1 src2));
11184 format %{ "XOR $dst, $src1, $src2 #@xorI_Reg_Reg" %}
11186 ins_encode %{
11187 Register dst = $dst$$Register;
11188 Register src1 = $src1$$Register;
11189 Register src2 = $src2$$Register;
11190 __ xorr(dst, src1, src2);
11191 __ sll(dst, dst, 0); /* long -> int */
11192 %}
11194 ins_pipe( ialu_regI_regI );
11195 %}
11197 // Or Instructions
11198 // Or Register with Register
11199 instruct orI_Reg_Reg(mRegI dst, mRegI src1, mRegI src2) %{
11200 match(Set dst (OrI src1 src2));
11202 format %{ "OR $dst, $src1, $src2 #@orI_Reg_Reg" %}
11203 ins_encode %{
11204 Register dst = $dst$$Register;
11205 Register src1 = $src1$$Register;
11206 Register src2 = $src2$$Register;
11207 __ orr(dst, src1, src2);
11208 %}
11210 ins_pipe( ialu_regI_regI );
11211 %}
11213 instruct rotI_shr_logical_Reg(mRegI dst, mRegI src, immI_0_31 rshift, immI_0_31 lshift, immI_1 one) %{
11214 match(Set dst (OrI (URShiftI src rshift) (LShiftI (AndI src one) lshift)));
11215 predicate(32 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int())));
11217 format %{ "rotr $dst, $src, 1 ...\n\t"
11218 "srl $dst, $dst, ($rshift-1) @ rotI_shr_logical_Reg" %}
11219 ins_encode %{
11220 Register dst = $dst$$Register;
11221 Register src = $src$$Register;
11222 int rshift = $rshift$$constant;
11224 __ rotr(dst, src, 1);
11225 if (rshift - 1) {
11226 __ srl(dst, dst, rshift - 1);
11227 }
11228 %}
11230 ins_pipe( ialu_regI_regI );
11231 %}
11233 instruct orI_Reg_castP2X(mRegL dst, mRegL src1, mRegP src2) %{
11234 match(Set dst (OrI src1 (CastP2X src2)));
11236 format %{ "OR $dst, $src1, $src2 #@orI_Reg_castP2X" %}
11237 ins_encode %{
11238 Register dst = $dst$$Register;
11239 Register src1 = $src1$$Register;
11240 Register src2 = $src2$$Register;
11241 __ orr(dst, src1, src2);
11242 %}
11244 ins_pipe( ialu_regI_regI );
11245 %}
11247 // Logical Shift Right by 8-bit immediate
11248 instruct shr_logical_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
11249 match(Set dst (URShiftI src shift));
11250 //effect(KILL cr);
11252 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_imm" %}
11253 ins_encode %{
11254 Register src = $src$$Register;
11255 Register dst = $dst$$Register;
11256 int shift = $shift$$constant;
11258 __ srl(dst, src, shift);
11259 %}
11260 ins_pipe( ialu_regI_regI );
11261 %}
11263 instruct shr_logical_Reg_imm_nonneg_mask(mRegI dst, mRegI src, immI_0_31 shift, immI_nonneg_mask mask) %{
11264 match(Set dst (AndI (URShiftI src shift) mask));
11266 format %{ "ext $dst, $src, $shift, one-bits($mask) #@shr_logical_Reg_imm_nonneg_mask" %}
11267 ins_encode %{
11268 Register src = $src$$Register;
11269 Register dst = $dst$$Register;
11270 int pos = $shift$$constant;
11271 int size = Assembler::is_int_mask($mask$$constant);
11273 __ ext(dst, src, pos, size);
11274 %}
11275 ins_pipe( ialu_regI_regI );
11276 %}
11278 instruct rolI_Reg_immI_0_31(mRegI dst, immI_0_31 lshift, immI_0_31 rshift)
11279 %{
11280 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
11281 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
11283 ins_cost(100);
11284 format %{ "rotr $dst, $dst, $rshift #@rolI_Reg_immI_0_31" %}
11285 ins_encode %{
11286 Register dst = $dst$$Register;
11287 int sa = $rshift$$constant;
11289 __ rotr(dst, dst, sa);
11290 %}
11291 ins_pipe( ialu_regI_regI );
11292 %}
11294 instruct rolL_Reg_immI_0_31(mRegL dst, immI_32_63 lshift, immI_0_31 rshift)
11295 %{
11296 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
11297 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
11299 ins_cost(100);
11300 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_0_31" %}
11301 ins_encode %{
11302 Register dst = $dst$$Register;
11303 int sa = $rshift$$constant;
11305 __ drotr(dst, dst, sa);
11306 %}
11307 ins_pipe( ialu_regI_regI );
11308 %}
11310 instruct rolL_Reg_immI_32_63(mRegL dst, immI_0_31 lshift, immI_32_63 rshift)
11311 %{
11312 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
11313 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
11315 ins_cost(100);
11316 format %{ "rotr $dst, $dst, $rshift #@rolL_Reg_immI_32_63" %}
11317 ins_encode %{
11318 Register dst = $dst$$Register;
11319 int sa = $rshift$$constant;
11321 __ drotr32(dst, dst, sa - 32);
11322 %}
11323 ins_pipe( ialu_regI_regI );
11324 %}
11326 instruct rorI_Reg_immI_0_31(mRegI dst, immI_0_31 rshift, immI_0_31 lshift)
11327 %{
11328 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
11329 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
11331 ins_cost(100);
11332 format %{ "rotr $dst, $dst, $rshift #@rorI_Reg_immI_0_31" %}
11333 ins_encode %{
11334 Register dst = $dst$$Register;
11335 int sa = $rshift$$constant;
11337 __ rotr(dst, dst, sa);
11338 %}
11339 ins_pipe( ialu_regI_regI );
11340 %}
11342 instruct rorL_Reg_immI_0_31(mRegL dst, immI_0_31 rshift, immI_32_63 lshift)
11343 %{
11344 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
11345 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
11347 ins_cost(100);
11348 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_0_31" %}
11349 ins_encode %{
11350 Register dst = $dst$$Register;
11351 int sa = $rshift$$constant;
11353 __ drotr(dst, dst, sa);
11354 %}
11355 ins_pipe( ialu_regI_regI );
11356 %}
11358 instruct rorL_Reg_immI_32_63(mRegL dst, immI_32_63 rshift, immI_0_31 lshift)
11359 %{
11360 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
11361 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
11363 ins_cost(100);
11364 format %{ "rotr $dst, $dst, $rshift #@rorL_Reg_immI_32_63" %}
11365 ins_encode %{
11366 Register dst = $dst$$Register;
11367 int sa = $rshift$$constant;
11369 __ drotr32(dst, dst, sa - 32);
11370 %}
11371 ins_pipe( ialu_regI_regI );
11372 %}
11374 // Logical Shift Right
11375 instruct shr_logical_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
11376 match(Set dst (URShiftI src shift));
11378 format %{ "SRL $dst, $src, $shift #@shr_logical_Reg_Reg" %}
11379 ins_encode %{
11380 Register src = $src$$Register;
11381 Register dst = $dst$$Register;
11382 Register shift = $shift$$Register;
11383 __ srlv(dst, src, shift);
11384 %}
11385 ins_pipe( ialu_regI_regI );
11386 %}
11389 instruct shr_arith_Reg_imm(mRegI dst, mRegI src, immI8 shift) %{
11390 match(Set dst (RShiftI src shift));
11391 // effect(KILL cr);
11393 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_imm" %}
11394 ins_encode %{
11395 Register src = $src$$Register;
11396 Register dst = $dst$$Register;
11397 int shift = $shift$$constant;
11398 __ sra(dst, src, shift);
11399 %}
11400 ins_pipe( ialu_regI_regI );
11401 %}
11403 instruct shr_arith_Reg_Reg(mRegI dst, mRegI src, mRegI shift) %{
11404 match(Set dst (RShiftI src shift));
11405 // effect(KILL cr);
11407 format %{ "SRA $dst, $src, $shift #@shr_arith_Reg_Reg" %}
11408 ins_encode %{
11409 Register src = $src$$Register;
11410 Register dst = $dst$$Register;
11411 Register shift = $shift$$Register;
11412 __ srav(dst, src, shift);
11413 %}
11414 ins_pipe( ialu_regI_regI );
11415 %}
11417 //----------Convert Int to Boolean---------------------------------------------
11419 instruct convI2B(mRegI dst, mRegI src) %{
11420 match(Set dst (Conv2B src));
11422 ins_cost(100);
11423 format %{ "convI2B $dst, $src @ convI2B" %}
11424 ins_encode %{
11425 Register dst = as_Register($dst$$reg);
11426 Register src = as_Register($src$$reg);
11428 if (dst != src) {
11429 __ daddiu(dst, R0, 1);
11430 __ movz(dst, R0, src);
11431 } else {
11432 __ move(AT, src);
11433 __ daddiu(dst, R0, 1);
11434 __ movz(dst, R0, AT);
11435 }
11436 %}
11438 ins_pipe( ialu_regL_regL );
11439 %}
11441 instruct convI2L_reg( mRegL dst, mRegI src) %{
11442 match(Set dst (ConvI2L src));
11444 ins_cost(100);
11445 format %{ "SLL $dst, $src @ convI2L_reg\t" %}
11446 ins_encode %{
11447 Register dst = as_Register($dst$$reg);
11448 Register src = as_Register($src$$reg);
11450 if(dst != src) __ sll(dst, src, 0);
11451 %}
11452 ins_pipe( ialu_regL_regL );
11453 %}
11456 instruct convL2I_reg( mRegI dst, mRegL src ) %{
11457 match(Set dst (ConvL2I src));
11459 format %{ "MOV $dst, $src @ convL2I_reg" %}
11460 ins_encode %{
11461 Register dst = as_Register($dst$$reg);
11462 Register src = as_Register($src$$reg);
11464 __ sll(dst, src, 0);
11465 %}
11467 ins_pipe( ialu_regI_regI );
11468 %}
11470 instruct convL2I2L_reg( mRegL dst, mRegL src ) %{
11471 match(Set dst (ConvI2L (ConvL2I src)));
11473 format %{ "sll $dst, $src, 0 @ convL2I2L_reg" %}
11474 ins_encode %{
11475 Register dst = as_Register($dst$$reg);
11476 Register src = as_Register($src$$reg);
11478 __ sll(dst, src, 0);
11479 %}
11481 ins_pipe( ialu_regI_regI );
11482 %}
11484 instruct convL2D_reg( regD dst, mRegL src ) %{
11485 match(Set dst (ConvL2D src));
11486 format %{ "convL2D $dst, $src @ convL2D_reg" %}
11487 ins_encode %{
11488 Register src = as_Register($src$$reg);
11489 FloatRegister dst = as_FloatRegister($dst$$reg);
11491 __ dmtc1(src, dst);
11492 __ cvt_d_l(dst, dst);
11493 %}
11495 ins_pipe( pipe_slow );
11496 %}
11499 instruct convD2L_reg_fast( mRegL dst, regD src ) %{
11500 match(Set dst (ConvD2L src));
11501 ins_cost(150);
11502 format %{ "convD2L $dst, $src @ convD2L_reg_fast" %}
11503 ins_encode %{
11504 Register dst = as_Register($dst$$reg);
11505 FloatRegister src = as_FloatRegister($src$$reg);
11507 Label Done;
11509 __ trunc_l_d(F30, src);
11510 // max_long: 0x7fffffffffffffff
11511 // __ set64(AT, 0x7fffffffffffffff);
11512 __ daddiu(AT, R0, -1);
11513 __ dsrl(AT, AT, 1);
11514 __ dmfc1(dst, F30);
11516 __ bne(dst, AT, Done);
11517 __ delayed()->mtc1(R0, F30);
11519 __ cvt_d_w(F30, F30);
11520 __ c_ult_d(src, F30);
11521 __ bc1f(Done);
11522 __ delayed()->daddiu(T9, R0, -1);
11524 __ c_un_d(src, src); //NaN?
11525 __ subu(dst, T9, AT);
11526 __ movt(dst, R0);
11528 __ bind(Done);
11529 %}
11531 ins_pipe( pipe_slow );
11532 %}
11535 instruct convD2L_reg_slow( mRegL dst, regD src ) %{
11536 match(Set dst (ConvD2L src));
11537 ins_cost(250);
11538 format %{ "convD2L $dst, $src @ convD2L_reg_slow" %}
11539 ins_encode %{
11540 Register dst = as_Register($dst$$reg);
11541 FloatRegister src = as_FloatRegister($src$$reg);
11543 Label L;
11545 __ c_un_d(src, src); //NaN?
11546 __ bc1t(L);
11547 __ delayed();
11548 __ move(dst, R0);
11550 __ trunc_l_d(F30, src);
11551 __ cfc1(AT, 31);
11552 __ li(T9, 0x10000);
11553 __ andr(AT, AT, T9);
11554 __ beq(AT, R0, L);
11555 __ delayed()->dmfc1(dst, F30);
11557 __ mov_d(F12, src);
11558 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2l), 1);
11559 __ move(dst, V0);
11560 __ bind(L);
11561 %}
11563 ins_pipe( pipe_slow );
11564 %}
11567 instruct convF2I_reg_fast( mRegI dst, regF src ) %{
11568 match(Set dst (ConvF2I src));
11569 ins_cost(150);
11570 format %{ "convf2i $dst, $src @ convF2I_reg_fast" %}
11571 ins_encode %{
11572 Register dreg = $dst$$Register;
11573 FloatRegister fval = $src$$FloatRegister;
11574 Label L;
11576 __ trunc_w_s(F30, fval);
11577 __ move(AT, 0x7fffffff);
11578 __ mfc1(dreg, F30);
11579 __ c_un_s(fval, fval); //NaN?
11580 __ movt(dreg, R0);
11582 __ bne(AT, dreg, L);
11583 __ delayed()->lui(T9, 0x8000);
11585 __ mfc1(AT, fval);
11586 __ andr(AT, AT, T9);
11588 __ movn(dreg, T9, AT);
11590 __ bind(L);
11592 %}
11594 ins_pipe( pipe_slow );
11595 %}
11599 instruct convF2I_reg_slow( mRegI dst, regF src ) %{
11600 match(Set dst (ConvF2I src));
11601 ins_cost(250);
11602 format %{ "convf2i $dst, $src @ convF2I_reg_slow" %}
11603 ins_encode %{
11604 Register dreg = $dst$$Register;
11605 FloatRegister fval = $src$$FloatRegister;
11606 Label L;
11608 __ c_un_s(fval, fval); //NaN?
11609 __ bc1t(L);
11610 __ delayed();
11611 __ move(dreg, R0);
11613 __ trunc_w_s(F30, fval);
11615 /* Call SharedRuntime:f2i() to do valid convention */
11616 __ cfc1(AT, 31);
11617 __ li(T9, 0x10000);
11618 __ andr(AT, AT, T9);
11619 __ beq(AT, R0, L);
11620 __ delayed()->mfc1(dreg, F30);
11622 __ mov_s(F12, fval);
11624 /* 2014/01/08 Fu : This bug was found when running ezDS's control-panel.
11625 * J 982 C2 javax.swing.text.BoxView.layoutMajorAxis(II[I[I)V (283 bytes) @ 0x000000555c46aa74
11626 *
11627 * An interger array index has been assigned to V0, and then changed from 1 to Integer.MAX_VALUE.
11628 * V0 is corrupted during call_VM_leaf(), and should be preserved.
11629 */
11630 __ push(fval);
11631 if(dreg != V0) {
11632 __ push(V0);
11633 }
11634 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2i), 1);
11635 if(dreg != V0) {
11636 __ move(dreg, V0);
11637 __ pop(V0);
11638 }
11639 __ pop(fval);
11640 __ bind(L);
11641 %}
11643 ins_pipe( pipe_slow );
11644 %}
11647 instruct convF2L_reg_fast( mRegL dst, regF src ) %{
11648 match(Set dst (ConvF2L src));
11649 ins_cost(150);
11650 format %{ "convf2l $dst, $src @ convF2L_reg_fast" %}
11651 ins_encode %{
11652 Register dreg = $dst$$Register;
11653 FloatRegister fval = $src$$FloatRegister;
11654 Label L;
11656 __ trunc_l_s(F30, fval);
11657 __ daddiu(AT, R0, -1);
11658 __ dsrl(AT, AT, 1);
11659 __ dmfc1(dreg, F30);
11660 __ c_un_s(fval, fval); //NaN?
11661 __ movt(dreg, R0);
11663 __ bne(AT, dreg, L);
11664 __ delayed()->lui(T9, 0x8000);
11666 __ mfc1(AT, fval);
11667 __ andr(AT, AT, T9);
11669 __ dsll32(T9, T9, 0);
11670 __ movn(dreg, T9, AT);
11672 __ bind(L);
11673 %}
11675 ins_pipe( pipe_slow );
11676 %}
11679 instruct convF2L_reg_slow( mRegL dst, regF src ) %{
11680 match(Set dst (ConvF2L src));
11681 ins_cost(250);
11682 format %{ "convf2l $dst, $src @ convF2L_reg_slow" %}
11683 ins_encode %{
11684 Register dst = as_Register($dst$$reg);
11685 FloatRegister fval = $src$$FloatRegister;
11686 Label L;
11688 __ c_un_s(fval, fval); //NaN?
11689 __ bc1t(L);
11690 __ delayed();
11691 __ move(dst, R0);
11693 __ trunc_l_s(F30, fval);
11694 __ cfc1(AT, 31);
11695 __ li(T9, 0x10000);
11696 __ andr(AT, AT, T9);
11697 __ beq(AT, R0, L);
11698 __ delayed()->dmfc1(dst, F30);
11700 __ mov_s(F12, fval);
11701 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::f2l), 1);
11702 __ move(dst, V0);
11703 __ bind(L);
11704 %}
11706 ins_pipe( pipe_slow );
11707 %}
11709 instruct convL2F_reg( regF dst, mRegL src ) %{
11710 match(Set dst (ConvL2F src));
11711 format %{ "convl2f $dst, $src @ convL2F_reg" %}
11712 ins_encode %{
11713 FloatRegister dst = $dst$$FloatRegister;
11714 Register src = as_Register($src$$reg);
11715 Label L;
11717 __ dmtc1(src, dst);
11718 __ cvt_s_l(dst, dst);
11719 %}
11721 ins_pipe( pipe_slow );
11722 %}
11724 instruct convI2F_reg( regF dst, mRegI src ) %{
11725 match(Set dst (ConvI2F src));
11726 format %{ "convi2f $dst, $src @ convI2F_reg" %}
11727 ins_encode %{
11728 Register src = $src$$Register;
11729 FloatRegister dst = $dst$$FloatRegister;
11731 __ mtc1(src, dst);
11732 __ cvt_s_w(dst, dst);
11733 %}
11735 ins_pipe( fpu_regF_regF );
11736 %}
11738 instruct cmpLTMask_immI0( mRegI dst, mRegI p, immI0 zero ) %{
11739 match(Set dst (CmpLTMask p zero));
11740 ins_cost(100);
11742 format %{ "sra $dst, $p, 31 @ cmpLTMask_immI0" %}
11743 ins_encode %{
11744 Register src = $p$$Register;
11745 Register dst = $dst$$Register;
11747 __ sra(dst, src, 31);
11748 %}
11749 ins_pipe( pipe_slow );
11750 %}
11753 instruct cmpLTMask( mRegI dst, mRegI p, mRegI q ) %{
11754 match(Set dst (CmpLTMask p q));
11755 ins_cost(400);
11757 format %{ "cmpLTMask $dst, $p, $q @ cmpLTMask" %}
11758 ins_encode %{
11759 Register p = $p$$Register;
11760 Register q = $q$$Register;
11761 Register dst = $dst$$Register;
11763 __ slt(dst, p, q);
11764 __ subu(dst, R0, dst);
11765 %}
11766 ins_pipe( pipe_slow );
11767 %}
11769 instruct convP2B(mRegI dst, mRegP src) %{
11770 match(Set dst (Conv2B src));
11772 ins_cost(100);
11773 format %{ "convP2B $dst, $src @ convP2B" %}
11774 ins_encode %{
11775 Register dst = as_Register($dst$$reg);
11776 Register src = as_Register($src$$reg);
11778 if (dst != src) {
11779 __ daddiu(dst, R0, 1);
11780 __ movz(dst, R0, src);
11781 } else {
11782 __ move(AT, src);
11783 __ daddiu(dst, R0, 1);
11784 __ movz(dst, R0, AT);
11785 }
11786 %}
11788 ins_pipe( ialu_regL_regL );
11789 %}
11792 instruct convI2D_reg_reg(regD dst, mRegI src) %{
11793 match(Set dst (ConvI2D src));
11794 format %{ "conI2D $dst, $src @convI2D_reg" %}
11795 ins_encode %{
11796 Register src = $src$$Register;
11797 FloatRegister dst = $dst$$FloatRegister;
11798 __ mtc1(src, dst);
11799 __ cvt_d_w(dst, dst);
11800 %}
11801 ins_pipe( fpu_regF_regF );
11802 %}
11804 instruct convF2D_reg_reg(regD dst, regF src) %{
11805 match(Set dst (ConvF2D src));
11806 format %{ "convF2D $dst, $src\t# @convF2D_reg_reg" %}
11807 ins_encode %{
11808 FloatRegister dst = $dst$$FloatRegister;
11809 FloatRegister src = $src$$FloatRegister;
11811 __ cvt_d_s(dst, src);
11812 %}
11813 ins_pipe( fpu_regF_regF );
11814 %}
11816 instruct convD2F_reg_reg(regF dst, regD src) %{
11817 match(Set dst (ConvD2F src));
11818 format %{ "convD2F $dst, $src\t# @convD2F_reg_reg" %}
11819 ins_encode %{
11820 FloatRegister dst = $dst$$FloatRegister;
11821 FloatRegister src = $src$$FloatRegister;
11823 __ cvt_s_d(dst, src);
11824 %}
11825 ins_pipe( fpu_regF_regF );
11826 %}
11829 // Convert a double to an int. If the double is a NAN, stuff a zero in instead.
11830 instruct convD2I_reg_reg_fast( mRegI dst, regD src ) %{
11831 match(Set dst (ConvD2I src));
11833 ins_cost(150);
11834 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_fast" %}
11836 ins_encode %{
11837 FloatRegister src = $src$$FloatRegister;
11838 Register dst = $dst$$Register;
11840 Label Done;
11842 __ trunc_w_d(F30, src);
11843 // max_int: 2147483647
11844 __ move(AT, 0x7fffffff);
11845 __ mfc1(dst, F30);
11847 __ bne(dst, AT, Done);
11848 __ delayed()->mtc1(R0, F30);
11850 __ cvt_d_w(F30, F30);
11851 __ c_ult_d(src, F30);
11852 __ bc1f(Done);
11853 __ delayed()->addiu(T9, R0, -1);
11855 __ c_un_d(src, src); //NaN?
11856 __ subu32(dst, T9, AT);
11857 __ movt(dst, R0);
11859 __ bind(Done);
11860 %}
11861 ins_pipe( pipe_slow );
11862 %}
11865 instruct convD2I_reg_reg_slow( mRegI dst, regD src ) %{
11866 match(Set dst (ConvD2I src));
11868 ins_cost(250);
11869 format %{ "convD2I $dst, $src\t# @ convD2I_reg_reg_slow" %}
11871 ins_encode %{
11872 FloatRegister src = $src$$FloatRegister;
11873 Register dst = $dst$$Register;
11874 Label L;
11876 __ trunc_w_d(F30, src);
11877 __ cfc1(AT, 31);
11878 __ li(T9, 0x10000);
11879 __ andr(AT, AT, T9);
11880 __ beq(AT, R0, L);
11881 __ delayed()->mfc1(dst, F30);
11883 __ mov_d(F12, src);
11884 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::d2i), 1);
11885 __ move(dst, V0);
11886 __ bind(L);
11888 %}
11889 ins_pipe( pipe_slow );
11890 %}
11892 // Convert oop pointer into compressed form
11893 instruct encodeHeapOop(mRegN dst, mRegP src) %{
11894 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
11895 match(Set dst (EncodeP src));
11896 format %{ "encode_heap_oop $dst,$src" %}
11897 ins_encode %{
11898 Register src = $src$$Register;
11899 Register dst = $dst$$Register;
11901 __ encode_heap_oop(dst, src);
11902 %}
11903 ins_pipe( ialu_regL_regL );
11904 %}
11906 instruct encodeHeapOop_not_null(mRegN dst, mRegP src) %{
11907 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
11908 match(Set dst (EncodeP src));
11909 format %{ "encode_heap_oop_not_null $dst,$src @ encodeHeapOop_not_null" %}
11910 ins_encode %{
11911 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
11912 %}
11913 ins_pipe( ialu_regL_regL );
11914 %}
11916 instruct decodeHeapOop(mRegP dst, mRegN src) %{
11917 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
11918 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
11919 match(Set dst (DecodeN src));
11920 format %{ "decode_heap_oop $dst,$src @ decodeHeapOop" %}
11921 ins_encode %{
11922 Register s = $src$$Register;
11923 Register d = $dst$$Register;
11925 __ decode_heap_oop(d, s);
11926 %}
11927 ins_pipe( ialu_regL_regL );
11928 %}
11930 instruct decodeHeapOop_not_null(mRegP dst, mRegN src) %{
11931 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
11932 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
11933 match(Set dst (DecodeN src));
11934 format %{ "decode_heap_oop_not_null $dst,$src @ decodeHeapOop_not_null" %}
11935 ins_encode %{
11936 Register s = $src$$Register;
11937 Register d = $dst$$Register;
11938 if (s != d) {
11939 __ decode_heap_oop_not_null(d, s);
11940 } else {
11941 __ decode_heap_oop_not_null(d);
11942 }
11943 %}
11944 ins_pipe( ialu_regL_regL );
11945 %}
11947 instruct encodeKlass_not_null(mRegN dst, mRegP src) %{
11948 match(Set dst (EncodePKlass src));
11949 format %{ "encode_heap_oop_not_null $dst,$src @ encodeKlass_not_null" %}
11950 ins_encode %{
11951 __ encode_klass_not_null($dst$$Register, $src$$Register);
11952 %}
11953 ins_pipe( ialu_regL_regL );
11954 %}
11956 instruct decodeKlass_not_null(mRegP dst, mRegN src) %{
11957 match(Set dst (DecodeNKlass src));
11958 format %{ "decode_heap_klass_not_null $dst,$src" %}
11959 ins_encode %{
11960 Register s = $src$$Register;
11961 Register d = $dst$$Register;
11962 if (s != d) {
11963 __ decode_klass_not_null(d, s);
11964 } else {
11965 __ decode_klass_not_null(d);
11966 }
11967 %}
11968 ins_pipe( ialu_regL_regL );
11969 %}
11971 //FIXME
11972 instruct tlsLoadP(mRegP dst) %{
11973 match(Set dst (ThreadLocal));
11975 ins_cost(0);
11976 format %{ " get_thread in $dst #@tlsLoadP" %}
11977 ins_encode %{
11978 Register dst = $dst$$Register;
11979 #ifdef OPT_THREAD
11980 __ move(dst, TREG);
11981 #else
11982 __ get_thread(dst);
11983 #endif
11984 %}
11986 ins_pipe( ialu_loadI );
11987 %}
11990 instruct checkCastPP( mRegP dst ) %{
11991 match(Set dst (CheckCastPP dst));
11993 format %{ "#checkcastPP of $dst (empty encoding) #@chekCastPP" %}
11994 ins_encode( /*empty encoding*/ );
11995 ins_pipe( empty );
11996 %}
11998 instruct castPP(mRegP dst)
11999 %{
12000 match(Set dst (CastPP dst));
12002 size(0);
12003 format %{ "# castPP of $dst" %}
12004 ins_encode(/* empty encoding */);
12005 ins_pipe(empty);
12006 %}
12008 instruct castII( mRegI dst ) %{
12009 match(Set dst (CastII dst));
12010 format %{ "#castII of $dst empty encoding" %}
12011 ins_encode( /*empty encoding*/ );
12012 ins_cost(0);
12013 ins_pipe( empty );
12014 %}
12016 // Return Instruction
12017 // Remove the return address & jump to it.
12018 instruct Ret() %{
12019 match(Return);
12020 format %{ "RET #@Ret" %}
12022 ins_encode %{
12023 __ jr(RA);
12024 __ nop();
12025 %}
12027 ins_pipe( pipe_jump );
12028 %}
12030 /*
12031 // For Loongson CPUs, jr seems too slow, so this rule shouldn't be imported.
12032 instruct jumpXtnd(mRegL switch_val) %{
12033 match(Jump switch_val);
12035 ins_cost(350);
12037 format %{ "load T9 <-- [$constanttablebase, $switch_val, $constantoffset] @ jumpXtnd\n\t"
12038 "jr T9\n\t"
12039 "nop" %}
12040 ins_encode %{
12041 Register table_base = $constanttablebase;
12042 int con_offset = $constantoffset;
12043 Register switch_reg = $switch_val$$Register;
12045 if (UseLoongsonISA) {
12046 if (Assembler::is_simm(con_offset, 8)) {
12047 __ gsldx(T9, table_base, switch_reg, con_offset);
12048 } else if (Assembler::is_simm16(con_offset)) {
12049 __ daddu(T9, table_base, switch_reg);
12050 __ ld(T9, T9, con_offset);
12051 } else {
12052 __ move(T9, con_offset);
12053 __ daddu(AT, table_base, switch_reg);
12054 __ gsldx(T9, AT, T9, 0);
12055 }
12056 } else {
12057 if (Assembler::is_simm16(con_offset)) {
12058 __ daddu(T9, table_base, switch_reg);
12059 __ ld(T9, T9, con_offset);
12060 } else {
12061 __ move(T9, con_offset);
12062 __ daddu(AT, table_base, switch_reg);
12063 __ daddu(AT, T9, AT);
12064 __ ld(T9, AT, 0);
12065 }
12066 }
12068 __ jr(T9);
12069 __ nop();
12071 %}
12072 ins_pipe(pipe_jump);
12073 %}
12074 */
12076 // Jump Direct - Label defines a relative address from JMP
12077 instruct jmpDir(label labl) %{
12078 match(Goto);
12079 effect(USE labl);
12081 ins_cost(300);
12082 format %{ "JMP $labl #@jmpDir" %}
12084 ins_encode %{
12085 Label &L = *($labl$$label);
12086 if(&L)
12087 __ b(L);
12088 else
12089 __ b(int(0));
12090 __ nop();
12091 %}
12093 ins_pipe( pipe_jump );
12094 ins_pc_relative(1);
12095 %}
12099 // Tail Jump; remove the return address; jump to target.
12100 // TailCall above leaves the return address around.
12101 // TailJump is used in only one place, the rethrow_Java stub (fancy_jump=2).
12102 // ex_oop (Exception Oop) is needed in %o0 at the jump. As there would be a
12103 // "restore" before this instruction (in Epilogue), we need to materialize it
12104 // in %i0.
12105 //FIXME
12106 instruct tailjmpInd(mRegP jump_target,mRegP ex_oop) %{
12107 match( TailJump jump_target ex_oop );
12108 ins_cost(200);
12109 format %{ "Jmp $jump_target ; ex_oop = $ex_oop #@tailjmpInd" %}
12110 ins_encode %{
12111 Register target = $jump_target$$Register;
12113 /* 2012/9/14 Jin: V0, V1 are indicated in:
12114 * [stubGenerator_mips.cpp] generate_forward_exception()
12115 * [runtime_mips.cpp] OptoRuntime::generate_exception_blob()
12116 */
12117 Register oop = $ex_oop$$Register;
12118 Register exception_oop = V0;
12119 Register exception_pc = V1;
12121 __ move(exception_pc, RA);
12122 __ move(exception_oop, oop);
12124 __ jr(target);
12125 __ nop();
12126 %}
12127 ins_pipe( pipe_jump );
12128 %}
12130 // ============================================================================
12131 // Procedure Call/Return Instructions
12132 // Call Java Static Instruction
12133 // Note: If this code changes, the corresponding ret_addr_offset() and
12134 // compute_padding() functions will have to be adjusted.
12135 instruct CallStaticJavaDirect(method meth) %{
12136 match(CallStaticJava);
12137 effect(USE meth);
12139 ins_cost(300);
12140 format %{ "CALL,static #@CallStaticJavaDirect " %}
12141 ins_encode( Java_Static_Call( meth ) );
12142 ins_pipe( pipe_slow );
12143 ins_pc_relative(1);
12144 %}
12146 // Call Java Dynamic Instruction
12147 // Note: If this code changes, the corresponding ret_addr_offset() and
12148 // compute_padding() functions will have to be adjusted.
12149 instruct CallDynamicJavaDirect(method meth) %{
12150 match(CallDynamicJava);
12151 effect(USE meth);
12153 ins_cost(300);
12154 format %{"MOV IC_Klass, (oop)-1\n\t"
12155 "CallDynamic @ CallDynamicJavaDirect" %}
12156 ins_encode( Java_Dynamic_Call( meth ) );
12157 ins_pipe( pipe_slow );
12158 ins_pc_relative(1);
12159 %}
12161 instruct CallLeafNoFPDirect(method meth) %{
12162 match(CallLeafNoFP);
12163 effect(USE meth);
12165 ins_cost(300);
12166 format %{ "CALL_LEAF_NOFP,runtime " %}
12167 ins_encode(Java_To_Runtime(meth));
12168 ins_pipe( pipe_slow );
12169 ins_pc_relative(1);
12170 ins_alignment(16);
12171 %}
12173 // Prefetch instructions.
12175 instruct prefetchrNTA( memory mem ) %{
12176 match(PrefetchRead mem);
12177 ins_cost(125);
12179 format %{ "pref $mem\t# Prefetch into non-temporal cache for read @ prefetchrNTA" %}
12180 ins_encode %{
12181 int base = $mem$$base;
12182 int index = $mem$$index;
12183 int scale = $mem$$scale;
12184 int disp = $mem$$disp;
12186 if( index != 0 ) {
12187 if (scale == 0) {
12188 __ daddu(AT, as_Register(base), as_Register(index));
12189 } else {
12190 __ dsll(AT, as_Register(index), scale);
12191 __ daddu(AT, as_Register(base), AT);
12192 }
12193 } else {
12194 __ move(AT, as_Register(base));
12195 }
12196 if( Assembler::is_simm16(disp) ) {
12197 __ daddiu(AT, as_Register(base), disp);
12198 __ daddiu(AT, AT, disp);
12199 } else {
12200 __ move(T9, disp);
12201 __ daddu(AT, as_Register(base), T9);
12202 }
12203 __ pref(0, AT, 0); //hint: 0:load
12204 %}
12205 ins_pipe(pipe_slow);
12206 %}
12208 instruct prefetchwNTA( memory mem ) %{
12209 match(PrefetchWrite mem);
12210 ins_cost(125);
12211 format %{ "pref $mem\t# Prefetch to non-temporal cache for write @ prefetchwNTA" %}
12212 ins_encode %{
12213 int base = $mem$$base;
12214 int index = $mem$$index;
12215 int scale = $mem$$scale;
12216 int disp = $mem$$disp;
12218 if( index != 0 ) {
12219 if (scale == 0) {
12220 __ daddu(AT, as_Register(base), as_Register(index));
12221 } else {
12222 __ dsll(AT, as_Register(index), scale);
12223 __ daddu(AT, as_Register(base), AT);
12224 }
12225 } else {
12226 __ move(AT, as_Register(base));
12227 }
12228 if( Assembler::is_simm16(disp) ) {
12229 __ daddiu(AT, as_Register(base), disp);
12230 __ daddiu(AT, AT, disp);
12231 } else {
12232 __ move(T9, disp);
12233 __ daddu(AT, as_Register(base), T9);
12234 }
12235 __ pref(1, AT, 0); //hint: 1:store
12236 %}
12237 ins_pipe(pipe_slow);
12238 %}
12240 // Prefetch instructions for allocation.
12242 instruct prefetchAllocNTA( memory mem ) %{
12243 match(PrefetchAllocation mem);
12244 ins_cost(125);
12245 format %{ "pref $mem\t# Prefetch allocation @ prefetchAllocNTA" %}
12246 ins_encode %{
12247 int base = $mem$$base;
12248 int index = $mem$$index;
12249 int scale = $mem$$scale;
12250 int disp = $mem$$disp;
12252 Register dst = R0;
12254 if( index != 0 ) {
12255 if( Assembler::is_simm16(disp) ) {
12256 if( UseLoongsonISA ) {
12257 if (scale == 0) {
12258 __ gslbx(dst, as_Register(base), as_Register(index), disp);
12259 } else {
12260 __ dsll(AT, as_Register(index), scale);
12261 __ gslbx(dst, as_Register(base), AT, disp);
12262 }
12263 } else {
12264 if (scale == 0) {
12265 __ addu(AT, as_Register(base), as_Register(index));
12266 } else {
12267 __ dsll(AT, as_Register(index), scale);
12268 __ addu(AT, as_Register(base), AT);
12269 }
12270 __ lb(dst, AT, disp);
12271 }
12272 } else {
12273 if (scale == 0) {
12274 __ addu(AT, as_Register(base), as_Register(index));
12275 } else {
12276 __ dsll(AT, as_Register(index), scale);
12277 __ addu(AT, as_Register(base), AT);
12278 }
12279 __ move(T9, disp);
12280 if( UseLoongsonISA ) {
12281 __ gslbx(dst, AT, T9, 0);
12282 } else {
12283 __ addu(AT, AT, T9);
12284 __ lb(dst, AT, 0);
12285 }
12286 }
12287 } else {
12288 if( Assembler::is_simm16(disp) ) {
12289 __ lb(dst, as_Register(base), disp);
12290 } else {
12291 __ move(T9, disp);
12292 if( UseLoongsonISA ) {
12293 __ gslbx(dst, as_Register(base), T9, 0);
12294 } else {
12295 __ addu(AT, as_Register(base), T9);
12296 __ lb(dst, AT, 0);
12297 }
12298 }
12299 }
12300 %}
12301 ins_pipe(pipe_slow);
12302 %}
12305 // Call runtime without safepoint
12306 instruct CallLeafDirect(method meth) %{
12307 match(CallLeaf);
12308 effect(USE meth);
12310 ins_cost(300);
12311 format %{ "CALL_LEAF,runtime #@CallLeafDirect " %}
12312 ins_encode(Java_To_Runtime(meth));
12313 ins_pipe( pipe_slow );
12314 ins_pc_relative(1);
12315 ins_alignment(16);
12316 %}
12318 // Load Char (16bit unsigned)
12319 instruct loadUS(mRegI dst, memory mem) %{
12320 match(Set dst (LoadUS mem));
12322 ins_cost(125);
12323 format %{ "loadUS $dst,$mem @ loadC" %}
12324 ins_encode(load_C_enc(dst, mem));
12325 ins_pipe( ialu_loadI );
12326 %}
12328 instruct loadUS_convI2L(mRegL dst, memory mem) %{
12329 match(Set dst (ConvI2L (LoadUS mem)));
12331 ins_cost(125);
12332 format %{ "loadUS $dst,$mem @ loadUS_convI2L" %}
12333 ins_encode(load_C_enc(dst, mem));
12334 ins_pipe( ialu_loadI );
12335 %}
12337 // Store Char (16bit unsigned)
12338 instruct storeC(memory mem, mRegI src) %{
12339 match(Set mem (StoreC mem src));
12341 ins_cost(125);
12342 format %{ "storeC $src, $mem @ storeC" %}
12343 ins_encode(store_C_reg_enc(mem, src));
12344 ins_pipe( ialu_loadI );
12345 %}
12347 instruct storeC0(memory mem, immI0 zero) %{
12348 match(Set mem (StoreC mem zero));
12350 ins_cost(125);
12351 format %{ "storeC $zero, $mem @ storeC0" %}
12352 ins_encode(store_C0_enc(mem));
12353 ins_pipe( ialu_loadI );
12354 %}
12357 instruct loadConF0(regF dst, immF0 zero) %{
12358 match(Set dst zero);
12359 ins_cost(100);
12361 format %{ "mov $dst, zero @ loadConF0\n"%}
12362 ins_encode %{
12363 FloatRegister dst = $dst$$FloatRegister;
12365 __ mtc1(R0, dst);
12366 %}
12367 ins_pipe( fpu_loadF );
12368 %}
12371 instruct loadConF(regF dst, immF src) %{
12372 match(Set dst src);
12373 ins_cost(125);
12375 format %{ "lwc1 $dst, $constantoffset[$constanttablebase] # load FLOAT $src from table @ loadConF" %}
12376 ins_encode %{
12377 int con_offset = $constantoffset($src);
12379 if (Assembler::is_simm16(con_offset)) {
12380 __ lwc1($dst$$FloatRegister, $constanttablebase, con_offset);
12381 } else {
12382 __ set64(AT, con_offset);
12383 if (UseLoongsonISA) {
12384 __ gslwxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
12385 } else {
12386 __ daddu(AT, $constanttablebase, AT);
12387 __ lwc1($dst$$FloatRegister, AT, 0);
12388 }
12389 }
12390 %}
12391 ins_pipe( fpu_loadF );
12392 %}
12395 instruct loadConD0(regD dst, immD0 zero) %{
12396 match(Set dst zero);
12397 ins_cost(100);
12399 format %{ "mov $dst, zero @ loadConD0"%}
12400 ins_encode %{
12401 FloatRegister dst = as_FloatRegister($dst$$reg);
12403 __ dmtc1(R0, dst);
12404 %}
12405 ins_pipe( fpu_loadF );
12406 %}
12408 instruct loadConD(regD dst, immD src) %{
12409 match(Set dst src);
12410 ins_cost(125);
12412 format %{ "ldc1 $dst, $constantoffset[$constanttablebase] # load DOUBLE $src from table @ loadConD" %}
12413 ins_encode %{
12414 int con_offset = $constantoffset($src);
12416 if (Assembler::is_simm16(con_offset)) {
12417 __ ldc1($dst$$FloatRegister, $constanttablebase, con_offset);
12418 } else {
12419 __ set64(AT, con_offset);
12420 if (UseLoongsonISA) {
12421 __ gsldxc1($dst$$FloatRegister, $constanttablebase, AT, 0);
12422 } else {
12423 __ daddu(AT, $constanttablebase, AT);
12424 __ ldc1($dst$$FloatRegister, AT, 0);
12425 }
12426 }
12427 %}
12428 ins_pipe( fpu_loadF );
12429 %}
12431 // Store register Float value (it is faster than store from FPU register)
12432 instruct storeF_reg( memory mem, regF src) %{
12433 match(Set mem (StoreF mem src));
12435 ins_cost(50);
12436 format %{ "store $mem, $src\t# store float @ storeF_reg" %}
12437 ins_encode(store_F_reg_enc(mem, src));
12438 ins_pipe( fpu_storeF );
12439 %}
12441 instruct storeF_imm0( memory mem, immF0 zero) %{
12442 match(Set mem (StoreF mem zero));
12444 ins_cost(40);
12445 format %{ "store $mem, zero\t# store float @ storeF_imm0" %}
12446 ins_encode %{
12447 int base = $mem$$base;
12448 int index = $mem$$index;
12449 int scale = $mem$$scale;
12450 int disp = $mem$$disp;
12452 if( index != 0 ) {
12453 if ( UseLoongsonISA ) {
12454 if ( Assembler::is_simm(disp, 8) ) {
12455 if ( scale == 0 ) {
12456 __ gsswx(R0, as_Register(base), as_Register(index), disp);
12457 } else {
12458 __ dsll(T9, as_Register(index), scale);
12459 __ gsswx(R0, as_Register(base), T9, disp);
12460 }
12461 } else if ( Assembler::is_simm16(disp) ) {
12462 if ( scale == 0 ) {
12463 __ daddu(AT, as_Register(base), as_Register(index));
12464 } else {
12465 __ dsll(T9, as_Register(index), scale);
12466 __ daddu(AT, as_Register(base), T9);
12467 }
12468 __ sw(R0, AT, disp);
12469 } else {
12470 if ( scale == 0 ) {
12471 __ move(T9, disp);
12472 __ daddu(AT, as_Register(index), T9);
12473 __ gsswx(R0, as_Register(base), AT, 0);
12474 } else {
12475 __ dsll(T9, as_Register(index), scale);
12476 __ move(AT, disp);
12477 __ daddu(AT, AT, T9);
12478 __ gsswx(R0, as_Register(base), AT, 0);
12479 }
12480 }
12481 } else { //not use loongson isa
12482 if(scale != 0) {
12483 __ dsll(T9, as_Register(index), scale);
12484 __ daddu(AT, as_Register(base), T9);
12485 } else {
12486 __ daddu(AT, as_Register(base), as_Register(index));
12487 }
12488 if( Assembler::is_simm16(disp) ) {
12489 __ sw(R0, AT, disp);
12490 } else {
12491 __ move(T9, disp);
12492 __ daddu(AT, AT, T9);
12493 __ sw(R0, AT, 0);
12494 }
12495 }
12496 } else { //index is 0
12497 if ( UseLoongsonISA ) {
12498 if ( Assembler::is_simm16(disp) ) {
12499 __ sw(R0, as_Register(base), disp);
12500 } else {
12501 __ move(T9, disp);
12502 __ gsswx(R0, as_Register(base), T9, 0);
12503 }
12504 } else {
12505 if( Assembler::is_simm16(disp) ) {
12506 __ sw(R0, as_Register(base), disp);
12507 } else {
12508 __ move(T9, disp);
12509 __ daddu(AT, as_Register(base), T9);
12510 __ sw(R0, AT, 0);
12511 }
12512 }
12513 }
12514 %}
12515 ins_pipe( ialu_storeI );
12516 %}
12518 // Load Double
12519 instruct loadD(regD dst, memory mem) %{
12520 match(Set dst (LoadD mem));
12522 ins_cost(150);
12523 format %{ "loadD $dst, $mem #@loadD" %}
12524 ins_encode(load_D_enc(dst, mem));
12525 ins_pipe( ialu_loadI );
12526 %}
12528 // Load Double - UNaligned
12529 instruct loadD_unaligned(regD dst, memory mem ) %{
12530 match(Set dst (LoadD_unaligned mem));
12531 ins_cost(250);
12532 // FIXME: Jin: Need more effective ldl/ldr
12533 format %{ "loadD_unaligned $dst, $mem #@loadD_unaligned" %}
12534 ins_encode(load_D_enc(dst, mem));
12535 ins_pipe( ialu_loadI );
12536 %}
12538 instruct storeD_reg( memory mem, regD src) %{
12539 match(Set mem (StoreD mem src));
12541 ins_cost(50);
12542 format %{ "store $mem, $src\t# store float @ storeD_reg" %}
12543 ins_encode(store_D_reg_enc(mem, src));
12544 ins_pipe( fpu_storeF );
12545 %}
12547 instruct storeD_imm0( memory mem, immD0 zero) %{
12548 match(Set mem (StoreD mem zero));
12550 ins_cost(40);
12551 format %{ "store $mem, zero\t# store float @ storeD_imm0" %}
12552 ins_encode %{
12553 int base = $mem$$base;
12554 int index = $mem$$index;
12555 int scale = $mem$$scale;
12556 int disp = $mem$$disp;
12558 __ mtc1(R0, F30);
12559 __ cvt_d_w(F30, F30);
12561 if( index != 0 ) {
12562 if ( UseLoongsonISA ) {
12563 if ( Assembler::is_simm(disp, 8) ) {
12564 if (scale == 0) {
12565 __ gssdxc1(F30, as_Register(base), as_Register(index), disp);
12566 } else {
12567 __ dsll(T9, as_Register(index), scale);
12568 __ gssdxc1(F30, as_Register(base), T9, disp);
12569 }
12570 } else if ( Assembler::is_simm16(disp) ) {
12571 if (scale == 0) {
12572 __ daddu(AT, as_Register(base), as_Register(index));
12573 __ sdc1(F30, AT, disp);
12574 } else {
12575 __ dsll(T9, as_Register(index), scale);
12576 __ daddu(AT, as_Register(base), T9);
12577 __ sdc1(F30, AT, disp);
12578 }
12579 } else {
12580 if (scale == 0) {
12581 __ move(T9, disp);
12582 __ daddu(AT, as_Register(index), T9);
12583 __ gssdxc1(F30, as_Register(base), AT, 0);
12584 } else {
12585 __ move(T9, disp);
12586 __ dsll(AT, as_Register(index), scale);
12587 __ daddu(AT, AT, T9);
12588 __ gssdxc1(F30, as_Register(base), AT, 0);
12589 }
12590 }
12591 } else { // not use loongson isa
12592 if(scale != 0) {
12593 __ dsll(T9, as_Register(index), scale);
12594 __ daddu(AT, as_Register(base), T9);
12595 } else {
12596 __ daddu(AT, as_Register(base), as_Register(index));
12597 }
12598 if( Assembler::is_simm16(disp) ) {
12599 __ sdc1(F30, AT, disp);
12600 } else {
12601 __ move(T9, disp);
12602 __ daddu(AT, AT, T9);
12603 __ sdc1(F30, AT, 0);
12604 }
12605 }
12606 } else {// index is 0
12607 if ( UseLoongsonISA ) {
12608 if ( Assembler::is_simm16(disp) ) {
12609 __ sdc1(F30, as_Register(base), disp);
12610 } else {
12611 __ move(T9, disp);
12612 __ gssdxc1(F30, as_Register(base), T9, 0);
12613 }
12614 } else {
12615 if( Assembler::is_simm16(disp) ) {
12616 __ sdc1(F30, as_Register(base), disp);
12617 } else {
12618 __ move(T9, disp);
12619 __ daddu(AT, as_Register(base), T9);
12620 __ sdc1(F30, AT, 0);
12621 }
12622 }
12623 }
12624 %}
12625 ins_pipe( ialu_storeI );
12626 %}
12628 instruct loadSSI(mRegI dst, stackSlotI src)
12629 %{
12630 match(Set dst src);
12632 ins_cost(125);
12633 format %{ "lw $dst, $src\t# int stk @ loadSSI" %}
12634 ins_encode %{
12635 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSI) !");
12636 __ lw($dst$$Register, SP, $src$$disp);
12637 %}
12638 ins_pipe(ialu_loadI);
12639 %}
12641 instruct storeSSI(stackSlotI dst, mRegI src)
12642 %{
12643 match(Set dst src);
12645 ins_cost(100);
12646 format %{ "sw $dst, $src\t# int stk @ storeSSI" %}
12647 ins_encode %{
12648 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSI) !");
12649 __ sw($src$$Register, SP, $dst$$disp);
12650 %}
12651 ins_pipe(ialu_storeI);
12652 %}
12654 instruct loadSSL(mRegL dst, stackSlotL src)
12655 %{
12656 match(Set dst src);
12658 ins_cost(125);
12659 format %{ "ld $dst, $src\t# long stk @ loadSSL" %}
12660 ins_encode %{
12661 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSL) !");
12662 __ ld($dst$$Register, SP, $src$$disp);
12663 %}
12664 ins_pipe(ialu_loadI);
12665 %}
12667 instruct storeSSL(stackSlotL dst, mRegL src)
12668 %{
12669 match(Set dst src);
12671 ins_cost(100);
12672 format %{ "sd $dst, $src\t# long stk @ storeSSL" %}
12673 ins_encode %{
12674 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSL) !");
12675 __ sd($src$$Register, SP, $dst$$disp);
12676 %}
12677 ins_pipe(ialu_storeI);
12678 %}
12680 instruct loadSSP(mRegP dst, stackSlotP src)
12681 %{
12682 match(Set dst src);
12684 ins_cost(125);
12685 format %{ "ld $dst, $src\t# ptr stk @ loadSSP" %}
12686 ins_encode %{
12687 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSP) !");
12688 __ ld($dst$$Register, SP, $src$$disp);
12689 %}
12690 ins_pipe(ialu_loadI);
12691 %}
12693 instruct storeSSP(stackSlotP dst, mRegP src)
12694 %{
12695 match(Set dst src);
12697 ins_cost(100);
12698 format %{ "sd $dst, $src\t# ptr stk @ storeSSP" %}
12699 ins_encode %{
12700 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSP) !");
12701 __ sd($src$$Register, SP, $dst$$disp);
12702 %}
12703 ins_pipe(ialu_storeI);
12704 %}
12706 instruct loadSSF(regF dst, stackSlotF src)
12707 %{
12708 match(Set dst src);
12710 ins_cost(125);
12711 format %{ "lwc1 $dst, $src\t# float stk @ loadSSF" %}
12712 ins_encode %{
12713 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSF) !");
12714 __ lwc1($dst$$FloatRegister, SP, $src$$disp);
12715 %}
12716 ins_pipe(ialu_loadI);
12717 %}
12719 instruct storeSSF(stackSlotF dst, regF src)
12720 %{
12721 match(Set dst src);
12723 ins_cost(100);
12724 format %{ "swc1 $dst, $src\t# float stk @ storeSSF" %}
12725 ins_encode %{
12726 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSF) !");
12727 __ swc1($src$$FloatRegister, SP, $dst$$disp);
12728 %}
12729 ins_pipe(fpu_storeF);
12730 %}
12732 // Use the same format since predicate() can not be used here.
12733 instruct loadSSD(regD dst, stackSlotD src)
12734 %{
12735 match(Set dst src);
12737 ins_cost(125);
12738 format %{ "ldc1 $dst, $src\t# double stk @ loadSSD" %}
12739 ins_encode %{
12740 guarantee( Assembler::is_simm16($src$$disp), "disp too long (loadSSD) !");
12741 __ ldc1($dst$$FloatRegister, SP, $src$$disp);
12742 %}
12743 ins_pipe(ialu_loadI);
12744 %}
12746 instruct storeSSD(stackSlotD dst, regD src)
12747 %{
12748 match(Set dst src);
12750 ins_cost(100);
12751 format %{ "sdc1 $dst, $src\t# double stk @ storeSSD" %}
12752 ins_encode %{
12753 guarantee( Assembler::is_simm16($dst$$disp), "disp too long (storeSSD) !");
12754 __ sdc1($src$$FloatRegister, SP, $dst$$disp);
12755 %}
12756 ins_pipe(fpu_storeF);
12757 %}
12759 instruct cmpFastLock( FlagsReg cr, mRegP object, s0_RegP box, mRegI tmp, mRegP scr) %{
12760 match( Set cr (FastLock object box) );
12761 effect( TEMP tmp, TEMP scr, USE_KILL box );
12762 ins_cost(300);
12763 format %{ "FASTLOCK $cr $object, $box, $tmp #@ cmpFastLock" %}
12764 ins_encode %{
12765 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register);
12766 %}
12768 ins_pipe( pipe_slow );
12769 ins_pc_relative(1);
12770 %}
12772 instruct cmpFastUnlock( FlagsReg cr, mRegP object, s0_RegP box, mRegP tmp ) %{
12773 match( Set cr (FastUnlock object box) );
12774 effect( TEMP tmp, USE_KILL box );
12775 ins_cost(300);
12776 format %{ "FASTUNLOCK $object, $box, $tmp #@cmpFastUnlock" %}
12777 ins_encode %{
12778 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register);
12779 %}
12781 ins_pipe( pipe_slow );
12782 ins_pc_relative(1);
12783 %}
12785 // Store CMS card-mark Immediate
12786 instruct storeImmCM(memory mem, immI8 src) %{
12787 match(Set mem (StoreCM mem src));
12789 ins_cost(150);
12790 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %}
12791 // opcode(0xC6);
12792 ins_encode(store_B_immI_enc_sync(mem, src));
12793 ins_pipe( ialu_storeI );
12794 %}
12796 // Die now
12797 instruct ShouldNotReachHere( )
12798 %{
12799 match(Halt);
12800 ins_cost(300);
12802 // Use the following format syntax
12803 format %{ "ILLTRAP ;#@ShouldNotReachHere" %}
12804 ins_encode %{
12805 // Here we should emit illtrap !
12807 __ stop("in ShoudNotReachHere");
12809 %}
12810 ins_pipe( pipe_jump );
12811 %}
12813 instruct leaP8Narrow(mRegP dst, indOffset8Narrow mem)
12814 %{
12815 predicate(Universe::narrow_oop_shift() == 0);
12816 match(Set dst mem);
12818 ins_cost(110);
12819 format %{ "leaq $dst, $mem\t# ptr off8narrow @ leaP8Narrow" %}
12820 ins_encode %{
12821 Register dst = $dst$$Register;
12822 Register base = as_Register($mem$$base);
12823 int disp = $mem$$disp;
12825 __ daddiu(dst, base, disp);
12826 %}
12827 ins_pipe( ialu_regI_imm16 );
12828 %}
12830 instruct leaPPosIdxScaleOff8(mRegP dst, basePosIndexScaleOffset8 mem)
12831 %{
12832 match(Set dst mem);
12834 ins_cost(110);
12835 format %{ "leaq $dst, $mem\t# @ PosIdxScaleOff8" %}
12836 ins_encode %{
12837 Register dst = $dst$$Register;
12838 Register base = as_Register($mem$$base);
12839 Register index = as_Register($mem$$index);
12840 int scale = $mem$$scale;
12841 int disp = $mem$$disp;
12843 if (scale == 0) {
12844 __ daddu(AT, base, index);
12845 __ daddiu(dst, AT, disp);
12846 } else {
12847 __ dsll(AT, index, scale);
12848 __ daddu(AT, base, AT);
12849 __ daddiu(dst, AT, disp);
12850 }
12851 %}
12853 ins_pipe( ialu_regI_imm16 );
12854 %}
12856 instruct leaPIdxScale(mRegP dst, indIndexScale mem)
12857 %{
12858 match(Set dst mem);
12860 ins_cost(110);
12861 format %{ "leaq $dst, $mem\t# @ leaPIdxScale" %}
12862 ins_encode %{
12863 Register dst = $dst$$Register;
12864 Register base = as_Register($mem$$base);
12865 Register index = as_Register($mem$$index);
12866 int scale = $mem$$scale;
12868 if (scale == 0) {
12869 __ daddu(dst, base, index);
12870 } else {
12871 __ dsll(AT, index, scale);
12872 __ daddu(dst, base, AT);
12873 }
12874 %}
12876 ins_pipe( ialu_regI_imm16 );
12877 %}
12879 // Jump Direct Conditional - Label defines a relative address from Jcc+1
12880 instruct jmpLoopEnd(cmpOp cop, mRegI src1, mRegI src2, label labl) %{
12881 match(CountedLoopEnd cop (CmpI src1 src2));
12882 effect(USE labl);
12884 ins_cost(300);
12885 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd" %}
12886 ins_encode %{
12887 Register op1 = $src1$$Register;
12888 Register op2 = $src2$$Register;
12889 Label &L = *($labl$$label);
12890 int flag = $cop$$cmpcode;
12892 switch(flag) {
12893 case 0x01: //equal
12894 if (&L)
12895 __ beq(op1, op2, L);
12896 else
12897 __ beq(op1, op2, (int)0);
12898 break;
12899 case 0x02: //not_equal
12900 if (&L)
12901 __ bne(op1, op2, L);
12902 else
12903 __ bne(op1, op2, (int)0);
12904 break;
12905 case 0x03: //above
12906 __ slt(AT, op2, op1);
12907 if(&L)
12908 __ bne(AT, R0, L);
12909 else
12910 __ bne(AT, R0, (int)0);
12911 break;
12912 case 0x04: //above_equal
12913 __ slt(AT, op1, op2);
12914 if(&L)
12915 __ beq(AT, R0, L);
12916 else
12917 __ beq(AT, R0, (int)0);
12918 break;
12919 case 0x05: //below
12920 __ slt(AT, op1, op2);
12921 if(&L)
12922 __ bne(AT, R0, L);
12923 else
12924 __ bne(AT, R0, (int)0);
12925 break;
12926 case 0x06: //below_equal
12927 __ slt(AT, op2, op1);
12928 if(&L)
12929 __ beq(AT, R0, L);
12930 else
12931 __ beq(AT, R0, (int)0);
12932 break;
12933 default:
12934 Unimplemented();
12935 }
12936 __ nop();
12937 %}
12938 ins_pipe( pipe_jump );
12939 ins_pc_relative(1);
12940 %}
12942 instruct jmpLoopEnd_reg_immI(cmpOp cop, mRegI src1, immI src2, label labl) %{
12943 match(CountedLoopEnd cop (CmpI src1 src2));
12944 effect(USE labl);
12946 ins_cost(300);
12947 format %{ "J$cop $src1, $src2, $labl\t# Loop end @ jmpLoopEnd_reg_immI" %}
12948 ins_encode %{
12949 Register op1 = $src1$$Register;
12950 Register op2 = AT;
12951 Label &L = *($labl$$label);
12952 int flag = $cop$$cmpcode;
12954 __ move(op2, $src2$$constant);
12956 switch(flag) {
12957 case 0x01: //equal
12958 if (&L)
12959 __ beq(op1, op2, L);
12960 else
12961 __ beq(op1, op2, (int)0);
12962 break;
12963 case 0x02: //not_equal
12964 if (&L)
12965 __ bne(op1, op2, L);
12966 else
12967 __ bne(op1, op2, (int)0);
12968 break;
12969 case 0x03: //above
12970 __ slt(AT, op2, op1);
12971 if(&L)
12972 __ bne(AT, R0, L);
12973 else
12974 __ bne(AT, R0, (int)0);
12975 break;
12976 case 0x04: //above_equal
12977 __ slt(AT, op1, op2);
12978 if(&L)
12979 __ beq(AT, R0, L);
12980 else
12981 __ beq(AT, R0, (int)0);
12982 break;
12983 case 0x05: //below
12984 __ slt(AT, op1, op2);
12985 if(&L)
12986 __ bne(AT, R0, L);
12987 else
12988 __ bne(AT, R0, (int)0);
12989 break;
12990 case 0x06: //below_equal
12991 __ slt(AT, op2, op1);
12992 if(&L)
12993 __ beq(AT, R0, L);
12994 else
12995 __ beq(AT, R0, (int)0);
12996 break;
12997 default:
12998 Unimplemented();
12999 }
13000 __ nop();
13001 %}
13002 ins_pipe( pipe_jump );
13003 ins_pc_relative(1);
13004 %}
13007 // This match pattern is created for StoreIConditional since I cannot match IfNode without a RegFlags! fujie 2012/07/17
13008 instruct jmpCon_flags(cmpOp cop, FlagsReg cr, label labl) %{
13009 match(If cop cr);
13010 effect(USE labl);
13012 ins_cost(300);
13013 format %{ "J$cop $labl #mips uses AT as eflag @jmpCon_flags" %}
13015 ins_encode %{
13016 Label &L = *($labl$$label);
13017 switch($cop$$cmpcode) {
13018 case 0x01: //equal
13019 if (&L)
13020 __ bne(AT, R0, L);
13021 else
13022 __ bne(AT, R0, (int)0);
13023 break;
13024 case 0x02: //not equal
13025 if (&L)
13026 __ beq(AT, R0, L);
13027 else
13028 __ beq(AT, R0, (int)0);
13029 break;
13030 default:
13031 Unimplemented();
13032 }
13033 __ nop();
13034 %}
13036 ins_pipe( pipe_jump );
13037 ins_pc_relative(1);
13038 %}
13041 // ============================================================================
13042 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass
13043 // array for an instance of the superklass. Set a hidden internal cache on a
13044 // hit (cache is checked with exposed code in gen_subtype_check()). Return
13045 // NZ for a miss or zero for a hit. The encoding ALSO sets flags.
13046 instruct partialSubtypeCheck( mRegP result, no_T8_mRegP sub, no_T8_mRegP super, mT8RegI tmp ) %{
13047 match(Set result (PartialSubtypeCheck sub super));
13048 effect(KILL tmp);
13049 ins_cost(1100); // slightly larger than the next version
13050 format %{ "partialSubtypeCheck result=$result, sub=$sub, super=$super, tmp=$tmp " %}
13052 ins_encode( enc_PartialSubtypeCheck(result, sub, super, tmp) );
13053 ins_pipe( pipe_slow );
13054 %}
13057 // Conditional-store of an int value.
13058 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
13059 instruct storeIConditional( memory mem, mRegI oldval, mRegI newval, FlagsReg cr ) %{
13060 match(Set cr (StoreIConditional mem (Binary oldval newval)));
13061 // effect(KILL oldval);
13062 format %{ "CMPXCHG $newval, $mem, $oldval \t# @storeIConditional" %}
13064 ins_encode %{
13065 Register oldval = $oldval$$Register;
13066 Register newval = $newval$$Register;
13067 Address addr(as_Register($mem$$base), $mem$$disp);
13068 Label again, failure;
13070 int index = $mem$$index;
13071 int scale = $mem$$scale;
13072 int disp = $mem$$disp;
13074 guarantee(Assembler::is_simm16(disp), "");
13076 if( index != 0 ) {
13077 __ stop("in storeIConditional: index != 0");
13078 } else {
13079 __ bind(again);
13080 if(UseSyncLevel >= 3000 || UseSyncLevel < 2000) __ sync();
13081 __ ll(AT, addr);
13082 __ bne(AT, oldval, failure);
13083 __ delayed()->addu(AT, R0, R0);
13085 __ addu(AT, newval, R0);
13086 __ sc(AT, addr);
13087 __ beq(AT, R0, again);
13088 __ delayed()->addiu(AT, R0, 0xFF);
13089 __ bind(failure);
13090 __ sync();
13091 }
13092 %}
13094 ins_pipe( long_memory_op );
13095 %}
13097 // Conditional-store of a long value.
13098 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
13099 instruct storeLConditional(memory mem, t2RegL oldval, mRegL newval, FlagsReg cr )
13100 %{
13101 match(Set cr (StoreLConditional mem (Binary oldval newval)));
13102 effect(KILL oldval);
13104 format %{ "cmpxchg $mem, $newval\t# If $oldval == $mem then store $newval into $mem" %}
13105 ins_encode%{
13106 Register oldval = $oldval$$Register;
13107 Register newval = $newval$$Register;
13108 Address addr((Register)$mem$$base, $mem$$disp);
13110 int index = $mem$$index;
13111 int scale = $mem$$scale;
13112 int disp = $mem$$disp;
13114 guarantee(Assembler::is_simm16(disp), "");
13116 if( index != 0 ) {
13117 __ stop("in storeIConditional: index != 0");
13118 } else {
13119 __ cmpxchg(newval, addr, oldval);
13120 }
13121 %}
13122 ins_pipe( long_memory_op );
13123 %}
13126 instruct compareAndSwapI( mRegI res, mRegP mem_ptr, mS2RegI oldval, mRegI newval) %{
13127 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
13128 effect(KILL oldval);
13129 // match(CompareAndSwapI mem_ptr (Binary oldval newval));
13130 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapL\n\t"
13131 "MOV $res, 1 @ compareAndSwapI\n\t"
13132 "BNE AT, R0 @ compareAndSwapI\n\t"
13133 "MOV $res, 0 @ compareAndSwapI\n"
13134 "L:" %}
13135 ins_encode %{
13136 Register newval = $newval$$Register;
13137 Register oldval = $oldval$$Register;
13138 Register res = $res$$Register;
13139 Address addr($mem_ptr$$Register, 0);
13140 Label L;
13142 __ cmpxchg32(newval, addr, oldval);
13143 __ move(res, AT);
13144 %}
13145 ins_pipe( long_memory_op );
13146 %}
13148 instruct compareAndSwapL( mRegI res, mRegP mem_ptr, s2RegL oldval, mRegL newval) %{
13149 predicate(VM_Version::supports_cx8());
13150 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
13151 effect(KILL oldval);
13152 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapI\n\t"
13153 "MOV $res, 1 @ compareAndSwapI\n\t"
13154 "BNE AT, R0 @ compareAndSwapI\n\t"
13155 "MOV $res, 0 @ compareAndSwapI\n"
13156 "L:" %}
13157 ins_encode %{
13158 Register newval = $newval$$Register;
13159 Register oldval = $oldval$$Register;
13160 Register res = $res$$Register;
13161 Address addr($mem_ptr$$Register, 0);
13162 Label L;
13164 __ cmpxchg(newval, addr, oldval);
13165 __ move(res, AT);
13166 %}
13167 ins_pipe( long_memory_op );
13168 %}
13170 //FIXME:
13171 instruct compareAndSwapP( mRegI res, mRegP mem_ptr, s2_RegP oldval, mRegP newval) %{
13172 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
13173 effect(KILL oldval);
13174 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapP\n\t"
13175 "MOV $res, AT @ compareAndSwapP\n\t"
13176 "L:" %}
13177 ins_encode %{
13178 Register newval = $newval$$Register;
13179 Register oldval = $oldval$$Register;
13180 Register res = $res$$Register;
13181 Address addr($mem_ptr$$Register, 0);
13182 Label L;
13184 __ cmpxchg(newval, addr, oldval);
13185 __ move(res, AT);
13186 %}
13187 ins_pipe( long_memory_op );
13188 %}
13190 instruct compareAndSwapN( mRegI res, mRegP mem_ptr, t2_RegN oldval, mRegN newval) %{
13191 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
13192 effect(KILL oldval);
13193 format %{ "CMPXCHG $newval, [$mem_ptr], $oldval @ compareAndSwapN\n\t"
13194 "MOV $res, AT @ compareAndSwapN\n\t"
13195 "L:" %}
13196 ins_encode %{
13197 Register newval = $newval$$Register;
13198 Register oldval = $oldval$$Register;
13199 Register res = $res$$Register;
13200 Address addr($mem_ptr$$Register, 0);
13201 Label L;
13203 /* 2013/7/19 Jin: cmpxchg32 is implemented with ll/sc, which will do sign extension.
13204 * Thus, we should extend oldval's sign for correct comparision.
13205 */
13206 __ sll(oldval, oldval, 0);
13208 __ cmpxchg32(newval, addr, oldval);
13209 __ move(res, AT);
13210 %}
13211 ins_pipe( long_memory_op );
13212 %}
13214 //----------Max and Min--------------------------------------------------------
13215 // Min Instructions
13216 ////
13217 // *** Min and Max using the conditional move are slower than the
13218 // *** branch version on a Pentium III.
13219 // // Conditional move for min
13220 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
13221 // effect( USE_DEF op2, USE op1, USE cr );
13222 // format %{ "CMOVlt $op2,$op1\t! min" %}
13223 // opcode(0x4C,0x0F);
13224 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
13225 // ins_pipe( pipe_cmov_reg );
13226 //%}
13227 //
13228 //// Min Register with Register (P6 version)
13229 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
13230 // predicate(VM_Version::supports_cmov() );
13231 // match(Set op2 (MinI op1 op2));
13232 // ins_cost(200);
13233 // expand %{
13234 // eFlagsReg cr;
13235 // compI_eReg(cr,op1,op2);
13236 // cmovI_reg_lt(op2,op1,cr);
13237 // %}
13238 //%}
13240 // Min Register with Register (generic version)
13241 instruct minI_Reg_Reg(mRegI dst, mRegI src) %{
13242 match(Set dst (MinI dst src));
13243 //effect(KILL flags);
13244 ins_cost(80);
13246 format %{ "MIN $dst, $src @minI_Reg_Reg" %}
13247 ins_encode %{
13248 Register dst = $dst$$Register;
13249 Register src = $src$$Register;
13251 __ slt(AT, src, dst);
13252 __ movn(dst, src, AT);
13254 %}
13256 ins_pipe( pipe_slow );
13257 %}
13259 // Max Register with Register
13260 // *** Min and Max using the conditional move are slower than the
13261 // *** branch version on a Pentium III.
13262 // // Conditional move for max
13263 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
13264 // effect( USE_DEF op2, USE op1, USE cr );
13265 // format %{ "CMOVgt $op2,$op1\t! max" %}
13266 // opcode(0x4F,0x0F);
13267 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
13268 // ins_pipe( pipe_cmov_reg );
13269 //%}
13270 //
13271 // // Max Register with Register (P6 version)
13272 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
13273 // predicate(VM_Version::supports_cmov() );
13274 // match(Set op2 (MaxI op1 op2));
13275 // ins_cost(200);
13276 // expand %{
13277 // eFlagsReg cr;
13278 // compI_eReg(cr,op1,op2);
13279 // cmovI_reg_gt(op2,op1,cr);
13280 // %}
13281 //%}
13283 // Max Register with Register (generic version)
13284 instruct maxI_Reg_Reg(mRegI dst, mRegI src) %{
13285 match(Set dst (MaxI dst src));
13286 ins_cost(80);
13288 format %{ "MAX $dst, $src @maxI_Reg_Reg" %}
13290 ins_encode %{
13291 Register dst = $dst$$Register;
13292 Register src = $src$$Register;
13294 __ slt(AT, dst, src);
13295 __ movn(dst, src, AT);
13297 %}
13299 ins_pipe( pipe_slow );
13300 %}
13302 instruct maxI_Reg_zero(mRegI dst, immI0 zero) %{
13303 match(Set dst (MaxI dst zero));
13304 ins_cost(50);
13306 format %{ "MAX $dst, 0 @maxI_Reg_zero" %}
13308 ins_encode %{
13309 Register dst = $dst$$Register;
13311 __ slt(AT, dst, R0);
13312 __ movn(dst, R0, AT);
13314 %}
13316 ins_pipe( pipe_slow );
13317 %}
13319 instruct zerox_long_reg_reg(mRegL dst, mRegL src, immL_32bits mask)
13320 %{
13321 match(Set dst (AndL src mask));
13323 format %{ "movl $dst, $src\t# zero-extend long @ zerox_long_reg_reg" %}
13324 ins_encode %{
13325 Register dst = $dst$$Register;
13326 Register src = $src$$Register;
13328 __ dext(dst, src, 0, 32);
13329 %}
13330 ins_pipe(ialu_regI_regI);
13331 %}
13333 instruct combine_i2l(mRegL dst, mRegI src1, immL_32bits mask, mRegI src2, immI_32 shift32)
13334 %{
13335 match(Set dst (OrL (AndL (ConvI2L src1) mask) (LShiftL (ConvI2L src2) shift32)));
13337 format %{ "combine_i2l $dst, $src2(H), $src1(L) @ combine_i2l" %}
13338 ins_encode %{
13339 Register dst = $dst$$Register;
13340 Register src1 = $src1$$Register;
13341 Register src2 = $src2$$Register;
13343 if (src1 == dst) {
13344 __ dinsu(dst, src2, 32, 32);
13345 } else if (src2 == dst) {
13346 __ dsll32(dst, dst, 0);
13347 __ dins(dst, src1, 0, 32);
13348 } else {
13349 __ dext(dst, src1, 0, 32);
13350 __ dinsu(dst, src2, 32, 32);
13351 }
13352 %}
13353 ins_pipe(ialu_regI_regI);
13354 %}
13356 // Zero-extend convert int to long
13357 instruct convI2L_reg_reg_zex(mRegL dst, mRegI src, immL_32bits mask)
13358 %{
13359 match(Set dst (AndL (ConvI2L src) mask));
13361 format %{ "movl $dst, $src\t# i2l zero-extend @ convI2L_reg_reg_zex" %}
13362 ins_encode %{
13363 Register dst = $dst$$Register;
13364 Register src = $src$$Register;
13366 __ dext(dst, src, 0, 32);
13367 %}
13368 ins_pipe(ialu_regI_regI);
13369 %}
13371 instruct convL2I2L_reg_reg_zex(mRegL dst, mRegL src, immL_32bits mask)
13372 %{
13373 match(Set dst (AndL (ConvI2L (ConvL2I src)) mask));
13375 format %{ "movl $dst, $src\t# i2l zero-extend @ convL2I2L_reg_reg_zex" %}
13376 ins_encode %{
13377 Register dst = $dst$$Register;
13378 Register src = $src$$Register;
13380 __ dext(dst, src, 0, 32);
13381 %}
13382 ins_pipe(ialu_regI_regI);
13383 %}
13385 // Match loading integer and casting it to unsigned int in long register.
13386 // LoadI + ConvI2L + AndL 0xffffffff.
13387 instruct loadUI2L_rmask(mRegL dst, memory mem, immL_32bits mask) %{
13388 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
13390 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_rmask" %}
13391 ins_encode (load_N_enc(dst, mem));
13392 ins_pipe(ialu_loadI);
13393 %}
13395 instruct loadUI2L_lmask(mRegL dst, memory mem, immL_32bits mask) %{
13396 match(Set dst (AndL mask (ConvI2L (LoadI mem))));
13398 format %{ "lwu $dst, $mem \t// zero-extend to long @ loadUI2L_lmask" %}
13399 ins_encode (load_N_enc(dst, mem));
13400 ins_pipe(ialu_loadI);
13401 %}
13404 // ============================================================================
13405 // Safepoint Instruction
13406 instruct safePoint_poll_reg(mRegP poll) %{
13407 match(SafePoint poll);
13408 predicate(false);
13409 effect(USE poll);
13411 ins_cost(125);
13412 format %{ "Safepoint @ [$poll] : poll for GC @ safePoint_poll_reg" %}
13414 ins_encode %{
13415 Register poll_reg = $poll$$Register;
13417 __ block_comment("Safepoint:");
13418 __ relocate(relocInfo::poll_type);
13419 __ lw(AT, poll_reg, 0);
13420 %}
13422 ins_pipe( ialu_storeI );
13423 %}
13425 instruct safePoint_poll() %{
13426 match(SafePoint);
13428 ins_cost(105);
13429 format %{ "poll for GC @ safePoint_poll" %}
13431 ins_encode %{
13432 __ block_comment("Safepoint:");
13433 __ set64(T9, (long)os::get_polling_page());
13434 __ relocate(relocInfo::poll_type);
13435 __ lw(AT, T9, 0);
13436 %}
13438 ins_pipe( ialu_storeI );
13439 %}
13441 //----------Arithmetic Conversion Instructions---------------------------------
13443 instruct roundFloat_nop(regF dst)
13444 %{
13445 match(Set dst (RoundFloat dst));
13447 ins_cost(0);
13448 ins_encode();
13449 ins_pipe(empty);
13450 %}
13452 instruct roundDouble_nop(regD dst)
13453 %{
13454 match(Set dst (RoundDouble dst));
13456 ins_cost(0);
13457 ins_encode();
13458 ins_pipe(empty);
13459 %}
13461 //---------- Zeros Count Instructions ------------------------------------------
13462 // CountLeadingZerosINode CountTrailingZerosINode
13463 instruct countLeadingZerosI(mRegI dst, mRegI src) %{
13464 predicate(UseCountLeadingZerosInstruction);
13465 match(Set dst (CountLeadingZerosI src));
13467 format %{ "clz $dst, $src\t# count leading zeros (int)" %}
13468 ins_encode %{
13469 __ clz($dst$$Register, $src$$Register);
13470 %}
13471 ins_pipe( ialu_regL_regL );
13472 %}
13474 instruct countLeadingZerosL(mRegI dst, mRegL src) %{
13475 predicate(UseCountLeadingZerosInstruction);
13476 match(Set dst (CountLeadingZerosL src));
13478 format %{ "dclz $dst, $src\t# count leading zeros (long)" %}
13479 ins_encode %{
13480 __ dclz($dst$$Register, $src$$Register);
13481 %}
13482 ins_pipe( ialu_regL_regL );
13483 %}
13485 instruct countTrailingZerosI(mRegI dst, mRegI src) %{
13486 predicate(UseCountTrailingZerosInstruction);
13487 match(Set dst (CountTrailingZerosI src));
13489 format %{ "ctz $dst, $src\t# count trailing zeros (int)" %}
13490 ins_encode %{
13491 // ctz and dctz is gs instructions.
13492 __ ctz($dst$$Register, $src$$Register);
13493 %}
13494 ins_pipe( ialu_regL_regL );
13495 %}
13497 instruct countTrailingZerosL(mRegI dst, mRegL src) %{
13498 predicate(UseCountTrailingZerosInstruction);
13499 match(Set dst (CountTrailingZerosL src));
13501 format %{ "dcto $dst, $src\t# count trailing zeros (long)" %}
13502 ins_encode %{
13503 __ dctz($dst$$Register, $src$$Register);
13504 %}
13505 ins_pipe( ialu_regL_regL );
13506 %}
13508 // ====================VECTOR INSTRUCTIONS=====================================
13510 // Load vectors (8 bytes long)
13511 instruct loadV8(vecD dst, memory mem) %{
13512 predicate(n->as_LoadVector()->memory_size() == 8);
13513 match(Set dst (LoadVector mem));
13514 ins_cost(125);
13515 format %{ "load $dst, $mem\t! load vector (8 bytes)" %}
13516 ins_encode(load_D_enc(dst, mem));
13517 ins_pipe( fpu_loadF );
13518 %}
13520 // Store vectors (8 bytes long)
13521 instruct storeV8(memory mem, vecD src) %{
13522 predicate(n->as_StoreVector()->memory_size() == 8);
13523 match(Set mem (StoreVector mem src));
13524 ins_cost(145);
13525 format %{ "store $mem, $src\t! store vector (8 bytes)" %}
13526 ins_encode(store_D_reg_enc(mem, src));
13527 ins_pipe( fpu_storeF );
13528 %}
13530 instruct Repl8B_DSP(vecD dst, mRegI src) %{
13531 predicate(n->as_Vector()->length() == 8 && Use3A2000);
13532 match(Set dst (ReplicateB src));
13533 ins_cost(100);
13534 format %{ "replv_ob AT, $src\n\t"
13535 "dmtc1 AT, $dst\t! replicate8B" %}
13536 ins_encode %{
13537 __ replv_ob(AT, $src$$Register);
13538 __ dmtc1(AT, $dst$$FloatRegister);
13539 %}
13540 ins_pipe( pipe_mtc1 );
13541 %}
13543 instruct Repl8B(vecD dst, mRegI src) %{
13544 predicate(n->as_Vector()->length() == 8);
13545 match(Set dst (ReplicateB src));
13546 ins_cost(140);
13547 format %{ "move AT, $src\n\t"
13548 "dins AT, AT, 8, 8\n\t"
13549 "dins AT, AT, 16, 16\n\t"
13550 "dinsu AT, AT, 32, 32\n\t"
13551 "dmtc1 AT, $dst\t! replicate8B" %}
13552 ins_encode %{
13553 __ move(AT, $src$$Register);
13554 __ dins(AT, AT, 8, 8);
13555 __ dins(AT, AT, 16, 16);
13556 __ dinsu(AT, AT, 32, 32);
13557 __ dmtc1(AT, $dst$$FloatRegister);
13558 %}
13559 ins_pipe( pipe_mtc1 );
13560 %}
13562 instruct Repl8B_imm_DSP(vecD dst, immI con) %{
13563 predicate(n->as_Vector()->length() == 8 && Use3A2000);
13564 match(Set dst (ReplicateB con));
13565 ins_cost(110);
13566 format %{ "repl_ob AT, [$con]\n\t"
13567 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
13568 ins_encode %{
13569 int val = $con$$constant;
13570 __ repl_ob(AT, val);
13571 __ dmtc1(AT, $dst$$FloatRegister);
13572 %}
13573 ins_pipe( pipe_mtc1 );
13574 %}
13576 instruct Repl8B_imm(vecD dst, immI con) %{
13577 predicate(n->as_Vector()->length() == 8);
13578 match(Set dst (ReplicateB con));
13579 ins_cost(150);
13580 format %{ "move AT, [$con]\n\t"
13581 "dins AT, AT, 8, 8\n\t"
13582 "dins AT, AT, 16, 16\n\t"
13583 "dinsu AT, AT, 32, 32\n\t"
13584 "dmtc1 AT, $dst,0x00\t! replicate8B($con)" %}
13585 ins_encode %{
13586 __ move(AT, $con$$constant);
13587 __ dins(AT, AT, 8, 8);
13588 __ dins(AT, AT, 16, 16);
13589 __ dinsu(AT, AT, 32, 32);
13590 __ dmtc1(AT, $dst$$FloatRegister);
13591 %}
13592 ins_pipe( pipe_mtc1 );
13593 %}
13595 instruct Repl8B_zero(vecD dst, immI0 zero) %{
13596 predicate(n->as_Vector()->length() == 8);
13597 match(Set dst (ReplicateB zero));
13598 ins_cost(90);
13599 format %{ "dmtc1 R0, $dst\t! replicate8B zero" %}
13600 ins_encode %{
13601 __ dmtc1(R0, $dst$$FloatRegister);
13602 %}
13603 ins_pipe( pipe_mtc1 );
13604 %}
13606 instruct Repl8B_M1(vecD dst, immI_M1 M1) %{
13607 predicate(n->as_Vector()->length() == 8);
13608 match(Set dst (ReplicateB M1));
13609 ins_cost(80);
13610 format %{ "dmtc1 -1, $dst\t! replicate8B -1" %}
13611 ins_encode %{
13612 __ nor(AT, R0, R0);
13613 __ dmtc1(AT, $dst$$FloatRegister);
13614 %}
13615 ins_pipe( pipe_mtc1 );
13616 %}
13618 instruct Repl4S_DSP(vecD dst, mRegI src) %{
13619 predicate(n->as_Vector()->length() == 4 && Use3A2000);
13620 match(Set dst (ReplicateS src));
13621 ins_cost(100);
13622 format %{ "replv_qh AT, $src\n\t"
13623 "dmtc1 AT, $dst\t! replicate4S" %}
13624 ins_encode %{
13625 __ replv_qh(AT, $src$$Register);
13626 __ dmtc1(AT, $dst$$FloatRegister);
13627 %}
13628 ins_pipe( pipe_mtc1 );
13629 %}
13631 instruct Repl4S(vecD dst, mRegI src) %{
13632 predicate(n->as_Vector()->length() == 4);
13633 match(Set dst (ReplicateS src));
13634 ins_cost(120);
13635 format %{ "move AT, $src \n\t"
13636 "dins AT, AT, 16, 16\n\t"
13637 "dinsu AT, AT, 32, 32\n\t"
13638 "dmtc1 AT, $dst\t! replicate4S" %}
13639 ins_encode %{
13640 __ move(AT, $src$$Register);
13641 __ dins(AT, AT, 16, 16);
13642 __ dinsu(AT, AT, 32, 32);
13643 __ dmtc1(AT, $dst$$FloatRegister);
13644 %}
13645 ins_pipe( pipe_mtc1 );
13646 %}
13648 instruct Repl4S_imm_DSP(vecD dst, immI con) %{
13649 predicate(n->as_Vector()->length() == 4 && Use3A2000);
13650 match(Set dst (ReplicateS con));
13651 ins_cost(100);
13652 format %{ "repl_qh AT, [$con]\n\t"
13653 "dmtc1 AT, $dst\t! replicate4S($con)" %}
13654 ins_encode %{
13655 int val = $con$$constant;
13656 if ( Assembler::is_simm(val, 10)) {
13657 //repl_qh supports 10 bits immediate
13658 __ repl_qh(AT, val);
13659 } else {
13660 __ li32(AT, val);
13661 __ replv_qh(AT, AT);
13662 }
13663 __ dmtc1(AT, $dst$$FloatRegister);
13664 %}
13665 ins_pipe( pipe_mtc1 );
13666 %}
13668 instruct Repl4S_imm(vecD dst, immI con) %{
13669 predicate(n->as_Vector()->length() == 4);
13670 match(Set dst (ReplicateS con));
13671 ins_cost(110);
13672 format %{ "move AT, [$con]\n\t"
13673 "dins AT, AT, 16, 16\n\t"
13674 "dinsu AT, AT, 32, 32\n\t"
13675 "dmtc1 AT, $dst\t! replicate4S($con)" %}
13676 ins_encode %{
13677 __ move(AT, $con$$constant);
13678 __ dins(AT, AT, 16, 16);
13679 __ dinsu(AT, AT, 32, 32);
13680 __ dmtc1(AT, $dst$$FloatRegister);
13681 %}
13682 ins_pipe( pipe_mtc1 );
13683 %}
13685 instruct Repl4S_zero(vecD dst, immI0 zero) %{
13686 predicate(n->as_Vector()->length() == 4);
13687 match(Set dst (ReplicateS zero));
13688 format %{ "dmtc1 R0, $dst\t! replicate4S zero" %}
13689 ins_encode %{
13690 __ dmtc1(R0, $dst$$FloatRegister);
13691 %}
13692 ins_pipe( pipe_mtc1 );
13693 %}
13695 instruct Repl4S_M1(vecD dst, immI_M1 M1) %{
13696 predicate(n->as_Vector()->length() == 4);
13697 match(Set dst (ReplicateS M1));
13698 format %{ "dmtc1 -1, $dst\t! replicate4S -1" %}
13699 ins_encode %{
13700 __ nor(AT, R0, R0);
13701 __ dmtc1(AT, $dst$$FloatRegister);
13702 %}
13703 ins_pipe( pipe_mtc1 );
13704 %}
13706 // Replicate integer (4 byte) scalar to be vector
13707 instruct Repl2I(vecD dst, mRegI src) %{
13708 predicate(n->as_Vector()->length() == 2);
13709 match(Set dst (ReplicateI src));
13710 format %{ "dins AT, $src, 0, 32\n\t"
13711 "dinsu AT, $src, 32, 32\n\t"
13712 "dmtc1 AT, $dst\t! replicate2I" %}
13713 ins_encode %{
13714 __ dins(AT, $src$$Register, 0, 32);
13715 __ dinsu(AT, $src$$Register, 32, 32);
13716 __ dmtc1(AT, $dst$$FloatRegister);
13717 %}
13718 ins_pipe( pipe_mtc1 );
13719 %}
13721 // Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
13722 instruct Repl2I_imm(vecD dst, immI con, mA7RegI tmp) %{
13723 predicate(n->as_Vector()->length() == 2);
13724 match(Set dst (ReplicateI con));
13725 effect(KILL tmp);
13726 format %{ "li32 AT, [$con], 32\n\t"
13727 "dinsu AT, AT\n\t"
13728 "dmtc1 AT, $dst\t! replicate2I($con)" %}
13729 ins_encode %{
13730 int val = $con$$constant;
13731 __ li32(AT, val);
13732 __ dinsu(AT, AT, 32, 32);
13733 __ dmtc1(AT, $dst$$FloatRegister);
13734 %}
13735 ins_pipe( pipe_mtc1 );
13736 %}
13738 // Replicate integer (4 byte) scalar zero to be vector
13739 instruct Repl2I_zero(vecD dst, immI0 zero) %{
13740 predicate(n->as_Vector()->length() == 2);
13741 match(Set dst (ReplicateI zero));
13742 format %{ "dmtc1 R0, $dst\t! replicate2I zero" %}
13743 ins_encode %{
13744 __ dmtc1(R0, $dst$$FloatRegister);
13745 %}
13746 ins_pipe( pipe_mtc1 );
13747 %}
13749 // Replicate integer (4 byte) scalar -1 to be vector
13750 instruct Repl2I_M1(vecD dst, immI_M1 M1) %{
13751 predicate(n->as_Vector()->length() == 2);
13752 match(Set dst (ReplicateI M1));
13753 format %{ "dmtc1 -1, $dst\t! replicate2I -1, use AT" %}
13754 ins_encode %{
13755 __ nor(AT, R0, R0);
13756 __ dmtc1(AT, $dst$$FloatRegister);
13757 %}
13758 ins_pipe( pipe_mtc1 );
13759 %}
13761 // Replicate float (4 byte) scalar to be vector
13762 instruct Repl2F(vecD dst, regF src) %{
13763 predicate(n->as_Vector()->length() == 2);
13764 match(Set dst (ReplicateF src));
13765 format %{ "cvt.ps $dst, $src, $src\t! replicate2F" %}
13766 ins_encode %{
13767 __ cvt_ps_s($dst$$FloatRegister, $src$$FloatRegister, $src$$FloatRegister);
13768 %}
13769 ins_pipe( pipe_slow );
13770 %}
13772 // Replicate float (4 byte) scalar zero to be vector
13773 instruct Repl2F_zero(vecD dst, immF0 zero) %{
13774 predicate(n->as_Vector()->length() == 2);
13775 match(Set dst (ReplicateF zero));
13776 format %{ "dmtc1 R0, $dst\t! replicate2F zero" %}
13777 ins_encode %{
13778 __ dmtc1(R0, $dst$$FloatRegister);
13779 %}
13780 ins_pipe( pipe_mtc1 );
13781 %}
13784 // ====================VECTOR ARITHMETIC=======================================
13786 // --------------------------------- ADD --------------------------------------
13788 // Floats vector add
13789 // kernel does not have emulation of PS instructions yet, so PS instructions is disabled.
13790 instruct vadd2F(vecD dst, vecD src) %{
13791 predicate(n->as_Vector()->length() == 2);
13792 match(Set dst (AddVF dst src));
13793 format %{ "add.ps $dst,$src\t! add packed2F" %}
13794 ins_encode %{
13795 __ add_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
13796 %}
13797 ins_pipe( pipe_slow );
13798 %}
13800 instruct vadd2F3(vecD dst, vecD src1, vecD src2) %{
13801 predicate(n->as_Vector()->length() == 2);
13802 match(Set dst (AddVF src1 src2));
13803 format %{ "add.ps $dst,$src1,$src2\t! add packed2F" %}
13804 ins_encode %{
13805 __ add_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
13806 %}
13807 ins_pipe( fpu_regF_regF );
13808 %}
13810 // --------------------------------- SUB --------------------------------------
13812 // Floats vector sub
13813 instruct vsub2F(vecD dst, vecD src) %{
13814 predicate(n->as_Vector()->length() == 2);
13815 match(Set dst (SubVF dst src));
13816 format %{ "sub.ps $dst,$src\t! sub packed2F" %}
13817 ins_encode %{
13818 __ sub_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
13819 %}
13820 ins_pipe( fpu_regF_regF );
13821 %}
13823 // --------------------------------- MUL --------------------------------------
13825 // Floats vector mul
13826 instruct vmul2F(vecD dst, vecD src) %{
13827 predicate(n->as_Vector()->length() == 2);
13828 match(Set dst (MulVF dst src));
13829 format %{ "mul.ps $dst, $src\t! mul packed2F" %}
13830 ins_encode %{
13831 __ mul_ps($dst$$FloatRegister, $dst$$FloatRegister, $src$$FloatRegister);
13832 %}
13833 ins_pipe( fpu_regF_regF );
13834 %}
13836 instruct vmul2F3(vecD dst, vecD src1, vecD src2) %{
13837 predicate(n->as_Vector()->length() == 2);
13838 match(Set dst (MulVF src1 src2));
13839 format %{ "mul.ps $dst, $src1, $src2\t! mul packed2F" %}
13840 ins_encode %{
13841 __ mul_ps($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
13842 %}
13843 ins_pipe( fpu_regF_regF );
13844 %}
13846 // --------------------------------- DIV --------------------------------------
13847 // MIPS do not have div.ps
13849 // --------------------------------- MADD --------------------------------------
13850 // Floats vector madd
13851 //instruct vmadd2F(vecD dst, vecD src1, vecD src2, vecD src3) %{
13852 // predicate(n->as_Vector()->length() == 2);
13853 // match(Set dst (AddVF (MulVF src1 src2) src3));
13854 // ins_cost(50);
13855 // format %{ "madd.ps $dst, $src3, $src1, $src2\t! madd packed2F" %}
13856 // ins_encode %{
13857 // __ madd_ps($dst$$FloatRegister, $src3$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
13858 // %}
13859 // ins_pipe( fpu_regF_regF );
13860 //%}
13863 //----------PEEPHOLE RULES-----------------------------------------------------
13864 // These must follow all instruction definitions as they use the names
13865 // defined in the instructions definitions.
13866 //
13867 // peepmatch ( root_instr_name [preceeding_instruction]* );
13868 //
13869 // peepconstraint %{
13870 // (instruction_number.operand_name relational_op instruction_number.operand_name
13871 // [, ...] );
13872 // // instruction numbers are zero-based using left to right order in peepmatch
13873 //
13874 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
13875 // // provide an instruction_number.operand_name for each operand that appears
13876 // // in the replacement instruction's match rule
13877 //
13878 // ---------VM FLAGS---------------------------------------------------------
13879 //
13880 // All peephole optimizations can be turned off using -XX:-OptoPeephole
13881 //
13882 // Each peephole rule is given an identifying number starting with zero and
13883 // increasing by one in the order seen by the parser. An individual peephole
13884 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
13885 // on the command-line.
13886 //
13887 // ---------CURRENT LIMITATIONS----------------------------------------------
13888 //
13889 // Only match adjacent instructions in same basic block
13890 // Only equality constraints
13891 // Only constraints between operands, not (0.dest_reg == EAX_enc)
13892 // Only one replacement instruction
13893 //
13894 // ---------EXAMPLE----------------------------------------------------------
13895 //
13896 // // pertinent parts of existing instructions in architecture description
13897 // instruct movI(eRegI dst, eRegI src) %{
13898 // match(Set dst (CopyI src));
13899 // %}
13900 //
13901 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
13902 // match(Set dst (AddI dst src));
13903 // effect(KILL cr);
13904 // %}
13905 //
13906 // // Change (inc mov) to lea
13907 // peephole %{
13908 // // increment preceeded by register-register move
13909 // peepmatch ( incI_eReg movI );
13910 // // require that the destination register of the increment
13911 // // match the destination register of the move
13912 // peepconstraint ( 0.dst == 1.dst );
13913 // // construct a replacement instruction that sets
13914 // // the destination to ( move's source register + one )
13915 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13916 // %}
13917 //
13918 // Implementation no longer uses movX instructions since
13919 // machine-independent system no longer uses CopyX nodes.
13920 //
13921 // peephole %{
13922 // peepmatch ( incI_eReg movI );
13923 // peepconstraint ( 0.dst == 1.dst );
13924 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13925 // %}
13926 //
13927 // peephole %{
13928 // peepmatch ( decI_eReg movI );
13929 // peepconstraint ( 0.dst == 1.dst );
13930 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13931 // %}
13932 //
13933 // peephole %{
13934 // peepmatch ( addI_eReg_imm movI );
13935 // peepconstraint ( 0.dst == 1.dst );
13936 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13937 // %}
13938 //
13939 // peephole %{
13940 // peepmatch ( addP_eReg_imm movP );
13941 // peepconstraint ( 0.dst == 1.dst );
13942 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
13943 // %}
13945 // // Change load of spilled value to only a spill
13946 // instruct storeI(memory mem, eRegI src) %{
13947 // match(Set mem (StoreI mem src));
13948 // %}
13949 //
13950 // instruct loadI(eRegI dst, memory mem) %{
13951 // match(Set dst (LoadI mem));
13952 // %}
13953 //
13954 //peephole %{
13955 // peepmatch ( loadI storeI );
13956 // peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
13957 // peepreplace ( storeI( 1.mem 1.mem 1.src ) );
13958 //%}
13960 //----------SMARTSPILL RULES---------------------------------------------------
13961 // These must follow all instruction definitions as they use the names
13962 // defined in the instructions definitions.