x86_64.ad revision 3142:9b8ce46870df
1//
2// Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
3// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4//
5// This code is free software; you can redistribute it and/or modify it
6// under the terms of the GNU General Public License version 2 only, as
7// published by the Free Software Foundation.
8//
9// This code is distributed in the hope that it will be useful, but WITHOUT
10// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12// version 2 for more details (a copy is included in the LICENSE file that
13// accompanied this code).
14//
15// You should have received a copy of the GNU General Public License version
16// 2 along with this work; if not, write to the Free Software Foundation,
17// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18//
19// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20// or visit www.oracle.com if you need additional information or have any
21// questions.
22//
23//
24
25// AMD64 Architecture Description File
26
27//----------REGISTER DEFINITION BLOCK------------------------------------------
28// This information is used by the matcher and the register allocator to
29// describe individual registers and classes of registers within the target
30// archtecture.
31
32register %{
33//----------Architecture Description Register Definitions----------------------
34// General Registers
35// "reg_def"  name ( register save type, C convention save type,
36//                   ideal register type, encoding );
37// Register Save Types:
38//
39// NS  = No-Save:       The register allocator assumes that these registers
40//                      can be used without saving upon entry to the method, &
41//                      that they do not need to be saved at call sites.
42//
43// SOC = Save-On-Call:  The register allocator assumes that these registers
44//                      can be used without saving upon entry to the method,
45//                      but that they must be saved at call sites.
46//
47// SOE = Save-On-Entry: The register allocator assumes that these registers
48//                      must be saved before using them upon entry to the
49//                      method, but they do not need to be saved at call
50//                      sites.
51//
52// AS  = Always-Save:   The register allocator assumes that these registers
53//                      must be saved before using them upon entry to the
54//                      method, & that they must be saved at call sites.
55//
56// Ideal Register Type is used to determine how to save & restore a
57// register.  Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
58// spilled with LoadP/StoreP.  If the register supports both, use Op_RegI.
59//
60// The encoding number is the actual bit-pattern placed into the opcodes.
61
62// General Registers
63// R8-R15 must be encoded with REX.  (RSP, RBP, RSI, RDI need REX when
64// used as byte registers)
65
66// Previously set RBX, RSI, and RDI as save-on-entry for java code
67// Turn off SOE in java-code due to frequent use of uncommon-traps.
68// Now that allocator is better, turn on RSI and RDI as SOE registers.
69
70reg_def RAX  (SOC, SOC, Op_RegI,  0, rax->as_VMReg());
71reg_def RAX_H(SOC, SOC, Op_RegI,  0, rax->as_VMReg()->next());
72
73reg_def RCX  (SOC, SOC, Op_RegI,  1, rcx->as_VMReg());
74reg_def RCX_H(SOC, SOC, Op_RegI,  1, rcx->as_VMReg()->next());
75
76reg_def RDX  (SOC, SOC, Op_RegI,  2, rdx->as_VMReg());
77reg_def RDX_H(SOC, SOC, Op_RegI,  2, rdx->as_VMReg()->next());
78
79reg_def RBX  (SOC, SOE, Op_RegI,  3, rbx->as_VMReg());
80reg_def RBX_H(SOC, SOE, Op_RegI,  3, rbx->as_VMReg()->next());
81
82reg_def RSP  (NS,  NS,  Op_RegI,  4, rsp->as_VMReg());
83reg_def RSP_H(NS,  NS,  Op_RegI,  4, rsp->as_VMReg()->next());
84
85// now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code
86reg_def RBP  (NS, SOE, Op_RegI,  5, rbp->as_VMReg());
87reg_def RBP_H(NS, SOE, Op_RegI,  5, rbp->as_VMReg()->next());
88
89#ifdef _WIN64
90
91reg_def RSI  (SOC, SOE, Op_RegI,  6, rsi->as_VMReg());
92reg_def RSI_H(SOC, SOE, Op_RegI,  6, rsi->as_VMReg()->next());
93
94reg_def RDI  (SOC, SOE, Op_RegI,  7, rdi->as_VMReg());
95reg_def RDI_H(SOC, SOE, Op_RegI,  7, rdi->as_VMReg()->next());
96
97#else
98
99reg_def RSI  (SOC, SOC, Op_RegI,  6, rsi->as_VMReg());
100reg_def RSI_H(SOC, SOC, Op_RegI,  6, rsi->as_VMReg()->next());
101
102reg_def RDI  (SOC, SOC, Op_RegI,  7, rdi->as_VMReg());
103reg_def RDI_H(SOC, SOC, Op_RegI,  7, rdi->as_VMReg()->next());
104
105#endif
106
107reg_def R8   (SOC, SOC, Op_RegI,  8, r8->as_VMReg());
108reg_def R8_H (SOC, SOC, Op_RegI,  8, r8->as_VMReg()->next());
109
110reg_def R9   (SOC, SOC, Op_RegI,  9, r9->as_VMReg());
111reg_def R9_H (SOC, SOC, Op_RegI,  9, r9->as_VMReg()->next());
112
113reg_def R10  (SOC, SOC, Op_RegI, 10, r10->as_VMReg());
114reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
115
116reg_def R11  (SOC, SOC, Op_RegI, 11, r11->as_VMReg());
117reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
118
119reg_def R12  (SOC, SOE, Op_RegI, 12, r12->as_VMReg());
120reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next());
121
122reg_def R13  (SOC, SOE, Op_RegI, 13, r13->as_VMReg());
123reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next());
124
125reg_def R14  (SOC, SOE, Op_RegI, 14, r14->as_VMReg());
126reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next());
127
128reg_def R15  (SOC, SOE, Op_RegI, 15, r15->as_VMReg());
129reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next());
130
131
132// Floating Point Registers
133
134// XMM registers.  128-bit registers or 4 words each, labeled (a)-d.
135// Word a in each register holds a Float, words ab hold a Double.  We
136// currently do not use the SIMD capabilities, so registers cd are
137// unused at the moment.
138// XMM8-XMM15 must be encoded with REX.
139// Linux ABI:   No register preserved across function calls
140//              XMM0-XMM7 might hold parameters
141// Windows ABI: XMM6-XMM15 preserved across function calls
142//              XMM0-XMM3 might hold parameters
143
144reg_def XMM0   (SOC, SOC, Op_RegF,  0, xmm0->as_VMReg());
145reg_def XMM0_H (SOC, SOC, Op_RegF,  0, xmm0->as_VMReg()->next());
146
147reg_def XMM1   (SOC, SOC, Op_RegF,  1, xmm1->as_VMReg());
148reg_def XMM1_H (SOC, SOC, Op_RegF,  1, xmm1->as_VMReg()->next());
149
150reg_def XMM2   (SOC, SOC, Op_RegF,  2, xmm2->as_VMReg());
151reg_def XMM2_H (SOC, SOC, Op_RegF,  2, xmm2->as_VMReg()->next());
152
153reg_def XMM3   (SOC, SOC, Op_RegF,  3, xmm3->as_VMReg());
154reg_def XMM3_H (SOC, SOC, Op_RegF,  3, xmm3->as_VMReg()->next());
155
156reg_def XMM4   (SOC, SOC, Op_RegF,  4, xmm4->as_VMReg());
157reg_def XMM4_H (SOC, SOC, Op_RegF,  4, xmm4->as_VMReg()->next());
158
159reg_def XMM5   (SOC, SOC, Op_RegF,  5, xmm5->as_VMReg());
160reg_def XMM5_H (SOC, SOC, Op_RegF,  5, xmm5->as_VMReg()->next());
161
162#ifdef _WIN64
163
164reg_def XMM6   (SOC, SOE, Op_RegF,  6, xmm6->as_VMReg());
165reg_def XMM6_H (SOC, SOE, Op_RegF,  6, xmm6->as_VMReg()->next());
166
167reg_def XMM7   (SOC, SOE, Op_RegF,  7, xmm7->as_VMReg());
168reg_def XMM7_H (SOC, SOE, Op_RegF,  7, xmm7->as_VMReg()->next());
169
170reg_def XMM8   (SOC, SOE, Op_RegF,  8, xmm8->as_VMReg());
171reg_def XMM8_H (SOC, SOE, Op_RegF,  8, xmm8->as_VMReg()->next());
172
173reg_def XMM9   (SOC, SOE, Op_RegF,  9, xmm9->as_VMReg());
174reg_def XMM9_H (SOC, SOE, Op_RegF,  9, xmm9->as_VMReg()->next());
175
176reg_def XMM10  (SOC, SOE, Op_RegF, 10, xmm10->as_VMReg());
177reg_def XMM10_H(SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next());
178
179reg_def XMM11  (SOC, SOE, Op_RegF, 11, xmm11->as_VMReg());
180reg_def XMM11_H(SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next());
181
182reg_def XMM12  (SOC, SOE, Op_RegF, 12, xmm12->as_VMReg());
183reg_def XMM12_H(SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next());
184
185reg_def XMM13  (SOC, SOE, Op_RegF, 13, xmm13->as_VMReg());
186reg_def XMM13_H(SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next());
187
188reg_def XMM14  (SOC, SOE, Op_RegF, 14, xmm14->as_VMReg());
189reg_def XMM14_H(SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next());
190
191reg_def XMM15  (SOC, SOE, Op_RegF, 15, xmm15->as_VMReg());
192reg_def XMM15_H(SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next());
193
194#else
195
196reg_def XMM6   (SOC, SOC, Op_RegF,  6, xmm6->as_VMReg());
197reg_def XMM6_H (SOC, SOC, Op_RegF,  6, xmm6->as_VMReg()->next());
198
199reg_def XMM7   (SOC, SOC, Op_RegF,  7, xmm7->as_VMReg());
200reg_def XMM7_H (SOC, SOC, Op_RegF,  7, xmm7->as_VMReg()->next());
201
202reg_def XMM8   (SOC, SOC, Op_RegF,  8, xmm8->as_VMReg());
203reg_def XMM8_H (SOC, SOC, Op_RegF,  8, xmm8->as_VMReg()->next());
204
205reg_def XMM9   (SOC, SOC, Op_RegF,  9, xmm9->as_VMReg());
206reg_def XMM9_H (SOC, SOC, Op_RegF,  9, xmm9->as_VMReg()->next());
207
208reg_def XMM10  (SOC, SOC, Op_RegF, 10, xmm10->as_VMReg());
209reg_def XMM10_H(SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next());
210
211reg_def XMM11  (SOC, SOC, Op_RegF, 11, xmm11->as_VMReg());
212reg_def XMM11_H(SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next());
213
214reg_def XMM12  (SOC, SOC, Op_RegF, 12, xmm12->as_VMReg());
215reg_def XMM12_H(SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next());
216
217reg_def XMM13  (SOC, SOC, Op_RegF, 13, xmm13->as_VMReg());
218reg_def XMM13_H(SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next());
219
220reg_def XMM14  (SOC, SOC, Op_RegF, 14, xmm14->as_VMReg());
221reg_def XMM14_H(SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next());
222
223reg_def XMM15  (SOC, SOC, Op_RegF, 15, xmm15->as_VMReg());
224reg_def XMM15_H(SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next());
225
226#endif // _WIN64
227
228reg_def RFLAGS(SOC, SOC, 0, 16, VMRegImpl::Bad());
229
230// Specify priority of register selection within phases of register
231// allocation.  Highest priority is first.  A useful heuristic is to
232// give registers a low priority when they are required by machine
233// instructions, like EAX and EDX on I486, and choose no-save registers
234// before save-on-call, & save-on-call before save-on-entry.  Registers
235// which participate in fixed calling sequences should come last.
236// Registers which are used as pairs must fall on an even boundary.
237
238alloc_class chunk0(R10,         R10_H,
239                   R11,         R11_H,
240                   R8,          R8_H,
241                   R9,          R9_H,
242                   R12,         R12_H,
243                   RCX,         RCX_H,
244                   RBX,         RBX_H,
245                   RDI,         RDI_H,
246                   RDX,         RDX_H,
247                   RSI,         RSI_H,
248                   RAX,         RAX_H,
249                   RBP,         RBP_H,
250                   R13,         R13_H,
251                   R14,         R14_H,
252                   R15,         R15_H,
253                   RSP,         RSP_H);
254
255// XXX probably use 8-15 first on Linux
256alloc_class chunk1(XMM0,  XMM0_H,
257                   XMM1,  XMM1_H,
258                   XMM2,  XMM2_H,
259                   XMM3,  XMM3_H,
260                   XMM4,  XMM4_H,
261                   XMM5,  XMM5_H,
262                   XMM6,  XMM6_H,
263                   XMM7,  XMM7_H,
264                   XMM8,  XMM8_H,
265                   XMM9,  XMM9_H,
266                   XMM10, XMM10_H,
267                   XMM11, XMM11_H,
268                   XMM12, XMM12_H,
269                   XMM13, XMM13_H,
270                   XMM14, XMM14_H,
271                   XMM15, XMM15_H);
272
273alloc_class chunk2(RFLAGS);
274
275
276//----------Architecture Description Register Classes--------------------------
277// Several register classes are automatically defined based upon information in
278// this architecture description.
279// 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
280// 2) reg_class compiler_method_oop_reg    ( /* as def'd in frame section */ )
281// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
282// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
283//
284
285// Class for all pointer registers (including RSP)
286reg_class any_reg(RAX, RAX_H,
287                  RDX, RDX_H,
288                  RBP, RBP_H,
289                  RDI, RDI_H,
290                  RSI, RSI_H,
291                  RCX, RCX_H,
292                  RBX, RBX_H,
293                  RSP, RSP_H,
294                  R8,  R8_H,
295                  R9,  R9_H,
296                  R10, R10_H,
297                  R11, R11_H,
298                  R12, R12_H,
299                  R13, R13_H,
300                  R14, R14_H,
301                  R15, R15_H);
302
303// Class for all pointer registers except RSP
304reg_class ptr_reg(RAX, RAX_H,
305                  RDX, RDX_H,
306                  RBP, RBP_H,
307                  RDI, RDI_H,
308                  RSI, RSI_H,
309                  RCX, RCX_H,
310                  RBX, RBX_H,
311                  R8,  R8_H,
312                  R9,  R9_H,
313                  R10, R10_H,
314                  R11, R11_H,
315                  R13, R13_H,
316                  R14, R14_H);
317
318// Class for all pointer registers except RAX and RSP
319reg_class ptr_no_rax_reg(RDX, RDX_H,
320                         RBP, RBP_H,
321                         RDI, RDI_H,
322                         RSI, RSI_H,
323                         RCX, RCX_H,
324                         RBX, RBX_H,
325                         R8,  R8_H,
326                         R9,  R9_H,
327                         R10, R10_H,
328                         R11, R11_H,
329                         R13, R13_H,
330                         R14, R14_H);
331
332reg_class ptr_no_rbp_reg(RDX, RDX_H,
333                         RAX, RAX_H,
334                         RDI, RDI_H,
335                         RSI, RSI_H,
336                         RCX, RCX_H,
337                         RBX, RBX_H,
338                         R8,  R8_H,
339                         R9,  R9_H,
340                         R10, R10_H,
341                         R11, R11_H,
342                         R13, R13_H,
343                         R14, R14_H);
344
345// Class for all pointer registers except RAX, RBX and RSP
346reg_class ptr_no_rax_rbx_reg(RDX, RDX_H,
347                             RBP, RBP_H,
348                             RDI, RDI_H,
349                             RSI, RSI_H,
350                             RCX, RCX_H,
351                             R8,  R8_H,
352                             R9,  R9_H,
353                             R10, R10_H,
354                             R11, R11_H,
355                             R13, R13_H,
356                             R14, R14_H);
357
358// Singleton class for RAX pointer register
359reg_class ptr_rax_reg(RAX, RAX_H);
360
361// Singleton class for RBX pointer register
362reg_class ptr_rbx_reg(RBX, RBX_H);
363
364// Singleton class for RSI pointer register
365reg_class ptr_rsi_reg(RSI, RSI_H);
366
367// Singleton class for RDI pointer register
368reg_class ptr_rdi_reg(RDI, RDI_H);
369
370// Singleton class for RBP pointer register
371reg_class ptr_rbp_reg(RBP, RBP_H);
372
373// Singleton class for stack pointer
374reg_class ptr_rsp_reg(RSP, RSP_H);
375
376// Singleton class for TLS pointer
377reg_class ptr_r15_reg(R15, R15_H);
378
379// Class for all long registers (except RSP)
380reg_class long_reg(RAX, RAX_H,
381                   RDX, RDX_H,
382                   RBP, RBP_H,
383                   RDI, RDI_H,
384                   RSI, RSI_H,
385                   RCX, RCX_H,
386                   RBX, RBX_H,
387                   R8,  R8_H,
388                   R9,  R9_H,
389                   R10, R10_H,
390                   R11, R11_H,
391                   R13, R13_H,
392                   R14, R14_H);
393
394// Class for all long registers except RAX, RDX (and RSP)
395reg_class long_no_rax_rdx_reg(RBP, RBP_H,
396                              RDI, RDI_H,
397                              RSI, RSI_H,
398                              RCX, RCX_H,
399                              RBX, RBX_H,
400                              R8,  R8_H,
401                              R9,  R9_H,
402                              R10, R10_H,
403                              R11, R11_H,
404                              R13, R13_H,
405                              R14, R14_H);
406
407// Class for all long registers except RCX (and RSP)
408reg_class long_no_rcx_reg(RBP, RBP_H,
409                          RDI, RDI_H,
410                          RSI, RSI_H,
411                          RAX, RAX_H,
412                          RDX, RDX_H,
413                          RBX, RBX_H,
414                          R8,  R8_H,
415                          R9,  R9_H,
416                          R10, R10_H,
417                          R11, R11_H,
418                          R13, R13_H,
419                          R14, R14_H);
420
421// Class for all long registers except RAX (and RSP)
422reg_class long_no_rax_reg(RBP, RBP_H,
423                          RDX, RDX_H,
424                          RDI, RDI_H,
425                          RSI, RSI_H,
426                          RCX, RCX_H,
427                          RBX, RBX_H,
428                          R8,  R8_H,
429                          R9,  R9_H,
430                          R10, R10_H,
431                          R11, R11_H,
432                          R13, R13_H,
433                          R14, R14_H);
434
435// Singleton class for RAX long register
436reg_class long_rax_reg(RAX, RAX_H);
437
438// Singleton class for RCX long register
439reg_class long_rcx_reg(RCX, RCX_H);
440
441// Singleton class for RDX long register
442reg_class long_rdx_reg(RDX, RDX_H);
443
444// Class for all int registers (except RSP)
445reg_class int_reg(RAX,
446                  RDX,
447                  RBP,
448                  RDI,
449                  RSI,
450                  RCX,
451                  RBX,
452                  R8,
453                  R9,
454                  R10,
455                  R11,
456                  R13,
457                  R14);
458
459// Class for all int registers except RCX (and RSP)
460reg_class int_no_rcx_reg(RAX,
461                         RDX,
462                         RBP,
463                         RDI,
464                         RSI,
465                         RBX,
466                         R8,
467                         R9,
468                         R10,
469                         R11,
470                         R13,
471                         R14);
472
473// Class for all int registers except RAX, RDX (and RSP)
474reg_class int_no_rax_rdx_reg(RBP,
475                             RDI,
476                             RSI,
477                             RCX,
478                             RBX,
479                             R8,
480                             R9,
481                             R10,
482                             R11,
483                             R13,
484                             R14);
485
486// Singleton class for RAX int register
487reg_class int_rax_reg(RAX);
488
489// Singleton class for RBX int register
490reg_class int_rbx_reg(RBX);
491
492// Singleton class for RCX int register
493reg_class int_rcx_reg(RCX);
494
495// Singleton class for RCX int register
496reg_class int_rdx_reg(RDX);
497
498// Singleton class for RCX int register
499reg_class int_rdi_reg(RDI);
500
501// Singleton class for instruction pointer
502// reg_class ip_reg(RIP);
503
504// Singleton class for condition codes
505reg_class int_flags(RFLAGS);
506
507// Class for all float registers
508reg_class float_reg(XMM0,
509                    XMM1,
510                    XMM2,
511                    XMM3,
512                    XMM4,
513                    XMM5,
514                    XMM6,
515                    XMM7,
516                    XMM8,
517                    XMM9,
518                    XMM10,
519                    XMM11,
520                    XMM12,
521                    XMM13,
522                    XMM14,
523                    XMM15);
524
525// Class for all double registers
526reg_class double_reg(XMM0,  XMM0_H,
527                     XMM1,  XMM1_H,
528                     XMM2,  XMM2_H,
529                     XMM3,  XMM3_H,
530                     XMM4,  XMM4_H,
531                     XMM5,  XMM5_H,
532                     XMM6,  XMM6_H,
533                     XMM7,  XMM7_H,
534                     XMM8,  XMM8_H,
535                     XMM9,  XMM9_H,
536                     XMM10, XMM10_H,
537                     XMM11, XMM11_H,
538                     XMM12, XMM12_H,
539                     XMM13, XMM13_H,
540                     XMM14, XMM14_H,
541                     XMM15, XMM15_H);
542%}
543
544
545//----------SOURCE BLOCK-------------------------------------------------------
546// This is a block of C++ code which provides values, functions, and
547// definitions necessary in the rest of the architecture description
548source %{
549#define   RELOC_IMM64    Assembler::imm_operand
550#define   RELOC_DISP32   Assembler::disp32_operand
551
552#define __ _masm.
553
554static int preserve_SP_size() {
555  return 3;  // rex.w, op, rm(reg/reg)
556}
557
558// !!!!! Special hack to get all types of calls to specify the byte offset
559//       from the start of the call to the point where the return address
560//       will point.
561int MachCallStaticJavaNode::ret_addr_offset()
562{
563  int offset = 5; // 5 bytes from start of call to where return address points
564  if (_method_handle_invoke)
565    offset += preserve_SP_size();
566  return offset;
567}
568
569int MachCallDynamicJavaNode::ret_addr_offset()
570{
571  return 15; // 15 bytes from start of call to where return address points
572}
573
574// In os_cpu .ad file
575// int MachCallRuntimeNode::ret_addr_offset()
576
577// Indicate if the safepoint node needs the polling page as an input,
578// it does if the polling page is more than disp32 away.
579bool SafePointNode::needs_polling_address_input()
580{
581  return Assembler::is_polling_page_far();
582}
583
584//
585// Compute padding required for nodes which need alignment
586//
587
588// The address of the call instruction needs to be 4-byte aligned to
589// ensure that it does not span a cache line so that it can be patched.
590int CallStaticJavaDirectNode::compute_padding(int current_offset) const
591{
592  current_offset += 1; // skip call opcode byte
593  return round_to(current_offset, alignment_required()) - current_offset;
594}
595
596// The address of the call instruction needs to be 4-byte aligned to
597// ensure that it does not span a cache line so that it can be patched.
598int CallStaticJavaHandleNode::compute_padding(int current_offset) const
599{
600  current_offset += preserve_SP_size();   // skip mov rbp, rsp
601  current_offset += 1; // skip call opcode byte
602  return round_to(current_offset, alignment_required()) - current_offset;
603}
604
605// The address of the call instruction needs to be 4-byte aligned to
606// ensure that it does not span a cache line so that it can be patched.
607int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
608{
609  current_offset += 11; // skip movq instruction + call opcode byte
610  return round_to(current_offset, alignment_required()) - current_offset;
611}
612
613// EMIT_RM()
614void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
615  unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
616  cbuf.insts()->emit_int8(c);
617}
618
619// EMIT_CC()
620void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
621  unsigned char c = (unsigned char) (f1 | f2);
622  cbuf.insts()->emit_int8(c);
623}
624
625// EMIT_OPCODE()
626void emit_opcode(CodeBuffer &cbuf, int code) {
627  cbuf.insts()->emit_int8((unsigned char) code);
628}
629
630// EMIT_OPCODE() w/ relocation information
631void emit_opcode(CodeBuffer &cbuf,
632                 int code, relocInfo::relocType reloc, int offset, int format)
633{
634  cbuf.relocate(cbuf.insts_mark() + offset, reloc, format);
635  emit_opcode(cbuf, code);
636}
637
638// EMIT_D8()
639void emit_d8(CodeBuffer &cbuf, int d8) {
640  cbuf.insts()->emit_int8((unsigned char) d8);
641}
642
643// EMIT_D16()
644void emit_d16(CodeBuffer &cbuf, int d16) {
645  cbuf.insts()->emit_int16(d16);
646}
647
648// EMIT_D32()
649void emit_d32(CodeBuffer &cbuf, int d32) {
650  cbuf.insts()->emit_int32(d32);
651}
652
653// EMIT_D64()
654void emit_d64(CodeBuffer &cbuf, int64_t d64) {
655  cbuf.insts()->emit_int64(d64);
656}
657
658// emit 32 bit value and construct relocation entry from relocInfo::relocType
659void emit_d32_reloc(CodeBuffer& cbuf,
660                    int d32,
661                    relocInfo::relocType reloc,
662                    int format)
663{
664  assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
665  cbuf.relocate(cbuf.insts_mark(), reloc, format);
666  cbuf.insts()->emit_int32(d32);
667}
668
669// emit 32 bit value and construct relocation entry from RelocationHolder
670void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) {
671#ifdef ASSERT
672  if (rspec.reloc()->type() == relocInfo::oop_type &&
673      d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
674    assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
675  }
676#endif
677  cbuf.relocate(cbuf.insts_mark(), rspec, format);
678  cbuf.insts()->emit_int32(d32);
679}
680
681void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
682  address next_ip = cbuf.insts_end() + 4;
683  emit_d32_reloc(cbuf, (int) (addr - next_ip),
684                 external_word_Relocation::spec(addr),
685                 RELOC_DISP32);
686}
687
688
689// emit 64 bit value and construct relocation entry from relocInfo::relocType
690void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) {
691  cbuf.relocate(cbuf.insts_mark(), reloc, format);
692  cbuf.insts()->emit_int64(d64);
693}
694
695// emit 64 bit value and construct relocation entry from RelocationHolder
696void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) {
697#ifdef ASSERT
698  if (rspec.reloc()->type() == relocInfo::oop_type &&
699      d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
700    assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()),
701           "cannot embed scavengable oops in code");
702  }
703#endif
704  cbuf.relocate(cbuf.insts_mark(), rspec, format);
705  cbuf.insts()->emit_int64(d64);
706}
707
708// Access stack slot for load or store
709void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp)
710{
711  emit_opcode(cbuf, opcode);                  // (e.g., FILD   [RSP+src])
712  if (-0x80 <= disp && disp < 0x80) {
713    emit_rm(cbuf, 0x01, rm_field, RSP_enc);   // R/M byte
714    emit_rm(cbuf, 0x00, RSP_enc, RSP_enc);    // SIB byte
715    emit_d8(cbuf, disp);     // Displacement  // R/M byte
716  } else {
717    emit_rm(cbuf, 0x02, rm_field, RSP_enc);   // R/M byte
718    emit_rm(cbuf, 0x00, RSP_enc, RSP_enc);    // SIB byte
719    emit_d32(cbuf, disp);     // Displacement // R/M byte
720  }
721}
722
723   // rRegI ereg, memory mem) %{    // emit_reg_mem
724void encode_RegMem(CodeBuffer &cbuf,
725                   int reg,
726                   int base, int index, int scale, int disp, bool disp_is_oop)
727{
728  assert(!disp_is_oop, "cannot have disp");
729  int regenc = reg & 7;
730  int baseenc = base & 7;
731  int indexenc = index & 7;
732
733  // There is no index & no scale, use form without SIB byte
734  if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) {
735    // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
736    if (disp == 0 && base != RBP_enc && base != R13_enc) {
737      emit_rm(cbuf, 0x0, regenc, baseenc); // *
738    } else if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) {
739      // If 8-bit displacement, mode 0x1
740      emit_rm(cbuf, 0x1, regenc, baseenc); // *
741      emit_d8(cbuf, disp);
742    } else {
743      // If 32-bit displacement
744      if (base == -1) { // Special flag for absolute address
745        emit_rm(cbuf, 0x0, regenc, 0x5); // *
746        if (disp_is_oop) {
747          emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
748        } else {
749          emit_d32(cbuf, disp);
750        }
751      } else {
752        // Normal base + offset
753        emit_rm(cbuf, 0x2, regenc, baseenc); // *
754        if (disp_is_oop) {
755          emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
756        } else {
757          emit_d32(cbuf, disp);
758        }
759      }
760    }
761  } else {
762    // Else, encode with the SIB byte
763    // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
764    if (disp == 0 && base != RBP_enc && base != R13_enc) {
765      // If no displacement
766      emit_rm(cbuf, 0x0, regenc, 0x4); // *
767      emit_rm(cbuf, scale, indexenc, baseenc);
768    } else {
769      if (-0x80 <= disp && disp < 0x80 && !disp_is_oop) {
770        // If 8-bit displacement, mode 0x1
771        emit_rm(cbuf, 0x1, regenc, 0x4); // *
772        emit_rm(cbuf, scale, indexenc, baseenc);
773        emit_d8(cbuf, disp);
774      } else {
775        // If 32-bit displacement
776        if (base == 0x04 ) {
777          emit_rm(cbuf, 0x2, regenc, 0x4);
778          emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
779        } else {
780          emit_rm(cbuf, 0x2, regenc, 0x4);
781          emit_rm(cbuf, scale, indexenc, baseenc); // *
782        }
783        if (disp_is_oop) {
784          emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
785        } else {
786          emit_d32(cbuf, disp);
787        }
788      }
789    }
790  }
791}
792
793// This could be in MacroAssembler but it's fairly C2 specific
794void emit_cmpfp_fixup(MacroAssembler& _masm) {
795  Label exit;
796  __ jccb(Assembler::noParity, exit);
797  __ pushf();
798  //
799  // comiss/ucomiss instructions set ZF,PF,CF flags and
800  // zero OF,AF,SF for NaN values.
801  // Fixup flags by zeroing ZF,PF so that compare of NaN
802  // values returns 'less than' result (CF is set).
803  // Leave the rest of flags unchanged.
804  //
805  //    7 6 5 4 3 2 1 0
806  //   |S|Z|r|A|r|P|r|C|  (r - reserved bit)
807  //    0 0 1 0 1 0 1 1   (0x2B)
808  //
809  __ andq(Address(rsp, 0), 0xffffff2b);
810  __ popf();
811  __ bind(exit);
812}
813
814void emit_cmpfp3(MacroAssembler& _masm, Register dst) {
815  Label done;
816  __ movl(dst, -1);
817  __ jcc(Assembler::parity, done);
818  __ jcc(Assembler::below, done);
819  __ setb(Assembler::notEqual, dst);
820  __ movzbl(dst, dst);
821  __ bind(done);
822}
823
824
825//=============================================================================
826const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
827
828int Compile::ConstantTable::calculate_table_base_offset() const {
829  return 0;  // absolute addressing, no offset
830}
831
832void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
833  // Empty encoding
834}
835
836uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
837  return 0;
838}
839
840#ifndef PRODUCT
841void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
842  st->print("# MachConstantBaseNode (empty encoding)");
843}
844#endif
845
846
847//=============================================================================
848#ifndef PRODUCT
849void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
850  Compile* C = ra_->C;
851
852  int framesize = C->frame_slots() << LogBytesPerInt;
853  assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
854  // Remove wordSize for return addr which is already pushed.
855  framesize -= wordSize;
856
857  if (C->need_stack_bang(framesize)) {
858    framesize -= wordSize;
859    st->print("# stack bang");
860    st->print("\n\t");
861    st->print("pushq   rbp\t# Save rbp");
862    if (framesize) {
863      st->print("\n\t");
864      st->print("subq    rsp, #%d\t# Create frame",framesize);
865    }
866  } else {
867    st->print("subq    rsp, #%d\t# Create frame",framesize);
868    st->print("\n\t");
869    framesize -= wordSize;
870    st->print("movq    [rsp + #%d], rbp\t# Save rbp",framesize);
871  }
872
873  if (VerifyStackAtCalls) {
874    st->print("\n\t");
875    framesize -= wordSize;
876    st->print("movq    [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize);
877#ifdef ASSERT
878    st->print("\n\t");
879    st->print("# stack alignment check");
880#endif
881  }
882  st->cr();
883}
884#endif
885
886void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
887  Compile* C = ra_->C;
888  MacroAssembler _masm(&cbuf);
889
890  int framesize = C->frame_slots() << LogBytesPerInt;
891
892  __ verified_entry(framesize, C->need_stack_bang(framesize), false);
893
894  C->set_frame_complete(cbuf.insts_size());
895
896  if (C->has_mach_constant_base_node()) {
897    // NOTE: We set the table base offset here because users might be
898    // emitted before MachConstantBaseNode.
899    Compile::ConstantTable& constant_table = C->constant_table();
900    constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
901  }
902}
903
904uint MachPrologNode::size(PhaseRegAlloc* ra_) const
905{
906  return MachNode::size(ra_); // too many variables; just compute it
907                              // the hard way
908}
909
910int MachPrologNode::reloc() const
911{
912  return 0; // a large enough number
913}
914
915//=============================================================================
916#ifndef PRODUCT
917void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
918{
919  Compile* C = ra_->C;
920  int framesize = C->frame_slots() << LogBytesPerInt;
921  assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
922  // Remove word for return adr already pushed
923  // and RBP
924  framesize -= 2*wordSize;
925
926  if (framesize) {
927    st->print_cr("addq    rsp, %d\t# Destroy frame", framesize);
928    st->print("\t");
929  }
930
931  st->print_cr("popq   rbp");
932  if (do_polling() && C->is_method_compilation()) {
933    st->print("\t");
934    if (Assembler::is_polling_page_far()) {
935      st->print_cr("movq   rscratch1, #polling_page_address\n\t"
936                   "testl  rax, [rscratch1]\t"
937                   "# Safepoint: poll for GC");
938    } else {
939      st->print_cr("testl  rax, [rip + #offset_to_poll_page]\t"
940                   "# Safepoint: poll for GC");
941    }
942  }
943}
944#endif
945
946void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
947{
948  Compile* C = ra_->C;
949  int framesize = C->frame_slots() << LogBytesPerInt;
950  assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
951  // Remove word for return adr already pushed
952  // and RBP
953  framesize -= 2*wordSize;
954
955  // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here
956
957  if (framesize) {
958    emit_opcode(cbuf, Assembler::REX_W);
959    if (framesize < 0x80) {
960      emit_opcode(cbuf, 0x83); // addq rsp, #framesize
961      emit_rm(cbuf, 0x3, 0x00, RSP_enc);
962      emit_d8(cbuf, framesize);
963    } else {
964      emit_opcode(cbuf, 0x81); // addq rsp, #framesize
965      emit_rm(cbuf, 0x3, 0x00, RSP_enc);
966      emit_d32(cbuf, framesize);
967    }
968  }
969
970  // popq rbp
971  emit_opcode(cbuf, 0x58 | RBP_enc);
972
973  if (do_polling() && C->is_method_compilation()) {
974    MacroAssembler _masm(&cbuf);
975    AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
976    if (Assembler::is_polling_page_far()) {
977      __ lea(rscratch1, polling_page);
978      __ relocate(relocInfo::poll_return_type);
979      __ testl(rax, Address(rscratch1, 0));
980    } else {
981      __ testl(rax, polling_page);
982    }
983  }
984}
985
986uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
987{
988  return MachNode::size(ra_); // too many variables; just compute it
989                              // the hard way
990}
991
992int MachEpilogNode::reloc() const
993{
994  return 2; // a large enough number
995}
996
997const Pipeline* MachEpilogNode::pipeline() const
998{
999  return MachNode::pipeline_class();
1000}
1001
1002int MachEpilogNode::safepoint_offset() const
1003{
1004  return 0;
1005}
1006
1007//=============================================================================
1008
1009enum RC {
1010  rc_bad,
1011  rc_int,
1012  rc_float,
1013  rc_stack
1014};
1015
1016static enum RC rc_class(OptoReg::Name reg)
1017{
1018  if( !OptoReg::is_valid(reg)  ) return rc_bad;
1019
1020  if (OptoReg::is_stack(reg)) return rc_stack;
1021
1022  VMReg r = OptoReg::as_VMReg(reg);
1023
1024  if (r->is_Register()) return rc_int;
1025
1026  assert(r->is_XMMRegister(), "must be");
1027  return rc_float;
1028}
1029
1030uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
1031                                       PhaseRegAlloc* ra_,
1032                                       bool do_size,
1033                                       outputStream* st) const
1034{
1035
1036  // Get registers to move
1037  OptoReg::Name src_second = ra_->get_reg_second(in(1));
1038  OptoReg::Name src_first = ra_->get_reg_first(in(1));
1039  OptoReg::Name dst_second = ra_->get_reg_second(this);
1040  OptoReg::Name dst_first = ra_->get_reg_first(this);
1041
1042  enum RC src_second_rc = rc_class(src_second);
1043  enum RC src_first_rc = rc_class(src_first);
1044  enum RC dst_second_rc = rc_class(dst_second);
1045  enum RC dst_first_rc = rc_class(dst_first);
1046
1047  assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
1048         "must move at least 1 register" );
1049
1050  if (src_first == dst_first && src_second == dst_second) {
1051    // Self copy, no move
1052    return 0;
1053  } else if (src_first_rc == rc_stack) {
1054    // mem ->
1055    if (dst_first_rc == rc_stack) {
1056      // mem -> mem
1057      assert(src_second != dst_first, "overlap");
1058      if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1059          (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1060        // 64-bit
1061        int src_offset = ra_->reg2offset(src_first);
1062        int dst_offset = ra_->reg2offset(dst_first);
1063        if (cbuf) {
1064          emit_opcode(*cbuf, 0xFF);
1065          encode_RegMem(*cbuf, RSI_enc, RSP_enc, 0x4, 0, src_offset, false);
1066
1067          emit_opcode(*cbuf, 0x8F);
1068          encode_RegMem(*cbuf, RAX_enc, RSP_enc, 0x4, 0, dst_offset, false);
1069
1070#ifndef PRODUCT
1071        } else if (!do_size) {
1072          st->print("pushq   [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1073                     "popq    [rsp + #%d]",
1074                     src_offset,
1075                     dst_offset);
1076#endif
1077        }
1078        return
1079          3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) +
1080          3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4));
1081      } else {
1082        // 32-bit
1083        assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1084        assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1085        // No pushl/popl, so:
1086        int src_offset = ra_->reg2offset(src_first);
1087        int dst_offset = ra_->reg2offset(dst_first);
1088        if (cbuf) {
1089          emit_opcode(*cbuf, Assembler::REX_W);
1090          emit_opcode(*cbuf, 0x89);
1091          emit_opcode(*cbuf, 0x44);
1092          emit_opcode(*cbuf, 0x24);
1093          emit_opcode(*cbuf, 0xF8);
1094
1095          emit_opcode(*cbuf, 0x8B);
1096          encode_RegMem(*cbuf,
1097                        RAX_enc,
1098                        RSP_enc, 0x4, 0, src_offset,
1099                        false);
1100
1101          emit_opcode(*cbuf, 0x89);
1102          encode_RegMem(*cbuf,
1103                        RAX_enc,
1104                        RSP_enc, 0x4, 0, dst_offset,
1105                        false);
1106
1107          emit_opcode(*cbuf, Assembler::REX_W);
1108          emit_opcode(*cbuf, 0x8B);
1109          emit_opcode(*cbuf, 0x44);
1110          emit_opcode(*cbuf, 0x24);
1111          emit_opcode(*cbuf, 0xF8);
1112
1113#ifndef PRODUCT
1114        } else if (!do_size) {
1115          st->print("movq    [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1116                     "movl    rax, [rsp + #%d]\n\t"
1117                     "movl    [rsp + #%d], rax\n\t"
1118                     "movq    rax, [rsp - #8]",
1119                     src_offset,
1120                     dst_offset);
1121#endif
1122        }
1123        return
1124          5 + // movq
1125          3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + // movl
1126          3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)) + // movl
1127          5; // movq
1128      }
1129    } else if (dst_first_rc == rc_int) {
1130      // mem -> gpr
1131      if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1132          (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1133        // 64-bit
1134        int offset = ra_->reg2offset(src_first);
1135        if (cbuf) {
1136          if (Matcher::_regEncode[dst_first] < 8) {
1137            emit_opcode(*cbuf, Assembler::REX_W);
1138          } else {
1139            emit_opcode(*cbuf, Assembler::REX_WR);
1140          }
1141          emit_opcode(*cbuf, 0x8B);
1142          encode_RegMem(*cbuf,
1143                        Matcher::_regEncode[dst_first],
1144                        RSP_enc, 0x4, 0, offset,
1145                        false);
1146#ifndef PRODUCT
1147        } else if (!do_size) {
1148          st->print("movq    %s, [rsp + #%d]\t# spill",
1149                     Matcher::regName[dst_first],
1150                     offset);
1151#endif
1152        }
1153        return
1154          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX
1155      } else {
1156        // 32-bit
1157        assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1158        assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1159        int offset = ra_->reg2offset(src_first);
1160        if (cbuf) {
1161          if (Matcher::_regEncode[dst_first] >= 8) {
1162            emit_opcode(*cbuf, Assembler::REX_R);
1163          }
1164          emit_opcode(*cbuf, 0x8B);
1165          encode_RegMem(*cbuf,
1166                        Matcher::_regEncode[dst_first],
1167                        RSP_enc, 0x4, 0, offset,
1168                        false);
1169#ifndef PRODUCT
1170        } else if (!do_size) {
1171          st->print("movl    %s, [rsp + #%d]\t# spill",
1172                     Matcher::regName[dst_first],
1173                     offset);
1174#endif
1175        }
1176        return
1177          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1178          ((Matcher::_regEncode[dst_first] < 8)
1179           ? 3
1180           : 4); // REX
1181      }
1182    } else if (dst_first_rc == rc_float) {
1183      // mem-> xmm
1184      if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1185          (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1186        // 64-bit
1187        int offset = ra_->reg2offset(src_first);
1188        if (cbuf) {
1189          MacroAssembler _masm(cbuf);
1190          __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1191#ifndef PRODUCT
1192        } else if (!do_size) {
1193          st->print("%s  %s, [rsp + #%d]\t# spill",
1194                     UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1195                     Matcher::regName[dst_first],
1196                     offset);
1197#endif
1198        }
1199        return
1200          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1201          ((Matcher::_regEncode[dst_first] >= 8)
1202           ? 6
1203           : (5 + ((UseAVX>0)?1:0))); // REX
1204      } else {
1205        // 32-bit
1206        assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1207        assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1208        int offset = ra_->reg2offset(src_first);
1209        if (cbuf) {
1210          MacroAssembler _masm(cbuf);
1211          __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1212#ifndef PRODUCT
1213        } else if (!do_size) {
1214          st->print("movss   %s, [rsp + #%d]\t# spill",
1215                     Matcher::regName[dst_first],
1216                     offset);
1217#endif
1218        }
1219        return
1220          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1221          ((Matcher::_regEncode[dst_first] >= 8)
1222           ? 6
1223           : (5 + ((UseAVX>0)?1:0))); // REX
1224      }
1225    }
1226  } else if (src_first_rc == rc_int) {
1227    // gpr ->
1228    if (dst_first_rc == rc_stack) {
1229      // gpr -> mem
1230      if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1231          (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1232        // 64-bit
1233        int offset = ra_->reg2offset(dst_first);
1234        if (cbuf) {
1235          if (Matcher::_regEncode[src_first] < 8) {
1236            emit_opcode(*cbuf, Assembler::REX_W);
1237          } else {
1238            emit_opcode(*cbuf, Assembler::REX_WR);
1239          }
1240          emit_opcode(*cbuf, 0x89);
1241          encode_RegMem(*cbuf,
1242                        Matcher::_regEncode[src_first],
1243                        RSP_enc, 0x4, 0, offset,
1244                        false);
1245#ifndef PRODUCT
1246        } else if (!do_size) {
1247          st->print("movq    [rsp + #%d], %s\t# spill",
1248                     offset,
1249                     Matcher::regName[src_first]);
1250#endif
1251        }
1252        return ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX
1253      } else {
1254        // 32-bit
1255        assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1256        assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1257        int offset = ra_->reg2offset(dst_first);
1258        if (cbuf) {
1259          if (Matcher::_regEncode[src_first] >= 8) {
1260            emit_opcode(*cbuf, Assembler::REX_R);
1261          }
1262          emit_opcode(*cbuf, 0x89);
1263          encode_RegMem(*cbuf,
1264                        Matcher::_regEncode[src_first],
1265                        RSP_enc, 0x4, 0, offset,
1266                        false);
1267#ifndef PRODUCT
1268        } else if (!do_size) {
1269          st->print("movl    [rsp + #%d], %s\t# spill",
1270                     offset,
1271                     Matcher::regName[src_first]);
1272#endif
1273        }
1274        return
1275          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1276          ((Matcher::_regEncode[src_first] < 8)
1277           ? 3
1278           : 4); // REX
1279      }
1280    } else if (dst_first_rc == rc_int) {
1281      // gpr -> gpr
1282      if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1283          (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1284        // 64-bit
1285        if (cbuf) {
1286          if (Matcher::_regEncode[dst_first] < 8) {
1287            if (Matcher::_regEncode[src_first] < 8) {
1288              emit_opcode(*cbuf, Assembler::REX_W);
1289            } else {
1290              emit_opcode(*cbuf, Assembler::REX_WB);
1291            }
1292          } else {
1293            if (Matcher::_regEncode[src_first] < 8) {
1294              emit_opcode(*cbuf, Assembler::REX_WR);
1295            } else {
1296              emit_opcode(*cbuf, Assembler::REX_WRB);
1297            }
1298          }
1299          emit_opcode(*cbuf, 0x8B);
1300          emit_rm(*cbuf, 0x3,
1301                  Matcher::_regEncode[dst_first] & 7,
1302                  Matcher::_regEncode[src_first] & 7);
1303#ifndef PRODUCT
1304        } else if (!do_size) {
1305          st->print("movq    %s, %s\t# spill",
1306                     Matcher::regName[dst_first],
1307                     Matcher::regName[src_first]);
1308#endif
1309        }
1310        return 3; // REX
1311      } else {
1312        // 32-bit
1313        assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1314        assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1315        if (cbuf) {
1316          if (Matcher::_regEncode[dst_first] < 8) {
1317            if (Matcher::_regEncode[src_first] >= 8) {
1318              emit_opcode(*cbuf, Assembler::REX_B);
1319            }
1320          } else {
1321            if (Matcher::_regEncode[src_first] < 8) {
1322              emit_opcode(*cbuf, Assembler::REX_R);
1323            } else {
1324              emit_opcode(*cbuf, Assembler::REX_RB);
1325            }
1326          }
1327          emit_opcode(*cbuf, 0x8B);
1328          emit_rm(*cbuf, 0x3,
1329                  Matcher::_regEncode[dst_first] & 7,
1330                  Matcher::_regEncode[src_first] & 7);
1331#ifndef PRODUCT
1332        } else if (!do_size) {
1333          st->print("movl    %s, %s\t# spill",
1334                     Matcher::regName[dst_first],
1335                     Matcher::regName[src_first]);
1336#endif
1337        }
1338        return
1339          (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
1340          ? 2
1341          : 3; // REX
1342      }
1343    } else if (dst_first_rc == rc_float) {
1344      // gpr -> xmm
1345      if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1346          (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1347        // 64-bit
1348        if (cbuf) {
1349          MacroAssembler _masm(cbuf);
1350          __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1351#ifndef PRODUCT
1352        } else if (!do_size) {
1353          st->print("movdq   %s, %s\t# spill",
1354                     Matcher::regName[dst_first],
1355                     Matcher::regName[src_first]);
1356#endif
1357        }
1358        return 5; // REX
1359      } else {
1360        // 32-bit
1361        assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1362        assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1363        if (cbuf) {
1364          MacroAssembler _masm(cbuf);
1365          __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1366#ifndef PRODUCT
1367        } else if (!do_size) {
1368          st->print("movdl   %s, %s\t# spill",
1369                     Matcher::regName[dst_first],
1370                     Matcher::regName[src_first]);
1371#endif
1372        }
1373        return
1374          (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1375          ? 5
1376          : (4 + ((UseAVX>0)?1:0)); // REX
1377      }
1378    }
1379  } else if (src_first_rc == rc_float) {
1380    // xmm ->
1381    if (dst_first_rc == rc_stack) {
1382      // xmm -> mem
1383      if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1384          (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1385        // 64-bit
1386        int offset = ra_->reg2offset(dst_first);
1387        if (cbuf) {
1388          MacroAssembler _masm(cbuf);
1389          __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1390#ifndef PRODUCT
1391        } else if (!do_size) {
1392          st->print("movsd   [rsp + #%d], %s\t# spill",
1393                     offset,
1394                     Matcher::regName[src_first]);
1395#endif
1396        }
1397        return
1398          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1399          ((Matcher::_regEncode[src_first] >= 8)
1400           ? 6
1401           : (5 + ((UseAVX>0)?1:0))); // REX
1402      } else {
1403        // 32-bit
1404        assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1405        assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1406        int offset = ra_->reg2offset(dst_first);
1407        if (cbuf) {
1408          MacroAssembler _masm(cbuf);
1409          __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1410#ifndef PRODUCT
1411        } else if (!do_size) {
1412          st->print("movss   [rsp + #%d], %s\t# spill",
1413                     offset,
1414                     Matcher::regName[src_first]);
1415#endif
1416        }
1417        return
1418          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
1419          ((Matcher::_regEncode[src_first] >=8)
1420           ? 6
1421           : (5 + ((UseAVX>0)?1:0))); // REX
1422      }
1423    } else if (dst_first_rc == rc_int) {
1424      // xmm -> gpr
1425      if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1426          (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1427        // 64-bit
1428        if (cbuf) {
1429          MacroAssembler _masm(cbuf);
1430          __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1431#ifndef PRODUCT
1432        } else if (!do_size) {
1433          st->print("movdq   %s, %s\t# spill",
1434                     Matcher::regName[dst_first],
1435                     Matcher::regName[src_first]);
1436#endif
1437        }
1438        return 5; // REX
1439      } else {
1440        // 32-bit
1441        assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1442        assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1443        if (cbuf) {
1444          MacroAssembler _masm(cbuf);
1445          __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1446#ifndef PRODUCT
1447        } else if (!do_size) {
1448          st->print("movdl   %s, %s\t# spill",
1449                     Matcher::regName[dst_first],
1450                     Matcher::regName[src_first]);
1451#endif
1452        }
1453        return
1454          (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1455          ? 5
1456          : (4 + ((UseAVX>0)?1:0)); // REX
1457      }
1458    } else if (dst_first_rc == rc_float) {
1459      // xmm -> xmm
1460      if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1461          (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1462        // 64-bit
1463        if (cbuf) {
1464          MacroAssembler _masm(cbuf);
1465          __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1466#ifndef PRODUCT
1467        } else if (!do_size) {
1468          st->print("%s  %s, %s\t# spill",
1469                     UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
1470                     Matcher::regName[dst_first],
1471                     Matcher::regName[src_first]);
1472#endif
1473        }
1474        return
1475          (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1476          ? 5
1477          : (4 + ((UseAVX>0)?1:0)); // REX
1478      } else {
1479        // 32-bit
1480        assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1481        assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1482        if (cbuf) {
1483          MacroAssembler _masm(cbuf);
1484          __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1485#ifndef PRODUCT
1486        } else if (!do_size) {
1487          st->print("%s  %s, %s\t# spill",
1488                     UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1489                     Matcher::regName[dst_first],
1490                     Matcher::regName[src_first]);
1491#endif
1492        }
1493        return ((UseAVX>0) ? 5:
1494          ((Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
1495           ? (UseXmmRegToRegMoveAll ? 4 : 5)
1496           : (UseXmmRegToRegMoveAll ? 3 : 4))); // REX
1497      }
1498    }
1499  }
1500
1501  assert(0," foo ");
1502  Unimplemented();
1503
1504  return 0;
1505}
1506
1507#ifndef PRODUCT
1508void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const
1509{
1510  implementation(NULL, ra_, false, st);
1511}
1512#endif
1513
1514void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const
1515{
1516  implementation(&cbuf, ra_, false, NULL);
1517}
1518
1519uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const
1520{
1521  return implementation(NULL, ra_, true, NULL);
1522}
1523
1524//=============================================================================
1525#ifndef PRODUCT
1526void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1527{
1528  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1529  int reg = ra_->get_reg_first(this);
1530  st->print("leaq    %s, [rsp + #%d]\t# box lock",
1531            Matcher::regName[reg], offset);
1532}
1533#endif
1534
1535void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1536{
1537  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1538  int reg = ra_->get_encode(this);
1539  if (offset >= 0x80) {
1540    emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1541    emit_opcode(cbuf, 0x8D); // LEA  reg,[SP+offset]
1542    emit_rm(cbuf, 0x2, reg & 7, 0x04);
1543    emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1544    emit_d32(cbuf, offset);
1545  } else {
1546    emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1547    emit_opcode(cbuf, 0x8D); // LEA  reg,[SP+offset]
1548    emit_rm(cbuf, 0x1, reg & 7, 0x04);
1549    emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1550    emit_d8(cbuf, offset);
1551  }
1552}
1553
1554uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1555{
1556  int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1557  return (offset < 0x80) ? 5 : 8; // REX
1558}
1559
1560//=============================================================================
1561
1562// emit call stub, compiled java to interpreter
1563void emit_java_to_interp(CodeBuffer& cbuf)
1564{
1565  // Stub is fixed up when the corresponding call is converted from
1566  // calling compiled code to calling interpreted code.
1567  // movq rbx, 0
1568  // jmp -5 # to self
1569
1570  address mark = cbuf.insts_mark();  // get mark within main instrs section
1571
1572  // Note that the code buffer's insts_mark is always relative to insts.
1573  // That's why we must use the macroassembler to generate a stub.
1574  MacroAssembler _masm(&cbuf);
1575
1576  address base =
1577  __ start_a_stub(Compile::MAX_stubs_size);
1578  if (base == NULL)  return;  // CodeBuffer::expand failed
1579  // static stub relocation stores the instruction address of the call
1580  __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64);
1581  // static stub relocation also tags the methodOop in the code-stream.
1582  __ movoop(rbx, (jobject) NULL);  // method is zapped till fixup time
1583  // This is recognized as unresolved by relocs/nativeinst/ic code
1584  __ jump(RuntimeAddress(__ pc()));
1585
1586  // Update current stubs pointer and restore insts_end.
1587  __ end_a_stub();
1588}
1589
1590// size of call stub, compiled java to interpretor
1591uint size_java_to_interp()
1592{
1593  return 15;  // movq (1+1+8); jmp (1+4)
1594}
1595
1596// relocation entries for call stub, compiled java to interpretor
1597uint reloc_java_to_interp()
1598{
1599  return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call
1600}
1601
1602//=============================================================================
1603#ifndef PRODUCT
1604void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1605{
1606  if (UseCompressedOops) {
1607    st->print_cr("movl    rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1608    if (Universe::narrow_oop_shift() != 0) {
1609      st->print_cr("\tdecode_heap_oop_not_null rscratch1, rscratch1");
1610    }
1611    st->print_cr("\tcmpq    rax, rscratch1\t # Inline cache check");
1612  } else {
1613    st->print_cr("\tcmpq    rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1614                 "# Inline cache check");
1615  }
1616  st->print_cr("\tjne     SharedRuntime::_ic_miss_stub");
1617  st->print_cr("\tnop\t# nops to align entry point");
1618}
1619#endif
1620
1621void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1622{
1623  MacroAssembler masm(&cbuf);
1624  uint insts_size = cbuf.insts_size();
1625  if (UseCompressedOops) {
1626    masm.load_klass(rscratch1, j_rarg0);
1627    masm.cmpptr(rax, rscratch1);
1628  } else {
1629    masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1630  }
1631
1632  masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1633
1634  /* WARNING these NOPs are critical so that verified entry point is properly
1635     4 bytes aligned for patching by NativeJump::patch_verified_entry() */
1636  int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
1637  if (OptoBreakpoint) {
1638    // Leave space for int3
1639    nops_cnt -= 1;
1640  }
1641  nops_cnt &= 0x3; // Do not add nops if code is aligned.
1642  if (nops_cnt > 0)
1643    masm.nop(nops_cnt);
1644}
1645
1646uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1647{
1648  return MachNode::size(ra_); // too many variables; just compute it
1649                              // the hard way
1650}
1651
1652
1653//=============================================================================
1654uint size_exception_handler()
1655{
1656  // NativeCall instruction size is the same as NativeJump.
1657  // Note that this value is also credited (in output.cpp) to
1658  // the size of the code section.
1659  return NativeJump::instruction_size;
1660}
1661
1662// Emit exception handler code.
1663int emit_exception_handler(CodeBuffer& cbuf)
1664{
1665
1666  // Note that the code buffer's insts_mark is always relative to insts.
1667  // That's why we must use the macroassembler to generate a handler.
1668  MacroAssembler _masm(&cbuf);
1669  address base =
1670  __ start_a_stub(size_exception_handler());
1671  if (base == NULL)  return 0;  // CodeBuffer::expand failed
1672  int offset = __ offset();
1673  __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
1674  assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
1675  __ end_a_stub();
1676  return offset;
1677}
1678
1679uint size_deopt_handler()
1680{
1681  // three 5 byte instructions
1682  return 15;
1683}
1684
1685// Emit deopt handler code.
1686int emit_deopt_handler(CodeBuffer& cbuf)
1687{
1688
1689  // Note that the code buffer's insts_mark is always relative to insts.
1690  // That's why we must use the macroassembler to generate a handler.
1691  MacroAssembler _masm(&cbuf);
1692  address base =
1693  __ start_a_stub(size_deopt_handler());
1694  if (base == NULL)  return 0;  // CodeBuffer::expand failed
1695  int offset = __ offset();
1696  address the_pc = (address) __ pc();
1697  Label next;
1698  // push a "the_pc" on the stack without destroying any registers
1699  // as they all may be live.
1700
1701  // push address of "next"
1702  __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
1703  __ bind(next);
1704  // adjust it so it matches "the_pc"
1705  __ subptr(Address(rsp, 0), __ offset() - offset);
1706  __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1707  assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1708  __ end_a_stub();
1709  return offset;
1710}
1711
1712
1713const bool Matcher::match_rule_supported(int opcode) {
1714  if (!has_match_rule(opcode))
1715    return false;
1716
1717  return true;  // Per default match rules are supported.
1718}
1719
1720int Matcher::regnum_to_fpu_offset(int regnum)
1721{
1722  return regnum - 32; // The FP registers are in the second chunk
1723}
1724
1725// This is UltraSparc specific, true just means we have fast l2f conversion
1726const bool Matcher::convL2FSupported(void) {
1727  return true;
1728}
1729
1730// Vector width in bytes
1731const uint Matcher::vector_width_in_bytes(void) {
1732  return 8;
1733}
1734
1735// Vector ideal reg
1736const uint Matcher::vector_ideal_reg(void) {
1737  return Op_RegD;
1738}
1739
1740// Is this branch offset short enough that a short branch can be used?
1741//
1742// NOTE: If the platform does not provide any short branch variants, then
1743//       this method should return false for offset 0.
1744bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1745  // The passed offset is relative to address of the branch.
1746  // On 86 a branch displacement is calculated relative to address
1747  // of a next instruction.
1748  offset -= br_size;
1749
1750  // the short version of jmpConUCF2 contains multiple branches,
1751  // making the reach slightly less
1752  if (rule == jmpConUCF2_rule)
1753    return (-126 <= offset && offset <= 125);
1754  return (-128 <= offset && offset <= 127);
1755}
1756
1757const bool Matcher::isSimpleConstant64(jlong value) {
1758  // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1759  //return value == (int) value;  // Cf. storeImmL and immL32.
1760
1761  // Probably always true, even if a temp register is required.
1762  return true;
1763}
1764
1765// The ecx parameter to rep stosq for the ClearArray node is in words.
1766const bool Matcher::init_array_count_is_in_bytes = false;
1767
1768// Threshold size for cleararray.
1769const int Matcher::init_array_short_size = 8 * BytesPerLong;
1770
1771// No additional cost for CMOVL.
1772const int Matcher::long_cmove_cost() { return 0; }
1773
1774// No CMOVF/CMOVD with SSE2
1775const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1776
1777// Should the Matcher clone shifts on addressing modes, expecting them
1778// to be subsumed into complex addressing expressions or compute them
1779// into registers?  True for Intel but false for most RISCs
1780const bool Matcher::clone_shift_expressions = true;
1781
1782// Do we need to mask the count passed to shift instructions or does
1783// the cpu only look at the lower 5/6 bits anyway?
1784const bool Matcher::need_masked_shift_count = false;
1785
1786bool Matcher::narrow_oop_use_complex_address() {
1787  assert(UseCompressedOops, "only for compressed oops code");
1788  return (LogMinObjAlignmentInBytes <= 3);
1789}
1790
1791// Is it better to copy float constants, or load them directly from
1792// memory?  Intel can load a float constant from a direct address,
1793// requiring no extra registers.  Most RISCs will have to materialize
1794// an address into a register first, so they would do better to copy
1795// the constant from stack.
1796const bool Matcher::rematerialize_float_constants = true; // XXX
1797
1798// If CPU can load and store mis-aligned doubles directly then no
1799// fixup is needed.  Else we split the double into 2 integer pieces
1800// and move it piece-by-piece.  Only happens when passing doubles into
1801// C code as the Java calling convention forces doubles to be aligned.
1802const bool Matcher::misaligned_doubles_ok = true;
1803
1804// No-op on amd64
1805void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {}
1806
1807// Advertise here if the CPU requires explicit rounding operations to
1808// implement the UseStrictFP mode.
1809const bool Matcher::strict_fp_requires_explicit_rounding = true;
1810
1811// Are floats conerted to double when stored to stack during deoptimization?
1812// On x64 it is stored without convertion so we can use normal access.
1813bool Matcher::float_in_double() { return false; }
1814
1815// Do ints take an entire long register or just half?
1816const bool Matcher::int_in_long = true;
1817
1818// Return whether or not this register is ever used as an argument.
1819// This function is used on startup to build the trampoline stubs in
1820// generateOptoStub.  Registers not mentioned will be killed by the VM
1821// call in the trampoline, and arguments in those registers not be
1822// available to the callee.
1823bool Matcher::can_be_java_arg(int reg)
1824{
1825  return
1826    reg ==  RDI_num || reg ==  RDI_H_num ||
1827    reg ==  RSI_num || reg ==  RSI_H_num ||
1828    reg ==  RDX_num || reg ==  RDX_H_num ||
1829    reg ==  RCX_num || reg ==  RCX_H_num ||
1830    reg ==   R8_num || reg ==   R8_H_num ||
1831    reg ==   R9_num || reg ==   R9_H_num ||
1832    reg ==  R12_num || reg ==  R12_H_num ||
1833    reg == XMM0_num || reg == XMM0_H_num ||
1834    reg == XMM1_num || reg == XMM1_H_num ||
1835    reg == XMM2_num || reg == XMM2_H_num ||
1836    reg == XMM3_num || reg == XMM3_H_num ||
1837    reg == XMM4_num || reg == XMM4_H_num ||
1838    reg == XMM5_num || reg == XMM5_H_num ||
1839    reg == XMM6_num || reg == XMM6_H_num ||
1840    reg == XMM7_num || reg == XMM7_H_num;
1841}
1842
1843bool Matcher::is_spillable_arg(int reg)
1844{
1845  return can_be_java_arg(reg);
1846}
1847
1848bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1849  // In 64 bit mode a code which use multiply when
1850  // devisor is constant is faster than hardware
1851  // DIV instruction (it uses MulHiL).
1852  return false;
1853}
1854
1855// Register for DIVI projection of divmodI
1856RegMask Matcher::divI_proj_mask() {
1857  return INT_RAX_REG_mask();
1858}
1859
1860// Register for MODI projection of divmodI
1861RegMask Matcher::modI_proj_mask() {
1862  return INT_RDX_REG_mask();
1863}
1864
1865// Register for DIVL projection of divmodL
1866RegMask Matcher::divL_proj_mask() {
1867  return LONG_RAX_REG_mask();
1868}
1869
1870// Register for MODL projection of divmodL
1871RegMask Matcher::modL_proj_mask() {
1872  return LONG_RDX_REG_mask();
1873}
1874
1875const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1876  return PTR_RBP_REG_mask();
1877}
1878
1879static Address build_address(int b, int i, int s, int d) {
1880  Register index = as_Register(i);
1881  Address::ScaleFactor scale = (Address::ScaleFactor)s;
1882  if (index == rsp) {
1883    index = noreg;
1884    scale = Address::no_scale;
1885  }
1886  Address addr(as_Register(b), index, scale, d);
1887  return addr;
1888}
1889
1890%}
1891
1892//----------ENCODING BLOCK-----------------------------------------------------
1893// This block specifies the encoding classes used by the compiler to
1894// output byte streams.  Encoding classes are parameterized macros
1895// used by Machine Instruction Nodes in order to generate the bit
1896// encoding of the instruction.  Operands specify their base encoding
1897// interface with the interface keyword.  There are currently
1898// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
1899// COND_INTER.  REG_INTER causes an operand to generate a function
1900// which returns its register number when queried.  CONST_INTER causes
1901// an operand to generate a function which returns the value of the
1902// constant when queried.  MEMORY_INTER causes an operand to generate
1903// four functions which return the Base Register, the Index Register,
1904// the Scale Value, and the Offset Value of the operand when queried.
1905// COND_INTER causes an operand to generate six functions which return
1906// the encoding code (ie - encoding bits for the instruction)
1907// associated with each basic boolean condition for a conditional
1908// instruction.
1909//
1910// Instructions specify two basic values for encoding.  Again, a
1911// function is available to check if the constant displacement is an
1912// oop. They use the ins_encode keyword to specify their encoding
1913// classes (which must be a sequence of enc_class names, and their
1914// parameters, specified in the encoding block), and they use the
1915// opcode keyword to specify, in order, their primary, secondary, and
1916// tertiary opcode.  Only the opcode sections which a particular
1917// instruction needs for encoding need to be specified.
1918encode %{
1919  // Build emit functions for each basic byte or larger field in the
1920  // intel encoding scheme (opcode, rm, sib, immediate), and call them
1921  // from C++ code in the enc_class source block.  Emit functions will
1922  // live in the main source block for now.  In future, we can
1923  // generalize this by adding a syntax that specifies the sizes of
1924  // fields in an order, so that the adlc can build the emit functions
1925  // automagically
1926
1927  // Emit primary opcode
1928  enc_class OpcP
1929  %{
1930    emit_opcode(cbuf, $primary);
1931  %}
1932
1933  // Emit secondary opcode
1934  enc_class OpcS
1935  %{
1936    emit_opcode(cbuf, $secondary);
1937  %}
1938
1939  // Emit tertiary opcode
1940  enc_class OpcT
1941  %{
1942    emit_opcode(cbuf, $tertiary);
1943  %}
1944
1945  // Emit opcode directly
1946  enc_class Opcode(immI d8)
1947  %{
1948    emit_opcode(cbuf, $d8$$constant);
1949  %}
1950
1951  // Emit size prefix
1952  enc_class SizePrefix
1953  %{
1954    emit_opcode(cbuf, 0x66);
1955  %}
1956
1957  enc_class reg(rRegI reg)
1958  %{
1959    emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
1960  %}
1961
1962  enc_class reg_reg(rRegI dst, rRegI src)
1963  %{
1964    emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1965  %}
1966
1967  enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
1968  %{
1969    emit_opcode(cbuf, $opcode$$constant);
1970    emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1971  %}
1972
1973  enc_class cdql_enc(no_rax_rdx_RegI div)
1974  %{
1975    // Full implementation of Java idiv and irem; checks for
1976    // special case as described in JVM spec., p.243 & p.271.
1977    //
1978    //         normal case                           special case
1979    //
1980    // input : rax: dividend                         min_int
1981    //         reg: divisor                          -1
1982    //
1983    // output: rax: quotient  (= rax idiv reg)       min_int
1984    //         rdx: remainder (= rax irem reg)       0
1985    //
1986    //  Code sequnce:
1987    //
1988    //    0:   3d 00 00 00 80          cmp    $0x80000000,%eax
1989    //    5:   75 07/08                jne    e <normal>
1990    //    7:   33 d2                   xor    %edx,%edx
1991    //  [div >= 8 -> offset + 1]
1992    //  [REX_B]
1993    //    9:   83 f9 ff                cmp    $0xffffffffffffffff,$div
1994    //    c:   74 03/04                je     11 <done>
1995    // 000000000000000e <normal>:
1996    //    e:   99                      cltd
1997    //  [div >= 8 -> offset + 1]
1998    //  [REX_B]
1999    //    f:   f7 f9                   idiv   $div
2000    // 0000000000000011 <done>:
2001
2002    // cmp    $0x80000000,%eax
2003    emit_opcode(cbuf, 0x3d);
2004    emit_d8(cbuf, 0x00);
2005    emit_d8(cbuf, 0x00);
2006    emit_d8(cbuf, 0x00);
2007    emit_d8(cbuf, 0x80);
2008
2009    // jne    e <normal>
2010    emit_opcode(cbuf, 0x75);
2011    emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08);
2012
2013    // xor    %edx,%edx
2014    emit_opcode(cbuf, 0x33);
2015    emit_d8(cbuf, 0xD2);
2016
2017    // cmp    $0xffffffffffffffff,%ecx
2018    if ($div$$reg >= 8) {
2019      emit_opcode(cbuf, Assembler::REX_B);
2020    }
2021    emit_opcode(cbuf, 0x83);
2022    emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
2023    emit_d8(cbuf, 0xFF);
2024
2025    // je     11 <done>
2026    emit_opcode(cbuf, 0x74);
2027    emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04);
2028
2029    // <normal>
2030    // cltd
2031    emit_opcode(cbuf, 0x99);
2032
2033    // idivl (note: must be emitted by the user of this rule)
2034    // <done>
2035  %}
2036
2037  enc_class cdqq_enc(no_rax_rdx_RegL div)
2038  %{
2039    // Full implementation of Java ldiv and lrem; checks for
2040    // special case as described in JVM spec., p.243 & p.271.
2041    //
2042    //         normal case                           special case
2043    //
2044    // input : rax: dividend                         min_long
2045    //         reg: divisor                          -1
2046    //
2047    // output: rax: quotient  (= rax idiv reg)       min_long
2048    //         rdx: remainder (= rax irem reg)       0
2049    //
2050    //  Code sequnce:
2051    //
2052    //    0:   48 ba 00 00 00 00 00    mov    $0x8000000000000000,%rdx
2053    //    7:   00 00 80
2054    //    a:   48 39 d0                cmp    %rdx,%rax
2055    //    d:   75 08                   jne    17 <normal>
2056    //    f:   33 d2                   xor    %edx,%edx
2057    //   11:   48 83 f9 ff             cmp    $0xffffffffffffffff,$div
2058    //   15:   74 05                   je     1c <done>
2059    // 0000000000000017 <normal>:
2060    //   17:   48 99                   cqto
2061    //   19:   48 f7 f9                idiv   $div
2062    // 000000000000001c <done>:
2063
2064    // mov    $0x8000000000000000,%rdx
2065    emit_opcode(cbuf, Assembler::REX_W);
2066    emit_opcode(cbuf, 0xBA);
2067    emit_d8(cbuf, 0x00);
2068    emit_d8(cbuf, 0x00);
2069    emit_d8(cbuf, 0x00);
2070    emit_d8(cbuf, 0x00);
2071    emit_d8(cbuf, 0x00);
2072    emit_d8(cbuf, 0x00);
2073    emit_d8(cbuf, 0x00);
2074    emit_d8(cbuf, 0x80);
2075
2076    // cmp    %rdx,%rax
2077    emit_opcode(cbuf, Assembler::REX_W);
2078    emit_opcode(cbuf, 0x39);
2079    emit_d8(cbuf, 0xD0);
2080
2081    // jne    17 <normal>
2082    emit_opcode(cbuf, 0x75);
2083    emit_d8(cbuf, 0x08);
2084
2085    // xor    %edx,%edx
2086    emit_opcode(cbuf, 0x33);
2087    emit_d8(cbuf, 0xD2);
2088
2089    // cmp    $0xffffffffffffffff,$div
2090    emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB);
2091    emit_opcode(cbuf, 0x83);
2092    emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
2093    emit_d8(cbuf, 0xFF);
2094
2095    // je     1e <done>
2096    emit_opcode(cbuf, 0x74);
2097    emit_d8(cbuf, 0x05);
2098
2099    // <normal>
2100    // cqto
2101    emit_opcode(cbuf, Assembler::REX_W);
2102    emit_opcode(cbuf, 0x99);
2103
2104    // idivq (note: must be emitted by the user of this rule)
2105    // <done>
2106  %}
2107
2108  // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
2109  enc_class OpcSE(immI imm)
2110  %{
2111    // Emit primary opcode and set sign-extend bit
2112    // Check for 8-bit immediate, and set sign extend bit in opcode
2113    if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2114      emit_opcode(cbuf, $primary | 0x02);
2115    } else {
2116      // 32-bit immediate
2117      emit_opcode(cbuf, $primary);
2118    }
2119  %}
2120
2121  enc_class OpcSErm(rRegI dst, immI imm)
2122  %{
2123    // OpcSEr/m
2124    int dstenc = $dst$$reg;
2125    if (dstenc >= 8) {
2126      emit_opcode(cbuf, Assembler::REX_B);
2127      dstenc -= 8;
2128    }
2129    // Emit primary opcode and set sign-extend bit
2130    // Check for 8-bit immediate, and set sign extend bit in opcode
2131    if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2132      emit_opcode(cbuf, $primary | 0x02);
2133    } else {
2134      // 32-bit immediate
2135      emit_opcode(cbuf, $primary);
2136    }
2137    // Emit r/m byte with secondary opcode, after primary opcode.
2138    emit_rm(cbuf, 0x3, $secondary, dstenc);
2139  %}
2140
2141  enc_class OpcSErm_wide(rRegL dst, immI imm)
2142  %{
2143    // OpcSEr/m
2144    int dstenc = $dst$$reg;
2145    if (dstenc < 8) {
2146      emit_opcode(cbuf, Assembler::REX_W);
2147    } else {
2148      emit_opcode(cbuf, Assembler::REX_WB);
2149      dstenc -= 8;
2150    }
2151    // Emit primary opcode and set sign-extend bit
2152    // Check for 8-bit immediate, and set sign extend bit in opcode
2153    if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2154      emit_opcode(cbuf, $primary | 0x02);
2155    } else {
2156      // 32-bit immediate
2157      emit_opcode(cbuf, $primary);
2158    }
2159    // Emit r/m byte with secondary opcode, after primary opcode.
2160    emit_rm(cbuf, 0x3, $secondary, dstenc);
2161  %}
2162
2163  enc_class Con8or32(immI imm)
2164  %{
2165    // Check for 8-bit immediate, and set sign extend bit in opcode
2166    if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
2167      $$$emit8$imm$$constant;
2168    } else {
2169      // 32-bit immediate
2170      $$$emit32$imm$$constant;
2171    }
2172  %}
2173
2174  enc_class opc2_reg(rRegI dst)
2175  %{
2176    // BSWAP
2177    emit_cc(cbuf, $secondary, $dst$$reg);
2178  %}
2179
2180  enc_class opc3_reg(rRegI dst)
2181  %{
2182    // BSWAP
2183    emit_cc(cbuf, $tertiary, $dst$$reg);
2184  %}
2185
2186  enc_class reg_opc(rRegI div)
2187  %{
2188    // INC, DEC, IDIV, IMOD, JMP indirect, ...
2189    emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
2190  %}
2191
2192  enc_class enc_cmov(cmpOp cop)
2193  %{
2194    // CMOV
2195    $$$emit8$primary;
2196    emit_cc(cbuf, $secondary, $cop$$cmpcode);
2197  %}
2198
2199  enc_class enc_PartialSubtypeCheck()
2200  %{
2201    Register Rrdi = as_Register(RDI_enc); // result register
2202    Register Rrax = as_Register(RAX_enc); // super class
2203    Register Rrcx = as_Register(RCX_enc); // killed
2204    Register Rrsi = as_Register(RSI_enc); // sub class
2205    Label miss;
2206    const bool set_cond_codes = true;
2207
2208    MacroAssembler _masm(&cbuf);
2209    __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
2210                                     NULL, &miss,
2211                                     /*set_cond_codes:*/ true);
2212    if ($primary) {
2213      __ xorptr(Rrdi, Rrdi);
2214    }
2215    __ bind(miss);
2216  %}
2217
2218  enc_class Java_To_Interpreter(method meth)
2219  %{
2220    // CALL Java_To_Interpreter
2221    // This is the instruction starting address for relocation info.
2222    cbuf.set_insts_mark();
2223    $$$emit8$primary;
2224    // CALL directly to the runtime
2225    emit_d32_reloc(cbuf,
2226                   (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2227                   runtime_call_Relocation::spec(),
2228                   RELOC_DISP32);
2229  %}
2230
2231  enc_class Java_Static_Call(method meth)
2232  %{
2233    // JAVA STATIC CALL
2234    // CALL to fixup routine.  Fixup routine uses ScopeDesc info to
2235    // determine who we intended to call.
2236    cbuf.set_insts_mark();
2237    $$$emit8$primary;
2238
2239    if (!_method) {
2240      emit_d32_reloc(cbuf,
2241                     (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2242                     runtime_call_Relocation::spec(),
2243                     RELOC_DISP32);
2244    } else if (_optimized_virtual) {
2245      emit_d32_reloc(cbuf,
2246                     (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2247                     opt_virtual_call_Relocation::spec(),
2248                     RELOC_DISP32);
2249    } else {
2250      emit_d32_reloc(cbuf,
2251                     (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2252                     static_call_Relocation::spec(),
2253                     RELOC_DISP32);
2254    }
2255    if (_method) {
2256      // Emit stub for static call
2257      emit_java_to_interp(cbuf);
2258    }
2259  %}
2260
2261  enc_class Java_Dynamic_Call(method meth)
2262  %{
2263    // JAVA DYNAMIC CALL
2264    // !!!!!
2265    // Generate  "movq rax, -1", placeholder instruction to load oop-info
2266    // emit_call_dynamic_prologue( cbuf );
2267    cbuf.set_insts_mark();
2268
2269    // movq rax, -1
2270    emit_opcode(cbuf, Assembler::REX_W);
2271    emit_opcode(cbuf, 0xB8 | RAX_enc);
2272    emit_d64_reloc(cbuf,
2273                   (int64_t) Universe::non_oop_word(),
2274                   oop_Relocation::spec_for_immediate(), RELOC_IMM64);
2275    address virtual_call_oop_addr = cbuf.insts_mark();
2276    // CALL to fixup routine.  Fixup routine uses ScopeDesc info to determine
2277    // who we intended to call.
2278    cbuf.set_insts_mark();
2279    $$$emit8$primary;
2280    emit_d32_reloc(cbuf,
2281                   (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2282                   virtual_call_Relocation::spec(virtual_call_oop_addr),
2283                   RELOC_DISP32);
2284  %}
2285
2286  enc_class Java_Compiled_Call(method meth)
2287  %{
2288    // JAVA COMPILED CALL
2289    int disp = in_bytes(methodOopDesc:: from_compiled_offset());
2290
2291    // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
2292    // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
2293
2294    // callq *disp(%rax)
2295    cbuf.set_insts_mark();
2296    $$$emit8$primary;
2297    if (disp < 0x80) {
2298      emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
2299      emit_d8(cbuf, disp); // Displacement
2300    } else {
2301      emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte
2302      emit_d32(cbuf, disp); // Displacement
2303    }
2304  %}
2305
2306  enc_class reg_opc_imm(rRegI dst, immI8 shift)
2307  %{
2308    // SAL, SAR, SHR
2309    int dstenc = $dst$$reg;
2310    if (dstenc >= 8) {
2311      emit_opcode(cbuf, Assembler::REX_B);
2312      dstenc -= 8;
2313    }
2314    $$$emit8$primary;
2315    emit_rm(cbuf, 0x3, $secondary, dstenc);
2316    $$$emit8$shift$$constant;
2317  %}
2318
2319  enc_class reg_opc_imm_wide(rRegL dst, immI8 shift)
2320  %{
2321    // SAL, SAR, SHR
2322    int dstenc = $dst$$reg;
2323    if (dstenc < 8) {
2324      emit_opcode(cbuf, Assembler::REX_W);
2325    } else {
2326      emit_opcode(cbuf, Assembler::REX_WB);
2327      dstenc -= 8;
2328    }
2329    $$$emit8$primary;
2330    emit_rm(cbuf, 0x3, $secondary, dstenc);
2331    $$$emit8$shift$$constant;
2332  %}
2333
2334  enc_class load_immI(rRegI dst, immI src)
2335  %{
2336    int dstenc = $dst$$reg;
2337    if (dstenc >= 8) {
2338      emit_opcode(cbuf, Assembler::REX_B);
2339      dstenc -= 8;
2340    }
2341    emit_opcode(cbuf, 0xB8 | dstenc);
2342    $$$emit32$src$$constant;
2343  %}
2344
2345  enc_class load_immL(rRegL dst, immL src)
2346  %{
2347    int dstenc = $dst$$reg;
2348    if (dstenc < 8) {
2349      emit_opcode(cbuf, Assembler::REX_W);
2350    } else {
2351      emit_opcode(cbuf, Assembler::REX_WB);
2352      dstenc -= 8;
2353    }
2354    emit_opcode(cbuf, 0xB8 | dstenc);
2355    emit_d64(cbuf, $src$$constant);
2356  %}
2357
2358  enc_class load_immUL32(rRegL dst, immUL32 src)
2359  %{
2360    // same as load_immI, but this time we care about zeroes in the high word
2361    int dstenc = $dst$$reg;
2362    if (dstenc >= 8) {
2363      emit_opcode(cbuf, Assembler::REX_B);
2364      dstenc -= 8;
2365    }
2366    emit_opcode(cbuf, 0xB8 | dstenc);
2367    $$$emit32$src$$constant;
2368  %}
2369
2370  enc_class load_immL32(rRegL dst, immL32 src)
2371  %{
2372    int dstenc = $dst$$reg;
2373    if (dstenc < 8) {
2374      emit_opcode(cbuf, Assembler::REX_W);
2375    } else {
2376      emit_opcode(cbuf, Assembler::REX_WB);
2377      dstenc -= 8;
2378    }
2379    emit_opcode(cbuf, 0xC7);
2380    emit_rm(cbuf, 0x03, 0x00, dstenc);
2381    $$$emit32$src$$constant;
2382  %}
2383
2384  enc_class load_immP31(rRegP dst, immP32 src)
2385  %{
2386    // same as load_immI, but this time we care about zeroes in the high word
2387    int dstenc = $dst$$reg;
2388    if (dstenc >= 8) {
2389      emit_opcode(cbuf, Assembler::REX_B);
2390      dstenc -= 8;
2391    }
2392    emit_opcode(cbuf, 0xB8 | dstenc);
2393    $$$emit32$src$$constant;
2394  %}
2395
2396  enc_class load_immP(rRegP dst, immP src)
2397  %{
2398    int dstenc = $dst$$reg;
2399    if (dstenc < 8) {
2400      emit_opcode(cbuf, Assembler::REX_W);
2401    } else {
2402      emit_opcode(cbuf, Assembler::REX_WB);
2403      dstenc -= 8;
2404    }
2405    emit_opcode(cbuf, 0xB8 | dstenc);
2406    // This next line should be generated from ADLC
2407    if ($src->constant_is_oop()) {
2408      emit_d64_reloc(cbuf, $src$$constant, relocInfo::oop_type, RELOC_IMM64);
2409    } else {
2410      emit_d64(cbuf, $src$$constant);
2411    }
2412  %}
2413
2414  enc_class Con32(immI src)
2415  %{
2416    // Output immediate
2417    $$$emit32$src$$constant;
2418  %}
2419
2420  enc_class Con64(immL src)
2421  %{
2422    // Output immediate
2423    emit_d64($src$$constant);
2424  %}
2425
2426  enc_class Con32F_as_bits(immF src)
2427  %{
2428    // Output Float immediate bits
2429    jfloat jf = $src$$constant;
2430    jint jf_as_bits = jint_cast(jf);
2431    emit_d32(cbuf, jf_as_bits);
2432  %}
2433
2434  enc_class Con16(immI src)
2435  %{
2436    // Output immediate
2437    $$$emit16$src$$constant;
2438  %}
2439
2440  // How is this different from Con32??? XXX
2441  enc_class Con_d32(immI src)
2442  %{
2443    emit_d32(cbuf,$src$$constant);
2444  %}
2445
2446  enc_class conmemref (rRegP t1) %{    // Con32(storeImmI)
2447    // Output immediate memory reference
2448    emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2449    emit_d32(cbuf, 0x00);
2450  %}
2451
2452  enc_class lock_prefix()
2453  %{
2454    if (os::is_MP()) {
2455      emit_opcode(cbuf, 0xF0); // lock
2456    }
2457  %}
2458
2459  enc_class REX_mem(memory mem)
2460  %{
2461    if ($mem$$base >= 8) {
2462      if ($mem$$index < 8) {
2463        emit_opcode(cbuf, Assembler::REX_B);
2464      } else {
2465        emit_opcode(cbuf, Assembler::REX_XB);
2466      }
2467    } else {
2468      if ($mem$$index >= 8) {
2469        emit_opcode(cbuf, Assembler::REX_X);
2470      }
2471    }
2472  %}
2473
2474  enc_class REX_mem_wide(memory mem)
2475  %{
2476    if ($mem$$base >= 8) {
2477      if ($mem$$index < 8) {
2478        emit_opcode(cbuf, Assembler::REX_WB);
2479      } else {
2480        emit_opcode(cbuf, Assembler::REX_WXB);
2481      }
2482    } else {
2483      if ($mem$$index < 8) {
2484        emit_opcode(cbuf, Assembler::REX_W);
2485      } else {
2486        emit_opcode(cbuf, Assembler::REX_WX);
2487      }
2488    }
2489  %}
2490
2491  // for byte regs
2492  enc_class REX_breg(rRegI reg)
2493  %{
2494    if ($reg$$reg >= 4) {
2495      emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2496    }
2497  %}
2498
2499  // for byte regs
2500  enc_class REX_reg_breg(rRegI dst, rRegI src)
2501  %{
2502    if ($dst$$reg < 8) {
2503      if ($src$$reg >= 4) {
2504        emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2505      }
2506    } else {
2507      if ($src$$reg < 8) {
2508        emit_opcode(cbuf, Assembler::REX_R);
2509      } else {
2510        emit_opcode(cbuf, Assembler::REX_RB);
2511      }
2512    }
2513  %}
2514
2515  // for byte regs
2516  enc_class REX_breg_mem(rRegI reg, memory mem)
2517  %{
2518    if ($reg$$reg < 8) {
2519      if ($mem$$base < 8) {
2520        if ($mem$$index >= 8) {
2521          emit_opcode(cbuf, Assembler::REX_X);
2522        } else if ($reg$$reg >= 4) {
2523          emit_opcode(cbuf, Assembler::REX);
2524        }
2525      } else {
2526        if ($mem$$index < 8) {
2527          emit_opcode(cbuf, Assembler::REX_B);
2528        } else {
2529          emit_opcode(cbuf, Assembler::REX_XB);
2530        }
2531      }
2532    } else {
2533      if ($mem$$base < 8) {
2534        if ($mem$$index < 8) {
2535          emit_opcode(cbuf, Assembler::REX_R);
2536        } else {
2537          emit_opcode(cbuf, Assembler::REX_RX);
2538        }
2539      } else {
2540        if ($mem$$index < 8) {
2541          emit_opcode(cbuf, Assembler::REX_RB);
2542        } else {
2543          emit_opcode(cbuf, Assembler::REX_RXB);
2544        }
2545      }
2546    }
2547  %}
2548
2549  enc_class REX_reg(rRegI reg)
2550  %{
2551    if ($reg$$reg >= 8) {
2552      emit_opcode(cbuf, Assembler::REX_B);
2553    }
2554  %}
2555
2556  enc_class REX_reg_wide(rRegI reg)
2557  %{
2558    if ($reg$$reg < 8) {
2559      emit_opcode(cbuf, Assembler::REX_W);
2560    } else {
2561      emit_opcode(cbuf, Assembler::REX_WB);
2562    }
2563  %}
2564
2565  enc_class REX_reg_reg(rRegI dst, rRegI src)
2566  %{
2567    if ($dst$$reg < 8) {
2568      if ($src$$reg >= 8) {
2569        emit_opcode(cbuf, Assembler::REX_B);
2570      }
2571    } else {
2572      if ($src$$reg < 8) {
2573        emit_opcode(cbuf, Assembler::REX_R);
2574      } else {
2575        emit_opcode(cbuf, Assembler::REX_RB);
2576      }
2577    }
2578  %}
2579
2580  enc_class REX_reg_reg_wide(rRegI dst, rRegI src)
2581  %{
2582    if ($dst$$reg < 8) {
2583      if ($src$$reg < 8) {
2584        emit_opcode(cbuf, Assembler::REX_W);
2585      } else {
2586        emit_opcode(cbuf, Assembler::REX_WB);
2587      }
2588    } else {
2589      if ($src$$reg < 8) {
2590        emit_opcode(cbuf, Assembler::REX_WR);
2591      } else {
2592        emit_opcode(cbuf, Assembler::REX_WRB);
2593      }
2594    }
2595  %}
2596
2597  enc_class REX_reg_mem(rRegI reg, memory mem)
2598  %{
2599    if ($reg$$reg < 8) {
2600      if ($mem$$base < 8) {
2601        if ($mem$$index >= 8) {
2602          emit_opcode(cbuf, Assembler::REX_X);
2603        }
2604      } else {
2605        if ($mem$$index < 8) {
2606          emit_opcode(cbuf, Assembler::REX_B);
2607        } else {
2608          emit_opcode(cbuf, Assembler::REX_XB);
2609        }
2610      }
2611    } else {
2612      if ($mem$$base < 8) {
2613        if ($mem$$index < 8) {
2614          emit_opcode(cbuf, Assembler::REX_R);
2615        } else {
2616          emit_opcode(cbuf, Assembler::REX_RX);
2617        }
2618      } else {
2619        if ($mem$$index < 8) {
2620          emit_opcode(cbuf, Assembler::REX_RB);
2621        } else {
2622          emit_opcode(cbuf, Assembler::REX_RXB);
2623        }
2624      }
2625    }
2626  %}
2627
2628  enc_class REX_reg_mem_wide(rRegL reg, memory mem)
2629  %{
2630    if ($reg$$reg < 8) {
2631      if ($mem$$base < 8) {
2632        if ($mem$$index < 8) {
2633          emit_opcode(cbuf, Assembler::REX_W);
2634        } else {
2635          emit_opcode(cbuf, Assembler::REX_WX);
2636        }
2637      } else {
2638        if ($mem$$index < 8) {
2639          emit_opcode(cbuf, Assembler::REX_WB);
2640        } else {
2641          emit_opcode(cbuf, Assembler::REX_WXB);
2642        }
2643      }
2644    } else {
2645      if ($mem$$base < 8) {
2646        if ($mem$$index < 8) {
2647          emit_opcode(cbuf, Assembler::REX_WR);
2648        } else {
2649          emit_opcode(cbuf, Assembler::REX_WRX);
2650        }
2651      } else {
2652        if ($mem$$index < 8) {
2653          emit_opcode(cbuf, Assembler::REX_WRB);
2654        } else {
2655          emit_opcode(cbuf, Assembler::REX_WRXB);
2656        }
2657      }
2658    }
2659  %}
2660
2661  enc_class reg_mem(rRegI ereg, memory mem)
2662  %{
2663    // High registers handle in encode_RegMem
2664    int reg = $ereg$$reg;
2665    int base = $mem$$base;
2666    int index = $mem$$index;
2667    int scale = $mem$$scale;
2668    int disp = $mem$$disp;
2669    bool disp_is_oop = $mem->disp_is_oop();
2670
2671    encode_RegMem(cbuf, reg, base, index, scale, disp, disp_is_oop);
2672  %}
2673
2674  enc_class RM_opc_mem(immI rm_opcode, memory mem)
2675  %{
2676    int rm_byte_opcode = $rm_opcode$$constant;
2677
2678    // High registers handle in encode_RegMem
2679    int base = $mem$$base;
2680    int index = $mem$$index;
2681    int scale = $mem$$scale;
2682    int displace = $mem$$disp;
2683
2684    bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when
2685                                            // working with static
2686                                            // globals
2687    encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace,
2688                  disp_is_oop);
2689  %}
2690
2691  enc_class reg_lea(rRegI dst, rRegI src0, immI src1)
2692  %{
2693    int reg_encoding = $dst$$reg;
2694    int base         = $src0$$reg;      // 0xFFFFFFFF indicates no base
2695    int index        = 0x04;            // 0x04 indicates no index
2696    int scale        = 0x00;            // 0x00 indicates no scale
2697    int displace     = $src1$$constant; // 0x00 indicates no displacement
2698    bool disp_is_oop = false;
2699    encode_RegMem(cbuf, reg_encoding, base, index, scale, displace,
2700                  disp_is_oop);
2701  %}
2702
2703  enc_class neg_reg(rRegI dst)
2704  %{
2705    int dstenc = $dst$$reg;
2706    if (dstenc >= 8) {
2707      emit_opcode(cbuf, Assembler::REX_B);
2708      dstenc -= 8;
2709    }
2710    // NEG $dst
2711    emit_opcode(cbuf, 0xF7);
2712    emit_rm(cbuf, 0x3, 0x03, dstenc);
2713  %}
2714
2715  enc_class neg_reg_wide(rRegI dst)
2716  %{
2717    int dstenc = $dst$$reg;
2718    if (dstenc < 8) {
2719      emit_opcode(cbuf, Assembler::REX_W);
2720    } else {
2721      emit_opcode(cbuf, Assembler::REX_WB);
2722      dstenc -= 8;
2723    }
2724    // NEG $dst
2725    emit_opcode(cbuf, 0xF7);
2726    emit_rm(cbuf, 0x3, 0x03, dstenc);
2727  %}
2728
2729  enc_class setLT_reg(rRegI dst)
2730  %{
2731    int dstenc = $dst$$reg;
2732    if (dstenc >= 8) {
2733      emit_opcode(cbuf, Assembler::REX_B);
2734      dstenc -= 8;
2735    } else if (dstenc >= 4) {
2736      emit_opcode(cbuf, Assembler::REX);
2737    }
2738    // SETLT $dst
2739    emit_opcode(cbuf, 0x0F);
2740    emit_opcode(cbuf, 0x9C);
2741    emit_rm(cbuf, 0x3, 0x0, dstenc);
2742  %}
2743
2744  enc_class setNZ_reg(rRegI dst)
2745  %{
2746    int dstenc = $dst$$reg;
2747    if (dstenc >= 8) {
2748      emit_opcode(cbuf, Assembler::REX_B);
2749      dstenc -= 8;
2750    } else if (dstenc >= 4) {
2751      emit_opcode(cbuf, Assembler::REX);
2752    }
2753    // SETNZ $dst
2754    emit_opcode(cbuf, 0x0F);
2755    emit_opcode(cbuf, 0x95);
2756    emit_rm(cbuf, 0x3, 0x0, dstenc);
2757  %}
2758
2759
2760  // Compare the lonogs and set -1, 0, or 1 into dst
2761  enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst)
2762  %{
2763    int src1enc = $src1$$reg;
2764    int src2enc = $src2$$reg;
2765    int dstenc = $dst$$reg;
2766
2767    // cmpq $src1, $src2
2768    if (src1enc < 8) {
2769      if (src2enc < 8) {
2770        emit_opcode(cbuf, Assembler::REX_W);
2771      } else {
2772        emit_opcode(cbuf, Assembler::REX_WB);
2773      }
2774    } else {
2775      if (src2enc < 8) {
2776        emit_opcode(cbuf, Assembler::REX_WR);
2777      } else {
2778        emit_opcode(cbuf, Assembler::REX_WRB);
2779      }
2780    }
2781    emit_opcode(cbuf, 0x3B);
2782    emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7);
2783
2784    // movl $dst, -1
2785    if (dstenc >= 8) {
2786      emit_opcode(cbuf, Assembler::REX_B);
2787    }
2788    emit_opcode(cbuf, 0xB8 | (dstenc & 7));
2789    emit_d32(cbuf, -1);
2790
2791    // jl,s done
2792    emit_opcode(cbuf, 0x7C);
2793    emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
2794
2795    // setne $dst
2796    if (dstenc >= 4) {
2797      emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
2798    }
2799    emit_opcode(cbuf, 0x0F);
2800    emit_opcode(cbuf, 0x95);
2801    emit_opcode(cbuf, 0xC0 | (dstenc & 7));
2802
2803    // movzbl $dst, $dst
2804    if (dstenc >= 4) {
2805      emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
2806    }
2807    emit_opcode(cbuf, 0x0F);
2808    emit_opcode(cbuf, 0xB6);
2809    emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
2810  %}
2811
2812  enc_class Push_ResultXD(regD dst) %{
2813    MacroAssembler _masm(&cbuf);
2814    __ fstp_d(Address(rsp, 0));
2815    __ movdbl($dst$$XMMRegister, Address(rsp, 0));
2816    __ addptr(rsp, 8);
2817  %}
2818
2819  enc_class Push_SrcXD(regD src) %{
2820    MacroAssembler _masm(&cbuf);
2821    __ subptr(rsp, 8);
2822    __ movdbl(Address(rsp, 0), $src$$XMMRegister);
2823    __ fld_d(Address(rsp, 0));
2824  %}
2825
2826
2827  // obj: object to lock
2828  // box: box address (header location) -- killed
2829  // tmp: rax -- killed
2830  // scr: rbx -- killed
2831  //
2832  // What follows is a direct transliteration of fast_lock() and fast_unlock()
2833  // from i486.ad.  See that file for comments.
2834  // TODO: where possible switch from movq (r, 0) to movl(r,0) and
2835  // use the shorter encoding.  (Movl clears the high-order 32-bits).
2836
2837
2838  enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr)
2839  %{
2840    Register objReg = as_Register((int)$obj$$reg);
2841    Register boxReg = as_Register((int)$box$$reg);
2842    Register tmpReg = as_Register($tmp$$reg);
2843    Register scrReg = as_Register($scr$$reg);
2844    MacroAssembler masm(&cbuf);
2845
2846    // Verify uniqueness of register assignments -- necessary but not sufficient
2847    assert (objReg != boxReg && objReg != tmpReg &&
2848            objReg != scrReg && tmpReg != scrReg, "invariant") ;
2849
2850    if (_counters != NULL) {
2851      masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr()));
2852    }
2853    if (EmitSync & 1) {
2854        // Without cast to int32_t a movptr will destroy r10 which is typically obj
2855        masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
2856        masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
2857    } else
2858    if (EmitSync & 2) {
2859        Label DONE_LABEL;
2860        if (UseBiasedLocking) {
2861           // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument.
2862          masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
2863        }
2864        // QQQ was movl...
2865        masm.movptr(tmpReg, 0x1);
2866        masm.orptr(tmpReg, Address(objReg, 0));
2867        masm.movptr(Address(boxReg, 0), tmpReg);
2868        if (os::is_MP()) {
2869          masm.lock();
2870        }
2871        masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
2872        masm.jcc(Assembler::equal, DONE_LABEL);
2873
2874        // Recursive locking
2875        masm.subptr(tmpReg, rsp);
2876        masm.andptr(tmpReg, 7 - os::vm_page_size());
2877        masm.movptr(Address(boxReg, 0), tmpReg);
2878
2879        masm.bind(DONE_LABEL);
2880        masm.nop(); // avoid branch to branch
2881    } else {
2882        Label DONE_LABEL, IsInflated, Egress;
2883
2884        masm.movptr(tmpReg, Address(objReg, 0)) ;
2885        masm.testl (tmpReg, 0x02) ;         // inflated vs stack-locked|neutral|biased
2886        masm.jcc   (Assembler::notZero, IsInflated) ;
2887
2888        // it's stack-locked, biased or neutral
2889        // TODO: optimize markword triage order to reduce the number of
2890        // conditional branches in the most common cases.
2891        // Beware -- there's a subtle invariant that fetch of the markword
2892        // at [FETCH], below, will never observe a biased encoding (*101b).
2893        // If this invariant is not held we'll suffer exclusion (safety) failure.
2894
2895        if (UseBiasedLocking && !UseOptoBiasInlining) {
2896          masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
2897          masm.movptr(tmpReg, Address(objReg, 0)) ;        // [FETCH]
2898        }
2899
2900        // was q will it destroy high?
2901        masm.orl   (tmpReg, 1) ;
2902        masm.movptr(Address(boxReg, 0), tmpReg) ;
2903        if (os::is_MP()) { masm.lock(); }
2904        masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
2905        if (_counters != NULL) {
2906           masm.cond_inc32(Assembler::equal,
2907                           ExternalAddress((address) _counters->fast_path_entry_count_addr()));
2908        }
2909        masm.jcc   (Assembler::equal, DONE_LABEL);
2910
2911        // Recursive locking
2912        masm.subptr(tmpReg, rsp);
2913        masm.andptr(tmpReg, 7 - os::vm_page_size());
2914        masm.movptr(Address(boxReg, 0), tmpReg);
2915        if (_counters != NULL) {
2916           masm.cond_inc32(Assembler::equal,
2917                           ExternalAddress((address) _counters->fast_path_entry_count_addr()));
2918        }
2919        masm.jmp   (DONE_LABEL) ;
2920
2921        masm.bind  (IsInflated) ;
2922        // It's inflated
2923
2924        // TODO: someday avoid the ST-before-CAS penalty by
2925        // relocating (deferring) the following ST.
2926        // We should also think about trying a CAS without having
2927        // fetched _owner.  If the CAS is successful we may
2928        // avoid an RTO->RTS upgrade on the $line.
2929        // Without cast to int32_t a movptr will destroy r10 which is typically obj
2930        masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
2931
2932        masm.mov    (boxReg, tmpReg) ;
2933        masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
2934        masm.testptr(tmpReg, tmpReg) ;
2935        masm.jcc    (Assembler::notZero, DONE_LABEL) ;
2936
2937        // It's inflated and appears unlocked
2938        if (os::is_MP()) { masm.lock(); }
2939        masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
2940        // Intentional fall-through into DONE_LABEL ...
2941
2942        masm.bind  (DONE_LABEL) ;
2943        masm.nop   () ;                 // avoid jmp to jmp
2944    }
2945  %}
2946
2947  // obj: object to unlock
2948  // box: box address (displaced header location), killed
2949  // RBX: killed tmp; cannot be obj nor box
2950  enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp)
2951  %{
2952
2953    Register objReg = as_Register($obj$$reg);
2954    Register boxReg = as_Register($box$$reg);
2955    Register tmpReg = as_Register($tmp$$reg);
2956    MacroAssembler masm(&cbuf);
2957
2958    if (EmitSync & 4) {
2959       masm.cmpptr(rsp, 0) ;
2960    } else
2961    if (EmitSync & 8) {
2962       Label DONE_LABEL;
2963       if (UseBiasedLocking) {
2964         masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
2965       }
2966
2967       // Check whether the displaced header is 0
2968       //(=> recursive unlock)
2969       masm.movptr(tmpReg, Address(boxReg, 0));
2970       masm.testptr(tmpReg, tmpReg);
2971       masm.jcc(Assembler::zero, DONE_LABEL);
2972
2973       // If not recursive lock, reset the header to displaced header
2974       if (os::is_MP()) {
2975         masm.lock();
2976       }
2977       masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
2978       masm.bind(DONE_LABEL);
2979       masm.nop(); // avoid branch to branch
2980    } else {
2981       Label DONE_LABEL, Stacked, CheckSucc ;
2982
2983       if (UseBiasedLocking && !UseOptoBiasInlining) {
2984         masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
2985       }
2986
2987       masm.movptr(tmpReg, Address(objReg, 0)) ;
2988       masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
2989       masm.jcc   (Assembler::zero, DONE_LABEL) ;
2990       masm.testl (tmpReg, 0x02) ;
2991       masm.jcc   (Assembler::zero, Stacked) ;
2992
2993       // It's inflated
2994       masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
2995       masm.xorptr(boxReg, r15_thread) ;
2996       masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
2997       masm.jcc   (Assembler::notZero, DONE_LABEL) ;
2998       masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
2999       masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
3000       masm.jcc   (Assembler::notZero, CheckSucc) ;
3001       masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3002       masm.jmp   (DONE_LABEL) ;
3003
3004       if ((EmitSync & 65536) == 0) {
3005         Label LSuccess, LGoSlowPath ;
3006         masm.bind  (CheckSucc) ;
3007         masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3008         masm.jcc   (Assembler::zero, LGoSlowPath) ;
3009
3010         // I'd much rather use lock:andl m->_owner, 0 as it's faster than the
3011         // the explicit ST;MEMBAR combination, but masm doesn't currently support
3012         // "ANDQ M,IMM".  Don't use MFENCE here.  lock:add to TOS, xchg, etc
3013         // are all faster when the write buffer is populated.
3014         masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3015         if (os::is_MP()) {
3016            masm.lock () ; masm.addl (Address(rsp, 0), 0) ;
3017         }
3018         masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3019         masm.jcc   (Assembler::notZero, LSuccess) ;
3020
3021         masm.movptr (boxReg, (int32_t)NULL_WORD) ;                   // box is really EAX
3022         if (os::is_MP()) { masm.lock(); }
3023         masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2));
3024         masm.jcc   (Assembler::notEqual, LSuccess) ;
3025         // Intentional fall-through into slow-path
3026
3027         masm.bind  (LGoSlowPath) ;
3028         masm.orl   (boxReg, 1) ;                      // set ICC.ZF=0 to indicate failure
3029         masm.jmp   (DONE_LABEL) ;
3030
3031         masm.bind  (LSuccess) ;
3032         masm.testl (boxReg, 0) ;                      // set ICC.ZF=1 to indicate success
3033         masm.jmp   (DONE_LABEL) ;
3034       }
3035
3036       masm.bind  (Stacked) ;
3037       masm.movptr(tmpReg, Address (boxReg, 0)) ;      // re-fetch
3038       if (os::is_MP()) { masm.lock(); }
3039       masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
3040
3041       if (EmitSync & 65536) {
3042          masm.bind (CheckSucc) ;
3043       }
3044       masm.bind(DONE_LABEL);
3045       if (EmitSync & 32768) {
3046          masm.nop();                      // avoid branch to branch
3047       }
3048    }
3049  %}
3050
3051
3052  enc_class enc_rethrow()
3053  %{
3054    cbuf.set_insts_mark();
3055    emit_opcode(cbuf, 0xE9); // jmp entry
3056    emit_d32_reloc(cbuf,
3057                   (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
3058                   runtime_call_Relocation::spec(),
3059                   RELOC_DISP32);
3060  %}
3061
3062%}
3063
3064
3065
3066//----------FRAME--------------------------------------------------------------
3067// Definition of frame structure and management information.
3068//
3069//  S T A C K   L A Y O U T    Allocators stack-slot number
3070//                             |   (to get allocators register number
3071//  G  Owned by    |        |  v    add OptoReg::stack0())
3072//  r   CALLER     |        |
3073//  o     |        +--------+      pad to even-align allocators stack-slot
3074//  w     V        |  pad0  |        numbers; owned by CALLER
3075//  t   -----------+--------+----> Matcher::_in_arg_limit, unaligned
3076//  h     ^        |   in   |  5
3077//        |        |  args  |  4   Holes in incoming args owned by SELF
3078//  |     |        |        |  3
3079//  |     |        +--------+
3080//  V     |        | old out|      Empty on Intel, window on Sparc
3081//        |    old |preserve|      Must be even aligned.
3082//        |     SP-+--------+----> Matcher::_old_SP, even aligned
3083//        |        |   in   |  3   area for Intel ret address
3084//     Owned by    |preserve|      Empty on Sparc.
3085//       SELF      +--------+
3086//        |        |  pad2  |  2   pad to align old SP
3087//        |        +--------+  1
3088//        |        | locks  |  0
3089//        |        +--------+----> OptoReg::stack0(), even aligned
3090//        |        |  pad1  | 11   pad to align new SP
3091//        |        +--------+
3092//        |        |        | 10
3093//        |        | spills |  9   spills
3094//        V        |        |  8   (pad0 slot for callee)
3095//      -----------+--------+----> Matcher::_out_arg_limit, unaligned
3096//        ^        |  out   |  7
3097//        |        |  args  |  6   Holes in outgoing args owned by CALLEE
3098//     Owned by    +--------+
3099//      CALLEE     | new out|  6   Empty on Intel, window on Sparc
3100//        |    new |preserve|      Must be even-aligned.
3101//        |     SP-+--------+----> Matcher::_new_SP, even aligned
3102//        |        |        |
3103//
3104// Note 1: Only region 8-11 is determined by the allocator.  Region 0-5 is
3105//         known from SELF's arguments and the Java calling convention.
3106//         Region 6-7 is determined per call site.
3107// Note 2: If the calling convention leaves holes in the incoming argument
3108//         area, those holes are owned by SELF.  Holes in the outgoing area
3109//         are owned by the CALLEE.  Holes should not be nessecary in the
3110//         incoming area, as the Java calling convention is completely under
3111//         the control of the AD file.  Doubles can be sorted and packed to
3112//         avoid holes.  Holes in the outgoing arguments may be nessecary for
3113//         varargs C calling conventions.
3114// Note 3: Region 0-3 is even aligned, with pad2 as needed.  Region 3-5 is
3115//         even aligned with pad0 as needed.
3116//         Region 6 is even aligned.  Region 6-7 is NOT even aligned;
3117//         region 6-11 is even aligned; it may be padded out more so that
3118//         the region from SP to FP meets the minimum stack alignment.
3119// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
3120//         alignment.  Region 11, pad1, may be dynamically extended so that
3121//         SP meets the minimum alignment.
3122
3123frame
3124%{
3125  // What direction does stack grow in (assumed to be same for C & Java)
3126  stack_direction(TOWARDS_LOW);
3127
3128  // These three registers define part of the calling convention
3129  // between compiled code and the interpreter.
3130  inline_cache_reg(RAX);                // Inline Cache Register
3131  interpreter_method_oop_reg(RBX);      // Method Oop Register when
3132                                        // calling interpreter
3133
3134  // Optional: name the operand used by cisc-spilling to access
3135  // [stack_pointer + offset]
3136  cisc_spilling_operand_name(indOffset32);
3137
3138  // Number of stack slots consumed by locking an object
3139  sync_stack_slots(2);
3140
3141  // Compiled code's Frame Pointer
3142  frame_pointer(RSP);
3143
3144  // Interpreter stores its frame pointer in a register which is
3145  // stored to the stack by I2CAdaptors.
3146  // I2CAdaptors convert from interpreted java to compiled java.
3147  interpreter_frame_pointer(RBP);
3148
3149  // Stack alignment requirement
3150  stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
3151
3152  // Number of stack slots between incoming argument block and the start of
3153  // a new frame.  The PROLOG must add this many slots to the stack.  The
3154  // EPILOG must remove this many slots.  amd64 needs two slots for
3155  // return address.
3156  in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls);
3157
3158  // Number of outgoing stack slots killed above the out_preserve_stack_slots
3159  // for calls to C.  Supports the var-args backing area for register parms.
3160  varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
3161
3162  // The after-PROLOG location of the return address.  Location of
3163  // return address specifies a type (REG or STACK) and a number
3164  // representing the register number (i.e. - use a register name) or
3165  // stack slot.
3166  // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
3167  // Otherwise, it is above the locks and verification slot and alignment word
3168  return_addr(STACK - 2 +
3169              round_to((Compile::current()->in_preserve_stack_slots() +
3170                        Compile::current()->fixed_slots()),
3171                       stack_alignment_in_slots()));
3172
3173  // Body of function which returns an integer array locating
3174  // arguments either in registers or in stack slots.  Passed an array
3175  // of ideal registers called "sig" and a "length" count.  Stack-slot
3176  // offsets are based on outgoing arguments, i.e. a CALLER setting up
3177  // arguments for a CALLEE.  Incoming stack arguments are
3178  // automatically biased by the preserve_stack_slots field above.
3179
3180  calling_convention
3181  %{
3182    // No difference between ingoing/outgoing just pass false
3183    SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
3184  %}
3185
3186  c_calling_convention
3187  %{
3188    // This is obviously always outgoing
3189    (void) SharedRuntime::c_calling_convention(sig_bt, regs, length);
3190  %}
3191
3192  // Location of compiled Java return values.  Same as C for now.
3193  return_value
3194  %{
3195    assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
3196           "only return normal values");
3197
3198    static const int lo[Op_RegL + 1] = {
3199      0,
3200      0,
3201      RAX_num,  // Op_RegN
3202      RAX_num,  // Op_RegI
3203      RAX_num,  // Op_RegP
3204      XMM0_num, // Op_RegF
3205      XMM0_num, // Op_RegD
3206      RAX_num   // Op_RegL
3207    };
3208    static const int hi[Op_RegL + 1] = {
3209      0,
3210      0,
3211      OptoReg::Bad, // Op_RegN
3212      OptoReg::Bad, // Op_RegI
3213      RAX_H_num,    // Op_RegP
3214      OptoReg::Bad, // Op_RegF
3215      XMM0_H_num,   // Op_RegD
3216      RAX_H_num     // Op_RegL
3217    };
3218    assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type");
3219    return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
3220  %}
3221%}
3222
3223//----------ATTRIBUTES---------------------------------------------------------
3224//----------Operand Attributes-------------------------------------------------
3225op_attrib op_cost(0);        // Required cost attribute
3226
3227//----------Instruction Attributes---------------------------------------------
3228ins_attrib ins_cost(100);       // Required cost attribute
3229ins_attrib ins_size(8);         // Required size attribute (in bits)
3230ins_attrib ins_short_branch(0); // Required flag: is this instruction
3231                                // a non-matching short branch variant
3232                                // of some long branch?
3233ins_attrib ins_alignment(1);    // Required alignment attribute (must
3234                                // be a power of 2) specifies the
3235                                // alignment that some part of the
3236                                // instruction (not necessarily the
3237                                // start) requires.  If > 1, a
3238                                // compute_padding() function must be
3239                                // provided for the instruction
3240
3241//----------OPERANDS-----------------------------------------------------------
3242// Operand definitions must precede instruction definitions for correct parsing
3243// in the ADLC because operands constitute user defined types which are used in
3244// instruction definitions.
3245
3246//----------Simple Operands----------------------------------------------------
3247// Immediate Operands
3248// Integer Immediate
3249operand immI()
3250%{
3251  match(ConI);
3252
3253  op_cost(10);
3254  format %{ %}
3255  interface(CONST_INTER);
3256%}
3257
3258// Constant for test vs zero
3259operand immI0()
3260%{
3261  predicate(n->get_int() == 0);
3262  match(ConI);
3263
3264  op_cost(0);
3265  format %{ %}
3266  interface(CONST_INTER);
3267%}
3268
3269// Constant for increment
3270operand immI1()
3271%{
3272  predicate(n->get_int() == 1);
3273  match(ConI);
3274
3275  op_cost(0);
3276  format %{ %}
3277  interface(CONST_INTER);
3278%}
3279
3280// Constant for decrement
3281operand immI_M1()
3282%{
3283  predicate(n->get_int() == -1);
3284  match(ConI);
3285
3286  op_cost(0);
3287  format %{ %}
3288  interface(CONST_INTER);
3289%}
3290
3291// Valid scale values for addressing modes
3292operand immI2()
3293%{
3294  predicate(0 <= n->get_int() && (n->get_int() <= 3));
3295  match(ConI);
3296
3297  format %{ %}
3298  interface(CONST_INTER);
3299%}
3300
3301operand immI8()
3302%{
3303  predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80));
3304  match(ConI);
3305
3306  op_cost(5);
3307  format %{ %}
3308  interface(CONST_INTER);
3309%}
3310
3311operand immI16()
3312%{
3313  predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
3314  match(ConI);
3315
3316  op_cost(10);
3317  format %{ %}
3318  interface(CONST_INTER);
3319%}
3320
3321// Constant for long shifts
3322operand immI_32()
3323%{
3324  predicate( n->get_int() == 32 );
3325  match(ConI);
3326
3327  op_cost(0);
3328  format %{ %}
3329  interface(CONST_INTER);
3330%}
3331
3332// Constant for long shifts
3333operand immI_64()
3334%{
3335  predicate( n->get_int() == 64 );
3336  match(ConI);
3337
3338  op_cost(0);
3339  format %{ %}
3340  interface(CONST_INTER);
3341%}
3342
3343// Pointer Immediate
3344operand immP()
3345%{
3346  match(ConP);
3347
3348  op_cost(10);
3349  format %{ %}
3350  interface(CONST_INTER);
3351%}
3352
3353// NULL Pointer Immediate
3354operand immP0()
3355%{
3356  predicate(n->get_ptr() == 0);
3357  match(ConP);
3358
3359  op_cost(5);
3360  format %{ %}
3361  interface(CONST_INTER);
3362%}
3363
3364operand immP_poll() %{
3365  predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
3366  match(ConP);
3367
3368  // formats are generated automatically for constants and base registers
3369  format %{ %}
3370  interface(CONST_INTER);
3371%}
3372
3373// Pointer Immediate
3374operand immN() %{
3375  match(ConN);
3376
3377  op_cost(10);
3378  format %{ %}
3379  interface(CONST_INTER);
3380%}
3381
3382// NULL Pointer Immediate
3383operand immN0() %{
3384  predicate(n->get_narrowcon() == 0);
3385  match(ConN);
3386
3387  op_cost(5);
3388  format %{ %}
3389  interface(CONST_INTER);
3390%}
3391
3392operand immP31()
3393%{
3394  predicate(!n->as_Type()->type()->isa_oopptr()
3395            && (n->get_ptr() >> 31) == 0);
3396  match(ConP);
3397
3398  op_cost(5);
3399  format %{ %}
3400  interface(CONST_INTER);
3401%}
3402
3403
3404// Long Immediate
3405operand immL()
3406%{
3407  match(ConL);
3408
3409  op_cost(20);
3410  format %{ %}
3411  interface(CONST_INTER);
3412%}
3413
3414// Long Immediate 8-bit
3415operand immL8()
3416%{
3417  predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3418  match(ConL);
3419
3420  op_cost(5);
3421  format %{ %}
3422  interface(CONST_INTER);
3423%}
3424
3425// Long Immediate 32-bit unsigned
3426operand immUL32()
3427%{
3428  predicate(n->get_long() == (unsigned int) (n->get_long()));
3429  match(ConL);
3430
3431  op_cost(10);
3432  format %{ %}
3433  interface(CONST_INTER);
3434%}
3435
3436// Long Immediate 32-bit signed
3437operand immL32()
3438%{
3439  predicate(n->get_long() == (int) (n->get_long()));
3440  match(ConL);
3441
3442  op_cost(15);
3443  format %{ %}
3444  interface(CONST_INTER);
3445%}
3446
3447// Long Immediate zero
3448operand immL0()
3449%{
3450  predicate(n->get_long() == 0L);
3451  match(ConL);
3452
3453  op_cost(10);
3454  format %{ %}
3455  interface(CONST_INTER);
3456%}
3457
3458// Constant for increment
3459operand immL1()
3460%{
3461  predicate(n->get_long() == 1);
3462  match(ConL);
3463
3464  format %{ %}
3465  interface(CONST_INTER);
3466%}
3467
3468// Constant for decrement
3469operand immL_M1()
3470%{
3471  predicate(n->get_long() == -1);
3472  match(ConL);
3473
3474  format %{ %}
3475  interface(CONST_INTER);
3476%}
3477
3478// Long Immediate: the value 10
3479operand immL10()
3480%{
3481  predicate(n->get_long() == 10);
3482  match(ConL);
3483
3484  format %{ %}
3485  interface(CONST_INTER);
3486%}
3487
3488// Long immediate from 0 to 127.
3489// Used for a shorter form of long mul by 10.
3490operand immL_127()
3491%{
3492  predicate(0 <= n->get_long() && n->get_long() < 0x80);
3493  match(ConL);
3494
3495  op_cost(10);
3496  format %{ %}
3497  interface(CONST_INTER);
3498%}
3499
3500// Long Immediate: low 32-bit mask
3501operand immL_32bits()
3502%{
3503  predicate(n->get_long() == 0xFFFFFFFFL);
3504  match(ConL);
3505  op_cost(20);
3506
3507  format %{ %}
3508  interface(CONST_INTER);
3509%}
3510
3511// Float Immediate zero
3512operand immF0()
3513%{
3514  predicate(jint_cast(n->getf()) == 0);
3515  match(ConF);
3516
3517  op_cost(5);
3518  format %{ %}
3519  interface(CONST_INTER);
3520%}
3521
3522// Float Immediate
3523operand immF()
3524%{
3525  match(ConF);
3526
3527  op_cost(15);
3528  format %{ %}
3529  interface(CONST_INTER);
3530%}
3531
3532// Double Immediate zero
3533operand immD0()
3534%{
3535  predicate(jlong_cast(n->getd()) == 0);
3536  match(ConD);
3537
3538  op_cost(5);
3539  format %{ %}
3540  interface(CONST_INTER);
3541%}
3542
3543// Double Immediate
3544operand immD()
3545%{
3546  match(ConD);
3547
3548  op_cost(15);
3549  format %{ %}
3550  interface(CONST_INTER);
3551%}
3552
3553// Immediates for special shifts (sign extend)
3554
3555// Constants for increment
3556operand immI_16()
3557%{
3558  predicate(n->get_int() == 16);
3559  match(ConI);
3560
3561  format %{ %}
3562  interface(CONST_INTER);
3563%}
3564
3565operand immI_24()
3566%{
3567  predicate(n->get_int() == 24);
3568  match(ConI);
3569
3570  format %{ %}
3571  interface(CONST_INTER);
3572%}
3573
3574// Constant for byte-wide masking
3575operand immI_255()
3576%{
3577  predicate(n->get_int() == 255);
3578  match(ConI);
3579
3580  format %{ %}
3581  interface(CONST_INTER);
3582%}
3583
3584// Constant for short-wide masking
3585operand immI_65535()
3586%{
3587  predicate(n->get_int() == 65535);
3588  match(ConI);
3589
3590  format %{ %}
3591  interface(CONST_INTER);
3592%}
3593
3594// Constant for byte-wide masking
3595operand immL_255()
3596%{
3597  predicate(n->get_long() == 255);
3598  match(ConL);
3599
3600  format %{ %}
3601  interface(CONST_INTER);
3602%}
3603
3604// Constant for short-wide masking
3605operand immL_65535()
3606%{
3607  predicate(n->get_long() == 65535);
3608  match(ConL);
3609
3610  format %{ %}
3611  interface(CONST_INTER);
3612%}
3613
3614// Register Operands
3615// Integer Register
3616operand rRegI()
3617%{
3618  constraint(ALLOC_IN_RC(int_reg));
3619  match(RegI);
3620
3621  match(rax_RegI);
3622  match(rbx_RegI);
3623  match(rcx_RegI);
3624  match(rdx_RegI);
3625  match(rdi_RegI);
3626
3627  format %{ %}
3628  interface(REG_INTER);
3629%}
3630
3631// Special Registers
3632operand rax_RegI()
3633%{
3634  constraint(ALLOC_IN_RC(int_rax_reg));
3635  match(RegI);
3636  match(rRegI);
3637
3638  format %{ "RAX" %}
3639  interface(REG_INTER);
3640%}
3641
3642// Special Registers
3643operand rbx_RegI()
3644%{
3645  constraint(ALLOC_IN_RC(int_rbx_reg));
3646  match(RegI);
3647  match(rRegI);
3648
3649  format %{ "RBX" %}
3650  interface(REG_INTER);
3651%}
3652
3653operand rcx_RegI()
3654%{
3655  constraint(ALLOC_IN_RC(int_rcx_reg));
3656  match(RegI);
3657  match(rRegI);
3658
3659  format %{ "RCX" %}
3660  interface(REG_INTER);
3661%}
3662
3663operand rdx_RegI()
3664%{
3665  constraint(ALLOC_IN_RC(int_rdx_reg));
3666  match(RegI);
3667  match(rRegI);
3668
3669  format %{ "RDX" %}
3670  interface(REG_INTER);
3671%}
3672
3673operand rdi_RegI()
3674%{
3675  constraint(ALLOC_IN_RC(int_rdi_reg));
3676  match(RegI);
3677  match(rRegI);
3678
3679  format %{ "RDI" %}
3680  interface(REG_INTER);
3681%}
3682
3683operand no_rcx_RegI()
3684%{
3685  constraint(ALLOC_IN_RC(int_no_rcx_reg));
3686  match(RegI);
3687  match(rax_RegI);
3688  match(rbx_RegI);
3689  match(rdx_RegI);
3690  match(rdi_RegI);
3691
3692  format %{ %}
3693  interface(REG_INTER);
3694%}
3695
3696operand no_rax_rdx_RegI()
3697%{
3698  constraint(ALLOC_IN_RC(int_no_rax_rdx_reg));
3699  match(RegI);
3700  match(rbx_RegI);
3701  match(rcx_RegI);
3702  match(rdi_RegI);
3703
3704  format %{ %}
3705  interface(REG_INTER);
3706%}
3707
3708// Pointer Register
3709operand any_RegP()
3710%{
3711  constraint(ALLOC_IN_RC(any_reg));
3712  match(RegP);
3713  match(rax_RegP);
3714  match(rbx_RegP);
3715  match(rdi_RegP);
3716  match(rsi_RegP);
3717  match(rbp_RegP);
3718  match(r15_RegP);
3719  match(rRegP);
3720
3721  format %{ %}
3722  interface(REG_INTER);
3723%}
3724
3725operand rRegP()
3726%{
3727  constraint(ALLOC_IN_RC(ptr_reg));
3728  match(RegP);
3729  match(rax_RegP);
3730  match(rbx_RegP);
3731  match(rdi_RegP);
3732  match(rsi_RegP);
3733  match(rbp_RegP);
3734  match(r15_RegP);  // See Q&A below about r15_RegP.
3735
3736  format %{ %}
3737  interface(REG_INTER);
3738%}
3739
3740operand rRegN() %{
3741  constraint(ALLOC_IN_RC(int_reg));
3742  match(RegN);
3743
3744  format %{ %}
3745  interface(REG_INTER);
3746%}
3747
3748// Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
3749// Answer: Operand match rules govern the DFA as it processes instruction inputs.
3750// It's fine for an instruction input which expects rRegP to match a r15_RegP.
3751// The output of an instruction is controlled by the allocator, which respects
3752// register class masks, not match rules.  Unless an instruction mentions
3753// r15_RegP or any_RegP explicitly as its output, r15 will not be considered
3754// by the allocator as an input.
3755
3756operand no_rax_RegP()
3757%{
3758  constraint(ALLOC_IN_RC(ptr_no_rax_reg));
3759  match(RegP);
3760  match(rbx_RegP);
3761  match(rsi_RegP);
3762  match(rdi_RegP);
3763
3764  format %{ %}
3765  interface(REG_INTER);
3766%}
3767
3768operand no_rbp_RegP()
3769%{
3770  constraint(ALLOC_IN_RC(ptr_no_rbp_reg));
3771  match(RegP);
3772  match(rbx_RegP);
3773  match(rsi_RegP);
3774  match(rdi_RegP);
3775
3776  format %{ %}
3777  interface(REG_INTER);
3778%}
3779
3780operand no_rax_rbx_RegP()
3781%{
3782  constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg));
3783  match(RegP);
3784  match(rsi_RegP);
3785  match(rdi_RegP);
3786
3787  format %{ %}
3788  interface(REG_INTER);
3789%}
3790
3791// Special Registers
3792// Return a pointer value
3793operand rax_RegP()
3794%{
3795  constraint(ALLOC_IN_RC(ptr_rax_reg));
3796  match(RegP);
3797  match(rRegP);
3798
3799  format %{ %}
3800  interface(REG_INTER);
3801%}
3802
3803// Special Registers
3804// Return a compressed pointer value
3805operand rax_RegN()
3806%{
3807  constraint(ALLOC_IN_RC(int_rax_reg));
3808  match(RegN);
3809  match(rRegN);
3810
3811  format %{ %}
3812  interface(REG_INTER);
3813%}
3814
3815// Used in AtomicAdd
3816operand rbx_RegP()
3817%{
3818  constraint(ALLOC_IN_RC(ptr_rbx_reg));
3819  match(RegP);
3820  match(rRegP);
3821
3822  format %{ %}
3823  interface(REG_INTER);
3824%}
3825
3826operand rsi_RegP()
3827%{
3828  constraint(ALLOC_IN_RC(ptr_rsi_reg));
3829  match(RegP);
3830  match(rRegP);
3831
3832  format %{ %}
3833  interface(REG_INTER);
3834%}
3835
3836// Used in rep stosq
3837operand rdi_RegP()
3838%{
3839  constraint(ALLOC_IN_RC(ptr_rdi_reg));
3840  match(RegP);
3841  match(rRegP);
3842
3843  format %{ %}
3844  interface(REG_INTER);
3845%}
3846
3847operand rbp_RegP()
3848%{
3849  constraint(ALLOC_IN_RC(ptr_rbp_reg));
3850  match(RegP);
3851  match(rRegP);
3852
3853  format %{ %}
3854  interface(REG_INTER);
3855%}
3856
3857operand r15_RegP()
3858%{
3859  constraint(ALLOC_IN_RC(ptr_r15_reg));
3860  match(RegP);
3861  match(rRegP);
3862
3863  format %{ %}
3864  interface(REG_INTER);
3865%}
3866
3867operand rRegL()
3868%{
3869  constraint(ALLOC_IN_RC(long_reg));
3870  match(RegL);
3871  match(rax_RegL);
3872  match(rdx_RegL);
3873
3874  format %{ %}
3875  interface(REG_INTER);
3876%}
3877
3878// Special Registers
3879operand no_rax_rdx_RegL()
3880%{
3881  constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3882  match(RegL);
3883  match(rRegL);
3884
3885  format %{ %}
3886  interface(REG_INTER);
3887%}
3888
3889operand no_rax_RegL()
3890%{
3891  constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3892  match(RegL);
3893  match(rRegL);
3894  match(rdx_RegL);
3895
3896  format %{ %}
3897  interface(REG_INTER);
3898%}
3899
3900operand no_rcx_RegL()
3901%{
3902  constraint(ALLOC_IN_RC(long_no_rcx_reg));
3903  match(RegL);
3904  match(rRegL);
3905
3906  format %{ %}
3907  interface(REG_INTER);
3908%}
3909
3910operand rax_RegL()
3911%{
3912  constraint(ALLOC_IN_RC(long_rax_reg));
3913  match(RegL);
3914  match(rRegL);
3915
3916  format %{ "RAX" %}
3917  interface(REG_INTER);
3918%}
3919
3920operand rcx_RegL()
3921%{
3922  constraint(ALLOC_IN_RC(long_rcx_reg));
3923  match(RegL);
3924  match(rRegL);
3925
3926  format %{ %}
3927  interface(REG_INTER);
3928%}
3929
3930operand rdx_RegL()
3931%{
3932  constraint(ALLOC_IN_RC(long_rdx_reg));
3933  match(RegL);
3934  match(rRegL);
3935
3936  format %{ %}
3937  interface(REG_INTER);
3938%}
3939
3940// Flags register, used as output of compare instructions
3941operand rFlagsReg()
3942%{
3943  constraint(ALLOC_IN_RC(int_flags));
3944  match(RegFlags);
3945
3946  format %{ "RFLAGS" %}
3947  interface(REG_INTER);
3948%}
3949
3950// Flags register, used as output of FLOATING POINT compare instructions
3951operand rFlagsRegU()
3952%{
3953  constraint(ALLOC_IN_RC(int_flags));
3954  match(RegFlags);
3955
3956  format %{ "RFLAGS_U" %}
3957  interface(REG_INTER);
3958%}
3959
3960operand rFlagsRegUCF() %{
3961  constraint(ALLOC_IN_RC(int_flags));
3962  match(RegFlags);
3963  predicate(false);
3964
3965  format %{ "RFLAGS_U_CF" %}
3966  interface(REG_INTER);
3967%}
3968
3969// Float register operands
3970operand regF()
3971%{
3972  constraint(ALLOC_IN_RC(float_reg));
3973  match(RegF);
3974
3975  format %{ %}
3976  interface(REG_INTER);
3977%}
3978
3979// Double register operands
3980operand regD()
3981%{
3982  constraint(ALLOC_IN_RC(double_reg));
3983  match(RegD);
3984
3985  format %{ %}
3986  interface(REG_INTER);
3987%}
3988
3989
3990//----------Memory Operands----------------------------------------------------
3991// Direct Memory Operand
3992// operand direct(immP addr)
3993// %{
3994//   match(addr);
3995
3996//   format %{ "[$addr]" %}
3997//   interface(MEMORY_INTER) %{
3998//     base(0xFFFFFFFF);
3999//     index(0x4);
4000//     scale(0x0);
4001//     disp($addr);
4002//   %}
4003// %}
4004
4005// Indirect Memory Operand
4006operand indirect(any_RegP reg)
4007%{
4008  constraint(ALLOC_IN_RC(ptr_reg));
4009  match(reg);
4010
4011  format %{ "[$reg]" %}
4012  interface(MEMORY_INTER) %{
4013    base($reg);
4014    index(0x4);
4015    scale(0x0);
4016    disp(0x0);
4017  %}
4018%}
4019
4020// Indirect Memory Plus Short Offset Operand
4021operand indOffset8(any_RegP reg, immL8 off)
4022%{
4023  constraint(ALLOC_IN_RC(ptr_reg));
4024  match(AddP reg off);
4025
4026  format %{ "[$reg + $off (8-bit)]" %}
4027  interface(MEMORY_INTER) %{
4028    base($reg);
4029    index(0x4);
4030    scale(0x0);
4031    disp($off);
4032  %}
4033%}
4034
4035// Indirect Memory Plus Long Offset Operand
4036operand indOffset32(any_RegP reg, immL32 off)
4037%{
4038  constraint(ALLOC_IN_RC(ptr_reg));
4039  match(AddP reg off);
4040
4041  format %{ "[$reg + $off (32-bit)]" %}
4042  interface(MEMORY_INTER) %{
4043    base($reg);
4044    index(0x4);
4045    scale(0x0);
4046    disp($off);
4047  %}
4048%}
4049
4050// Indirect Memory Plus Index Register Plus Offset Operand
4051operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off)
4052%{
4053  constraint(ALLOC_IN_RC(ptr_reg));
4054  match(AddP (AddP reg lreg) off);
4055
4056  op_cost(10);
4057  format %{"[$reg + $off + $lreg]" %}
4058  interface(MEMORY_INTER) %{
4059    base($reg);
4060    index($lreg);
4061    scale(0x0);
4062    disp($off);
4063  %}
4064%}
4065
4066// Indirect Memory Plus Index Register Plus Offset Operand
4067operand indIndex(any_RegP reg, rRegL lreg)
4068%{
4069  constraint(ALLOC_IN_RC(ptr_reg));
4070  match(AddP reg lreg);
4071
4072  op_cost(10);
4073  format %{"[$reg + $lreg]" %}
4074  interface(MEMORY_INTER) %{
4075    base($reg);
4076    index($lreg);
4077    scale(0x0);
4078    disp(0x0);
4079  %}
4080%}
4081
4082// Indirect Memory Times Scale Plus Index Register
4083operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale)
4084%{
4085  constraint(ALLOC_IN_RC(ptr_reg));
4086  match(AddP reg (LShiftL lreg scale));
4087
4088  op_cost(10);
4089  format %{"[$reg + $lreg << $scale]" %}
4090  interface(MEMORY_INTER) %{
4091    base($reg);
4092    index($lreg);
4093    scale($scale);
4094    disp(0x0);
4095  %}
4096%}
4097
4098// Indirect Memory Times Scale Plus Index Register Plus Offset Operand
4099operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
4100%{
4101  constraint(ALLOC_IN_RC(ptr_reg));
4102  match(AddP (AddP reg (LShiftL lreg scale)) off);
4103
4104  op_cost(10);
4105  format %{"[$reg + $off + $lreg << $scale]" %}
4106  interface(MEMORY_INTER) %{
4107    base($reg);
4108    index($lreg);
4109    scale($scale);
4110    disp($off);
4111  %}
4112%}
4113
4114// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
4115operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale)
4116%{
4117  constraint(ALLOC_IN_RC(ptr_reg));
4118  predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4119  match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off);
4120
4121  op_cost(10);
4122  format %{"[$reg + $off + $idx << $scale]" %}
4123  interface(MEMORY_INTER) %{
4124    base($reg);
4125    index($idx);
4126    scale($scale);
4127    disp($off);
4128  %}
4129%}
4130
4131// Indirect Narrow Oop Plus Offset Operand
4132// Note: x86 architecture doesn't support "scale * index + offset" without a base
4133// we can't free r12 even with Universe::narrow_oop_base() == NULL.
4134operand indCompressedOopOffset(rRegN reg, immL32 off) %{
4135  predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8));
4136  constraint(ALLOC_IN_RC(ptr_reg));
4137  match(AddP (DecodeN reg) off);
4138
4139  op_cost(10);
4140  format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
4141  interface(MEMORY_INTER) %{
4142    base(0xc); // R12
4143    index($reg);
4144    scale(0x3);
4145    disp($off);
4146  %}
4147%}
4148
4149// Indirect Memory Operand
4150operand indirectNarrow(rRegN reg)
4151%{
4152  predicate(Universe::narrow_oop_shift() == 0);
4153  constraint(ALLOC_IN_RC(ptr_reg));
4154  match(DecodeN reg);
4155
4156  format %{ "[$reg]" %}
4157  interface(MEMORY_INTER) %{
4158    base($reg);
4159    index(0x4);
4160    scale(0x0);
4161    disp(0x0);
4162  %}
4163%}
4164
4165// Indirect Memory Plus Short Offset Operand
4166operand indOffset8Narrow(rRegN reg, immL8 off)
4167%{
4168  predicate(Universe::narrow_oop_shift() == 0);
4169  constraint(ALLOC_IN_RC(ptr_reg));
4170  match(AddP (DecodeN reg) off);
4171
4172  format %{ "[$reg + $off (8-bit)]" %}
4173  interface(MEMORY_INTER) %{
4174    base($reg);
4175    index(0x4);
4176    scale(0x0);
4177    disp($off);
4178  %}
4179%}
4180
4181// Indirect Memory Plus Long Offset Operand
4182operand indOffset32Narrow(rRegN reg, immL32 off)
4183%{
4184  predicate(Universe::narrow_oop_shift() == 0);
4185  constraint(ALLOC_IN_RC(ptr_reg));
4186  match(AddP (DecodeN reg) off);
4187
4188  format %{ "[$reg + $off (32-bit)]" %}
4189  interface(MEMORY_INTER) %{
4190    base($reg);
4191    index(0x4);
4192    scale(0x0);
4193    disp($off);
4194  %}
4195%}
4196
4197// Indirect Memory Plus Index Register Plus Offset Operand
4198operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off)
4199%{
4200  predicate(Universe::narrow_oop_shift() == 0);
4201  constraint(ALLOC_IN_RC(ptr_reg));
4202  match(AddP (AddP (DecodeN reg) lreg) off);
4203
4204  op_cost(10);
4205  format %{"[$reg + $off + $lreg]" %}
4206  interface(MEMORY_INTER) %{
4207    base($reg);
4208    index($lreg);
4209    scale(0x0);
4210    disp($off);
4211  %}
4212%}
4213
4214// Indirect Memory Plus Index Register Plus Offset Operand
4215operand indIndexNarrow(rRegN reg, rRegL lreg)
4216%{
4217  predicate(Universe::narrow_oop_shift() == 0);
4218  constraint(ALLOC_IN_RC(ptr_reg));
4219  match(AddP (DecodeN reg) lreg);
4220
4221  op_cost(10);
4222  format %{"[$reg + $lreg]" %}
4223  interface(MEMORY_INTER) %{
4224    base($reg);
4225    index($lreg);
4226    scale(0x0);
4227    disp(0x0);
4228  %}
4229%}
4230
4231// Indirect Memory Times Scale Plus Index Register
4232operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale)
4233%{
4234  predicate(Universe::narrow_oop_shift() == 0);
4235  constraint(ALLOC_IN_RC(ptr_reg));
4236  match(AddP (DecodeN reg) (LShiftL lreg scale));
4237
4238  op_cost(10);
4239  format %{"[$reg + $lreg << $scale]" %}
4240  interface(MEMORY_INTER) %{
4241    base($reg);
4242    index($lreg);
4243    scale($scale);
4244    disp(0x0);
4245  %}
4246%}
4247
4248// Indirect Memory Times Scale Plus Index Register Plus Offset Operand
4249operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
4250%{
4251  predicate(Universe::narrow_oop_shift() == 0);
4252  constraint(ALLOC_IN_RC(ptr_reg));
4253  match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
4254
4255  op_cost(10);
4256  format %{"[$reg + $off + $lreg << $scale]" %}
4257  interface(MEMORY_INTER) %{
4258    base($reg);
4259    index($lreg);
4260    scale($scale);
4261    disp($off);
4262  %}
4263%}
4264
4265// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
4266operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4267%{
4268  constraint(ALLOC_IN_RC(ptr_reg));
4269  predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4270  match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
4271
4272  op_cost(10);
4273  format %{"[$reg + $off + $idx << $scale]" %}
4274  interface(MEMORY_INTER) %{
4275    base($reg);
4276    index($idx);
4277    scale($scale);
4278    disp($off);
4279  %}
4280%}
4281
4282
4283//----------Special Memory Operands--------------------------------------------
4284// Stack Slot Operand - This operand is used for loading and storing temporary
4285//                      values on the stack where a match requires a value to
4286//                      flow through memory.
4287operand stackSlotP(sRegP reg)
4288%{
4289  constraint(ALLOC_IN_RC(stack_slots));
4290  // No match rule because this operand is only generated in matching
4291
4292  format %{ "[$reg]" %}
4293  interface(MEMORY_INTER) %{
4294    base(0x4);   // RSP
4295    index(0x4);  // No Index
4296    scale(0x0);  // No Scale
4297    disp($reg);  // Stack Offset
4298  %}
4299%}
4300
4301operand stackSlotI(sRegI reg)
4302%{
4303  constraint(ALLOC_IN_RC(stack_slots));
4304  // No match rule because this operand is only generated in matching
4305
4306  format %{ "[$reg]" %}
4307  interface(MEMORY_INTER) %{
4308    base(0x4);   // RSP
4309    index(0x4);  // No Index
4310    scale(0x0);  // No Scale
4311    disp($reg);  // Stack Offset
4312  %}
4313%}
4314
4315operand stackSlotF(sRegF reg)
4316%{
4317  constraint(ALLOC_IN_RC(stack_slots));
4318  // No match rule because this operand is only generated in matching
4319
4320  format %{ "[$reg]" %}
4321  interface(MEMORY_INTER) %{
4322    base(0x4);   // RSP
4323    index(0x4);  // No Index
4324    scale(0x0);  // No Scale
4325    disp($reg);  // Stack Offset
4326  %}
4327%}
4328
4329operand stackSlotD(sRegD reg)
4330%{
4331  constraint(ALLOC_IN_RC(stack_slots));
4332  // No match rule because this operand is only generated in matching
4333
4334  format %{ "[$reg]" %}
4335  interface(MEMORY_INTER) %{
4336    base(0x4);   // RSP
4337    index(0x4);  // No Index
4338    scale(0x0);  // No Scale
4339    disp($reg);  // Stack Offset
4340  %}
4341%}
4342operand stackSlotL(sRegL reg)
4343%{
4344  constraint(ALLOC_IN_RC(stack_slots));
4345  // No match rule because this operand is only generated in matching
4346
4347  format %{ "[$reg]" %}
4348  interface(MEMORY_INTER) %{
4349    base(0x4);   // RSP
4350    index(0x4);  // No Index
4351    scale(0x0);  // No Scale
4352    disp($reg);  // Stack Offset
4353  %}
4354%}
4355
4356//----------Conditional Branch Operands----------------------------------------
4357// Comparison Op  - This is the operation of the comparison, and is limited to
4358//                  the following set of codes:
4359//                  L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
4360//
4361// Other attributes of the comparison, such as unsignedness, are specified
4362// by the comparison instruction that sets a condition code flags register.
4363// That result is represented by a flags operand whose subtype is appropriate
4364// to the unsignedness (etc.) of the comparison.
4365//
4366// Later, the instruction which matches both the Comparison Op (a Bool) and
4367// the flags (produced by the Cmp) specifies the coding of the comparison op
4368// by matching a specific subtype of Bool operand below, such as cmpOpU.
4369
4370// Comparision Code
4371operand cmpOp()
4372%{
4373  match(Bool);
4374
4375  format %{ "" %}
4376  interface(COND_INTER) %{
4377    equal(0x4, "e");
4378    not_equal(0x5, "ne");
4379    less(0xC, "l");
4380    greater_equal(0xD, "ge");
4381    less_equal(0xE, "le");
4382    greater(0xF, "g");
4383  %}
4384%}
4385
4386// Comparison Code, unsigned compare.  Used by FP also, with
4387// C2 (unordered) turned into GT or LT already.  The other bits
4388// C0 and C3 are turned into Carry & Zero flags.
4389operand cmpOpU()
4390%{
4391  match(Bool);
4392
4393  format %{ "" %}
4394  interface(COND_INTER) %{
4395    equal(0x4, "e");
4396    not_equal(0x5, "ne");
4397    less(0x2, "b");
4398    greater_equal(0x3, "nb");
4399    less_equal(0x6, "be");
4400    greater(0x7, "nbe");
4401  %}
4402%}
4403
4404
4405// Floating comparisons that don't require any fixup for the unordered case
4406operand cmpOpUCF() %{
4407  match(Bool);
4408  predicate(n->as_Bool()->_test._test == BoolTest::lt ||
4409            n->as_Bool()->_test._test == BoolTest::ge ||
4410            n->as_Bool()->_test._test == BoolTest::le ||
4411            n->as_Bool()->_test._test == BoolTest::gt);
4412  format %{ "" %}
4413  interface(COND_INTER) %{
4414    equal(0x4, "e");
4415    not_equal(0x5, "ne");
4416    less(0x2, "b");
4417    greater_equal(0x3, "nb");
4418    less_equal(0x6, "be");
4419    greater(0x7, "nbe");
4420  %}
4421%}
4422
4423
4424// Floating comparisons that can be fixed up with extra conditional jumps
4425operand cmpOpUCF2() %{
4426  match(Bool);
4427  predicate(n->as_Bool()->_test._test == BoolTest::ne ||
4428            n->as_Bool()->_test._test == BoolTest::eq);
4429  format %{ "" %}
4430  interface(COND_INTER) %{
4431    equal(0x4, "e");
4432    not_equal(0x5, "ne");
4433    less(0x2, "b");
4434    greater_equal(0x3, "nb");
4435    less_equal(0x6, "be");
4436    greater(0x7, "nbe");
4437  %}
4438%}
4439
4440
4441//----------OPERAND CLASSES----------------------------------------------------
4442// Operand Classes are groups of operands that are used as to simplify
4443// instruction definitions by not requiring the AD writer to specify separate
4444// instructions for every form of operand when the instruction accepts
4445// multiple operand types with the same basic encoding and format.  The classic
4446// case of this is memory operands.
4447
4448opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
4449               indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
4450               indCompressedOopOffset,
4451               indirectNarrow, indOffset8Narrow, indOffset32Narrow,
4452               indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
4453               indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow);
4454
4455//----------PIPELINE-----------------------------------------------------------
4456// Rules which define the behavior of the target architectures pipeline.
4457pipeline %{
4458
4459//----------ATTRIBUTES---------------------------------------------------------
4460attributes %{
4461  variable_size_instructions;        // Fixed size instructions
4462  max_instructions_per_bundle = 3;   // Up to 3 instructions per bundle
4463  instruction_unit_size = 1;         // An instruction is 1 bytes long
4464  instruction_fetch_unit_size = 16;  // The processor fetches one line
4465  instruction_fetch_units = 1;       // of 16 bytes
4466
4467  // List of nop instructions
4468  nops( MachNop );
4469%}
4470
4471//----------RESOURCES----------------------------------------------------------
4472// Resources are the functional units available to the machine
4473
4474// Generic P2/P3 pipeline
4475// 3 decoders, only D0 handles big operands; a "bundle" is the limit of
4476// 3 instructions decoded per cycle.
4477// 2 load/store ops per cycle, 1 branch, 1 FPU,
4478// 3 ALU op, only ALU0 handles mul instructions.
4479resources( D0, D1, D2, DECODE = D0 | D1 | D2,
4480           MS0, MS1, MS2, MEM = MS0 | MS1 | MS2,
4481           BR, FPU,
4482           ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2);
4483
4484//----------PIPELINE DESCRIPTION-----------------------------------------------
4485// Pipeline Description specifies the stages in the machine's pipeline
4486
4487// Generic P2/P3 pipeline
4488pipe_desc(S0, S1, S2, S3, S4, S5);
4489
4490//----------PIPELINE CLASSES---------------------------------------------------
4491// Pipeline Classes describe the stages in which input and output are
4492// referenced by the hardware pipeline.
4493
4494// Naming convention: ialu or fpu
4495// Then: _reg
4496// Then: _reg if there is a 2nd register
4497// Then: _long if it's a pair of instructions implementing a long
4498// Then: _fat if it requires the big decoder
4499//   Or: _mem if it requires the big decoder and a memory unit.
4500
4501// Integer ALU reg operation
4502pipe_class ialu_reg(rRegI dst)
4503%{
4504    single_instruction;
4505    dst    : S4(write);
4506    dst    : S3(read);
4507    DECODE : S0;        // any decoder
4508    ALU    : S3;        // any alu
4509%}
4510
4511// Long ALU reg operation
4512pipe_class ialu_reg_long(rRegL dst)
4513%{
4514    instruction_count(2);
4515    dst    : S4(write);
4516    dst    : S3(read);
4517    DECODE : S0(2);     // any 2 decoders
4518    ALU    : S3(2);     // both alus
4519%}
4520
4521// Integer ALU reg operation using big decoder
4522pipe_class ialu_reg_fat(rRegI dst)
4523%{
4524    single_instruction;
4525    dst    : S4(write);
4526    dst    : S3(read);
4527    D0     : S0;        // big decoder only
4528    ALU    : S3;        // any alu
4529%}
4530
4531// Long ALU reg operation using big decoder
4532pipe_class ialu_reg_long_fat(rRegL dst)
4533%{
4534    instruction_count(2);
4535    dst    : S4(write);
4536    dst    : S3(read);
4537    D0     : S0(2);     // big decoder only; twice
4538    ALU    : S3(2);     // any 2 alus
4539%}
4540
4541// Integer ALU reg-reg operation
4542pipe_class ialu_reg_reg(rRegI dst, rRegI src)
4543%{
4544    single_instruction;
4545    dst    : S4(write);
4546    src    : S3(read);
4547    DECODE : S0;        // any decoder
4548    ALU    : S3;        // any alu
4549%}
4550
4551// Long ALU reg-reg operation
4552pipe_class ialu_reg_reg_long(rRegL dst, rRegL src)
4553%{
4554    instruction_count(2);
4555    dst    : S4(write);
4556    src    : S3(read);
4557    DECODE : S0(2);     // any 2 decoders
4558    ALU    : S3(2);     // both alus
4559%}
4560
4561// Integer ALU reg-reg operation
4562pipe_class ialu_reg_reg_fat(rRegI dst, memory src)
4563%{
4564    single_instruction;
4565    dst    : S4(write);
4566    src    : S3(read);
4567    D0     : S0;        // big decoder only
4568    ALU    : S3;        // any alu
4569%}
4570
4571// Long ALU reg-reg operation
4572pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src)
4573%{
4574    instruction_count(2);
4575    dst    : S4(write);
4576    src    : S3(read);
4577    D0     : S0(2);     // big decoder only; twice
4578    ALU    : S3(2);     // both alus
4579%}
4580
4581// Integer ALU reg-mem operation
4582pipe_class ialu_reg_mem(rRegI dst, memory mem)
4583%{
4584    single_instruction;
4585    dst    : S5(write);
4586    mem    : S3(read);
4587    D0     : S0;        // big decoder only
4588    ALU    : S4;        // any alu
4589    MEM    : S3;        // any mem
4590%}
4591
4592// Integer mem operation (prefetch)
4593pipe_class ialu_mem(memory mem)
4594%{
4595    single_instruction;
4596    mem    : S3(read);
4597    D0     : S0;        // big decoder only
4598    MEM    : S3;        // any mem
4599%}
4600
4601// Integer Store to Memory
4602pipe_class ialu_mem_reg(memory mem, rRegI src)
4603%{
4604    single_instruction;
4605    mem    : S3(read);
4606    src    : S5(read);
4607    D0     : S0;        // big decoder only
4608    ALU    : S4;        // any alu
4609    MEM    : S3;
4610%}
4611
4612// // Long Store to Memory
4613// pipe_class ialu_mem_long_reg(memory mem, rRegL src)
4614// %{
4615//     instruction_count(2);
4616//     mem    : S3(read);
4617//     src    : S5(read);
4618//     D0     : S0(2);          // big decoder only; twice
4619//     ALU    : S4(2);     // any 2 alus
4620//     MEM    : S3(2);  // Both mems
4621// %}
4622
4623// Integer Store to Memory
4624pipe_class ialu_mem_imm(memory mem)
4625%{
4626    single_instruction;
4627    mem    : S3(read);
4628    D0     : S0;        // big decoder only
4629    ALU    : S4;        // any alu
4630    MEM    : S3;
4631%}
4632
4633// Integer ALU0 reg-reg operation
4634pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src)
4635%{
4636    single_instruction;
4637    dst    : S4(write);
4638    src    : S3(read);
4639    D0     : S0;        // Big decoder only
4640    ALU0   : S3;        // only alu0
4641%}
4642
4643// Integer ALU0 reg-mem operation
4644pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem)
4645%{
4646    single_instruction;
4647    dst    : S5(write);
4648    mem    : S3(read);
4649    D0     : S0;        // big decoder only
4650    ALU0   : S4;        // ALU0 only
4651    MEM    : S3;        // any mem
4652%}
4653
4654// Integer ALU reg-reg operation
4655pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2)
4656%{
4657    single_instruction;
4658    cr     : S4(write);
4659    src1   : S3(read);
4660    src2   : S3(read);
4661    DECODE : S0;        // any decoder
4662    ALU    : S3;        // any alu
4663%}
4664
4665// Integer ALU reg-imm operation
4666pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1)
4667%{
4668    single_instruction;
4669    cr     : S4(write);
4670    src1   : S3(read);
4671    DECODE : S0;        // any decoder
4672    ALU    : S3;        // any alu
4673%}
4674
4675// Integer ALU reg-mem operation
4676pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2)
4677%{
4678    single_instruction;
4679    cr     : S4(write);
4680    src1   : S3(read);
4681    src2   : S3(read);
4682    D0     : S0;        // big decoder only
4683    ALU    : S4;        // any alu
4684    MEM    : S3;
4685%}
4686
4687// Conditional move reg-reg
4688pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y)
4689%{
4690    instruction_count(4);
4691    y      : S4(read);
4692    q      : S3(read);
4693    p      : S3(read);
4694    DECODE : S0(4);     // any decoder
4695%}
4696
4697// Conditional move reg-reg
4698pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr)
4699%{
4700    single_instruction;
4701    dst    : S4(write);
4702    src    : S3(read);
4703    cr     : S3(read);
4704    DECODE : S0;        // any decoder
4705%}
4706
4707// Conditional move reg-mem
4708pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src)
4709%{
4710    single_instruction;
4711    dst    : S4(write);
4712    src    : S3(read);
4713    cr     : S3(read);
4714    DECODE : S0;        // any decoder
4715    MEM    : S3;
4716%}
4717
4718// Conditional move reg-reg long
4719pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src)
4720%{
4721    single_instruction;
4722    dst    : S4(write);
4723    src    : S3(read);
4724    cr     : S3(read);
4725    DECODE : S0(2);     // any 2 decoders
4726%}
4727
4728// XXX
4729// // Conditional move double reg-reg
4730// pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src)
4731// %{
4732//     single_instruction;
4733//     dst    : S4(write);
4734//     src    : S3(read);
4735//     cr     : S3(read);
4736//     DECODE : S0;     // any decoder
4737// %}
4738
4739// Float reg-reg operation
4740pipe_class fpu_reg(regD dst)
4741%{
4742    instruction_count(2);
4743    dst    : S3(read);
4744    DECODE : S0(2);     // any 2 decoders
4745    FPU    : S3;
4746%}
4747
4748// Float reg-reg operation
4749pipe_class fpu_reg_reg(regD dst, regD src)
4750%{
4751    instruction_count(2);
4752    dst    : S4(write);
4753    src    : S3(read);
4754    DECODE : S0(2);     // any 2 decoders
4755    FPU    : S3;
4756%}
4757
4758// Float reg-reg operation
4759pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2)
4760%{
4761    instruction_count(3);
4762    dst    : S4(write);
4763    src1   : S3(read);
4764    src2   : S3(read);
4765    DECODE : S0(3);     // any 3 decoders
4766    FPU    : S3(2);
4767%}
4768
4769// Float reg-reg operation
4770pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3)
4771%{
4772    instruction_count(4);
4773    dst    : S4(write);
4774    src1   : S3(read);
4775    src2   : S3(read);
4776    src3   : S3(read);
4777    DECODE : S0(4);     // any 3 decoders
4778    FPU    : S3(2);
4779%}
4780
4781// Float reg-reg operation
4782pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3)
4783%{
4784    instruction_count(4);
4785    dst    : S4(write);
4786    src1   : S3(read);
4787    src2   : S3(read);
4788    src3   : S3(read);
4789    DECODE : S1(3);     // any 3 decoders
4790    D0     : S0;        // Big decoder only
4791    FPU    : S3(2);
4792    MEM    : S3;
4793%}
4794
4795// Float reg-mem operation
4796pipe_class fpu_reg_mem(regD dst, memory mem)
4797%{
4798    instruction_count(2);
4799    dst    : S5(write);
4800    mem    : S3(read);
4801    D0     : S0;        // big decoder only
4802    DECODE : S1;        // any decoder for FPU POP
4803    FPU    : S4;
4804    MEM    : S3;        // any mem
4805%}
4806
4807// Float reg-mem operation
4808pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem)
4809%{
4810    instruction_count(3);
4811    dst    : S5(write);
4812    src1   : S3(read);
4813    mem    : S3(read);
4814    D0     : S0;        // big decoder only
4815    DECODE : S1(2);     // any decoder for FPU POP
4816    FPU    : S4;
4817    MEM    : S3;        // any mem
4818%}
4819
4820// Float mem-reg operation
4821pipe_class fpu_mem_reg(memory mem, regD src)
4822%{
4823    instruction_count(2);
4824    src    : S5(read);
4825    mem    : S3(read);
4826    DECODE : S0;        // any decoder for FPU PUSH
4827    D0     : S1;        // big decoder only
4828    FPU    : S4;
4829    MEM    : S3;        // any mem
4830%}
4831
4832pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2)
4833%{
4834    instruction_count(3);
4835    src1   : S3(read);
4836    src2   : S3(read);
4837    mem    : S3(read);
4838    DECODE : S0(2);     // any decoder for FPU PUSH
4839    D0     : S1;        // big decoder only
4840    FPU    : S4;
4841    MEM    : S3;        // any mem
4842%}
4843
4844pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2)
4845%{
4846    instruction_count(3);
4847    src1   : S3(read);
4848    src2   : S3(read);
4849    mem    : S4(read);
4850    DECODE : S0;        // any decoder for FPU PUSH
4851    D0     : S0(2);     // big decoder only
4852    FPU    : S4;
4853    MEM    : S3(2);     // any mem
4854%}
4855
4856pipe_class fpu_mem_mem(memory dst, memory src1)
4857%{
4858    instruction_count(2);
4859    src1   : S3(read);
4860    dst    : S4(read);
4861    D0     : S0(2);     // big decoder only
4862    MEM    : S3(2);     // any mem
4863%}
4864
4865pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2)
4866%{
4867    instruction_count(3);
4868    src1   : S3(read);
4869    src2   : S3(read);
4870    dst    : S4(read);
4871    D0     : S0(3);     // big decoder only
4872    FPU    : S4;
4873    MEM    : S3(3);     // any mem
4874%}
4875
4876pipe_class fpu_mem_reg_con(memory mem, regD src1)
4877%{
4878    instruction_count(3);
4879    src1   : S4(read);
4880    mem    : S4(read);
4881    DECODE : S0;        // any decoder for FPU PUSH
4882    D0     : S0(2);     // big decoder only
4883    FPU    : S4;
4884    MEM    : S3(2);     // any mem
4885%}
4886
4887// Float load constant
4888pipe_class fpu_reg_con(regD dst)
4889%{
4890    instruction_count(2);
4891    dst    : S5(write);
4892    D0     : S0;        // big decoder only for the load
4893    DECODE : S1;        // any decoder for FPU POP
4894    FPU    : S4;
4895    MEM    : S3;        // any mem
4896%}
4897
4898// Float load constant
4899pipe_class fpu_reg_reg_con(regD dst, regD src)
4900%{
4901    instruction_count(3);
4902    dst    : S5(write);
4903    src    : S3(read);
4904    D0     : S0;        // big decoder only for the load
4905    DECODE : S1(2);     // any decoder for FPU POP
4906    FPU    : S4;
4907    MEM    : S3;        // any mem
4908%}
4909
4910// UnConditional branch
4911pipe_class pipe_jmp(label labl)
4912%{
4913    single_instruction;
4914    BR   : S3;
4915%}
4916
4917// Conditional branch
4918pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl)
4919%{
4920    single_instruction;
4921    cr    : S1(read);
4922    BR    : S3;
4923%}
4924
4925// Allocation idiom
4926pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr)
4927%{
4928    instruction_count(1); force_serialization;
4929    fixed_latency(6);
4930    heap_ptr : S3(read);
4931    DECODE   : S0(3);
4932    D0       : S2;
4933    MEM      : S3;
4934    ALU      : S3(2);
4935    dst      : S5(write);
4936    BR       : S5;
4937%}
4938
4939// Generic big/slow expanded idiom
4940pipe_class pipe_slow()
4941%{
4942    instruction_count(10); multiple_bundles; force_serialization;
4943    fixed_latency(100);
4944    D0  : S0(2);
4945    MEM : S3(2);
4946%}
4947
4948// The real do-nothing guy
4949pipe_class empty()
4950%{
4951    instruction_count(0);
4952%}
4953
4954// Define the class for the Nop node
4955define
4956%{
4957   MachNop = empty;
4958%}
4959
4960%}
4961
4962//----------INSTRUCTIONS-------------------------------------------------------
4963//
4964// match      -- States which machine-independent subtree may be replaced
4965//               by this instruction.
4966// ins_cost   -- The estimated cost of this instruction is used by instruction
4967//               selection to identify a minimum cost tree of machine
4968//               instructions that matches a tree of machine-independent
4969//               instructions.
4970// format     -- A string providing the disassembly for this instruction.
4971//               The value of an instruction's operand may be inserted
4972//               by referring to it with a '$' prefix.
4973// opcode     -- Three instruction opcodes may be provided.  These are referred
4974//               to within an encode class as $primary, $secondary, and $tertiary
4975//               rrspectively.  The primary opcode is commonly used to
4976//               indicate the type of machine instruction, while secondary
4977//               and tertiary are often used for prefix options or addressing
4978//               modes.
4979// ins_encode -- A list of encode classes with parameters. The encode class
4980//               name must have been defined in an 'enc_class' specification
4981//               in the encode section of the architecture description.
4982
4983
4984//----------Load/Store/Move Instructions---------------------------------------
4985//----------Load Instructions--------------------------------------------------
4986
4987// Load Byte (8 bit signed)
4988instruct loadB(rRegI dst, memory mem)
4989%{
4990  match(Set dst (LoadB mem));
4991
4992  ins_cost(125);
4993  format %{ "movsbl  $dst, $mem\t# byte" %}
4994
4995  ins_encode %{
4996    __ movsbl($dst$$Register, $mem$$Address);
4997  %}
4998
4999  ins_pipe(ialu_reg_mem);
5000%}
5001
5002// Load Byte (8 bit signed) into Long Register
5003instruct loadB2L(rRegL dst, memory mem)
5004%{
5005  match(Set dst (ConvI2L (LoadB mem)));
5006
5007  ins_cost(125);
5008  format %{ "movsbq  $dst, $mem\t# byte -> long" %}
5009
5010  ins_encode %{
5011    __ movsbq($dst$$Register, $mem$$Address);
5012  %}
5013
5014  ins_pipe(ialu_reg_mem);
5015%}
5016
5017// Load Unsigned Byte (8 bit UNsigned)
5018instruct loadUB(rRegI dst, memory mem)
5019%{
5020  match(Set dst (LoadUB mem));
5021
5022  ins_cost(125);
5023  format %{ "movzbl  $dst, $mem\t# ubyte" %}
5024
5025  ins_encode %{
5026    __ movzbl($dst$$Register, $mem$$Address);
5027  %}
5028
5029  ins_pipe(ialu_reg_mem);
5030%}
5031
5032// Load Unsigned Byte (8 bit UNsigned) into Long Register
5033instruct loadUB2L(rRegL dst, memory mem)
5034%{
5035  match(Set dst (ConvI2L (LoadUB mem)));
5036
5037  ins_cost(125);
5038  format %{ "movzbq  $dst, $mem\t# ubyte -> long" %}
5039
5040  ins_encode %{
5041    __ movzbq($dst$$Register, $mem$$Address);
5042  %}
5043
5044  ins_pipe(ialu_reg_mem);
5045%}
5046
5047// Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register
5048instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{
5049  match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
5050  effect(KILL cr);
5051
5052  format %{ "movzbq  $dst, $mem\t# ubyte & 8-bit mask -> long\n\t"
5053            "andl    $dst, $mask" %}
5054  ins_encode %{
5055    Register Rdst = $dst$$Register;
5056    __ movzbq(Rdst, $mem$$Address);
5057    __ andl(Rdst, $mask$$constant);
5058  %}
5059  ins_pipe(ialu_reg_mem);
5060%}
5061
5062// Load Short (16 bit signed)
5063instruct loadS(rRegI dst, memory mem)
5064%{
5065  match(Set dst (LoadS mem));
5066
5067  ins_cost(125);
5068  format %{ "movswl $dst, $mem\t# short" %}
5069
5070  ins_encode %{
5071    __ movswl($dst$$Register, $mem$$Address);
5072  %}
5073
5074  ins_pipe(ialu_reg_mem);
5075%}
5076
5077// Load Short (16 bit signed) to Byte (8 bit signed)
5078instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
5079  match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
5080
5081  ins_cost(125);
5082  format %{ "movsbl $dst, $mem\t# short -> byte" %}
5083  ins_encode %{
5084    __ movsbl($dst$$Register, $mem$$Address);
5085  %}
5086  ins_pipe(ialu_reg_mem);
5087%}
5088
5089// Load Short (16 bit signed) into Long Register
5090instruct loadS2L(rRegL dst, memory mem)
5091%{
5092  match(Set dst (ConvI2L (LoadS mem)));
5093
5094  ins_cost(125);
5095  format %{ "movswq $dst, $mem\t# short -> long" %}
5096
5097  ins_encode %{
5098    __ movswq($dst$$Register, $mem$$Address);
5099  %}
5100
5101  ins_pipe(ialu_reg_mem);
5102%}
5103
5104// Load Unsigned Short/Char (16 bit UNsigned)
5105instruct loadUS(rRegI dst, memory mem)
5106%{
5107  match(Set dst (LoadUS mem));
5108
5109  ins_cost(125);
5110  format %{ "movzwl  $dst, $mem\t# ushort/char" %}
5111
5112  ins_encode %{
5113    __ movzwl($dst$$Register, $mem$$Address);
5114  %}
5115
5116  ins_pipe(ialu_reg_mem);
5117%}
5118
5119// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
5120instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
5121  match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
5122
5123  ins_cost(125);
5124  format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
5125  ins_encode %{
5126    __ movsbl($dst$$Register, $mem$$Address);
5127  %}
5128  ins_pipe(ialu_reg_mem);
5129%}
5130
5131// Load Unsigned Short/Char (16 bit UNsigned) into Long Register
5132instruct loadUS2L(rRegL dst, memory mem)
5133%{
5134  match(Set dst (ConvI2L (LoadUS mem)));
5135
5136  ins_cost(125);
5137  format %{ "movzwq  $dst, $mem\t# ushort/char -> long" %}
5138
5139  ins_encode %{
5140    __ movzwq($dst$$Register, $mem$$Address);
5141  %}
5142
5143  ins_pipe(ialu_reg_mem);
5144%}
5145
5146// Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register
5147instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
5148  match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
5149
5150  format %{ "movzbq  $dst, $mem\t# ushort/char & 0xFF -> long" %}
5151  ins_encode %{
5152    __ movzbq($dst$$Register, $mem$$Address);
5153  %}
5154  ins_pipe(ialu_reg_mem);
5155%}
5156
5157// Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register
5158instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{
5159  match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
5160  effect(KILL cr);
5161
5162  format %{ "movzwq  $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t"
5163            "andl    $dst, $mask" %}
5164  ins_encode %{
5165    Register Rdst = $dst$$Register;
5166    __ movzwq(Rdst, $mem$$Address);
5167    __ andl(Rdst, $mask$$constant);
5168  %}
5169  ins_pipe(ialu_reg_mem);
5170%}
5171
5172// Load Integer
5173instruct loadI(rRegI dst, memory mem)
5174%{
5175  match(Set dst (LoadI mem));
5176
5177  ins_cost(125);
5178  format %{ "movl    $dst, $mem\t# int" %}
5179
5180  ins_encode %{
5181    __ movl($dst$$Register, $mem$$Address);
5182  %}
5183
5184  ins_pipe(ialu_reg_mem);
5185%}
5186
5187// Load Integer (32 bit signed) to Byte (8 bit signed)
5188instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
5189  match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
5190
5191  ins_cost(125);
5192  format %{ "movsbl  $dst, $mem\t# int -> byte" %}
5193  ins_encode %{
5194    __ movsbl($dst$$Register, $mem$$Address);
5195  %}
5196  ins_pipe(ialu_reg_mem);
5197%}
5198
5199// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
5200instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
5201  match(Set dst (AndI (LoadI mem) mask));
5202
5203  ins_cost(125);
5204  format %{ "movzbl  $dst, $mem\t# int -> ubyte" %}
5205  ins_encode %{
5206    __ movzbl($dst$$Register, $mem$$Address);
5207  %}
5208  ins_pipe(ialu_reg_mem);
5209%}
5210
5211// Load Integer (32 bit signed) to Short (16 bit signed)
5212instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
5213  match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
5214
5215  ins_cost(125);
5216  format %{ "movswl  $dst, $mem\t# int -> short" %}
5217  ins_encode %{
5218    __ movswl($dst$$Register, $mem$$Address);
5219  %}
5220  ins_pipe(ialu_reg_mem);
5221%}
5222
5223// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
5224instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
5225  match(Set dst (AndI (LoadI mem) mask));
5226
5227  ins_cost(125);
5228  format %{ "movzwl  $dst, $mem\t# int -> ushort/char" %}
5229  ins_encode %{
5230    __ movzwl($dst$$Register, $mem$$Address);
5231  %}
5232  ins_pipe(ialu_reg_mem);
5233%}
5234
5235// Load Integer into Long Register
5236instruct loadI2L(rRegL dst, memory mem)
5237%{
5238  match(Set dst (ConvI2L (LoadI mem)));
5239
5240  ins_cost(125);
5241  format %{ "movslq  $dst, $mem\t# int -> long" %}
5242
5243  ins_encode %{
5244    __ movslq($dst$$Register, $mem$$Address);
5245  %}
5246
5247  ins_pipe(ialu_reg_mem);
5248%}
5249
5250// Load Integer with mask 0xFF into Long Register
5251instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
5252  match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5253
5254  format %{ "movzbq  $dst, $mem\t# int & 0xFF -> long" %}
5255  ins_encode %{
5256    __ movzbq($dst$$Register, $mem$$Address);
5257  %}
5258  ins_pipe(ialu_reg_mem);
5259%}
5260
5261// Load Integer with mask 0xFFFF into Long Register
5262instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{
5263  match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5264
5265  format %{ "movzwq  $dst, $mem\t# int & 0xFFFF -> long" %}
5266  ins_encode %{
5267    __ movzwq($dst$$Register, $mem$$Address);
5268  %}
5269  ins_pipe(ialu_reg_mem);
5270%}
5271
5272// Load Integer with a 32-bit mask into Long Register
5273instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
5274  match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5275  effect(KILL cr);
5276
5277  format %{ "movl    $dst, $mem\t# int & 32-bit mask -> long\n\t"
5278            "andl    $dst, $mask" %}
5279  ins_encode %{
5280    Register Rdst = $dst$$Register;
5281    __ movl(Rdst, $mem$$Address);
5282    __ andl(Rdst, $mask$$constant);
5283  %}
5284  ins_pipe(ialu_reg_mem);
5285%}
5286
5287// Load Unsigned Integer into Long Register
5288instruct loadUI2L(rRegL dst, memory mem)
5289%{
5290  match(Set dst (LoadUI2L mem));
5291
5292  ins_cost(125);
5293  format %{ "movl    $dst, $mem\t# uint -> long" %}
5294
5295  ins_encode %{
5296    __ movl($dst$$Register, $mem$$Address);
5297  %}
5298
5299  ins_pipe(ialu_reg_mem);
5300%}
5301
5302// Load Long
5303instruct loadL(rRegL dst, memory mem)
5304%{
5305  match(Set dst (LoadL mem));
5306
5307  ins_cost(125);
5308  format %{ "movq    $dst, $mem\t# long" %}
5309
5310  ins_encode %{
5311    __ movq($dst$$Register, $mem$$Address);
5312  %}
5313
5314  ins_pipe(ialu_reg_mem); // XXX
5315%}
5316
5317// Load Range
5318instruct loadRange(rRegI dst, memory mem)
5319%{
5320  match(Set dst (LoadRange mem));
5321
5322  ins_cost(125); // XXX
5323  format %{ "movl    $dst, $mem\t# range" %}
5324  opcode(0x8B);
5325  ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem));
5326  ins_pipe(ialu_reg_mem);
5327%}
5328
5329// Load Pointer
5330instruct loadP(rRegP dst, memory mem)
5331%{
5332  match(Set dst (LoadP mem));
5333
5334  ins_cost(125); // XXX
5335  format %{ "movq    $dst, $mem\t# ptr" %}
5336  opcode(0x8B);
5337  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5338  ins_pipe(ialu_reg_mem); // XXX
5339%}
5340
5341// Load Compressed Pointer
5342instruct loadN(rRegN dst, memory mem)
5343%{
5344   match(Set dst (LoadN mem));
5345
5346   ins_cost(125); // XXX
5347   format %{ "movl    $dst, $mem\t# compressed ptr" %}
5348   ins_encode %{
5349     __ movl($dst$$Register, $mem$$Address);
5350   %}
5351   ins_pipe(ialu_reg_mem); // XXX
5352%}
5353
5354
5355// Load Klass Pointer
5356instruct loadKlass(rRegP dst, memory mem)
5357%{
5358  match(Set dst (LoadKlass mem));
5359
5360  ins_cost(125); // XXX
5361  format %{ "movq    $dst, $mem\t# class" %}
5362  opcode(0x8B);
5363  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5364  ins_pipe(ialu_reg_mem); // XXX
5365%}
5366
5367// Load narrow Klass Pointer
5368instruct loadNKlass(rRegN dst, memory mem)
5369%{
5370  match(Set dst (LoadNKlass mem));
5371
5372  ins_cost(125); // XXX
5373  format %{ "movl    $dst, $mem\t# compressed klass ptr" %}
5374  ins_encode %{
5375    __ movl($dst$$Register, $mem$$Address);
5376  %}
5377  ins_pipe(ialu_reg_mem); // XXX
5378%}
5379
5380// Load Float
5381instruct loadF(regF dst, memory mem)
5382%{
5383  match(Set dst (LoadF mem));
5384
5385  ins_cost(145); // XXX
5386  format %{ "movss   $dst, $mem\t# float" %}
5387  ins_encode %{
5388    __ movflt($dst$$XMMRegister, $mem$$Address);
5389  %}
5390  ins_pipe(pipe_slow); // XXX
5391%}
5392
5393// Load Double
5394instruct loadD_partial(regD dst, memory mem)
5395%{
5396  predicate(!UseXmmLoadAndClearUpper);
5397  match(Set dst (LoadD mem));
5398
5399  ins_cost(145); // XXX
5400  format %{ "movlpd  $dst, $mem\t# double" %}
5401  ins_encode %{
5402    __ movdbl($dst$$XMMRegister, $mem$$Address);
5403  %}
5404  ins_pipe(pipe_slow); // XXX
5405%}
5406
5407instruct loadD(regD dst, memory mem)
5408%{
5409  predicate(UseXmmLoadAndClearUpper);
5410  match(Set dst (LoadD mem));
5411
5412  ins_cost(145); // XXX
5413  format %{ "movsd   $dst, $mem\t# double" %}
5414  ins_encode %{
5415    __ movdbl($dst$$XMMRegister, $mem$$Address);
5416  %}
5417  ins_pipe(pipe_slow); // XXX
5418%}
5419
5420// Load Aligned Packed Byte to XMM register
5421instruct loadA8B(regD dst, memory mem) %{
5422  match(Set dst (Load8B mem));
5423  ins_cost(125);
5424  format %{ "MOVQ  $dst,$mem\t! packed8B" %}
5425  ins_encode %{
5426    __ movq($dst$$XMMRegister, $mem$$Address);
5427  %}
5428  ins_pipe( pipe_slow );
5429%}
5430
5431// Load Aligned Packed Short to XMM register
5432instruct loadA4S(regD dst, memory mem) %{
5433  match(Set dst (Load4S mem));
5434  ins_cost(125);
5435  format %{ "MOVQ  $dst,$mem\t! packed4S" %}
5436  ins_encode %{
5437    __ movq($dst$$XMMRegister, $mem$$Address);
5438  %}
5439  ins_pipe( pipe_slow );
5440%}
5441
5442// Load Aligned Packed Char to XMM register
5443instruct loadA4C(regD dst, memory mem) %{
5444  match(Set dst (Load4C mem));
5445  ins_cost(125);
5446  format %{ "MOVQ  $dst,$mem\t! packed4C" %}
5447  ins_encode %{
5448    __ movq($dst$$XMMRegister, $mem$$Address);
5449  %}
5450  ins_pipe( pipe_slow );
5451%}
5452
5453// Load Aligned Packed Integer to XMM register
5454instruct load2IU(regD dst, memory mem) %{
5455  match(Set dst (Load2I mem));
5456  ins_cost(125);
5457  format %{ "MOVQ  $dst,$mem\t! packed2I" %}
5458  ins_encode %{
5459    __ movq($dst$$XMMRegister, $mem$$Address);
5460  %}
5461  ins_pipe( pipe_slow );
5462%}
5463
5464// Load Aligned Packed Single to XMM
5465instruct loadA2F(regD dst, memory mem) %{
5466  match(Set dst (Load2F mem));
5467  ins_cost(125);
5468  format %{ "MOVQ  $dst,$mem\t! packed2F" %}
5469  ins_encode %{
5470    __ movq($dst$$XMMRegister, $mem$$Address);
5471  %}
5472  ins_pipe( pipe_slow );
5473%}
5474
5475// Load Effective Address
5476instruct leaP8(rRegP dst, indOffset8 mem)
5477%{
5478  match(Set dst mem);
5479
5480  ins_cost(110); // XXX
5481  format %{ "leaq    $dst, $mem\t# ptr 8" %}
5482  opcode(0x8D);
5483  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5484  ins_pipe(ialu_reg_reg_fat);
5485%}
5486
5487instruct leaP32(rRegP dst, indOffset32 mem)
5488%{
5489  match(Set dst mem);
5490
5491  ins_cost(110);
5492  format %{ "leaq    $dst, $mem\t# ptr 32" %}
5493  opcode(0x8D);
5494  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5495  ins_pipe(ialu_reg_reg_fat);
5496%}
5497
5498// instruct leaPIdx(rRegP dst, indIndex mem)
5499// %{
5500//   match(Set dst mem);
5501
5502//   ins_cost(110);
5503//   format %{ "leaq    $dst, $mem\t# ptr idx" %}
5504//   opcode(0x8D);
5505//   ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5506//   ins_pipe(ialu_reg_reg_fat);
5507// %}
5508
5509instruct leaPIdxOff(rRegP dst, indIndexOffset mem)
5510%{
5511  match(Set dst mem);
5512
5513  ins_cost(110);
5514  format %{ "leaq    $dst, $mem\t# ptr idxoff" %}
5515  opcode(0x8D);
5516  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5517  ins_pipe(ialu_reg_reg_fat);
5518%}
5519
5520instruct leaPIdxScale(rRegP dst, indIndexScale mem)
5521%{
5522  match(Set dst mem);
5523
5524  ins_cost(110);
5525  format %{ "leaq    $dst, $mem\t# ptr idxscale" %}
5526  opcode(0x8D);
5527  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5528  ins_pipe(ialu_reg_reg_fat);
5529%}
5530
5531instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem)
5532%{
5533  match(Set dst mem);
5534
5535  ins_cost(110);
5536  format %{ "leaq    $dst, $mem\t# ptr idxscaleoff" %}
5537  opcode(0x8D);
5538  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5539  ins_pipe(ialu_reg_reg_fat);
5540%}
5541
5542instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem)
5543%{
5544  match(Set dst mem);
5545
5546  ins_cost(110);
5547  format %{ "leaq    $dst, $mem\t# ptr posidxscaleoff" %}
5548  opcode(0x8D);
5549  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5550  ins_pipe(ialu_reg_reg_fat);
5551%}
5552
5553// Load Effective Address which uses Narrow (32-bits) oop
5554instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem)
5555%{
5556  predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0));
5557  match(Set dst mem);
5558
5559  ins_cost(110);
5560  format %{ "leaq    $dst, $mem\t# ptr compressedoopoff32" %}
5561  opcode(0x8D);
5562  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5563  ins_pipe(ialu_reg_reg_fat);
5564%}
5565
5566instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem)
5567%{
5568  predicate(Universe::narrow_oop_shift() == 0);
5569  match(Set dst mem);
5570
5571  ins_cost(110); // XXX
5572  format %{ "leaq    $dst, $mem\t# ptr off8narrow" %}
5573  opcode(0x8D);
5574  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5575  ins_pipe(ialu_reg_reg_fat);
5576%}
5577
5578instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem)
5579%{
5580  predicate(Universe::narrow_oop_shift() == 0);
5581  match(Set dst mem);
5582
5583  ins_cost(110);
5584  format %{ "leaq    $dst, $mem\t# ptr off32narrow" %}
5585  opcode(0x8D);
5586  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5587  ins_pipe(ialu_reg_reg_fat);
5588%}
5589
5590instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem)
5591%{
5592  predicate(Universe::narrow_oop_shift() == 0);
5593  match(Set dst mem);
5594
5595  ins_cost(110);
5596  format %{ "leaq    $dst, $mem\t# ptr idxoffnarrow" %}
5597  opcode(0x8D);
5598  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5599  ins_pipe(ialu_reg_reg_fat);
5600%}
5601
5602instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem)
5603%{
5604  predicate(Universe::narrow_oop_shift() == 0);
5605  match(Set dst mem);
5606
5607  ins_cost(110);
5608  format %{ "leaq    $dst, $mem\t# ptr idxscalenarrow" %}
5609  opcode(0x8D);
5610  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5611  ins_pipe(ialu_reg_reg_fat);
5612%}
5613
5614instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem)
5615%{
5616  predicate(Universe::narrow_oop_shift() == 0);
5617  match(Set dst mem);
5618
5619  ins_cost(110);
5620  format %{ "leaq    $dst, $mem\t# ptr idxscaleoffnarrow" %}
5621  opcode(0x8D);
5622  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5623  ins_pipe(ialu_reg_reg_fat);
5624%}
5625
5626instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem)
5627%{
5628  predicate(Universe::narrow_oop_shift() == 0);
5629  match(Set dst mem);
5630
5631  ins_cost(110);
5632  format %{ "leaq    $dst, $mem\t# ptr posidxscaleoffnarrow" %}
5633  opcode(0x8D);
5634  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5635  ins_pipe(ialu_reg_reg_fat);
5636%}
5637
5638instruct loadConI(rRegI dst, immI src)
5639%{
5640  match(Set dst src);
5641
5642  format %{ "movl    $dst, $src\t# int" %}
5643  ins_encode(load_immI(dst, src));
5644  ins_pipe(ialu_reg_fat); // XXX
5645%}
5646
5647instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr)
5648%{
5649  match(Set dst src);
5650  effect(KILL cr);
5651
5652  ins_cost(50);
5653  format %{ "xorl    $dst, $dst\t# int" %}
5654  opcode(0x33); /* + rd */
5655  ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5656  ins_pipe(ialu_reg);
5657%}
5658
5659instruct loadConL(rRegL dst, immL src)
5660%{
5661  match(Set dst src);
5662
5663  ins_cost(150);
5664  format %{ "movq    $dst, $src\t# long" %}
5665  ins_encode(load_immL(dst, src));
5666  ins_pipe(ialu_reg);
5667%}
5668
5669instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr)
5670%{
5671  match(Set dst src);
5672  effect(KILL cr);
5673
5674  ins_cost(50);
5675  format %{ "xorl    $dst, $dst\t# long" %}
5676  opcode(0x33); /* + rd */
5677  ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5678  ins_pipe(ialu_reg); // XXX
5679%}
5680
5681instruct loadConUL32(rRegL dst, immUL32 src)
5682%{
5683  match(Set dst src);
5684
5685  ins_cost(60);
5686  format %{ "movl    $dst, $src\t# long (unsigned 32-bit)" %}
5687  ins_encode(load_immUL32(dst, src));
5688  ins_pipe(ialu_reg);
5689%}
5690
5691instruct loadConL32(rRegL dst, immL32 src)
5692%{
5693  match(Set dst src);
5694
5695  ins_cost(70);
5696  format %{ "movq    $dst, $src\t# long (32-bit)" %}
5697  ins_encode(load_immL32(dst, src));
5698  ins_pipe(ialu_reg);
5699%}
5700
5701instruct loadConP(rRegP dst, immP con) %{
5702  match(Set dst con);
5703
5704  format %{ "movq    $dst, $con\t# ptr" %}
5705  ins_encode(load_immP(dst, con));
5706  ins_pipe(ialu_reg_fat); // XXX
5707%}
5708
5709instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
5710%{
5711  match(Set dst src);
5712  effect(KILL cr);
5713
5714  ins_cost(50);
5715  format %{ "xorl    $dst, $dst\t# ptr" %}
5716  opcode(0x33); /* + rd */
5717  ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5718  ins_pipe(ialu_reg);
5719%}
5720
5721instruct loadConP_poll(rRegP dst, immP_poll src) %{
5722  match(Set dst src);
5723  format %{ "movq    $dst, $src\t!ptr" %}
5724  ins_encode %{
5725    AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
5726    __ lea($dst$$Register, polling_page);
5727  %}
5728  ins_pipe(ialu_reg_fat);
5729%}
5730
5731instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
5732%{
5733  match(Set dst src);
5734  effect(KILL cr);
5735
5736  ins_cost(60);
5737  format %{ "movl    $dst, $src\t# ptr (positive 32-bit)" %}
5738  ins_encode(load_immP31(dst, src));
5739  ins_pipe(ialu_reg);
5740%}
5741
5742instruct loadConF(regF dst, immF con) %{
5743  match(Set dst con);
5744  ins_cost(125);
5745  format %{ "movss   $dst, [$constantaddress]\t# load from constant table: float=$con" %}
5746  ins_encode %{
5747    __ movflt($dst$$XMMRegister, $constantaddress($con));
5748  %}
5749  ins_pipe(pipe_slow);
5750%}
5751
5752instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
5753  match(Set dst src);
5754  effect(KILL cr);
5755  format %{ "xorq    $dst, $src\t# compressed NULL ptr" %}
5756  ins_encode %{
5757    __ xorq($dst$$Register, $dst$$Register);
5758  %}
5759  ins_pipe(ialu_reg);
5760%}
5761
5762instruct loadConN(rRegN dst, immN src) %{
5763  match(Set dst src);
5764
5765  ins_cost(125);
5766  format %{ "movl    $dst, $src\t# compressed ptr" %}
5767  ins_encode %{
5768    address con = (address)$src$$constant;
5769    if (con == NULL) {
5770      ShouldNotReachHere();
5771    } else {
5772      __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
5773    }
5774  %}
5775  ins_pipe(ialu_reg_fat); // XXX
5776%}
5777
5778instruct loadConF0(regF dst, immF0 src)
5779%{
5780  match(Set dst src);
5781  ins_cost(100);
5782
5783  format %{ "xorps   $dst, $dst\t# float 0.0" %}
5784  ins_encode %{
5785    __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
5786  %}
5787  ins_pipe(pipe_slow);
5788%}
5789
5790// Use the same format since predicate() can not be used here.
5791instruct loadConD(regD dst, immD con) %{
5792  match(Set dst con);
5793  ins_cost(125);
5794  format %{ "movsd   $dst, [$constantaddress]\t# load from constant table: double=$con" %}
5795  ins_encode %{
5796    __ movdbl($dst$$XMMRegister, $constantaddress($con));
5797  %}
5798  ins_pipe(pipe_slow);
5799%}
5800
5801instruct loadConD0(regD dst, immD0 src)
5802%{
5803  match(Set dst src);
5804  ins_cost(100);
5805
5806  format %{ "xorpd   $dst, $dst\t# double 0.0" %}
5807  ins_encode %{
5808    __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
5809  %}
5810  ins_pipe(pipe_slow);
5811%}
5812
5813instruct loadSSI(rRegI dst, stackSlotI src)
5814%{
5815  match(Set dst src);
5816
5817  ins_cost(125);
5818  format %{ "movl    $dst, $src\t# int stk" %}
5819  opcode(0x8B);
5820  ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
5821  ins_pipe(ialu_reg_mem);
5822%}
5823
5824instruct loadSSL(rRegL dst, stackSlotL src)
5825%{
5826  match(Set dst src);
5827
5828  ins_cost(125);
5829  format %{ "movq    $dst, $src\t# long stk" %}
5830  opcode(0x8B);
5831  ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5832  ins_pipe(ialu_reg_mem);
5833%}
5834
5835instruct loadSSP(rRegP dst, stackSlotP src)
5836%{
5837  match(Set dst src);
5838
5839  ins_cost(125);
5840  format %{ "movq    $dst, $src\t# ptr stk" %}
5841  opcode(0x8B);
5842  ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5843  ins_pipe(ialu_reg_mem);
5844%}
5845
5846instruct loadSSF(regF dst, stackSlotF src)
5847%{
5848  match(Set dst src);
5849
5850  ins_cost(125);
5851  format %{ "movss   $dst, $src\t# float stk" %}
5852  ins_encode %{
5853    __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
5854  %}
5855  ins_pipe(pipe_slow); // XXX
5856%}
5857
5858// Use the same format since predicate() can not be used here.
5859instruct loadSSD(regD dst, stackSlotD src)
5860%{
5861  match(Set dst src);
5862
5863  ins_cost(125);
5864  format %{ "movsd   $dst, $src\t# double stk" %}
5865  ins_encode  %{
5866    __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
5867  %}
5868  ins_pipe(pipe_slow); // XXX
5869%}
5870
5871// Prefetch instructions.
5872// Must be safe to execute with invalid address (cannot fault).
5873
5874instruct prefetchr( memory mem ) %{
5875  predicate(ReadPrefetchInstr==3);
5876  match(PrefetchRead mem);
5877  ins_cost(125);
5878
5879  format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %}
5880  ins_encode %{
5881    __ prefetchr($mem$$Address);
5882  %}
5883  ins_pipe(ialu_mem);
5884%}
5885
5886instruct prefetchrNTA( memory mem ) %{
5887  predicate(ReadPrefetchInstr==0);
5888  match(PrefetchRead mem);
5889  ins_cost(125);
5890
5891  format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %}
5892  ins_encode %{
5893    __ prefetchnta($mem$$Address);
5894  %}
5895  ins_pipe(ialu_mem);
5896%}
5897
5898instruct prefetchrT0( memory mem ) %{
5899  predicate(ReadPrefetchInstr==1);
5900  match(PrefetchRead mem);
5901  ins_cost(125);
5902
5903  format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %}
5904  ins_encode %{
5905    __ prefetcht0($mem$$Address);
5906  %}
5907  ins_pipe(ialu_mem);
5908%}
5909
5910instruct prefetchrT2( memory mem ) %{
5911  predicate(ReadPrefetchInstr==2);
5912  match(PrefetchRead mem);
5913  ins_cost(125);
5914
5915  format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %}
5916  ins_encode %{
5917    __ prefetcht2($mem$$Address);
5918  %}
5919  ins_pipe(ialu_mem);
5920%}
5921
5922instruct prefetchwNTA( memory mem ) %{
5923  match(PrefetchWrite mem);
5924  ins_cost(125);
5925
5926  format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %}
5927  ins_encode %{
5928    __ prefetchnta($mem$$Address);
5929  %}
5930  ins_pipe(ialu_mem);
5931%}
5932
5933// Prefetch instructions for allocation.
5934
5935instruct prefetchAlloc( memory mem ) %{
5936  predicate(AllocatePrefetchInstr==3);
5937  match(PrefetchAllocation mem);
5938  ins_cost(125);
5939
5940  format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %}
5941  ins_encode %{
5942    __ prefetchw($mem$$Address);
5943  %}
5944  ins_pipe(ialu_mem);
5945%}
5946
5947instruct prefetchAllocNTA( memory mem ) %{
5948  predicate(AllocatePrefetchInstr==0);
5949  match(PrefetchAllocation mem);
5950  ins_cost(125);
5951
5952  format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %}
5953  ins_encode %{
5954    __ prefetchnta($mem$$Address);
5955  %}
5956  ins_pipe(ialu_mem);
5957%}
5958
5959instruct prefetchAllocT0( memory mem ) %{
5960  predicate(AllocatePrefetchInstr==1);
5961  match(PrefetchAllocation mem);
5962  ins_cost(125);
5963
5964  format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %}
5965  ins_encode %{
5966    __ prefetcht0($mem$$Address);
5967  %}
5968  ins_pipe(ialu_mem);
5969%}
5970
5971instruct prefetchAllocT2( memory mem ) %{
5972  predicate(AllocatePrefetchInstr==2);
5973  match(PrefetchAllocation mem);
5974  ins_cost(125);
5975
5976  format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %}
5977  ins_encode %{
5978    __ prefetcht2($mem$$Address);
5979  %}
5980  ins_pipe(ialu_mem);
5981%}
5982
5983//----------Store Instructions-------------------------------------------------
5984
5985// Store Byte
5986instruct storeB(memory mem, rRegI src)
5987%{
5988  match(Set mem (StoreB mem src));
5989
5990  ins_cost(125); // XXX
5991  format %{ "movb    $mem, $src\t# byte" %}
5992  opcode(0x88);
5993  ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem));
5994  ins_pipe(ialu_mem_reg);
5995%}
5996
5997// Store Char/Short
5998instruct storeC(memory mem, rRegI src)
5999%{
6000  match(Set mem (StoreC mem src));
6001
6002  ins_cost(125); // XXX
6003  format %{ "movw    $mem, $src\t# char/short" %}
6004  opcode(0x89);
6005  ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
6006  ins_pipe(ialu_mem_reg);
6007%}
6008
6009// Store Integer
6010instruct storeI(memory mem, rRegI src)
6011%{
6012  match(Set mem (StoreI mem src));
6013
6014  ins_cost(125); // XXX
6015  format %{ "movl    $mem, $src\t# int" %}
6016  opcode(0x89);
6017  ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
6018  ins_pipe(ialu_mem_reg);
6019%}
6020
6021// Store Long
6022instruct storeL(memory mem, rRegL src)
6023%{
6024  match(Set mem (StoreL mem src));
6025
6026  ins_cost(125); // XXX
6027  format %{ "movq    $mem, $src\t# long" %}
6028  opcode(0x89);
6029  ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
6030  ins_pipe(ialu_mem_reg); // XXX
6031%}
6032
6033// Store Pointer
6034instruct storeP(memory mem, any_RegP src)
6035%{
6036  match(Set mem (StoreP mem src));
6037
6038  ins_cost(125); // XXX
6039  format %{ "movq    $mem, $src\t# ptr" %}
6040  opcode(0x89);
6041  ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
6042  ins_pipe(ialu_mem_reg);
6043%}
6044
6045instruct storeImmP0(memory mem, immP0 zero)
6046%{
6047  predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6048  match(Set mem (StoreP mem zero));
6049
6050  ins_cost(125); // XXX
6051  format %{ "movq    $mem, R12\t# ptr (R12_heapbase==0)" %}
6052  ins_encode %{
6053    __ movq($mem$$Address, r12);
6054  %}
6055  ins_pipe(ialu_mem_reg);
6056%}
6057
6058// Store NULL Pointer, mark word, or other simple pointer constant.
6059instruct storeImmP(memory mem, immP31 src)
6060%{
6061  match(Set mem (StoreP mem src));
6062
6063  ins_cost(150); // XXX
6064  format %{ "movq    $mem, $src\t# ptr" %}
6065  opcode(0xC7); /* C7 /0 */
6066  ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6067  ins_pipe(ialu_mem_imm);
6068%}
6069
6070// Store Compressed Pointer
6071instruct storeN(memory mem, rRegN src)
6072%{
6073  match(Set mem (StoreN mem src));
6074
6075  ins_cost(125); // XXX
6076  format %{ "movl    $mem, $src\t# compressed ptr" %}
6077  ins_encode %{
6078    __ movl($mem$$Address, $src$$Register);
6079  %}
6080  ins_pipe(ialu_mem_reg);
6081%}
6082
6083instruct storeImmN0(memory mem, immN0 zero)
6084%{
6085  predicate(Universe::narrow_oop_base() == NULL);
6086  match(Set mem (StoreN mem zero));
6087
6088  ins_cost(125); // XXX
6089  format %{ "movl    $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
6090  ins_encode %{
6091    __ movl($mem$$Address, r12);
6092  %}
6093  ins_pipe(ialu_mem_reg);
6094%}
6095
6096instruct storeImmN(memory mem, immN src)
6097%{
6098  match(Set mem (StoreN mem src));
6099
6100  ins_cost(150); // XXX
6101  format %{ "movl    $mem, $src\t# compressed ptr" %}
6102  ins_encode %{
6103    address con = (address)$src$$constant;
6104    if (con == NULL) {
6105      __ movl($mem$$Address, (int32_t)0);
6106    } else {
6107      __ set_narrow_oop($mem$$Address, (jobject)$src$$constant);
6108    }
6109  %}
6110  ins_pipe(ialu_mem_imm);
6111%}
6112
6113// Store Integer Immediate
6114instruct storeImmI0(memory mem, immI0 zero)
6115%{
6116  predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6117  match(Set mem (StoreI mem zero));
6118
6119  ins_cost(125); // XXX
6120  format %{ "movl    $mem, R12\t# int (R12_heapbase==0)" %}
6121  ins_encode %{
6122    __ movl($mem$$Address, r12);
6123  %}
6124  ins_pipe(ialu_mem_reg);
6125%}
6126
6127instruct storeImmI(memory mem, immI src)
6128%{
6129  match(Set mem (StoreI mem src));
6130
6131  ins_cost(150);
6132  format %{ "movl    $mem, $src\t# int" %}
6133  opcode(0xC7); /* C7 /0 */
6134  ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6135  ins_pipe(ialu_mem_imm);
6136%}
6137
6138// Store Long Immediate
6139instruct storeImmL0(memory mem, immL0 zero)
6140%{
6141  predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6142  match(Set mem (StoreL mem zero));
6143
6144  ins_cost(125); // XXX
6145  format %{ "movq    $mem, R12\t# long (R12_heapbase==0)" %}
6146  ins_encode %{
6147    __ movq($mem$$Address, r12);
6148  %}
6149  ins_pipe(ialu_mem_reg);
6150%}
6151
6152instruct storeImmL(memory mem, immL32 src)
6153%{
6154  match(Set mem (StoreL mem src));
6155
6156  ins_cost(150);
6157  format %{ "movq    $mem, $src\t# long" %}
6158  opcode(0xC7); /* C7 /0 */
6159  ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6160  ins_pipe(ialu_mem_imm);
6161%}
6162
6163// Store Short/Char Immediate
6164instruct storeImmC0(memory mem, immI0 zero)
6165%{
6166  predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6167  match(Set mem (StoreC mem zero));
6168
6169  ins_cost(125); // XXX
6170  format %{ "movw    $mem, R12\t# short/char (R12_heapbase==0)" %}
6171  ins_encode %{
6172    __ movw($mem$$Address, r12);
6173  %}
6174  ins_pipe(ialu_mem_reg);
6175%}
6176
6177instruct storeImmI16(memory mem, immI16 src)
6178%{
6179  predicate(UseStoreImmI16);
6180  match(Set mem (StoreC mem src));
6181
6182  ins_cost(150);
6183  format %{ "movw    $mem, $src\t# short/char" %}
6184  opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */
6185  ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src));
6186  ins_pipe(ialu_mem_imm);
6187%}
6188
6189// Store Byte Immediate
6190instruct storeImmB0(memory mem, immI0 zero)
6191%{
6192  predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6193  match(Set mem (StoreB mem zero));
6194
6195  ins_cost(125); // XXX
6196  format %{ "movb    $mem, R12\t# short/char (R12_heapbase==0)" %}
6197  ins_encode %{
6198    __ movb($mem$$Address, r12);
6199  %}
6200  ins_pipe(ialu_mem_reg);
6201%}
6202
6203instruct storeImmB(memory mem, immI8 src)
6204%{
6205  match(Set mem (StoreB mem src));
6206
6207  ins_cost(150); // XXX
6208  format %{ "movb    $mem, $src\t# byte" %}
6209  opcode(0xC6); /* C6 /0 */
6210  ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6211  ins_pipe(ialu_mem_imm);
6212%}
6213
6214// Store Aligned Packed Byte XMM register to memory
6215instruct storeA8B(memory mem, regD src) %{
6216  match(Set mem (Store8B mem src));
6217  ins_cost(145);
6218  format %{ "MOVQ  $mem,$src\t! packed8B" %}
6219  ins_encode %{
6220    __ movq($mem$$Address, $src$$XMMRegister);
6221  %}
6222  ins_pipe( pipe_slow );
6223%}
6224
6225// Store Aligned Packed Char/Short XMM register to memory
6226instruct storeA4C(memory mem, regD src) %{
6227  match(Set mem (Store4C mem src));
6228  ins_cost(145);
6229  format %{ "MOVQ  $mem,$src\t! packed4C" %}
6230  ins_encode %{
6231    __ movq($mem$$Address, $src$$XMMRegister);
6232  %}
6233  ins_pipe( pipe_slow );
6234%}
6235
6236// Store Aligned Packed Integer XMM register to memory
6237instruct storeA2I(memory mem, regD src) %{
6238  match(Set mem (Store2I mem src));
6239  ins_cost(145);
6240  format %{ "MOVQ  $mem,$src\t! packed2I" %}
6241  ins_encode %{
6242    __ movq($mem$$Address, $src$$XMMRegister);
6243  %}
6244  ins_pipe( pipe_slow );
6245%}
6246
6247// Store CMS card-mark Immediate
6248instruct storeImmCM0_reg(memory mem, immI0 zero)
6249%{
6250  predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6251  match(Set mem (StoreCM mem zero));
6252
6253  ins_cost(125); // XXX
6254  format %{ "movb    $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
6255  ins_encode %{
6256    __ movb($mem$$Address, r12);
6257  %}
6258  ins_pipe(ialu_mem_reg);
6259%}
6260
6261instruct storeImmCM0(memory mem, immI0 src)
6262%{
6263  match(Set mem (StoreCM mem src));
6264
6265  ins_cost(150); // XXX
6266  format %{ "movb    $mem, $src\t# CMS card-mark byte 0" %}
6267  opcode(0xC6); /* C6 /0 */
6268  ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6269  ins_pipe(ialu_mem_imm);
6270%}
6271
6272// Store Aligned Packed Single Float XMM register to memory
6273instruct storeA2F(memory mem, regD src) %{
6274  match(Set mem (Store2F mem src));
6275  ins_cost(145);
6276  format %{ "MOVQ  $mem,$src\t! packed2F" %}
6277  ins_encode %{
6278    __ movq($mem$$Address, $src$$XMMRegister);
6279  %}
6280  ins_pipe( pipe_slow );
6281%}
6282
6283// Store Float
6284instruct storeF(memory mem, regF src)
6285%{
6286  match(Set mem (StoreF mem src));
6287
6288  ins_cost(95); // XXX
6289  format %{ "movss   $mem, $src\t# float" %}
6290  ins_encode %{
6291    __ movflt($mem$$Address, $src$$XMMRegister);
6292  %}
6293  ins_pipe(pipe_slow); // XXX
6294%}
6295
6296// Store immediate Float value (it is faster than store from XMM register)
6297instruct storeF0(memory mem, immF0 zero)
6298%{
6299  predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6300  match(Set mem (StoreF mem zero));
6301
6302  ins_cost(25); // XXX
6303  format %{ "movl    $mem, R12\t# float 0. (R12_heapbase==0)" %}
6304  ins_encode %{
6305    __ movl($mem$$Address, r12);
6306  %}
6307  ins_pipe(ialu_mem_reg);
6308%}
6309
6310instruct storeF_imm(memory mem, immF src)
6311%{
6312  match(Set mem (StoreF mem src));
6313
6314  ins_cost(50);
6315  format %{ "movl    $mem, $src\t# float" %}
6316  opcode(0xC7); /* C7 /0 */
6317  ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6318  ins_pipe(ialu_mem_imm);
6319%}
6320
6321// Store Double
6322instruct storeD(memory mem, regD src)
6323%{
6324  match(Set mem (StoreD mem src));
6325
6326  ins_cost(95); // XXX
6327  format %{ "movsd   $mem, $src\t# double" %}
6328  ins_encode %{
6329    __ movdbl($mem$$Address, $src$$XMMRegister);
6330  %}
6331  ins_pipe(pipe_slow); // XXX
6332%}
6333
6334// Store immediate double 0.0 (it is faster than store from XMM register)
6335instruct storeD0_imm(memory mem, immD0 src)
6336%{
6337  predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
6338  match(Set mem (StoreD mem src));
6339
6340  ins_cost(50);
6341  format %{ "movq    $mem, $src\t# double 0." %}
6342  opcode(0xC7); /* C7 /0 */
6343  ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6344  ins_pipe(ialu_mem_imm);
6345%}
6346
6347instruct storeD0(memory mem, immD0 zero)
6348%{
6349  predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
6350  match(Set mem (StoreD mem zero));
6351
6352  ins_cost(25); // XXX
6353  format %{ "movq    $mem, R12\t# double 0. (R12_heapbase==0)" %}
6354  ins_encode %{
6355    __ movq($mem$$Address, r12);
6356  %}
6357  ins_pipe(ialu_mem_reg);
6358%}
6359
6360instruct storeSSI(stackSlotI dst, rRegI src)
6361%{
6362  match(Set dst src);
6363
6364  ins_cost(100);
6365  format %{ "movl    $dst, $src\t# int stk" %}
6366  opcode(0x89);
6367  ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
6368  ins_pipe( ialu_mem_reg );
6369%}
6370
6371instruct storeSSL(stackSlotL dst, rRegL src)
6372%{
6373  match(Set dst src);
6374
6375  ins_cost(100);
6376  format %{ "movq    $dst, $src\t# long stk" %}
6377  opcode(0x89);
6378  ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6379  ins_pipe(ialu_mem_reg);
6380%}
6381
6382instruct storeSSP(stackSlotP dst, rRegP src)
6383%{
6384  match(Set dst src);
6385
6386  ins_cost(100);
6387  format %{ "movq    $dst, $src\t# ptr stk" %}
6388  opcode(0x89);
6389  ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6390  ins_pipe(ialu_mem_reg);
6391%}
6392
6393instruct storeSSF(stackSlotF dst, regF src)
6394%{
6395  match(Set dst src);
6396
6397  ins_cost(95); // XXX
6398  format %{ "movss   $dst, $src\t# float stk" %}
6399  ins_encode %{
6400    __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
6401  %}
6402  ins_pipe(pipe_slow); // XXX
6403%}
6404
6405instruct storeSSD(stackSlotD dst, regD src)
6406%{
6407  match(Set dst src);
6408
6409  ins_cost(95); // XXX
6410  format %{ "movsd   $dst, $src\t# double stk" %}
6411  ins_encode %{
6412    __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
6413  %}
6414  ins_pipe(pipe_slow); // XXX
6415%}
6416
6417//----------BSWAP Instructions-------------------------------------------------
6418instruct bytes_reverse_int(rRegI dst) %{
6419  match(Set dst (ReverseBytesI dst));
6420
6421  format %{ "bswapl  $dst" %}
6422  opcode(0x0F, 0xC8);  /*Opcode 0F /C8 */
6423  ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) );
6424  ins_pipe( ialu_reg );
6425%}
6426
6427instruct bytes_reverse_long(rRegL dst) %{
6428  match(Set dst (ReverseBytesL dst));
6429
6430  format %{ "bswapq  $dst" %}
6431
6432  opcode(0x0F, 0xC8); /* Opcode 0F /C8 */
6433  ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) );
6434  ins_pipe( ialu_reg);
6435%}
6436
6437instruct bytes_reverse_unsigned_short(rRegI dst) %{
6438  match(Set dst (ReverseBytesUS dst));
6439
6440  format %{ "bswapl  $dst\n\t"
6441            "shrl    $dst,16\n\t" %}
6442  ins_encode %{
6443    __ bswapl($dst$$Register);
6444    __ shrl($dst$$Register, 16);
6445  %}
6446  ins_pipe( ialu_reg );
6447%}
6448
6449instruct bytes_reverse_short(rRegI dst) %{
6450  match(Set dst (ReverseBytesS dst));
6451
6452  format %{ "bswapl  $dst\n\t"
6453            "sar     $dst,16\n\t" %}
6454  ins_encode %{
6455    __ bswapl($dst$$Register);
6456    __ sarl($dst$$Register, 16);
6457  %}
6458  ins_pipe( ialu_reg );
6459%}
6460
6461//---------- Zeros Count Instructions ------------------------------------------
6462
6463instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6464  predicate(UseCountLeadingZerosInstruction);
6465  match(Set dst (CountLeadingZerosI src));
6466  effect(KILL cr);
6467
6468  format %{ "lzcntl  $dst, $src\t# count leading zeros (int)" %}
6469  ins_encode %{
6470    __ lzcntl($dst$$Register, $src$$Register);
6471  %}
6472  ins_pipe(ialu_reg);
6473%}
6474
6475instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{
6476  predicate(!UseCountLeadingZerosInstruction);
6477  match(Set dst (CountLeadingZerosI src));
6478  effect(KILL cr);
6479
6480  format %{ "bsrl    $dst, $src\t# count leading zeros (int)\n\t"
6481            "jnz     skip\n\t"
6482            "movl    $dst, -1\n"
6483      "skip:\n\t"
6484            "negl    $dst\n\t"
6485            "addl    $dst, 31" %}
6486  ins_encode %{
6487    Register Rdst = $dst$$Register;
6488    Register Rsrc = $src$$Register;
6489    Label skip;
6490    __ bsrl(Rdst, Rsrc);
6491    __ jccb(Assembler::notZero, skip);
6492    __ movl(Rdst, -1);
6493    __ bind(skip);
6494    __ negl(Rdst);
6495    __ addl(Rdst, BitsPerInt - 1);
6496  %}
6497  ins_pipe(ialu_reg);
6498%}
6499
6500instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6501  predicate(UseCountLeadingZerosInstruction);
6502  match(Set dst (CountLeadingZerosL src));
6503  effect(KILL cr);
6504
6505  format %{ "lzcntq  $dst, $src\t# count leading zeros (long)" %}
6506  ins_encode %{
6507    __ lzcntq($dst$$Register, $src$$Register);
6508  %}
6509  ins_pipe(ialu_reg);
6510%}
6511
6512instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{
6513  predicate(!UseCountLeadingZerosInstruction);
6514  match(Set dst (CountLeadingZerosL src));
6515  effect(KILL cr);
6516
6517  format %{ "bsrq    $dst, $src\t# count leading zeros (long)\n\t"
6518            "jnz     skip\n\t"
6519            "movl    $dst, -1\n"
6520      "skip:\n\t"
6521            "negl    $dst\n\t"
6522            "addl    $dst, 63" %}
6523  ins_encode %{
6524    Register Rdst = $dst$$Register;
6525    Register Rsrc = $src$$Register;
6526    Label skip;
6527    __ bsrq(Rdst, Rsrc);
6528    __ jccb(Assembler::notZero, skip);
6529    __ movl(Rdst, -1);
6530    __ bind(skip);
6531    __ negl(Rdst);
6532    __ addl(Rdst, BitsPerLong - 1);
6533  %}
6534  ins_pipe(ialu_reg);
6535%}
6536
6537instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6538  match(Set dst (CountTrailingZerosI src));
6539  effect(KILL cr);
6540
6541  format %{ "bsfl    $dst, $src\t# count trailing zeros (int)\n\t"
6542            "jnz     done\n\t"
6543            "movl    $dst, 32\n"
6544      "done:" %}
6545  ins_encode %{
6546    Register Rdst = $dst$$Register;
6547    Label done;
6548    __ bsfl(Rdst, $src$$Register);
6549    __ jccb(Assembler::notZero, done);
6550    __ movl(Rdst, BitsPerInt);
6551    __ bind(done);
6552  %}
6553  ins_pipe(ialu_reg);
6554%}
6555
6556instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6557  match(Set dst (CountTrailingZerosL src));
6558  effect(KILL cr);
6559
6560  format %{ "bsfq    $dst, $src\t# count trailing zeros (long)\n\t"
6561            "jnz     done\n\t"
6562            "movl    $dst, 64\n"
6563      "done:" %}
6564  ins_encode %{
6565    Register Rdst = $dst$$Register;
6566    Label done;
6567    __ bsfq(Rdst, $src$$Register);
6568    __ jccb(Assembler::notZero, done);
6569    __ movl(Rdst, BitsPerLong);
6570    __ bind(done);
6571  %}
6572  ins_pipe(ialu_reg);
6573%}
6574
6575
6576//---------- Population Count Instructions -------------------------------------
6577
6578instruct popCountI(rRegI dst, rRegI src) %{
6579  predicate(UsePopCountInstruction);
6580  match(Set dst (PopCountI src));
6581
6582  format %{ "popcnt  $dst, $src" %}
6583  ins_encode %{
6584    __ popcntl($dst$$Register, $src$$Register);
6585  %}
6586  ins_pipe(ialu_reg);
6587%}
6588
6589instruct popCountI_mem(rRegI dst, memory mem) %{
6590  predicate(UsePopCountInstruction);
6591  match(Set dst (PopCountI (LoadI mem)));
6592
6593  format %{ "popcnt  $dst, $mem" %}
6594  ins_encode %{
6595    __ popcntl($dst$$Register, $mem$$Address);
6596  %}
6597  ins_pipe(ialu_reg);
6598%}
6599
6600// Note: Long.bitCount(long) returns an int.
6601instruct popCountL(rRegI dst, rRegL src) %{
6602  predicate(UsePopCountInstruction);
6603  match(Set dst (PopCountL src));
6604
6605  format %{ "popcnt  $dst, $src" %}
6606  ins_encode %{
6607    __ popcntq($dst$$Register, $src$$Register);
6608  %}
6609  ins_pipe(ialu_reg);
6610%}
6611
6612// Note: Long.bitCount(long) returns an int.
6613instruct popCountL_mem(rRegI dst, memory mem) %{
6614  predicate(UsePopCountInstruction);
6615  match(Set dst (PopCountL (LoadL mem)));
6616
6617  format %{ "popcnt  $dst, $mem" %}
6618  ins_encode %{
6619    __ popcntq($dst$$Register, $mem$$Address);
6620  %}
6621  ins_pipe(ialu_reg);
6622%}
6623
6624
6625//----------MemBar Instructions-----------------------------------------------
6626// Memory barrier flavors
6627
6628instruct membar_acquire()
6629%{
6630  match(MemBarAcquire);
6631  ins_cost(0);
6632
6633  size(0);
6634  format %{ "MEMBAR-acquire ! (empty encoding)" %}
6635  ins_encode();
6636  ins_pipe(empty);
6637%}
6638
6639instruct membar_acquire_lock()
6640%{
6641  match(MemBarAcquireLock);
6642  ins_cost(0);
6643
6644  size(0);
6645  format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %}
6646  ins_encode();
6647  ins_pipe(empty);
6648%}
6649
6650instruct membar_release()
6651%{
6652  match(MemBarRelease);
6653  ins_cost(0);
6654
6655  size(0);
6656  format %{ "MEMBAR-release ! (empty encoding)" %}
6657  ins_encode();
6658  ins_pipe(empty);
6659%}
6660
6661instruct membar_release_lock()
6662%{
6663  match(MemBarReleaseLock);
6664  ins_cost(0);
6665
6666  size(0);
6667  format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
6668  ins_encode();
6669  ins_pipe(empty);
6670%}
6671
6672instruct membar_volatile(rFlagsReg cr) %{
6673  match(MemBarVolatile);
6674  effect(KILL cr);
6675  ins_cost(400);
6676
6677  format %{
6678    $$template
6679    if (os::is_MP()) {
6680      $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
6681    } else {
6682      $$emit$$"MEMBAR-volatile ! (empty encoding)"
6683    }
6684  %}
6685  ins_encode %{
6686    __ membar(Assembler::StoreLoad);
6687  %}
6688  ins_pipe(pipe_slow);
6689%}
6690
6691instruct unnecessary_membar_volatile()
6692%{
6693  match(MemBarVolatile);
6694  predicate(Matcher::post_store_load_barrier(n));
6695  ins_cost(0);
6696
6697  size(0);
6698  format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
6699  ins_encode();
6700  ins_pipe(empty);
6701%}
6702
6703instruct membar_storestore() %{
6704  match(MemBarStoreStore);
6705  ins_cost(0);
6706
6707  size(0);
6708  format %{ "MEMBAR-storestore (empty encoding)" %}
6709  ins_encode( );
6710  ins_pipe(empty);
6711%}
6712
6713//----------Move Instructions--------------------------------------------------
6714
6715instruct castX2P(rRegP dst, rRegL src)
6716%{
6717  match(Set dst (CastX2P src));
6718
6719  format %{ "movq    $dst, $src\t# long->ptr" %}
6720  ins_encode %{
6721    if ($dst$$reg != $src$$reg) {
6722      __ movptr($dst$$Register, $src$$Register);
6723    }
6724  %}
6725  ins_pipe(ialu_reg_reg); // XXX
6726%}
6727
6728instruct castP2X(rRegL dst, rRegP src)
6729%{
6730  match(Set dst (CastP2X src));
6731
6732  format %{ "movq    $dst, $src\t# ptr -> long" %}
6733  ins_encode %{
6734    if ($dst$$reg != $src$$reg) {
6735      __ movptr($dst$$Register, $src$$Register);
6736    }
6737  %}
6738  ins_pipe(ialu_reg_reg); // XXX
6739%}
6740
6741
6742// Convert oop pointer into compressed form
6743instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
6744  predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
6745  match(Set dst (EncodeP src));
6746  effect(KILL cr);
6747  format %{ "encode_heap_oop $dst,$src" %}
6748  ins_encode %{
6749    Register s = $src$$Register;
6750    Register d = $dst$$Register;
6751    if (s != d) {
6752      __ movq(d, s);
6753    }
6754    __ encode_heap_oop(d);
6755  %}
6756  ins_pipe(ialu_reg_long);
6757%}
6758
6759instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6760  predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
6761  match(Set dst (EncodeP src));
6762  effect(KILL cr);
6763  format %{ "encode_heap_oop_not_null $dst,$src" %}
6764  ins_encode %{
6765    __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
6766  %}
6767  ins_pipe(ialu_reg_long);
6768%}
6769
6770instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
6771  predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
6772            n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
6773  match(Set dst (DecodeN src));
6774  effect(KILL cr);
6775  format %{ "decode_heap_oop $dst,$src" %}
6776  ins_encode %{
6777    Register s = $src$$Register;
6778    Register d = $dst$$Register;
6779    if (s != d) {
6780      __ movq(d, s);
6781    }
6782    __ decode_heap_oop(d);
6783  %}
6784  ins_pipe(ialu_reg_long);
6785%}
6786
6787instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6788  predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
6789            n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
6790  match(Set dst (DecodeN src));
6791  effect(KILL cr);
6792  format %{ "decode_heap_oop_not_null $dst,$src" %}
6793  ins_encode %{
6794    Register s = $src$$Register;
6795    Register d = $dst$$Register;
6796    if (s != d) {
6797      __ decode_heap_oop_not_null(d, s);
6798    } else {
6799      __ decode_heap_oop_not_null(d);
6800    }
6801  %}
6802  ins_pipe(ialu_reg_long);
6803%}
6804
6805
6806//----------Conditional Move---------------------------------------------------
6807// Jump
6808// dummy instruction for generating temp registers
6809instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
6810  match(Jump (LShiftL switch_val shift));
6811  ins_cost(350);
6812  predicate(false);
6813  effect(TEMP dest);
6814
6815  format %{ "leaq    $dest, [$constantaddress]\n\t"
6816            "jmp     [$dest + $switch_val << $shift]\n\t" %}
6817  ins_encode %{
6818    // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6819    // to do that and the compiler is using that register as one it can allocate.
6820    // So we build it all by hand.
6821    // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
6822    // ArrayAddress dispatch(table, index);
6823    Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
6824    __ lea($dest$$Register, $constantaddress);
6825    __ jmp(dispatch);
6826  %}
6827  ins_pipe(pipe_jmp);
6828%}
6829
6830instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
6831  match(Jump (AddL (LShiftL switch_val shift) offset));
6832  ins_cost(350);
6833  effect(TEMP dest);
6834
6835  format %{ "leaq    $dest, [$constantaddress]\n\t"
6836            "jmp     [$dest + $switch_val << $shift + $offset]\n\t" %}
6837  ins_encode %{
6838    // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6839    // to do that and the compiler is using that register as one it can allocate.
6840    // So we build it all by hand.
6841    // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6842    // ArrayAddress dispatch(table, index);
6843    Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6844    __ lea($dest$$Register, $constantaddress);
6845    __ jmp(dispatch);
6846  %}
6847  ins_pipe(pipe_jmp);
6848%}
6849
6850instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
6851  match(Jump switch_val);
6852  ins_cost(350);
6853  effect(TEMP dest);
6854
6855  format %{ "leaq    $dest, [$constantaddress]\n\t"
6856            "jmp     [$dest + $switch_val]\n\t" %}
6857  ins_encode %{
6858    // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6859    // to do that and the compiler is using that register as one it can allocate.
6860    // So we build it all by hand.
6861    // Address index(noreg, switch_reg, Address::times_1);
6862    // ArrayAddress dispatch(table, index);
6863    Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1);
6864    __ lea($dest$$Register, $constantaddress);
6865    __ jmp(dispatch);
6866  %}
6867  ins_pipe(pipe_jmp);
6868%}
6869
6870// Conditional move
6871instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
6872%{
6873  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6874
6875  ins_cost(200); // XXX
6876  format %{ "cmovl$cop $dst, $src\t# signed, int" %}
6877  opcode(0x0F, 0x40);
6878  ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6879  ins_pipe(pipe_cmov_reg);
6880%}
6881
6882instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
6883  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6884
6885  ins_cost(200); // XXX
6886  format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
6887  opcode(0x0F, 0x40);
6888  ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6889  ins_pipe(pipe_cmov_reg);
6890%}
6891
6892instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
6893  match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6894  ins_cost(200);
6895  expand %{
6896    cmovI_regU(cop, cr, dst, src);
6897  %}
6898%}
6899
6900// Conditional move
6901instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
6902  match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6903
6904  ins_cost(250); // XXX
6905  format %{ "cmovl$cop $dst, $src\t# signed, int" %}
6906  opcode(0x0F, 0x40);
6907  ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
6908  ins_pipe(pipe_cmov_mem);
6909%}
6910
6911// Conditional move
6912instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
6913%{
6914  match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6915
6916  ins_cost(250); // XXX
6917  format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
6918  opcode(0x0F, 0x40);
6919  ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
6920  ins_pipe(pipe_cmov_mem);
6921%}
6922
6923instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
6924  match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6925  ins_cost(250);
6926  expand %{
6927    cmovI_memU(cop, cr, dst, src);
6928  %}
6929%}
6930
6931// Conditional move
6932instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
6933%{
6934  match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6935
6936  ins_cost(200); // XXX
6937  format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
6938  opcode(0x0F, 0x40);
6939  ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6940  ins_pipe(pipe_cmov_reg);
6941%}
6942
6943// Conditional move
6944instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
6945%{
6946  match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6947
6948  ins_cost(200); // XXX
6949  format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
6950  opcode(0x0F, 0x40);
6951  ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6952  ins_pipe(pipe_cmov_reg);
6953%}
6954
6955instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
6956  match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6957  ins_cost(200);
6958  expand %{
6959    cmovN_regU(cop, cr, dst, src);
6960  %}
6961%}
6962
6963// Conditional move
6964instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
6965%{
6966  match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6967
6968  ins_cost(200); // XXX
6969  format %{ "cmovq$cop $dst, $src\t# signed, ptr" %}
6970  opcode(0x0F, 0x40);
6971  ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6972  ins_pipe(pipe_cmov_reg);  // XXX
6973%}
6974
6975// Conditional move
6976instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
6977%{
6978  match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6979
6980  ins_cost(200); // XXX
6981  format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %}
6982  opcode(0x0F, 0x40);
6983  ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6984  ins_pipe(pipe_cmov_reg); // XXX
6985%}
6986
6987instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
6988  match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6989  ins_cost(200);
6990  expand %{
6991    cmovP_regU(cop, cr, dst, src);
6992  %}
6993%}
6994
6995// DISABLED: Requires the ADLC to emit a bottom_type call that
6996// correctly meets the two pointer arguments; one is an incoming
6997// register but the other is a memory operand.  ALSO appears to
6998// be buggy with implicit null checks.
6999//
7000//// Conditional move
7001//instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src)
7002//%{
7003//  match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
7004//  ins_cost(250);
7005//  format %{ "CMOV$cop $dst,$src\t# ptr" %}
7006//  opcode(0x0F,0x40);
7007//  ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
7008//  ins_pipe( pipe_cmov_mem );
7009//%}
7010//
7011//// Conditional move
7012//instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src)
7013//%{
7014//  match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
7015//  ins_cost(250);
7016//  format %{ "CMOV$cop $dst,$src\t# ptr" %}
7017//  opcode(0x0F,0x40);
7018//  ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
7019//  ins_pipe( pipe_cmov_mem );
7020//%}
7021
7022instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src)
7023%{
7024  match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7025
7026  ins_cost(200); // XXX
7027  format %{ "cmovq$cop $dst, $src\t# signed, long" %}
7028  opcode(0x0F, 0x40);
7029  ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7030  ins_pipe(pipe_cmov_reg);  // XXX
7031%}
7032
7033instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src)
7034%{
7035  match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7036
7037  ins_cost(200); // XXX
7038  format %{ "cmovq$cop $dst, $src\t# signed, long" %}
7039  opcode(0x0F, 0x40);
7040  ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7041  ins_pipe(pipe_cmov_mem);  // XXX
7042%}
7043
7044instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src)
7045%{
7046  match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7047
7048  ins_cost(200); // XXX
7049  format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7050  opcode(0x0F, 0x40);
7051  ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
7052  ins_pipe(pipe_cmov_reg); // XXX
7053%}
7054
7055instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
7056  match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7057  ins_cost(200);
7058  expand %{
7059    cmovL_regU(cop, cr, dst, src);
7060  %}
7061%}
7062
7063instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
7064%{
7065  match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7066
7067  ins_cost(200); // XXX
7068  format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
7069  opcode(0x0F, 0x40);
7070  ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
7071  ins_pipe(pipe_cmov_mem); // XXX
7072%}
7073
7074instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
7075  match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
7076  ins_cost(200);
7077  expand %{
7078    cmovL_memU(cop, cr, dst, src);
7079  %}
7080%}
7081
7082instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
7083%{
7084  match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7085
7086  ins_cost(200); // XXX
7087  format %{ "jn$cop    skip\t# signed cmove float\n\t"
7088            "movss     $dst, $src\n"
7089    "skip:" %}
7090  ins_encode %{
7091    Label Lskip;
7092    // Invert sense of branch from sense of CMOV
7093    __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7094    __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7095    __ bind(Lskip);
7096  %}
7097  ins_pipe(pipe_slow);
7098%}
7099
7100// instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
7101// %{
7102//   match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src))));
7103
7104//   ins_cost(200); // XXX
7105//   format %{ "jn$cop    skip\t# signed cmove float\n\t"
7106//             "movss     $dst, $src\n"
7107//     "skip:" %}
7108//   ins_encode(enc_cmovf_mem_branch(cop, dst, src));
7109//   ins_pipe(pipe_slow);
7110// %}
7111
7112instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
7113%{
7114  match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7115
7116  ins_cost(200); // XXX
7117  format %{ "jn$cop    skip\t# unsigned cmove float\n\t"
7118            "movss     $dst, $src\n"
7119    "skip:" %}
7120  ins_encode %{
7121    Label Lskip;
7122    // Invert sense of branch from sense of CMOV
7123    __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7124    __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7125    __ bind(Lskip);
7126  %}
7127  ins_pipe(pipe_slow);
7128%}
7129
7130instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
7131  match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7132  ins_cost(200);
7133  expand %{
7134    cmovF_regU(cop, cr, dst, src);
7135  %}
7136%}
7137
7138instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
7139%{
7140  match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7141
7142  ins_cost(200); // XXX
7143  format %{ "jn$cop    skip\t# signed cmove double\n\t"
7144            "movsd     $dst, $src\n"
7145    "skip:" %}
7146  ins_encode %{
7147    Label Lskip;
7148    // Invert sense of branch from sense of CMOV
7149    __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7150    __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7151    __ bind(Lskip);
7152  %}
7153  ins_pipe(pipe_slow);
7154%}
7155
7156instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
7157%{
7158  match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7159
7160  ins_cost(200); // XXX
7161  format %{ "jn$cop    skip\t# unsigned cmove double\n\t"
7162            "movsd     $dst, $src\n"
7163    "skip:" %}
7164  ins_encode %{
7165    Label Lskip;
7166    // Invert sense of branch from sense of CMOV
7167    __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7168    __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7169    __ bind(Lskip);
7170  %}
7171  ins_pipe(pipe_slow);
7172%}
7173
7174instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
7175  match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7176  ins_cost(200);
7177  expand %{
7178    cmovD_regU(cop, cr, dst, src);
7179  %}
7180%}
7181
7182//----------Arithmetic Instructions--------------------------------------------
7183//----------Addition Instructions----------------------------------------------
7184
7185instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7186%{
7187  match(Set dst (AddI dst src));
7188  effect(KILL cr);
7189
7190  format %{ "addl    $dst, $src\t# int" %}
7191  opcode(0x03);
7192  ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
7193  ins_pipe(ialu_reg_reg);
7194%}
7195
7196instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7197%{
7198  match(Set dst (AddI dst src));
7199  effect(KILL cr);
7200
7201  format %{ "addl    $dst, $src\t# int" %}
7202  opcode(0x81, 0x00); /* /0 id */
7203  ins_encode(OpcSErm(dst, src), Con8or32(src));
7204  ins_pipe( ialu_reg );
7205%}
7206
7207instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
7208%{
7209  match(Set dst (AddI dst (LoadI src)));
7210  effect(KILL cr);
7211
7212  ins_cost(125); // XXX
7213  format %{ "addl    $dst, $src\t# int" %}
7214  opcode(0x03);
7215  ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
7216  ins_pipe(ialu_reg_mem);
7217%}
7218
7219instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
7220%{
7221  match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7222  effect(KILL cr);
7223
7224  ins_cost(150); // XXX
7225  format %{ "addl    $dst, $src\t# int" %}
7226  opcode(0x01); /* Opcode 01 /r */
7227  ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
7228  ins_pipe(ialu_mem_reg);
7229%}
7230
7231instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr)
7232%{
7233  match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7234  effect(KILL cr);
7235
7236  ins_cost(125); // XXX
7237  format %{ "addl    $dst, $src\t# int" %}
7238  opcode(0x81); /* Opcode 81 /0 id */
7239  ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
7240  ins_pipe(ialu_mem_imm);
7241%}
7242
7243instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
7244%{
7245  predicate(UseIncDec);
7246  match(Set dst (AddI dst src));
7247  effect(KILL cr);
7248
7249  format %{ "incl    $dst\t# int" %}
7250  opcode(0xFF, 0x00); // FF /0
7251  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7252  ins_pipe(ialu_reg);
7253%}
7254
7255instruct incI_mem(memory dst, immI1 src, rFlagsReg cr)
7256%{
7257  predicate(UseIncDec);
7258  match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7259  effect(KILL cr);
7260
7261  ins_cost(125); // XXX
7262  format %{ "incl    $dst\t# int" %}
7263  opcode(0xFF); /* Opcode FF /0 */
7264  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst));
7265  ins_pipe(ialu_mem_imm);
7266%}
7267
7268// XXX why does that use AddI
7269instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr)
7270%{
7271  predicate(UseIncDec);
7272  match(Set dst (AddI dst src));
7273  effect(KILL cr);
7274
7275  format %{ "decl    $dst\t# int" %}
7276  opcode(0xFF, 0x01); // FF /1
7277  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7278  ins_pipe(ialu_reg);
7279%}
7280
7281// XXX why does that use AddI
7282instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr)
7283%{
7284  predicate(UseIncDec);
7285  match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7286  effect(KILL cr);
7287
7288  ins_cost(125); // XXX
7289  format %{ "decl    $dst\t# int" %}
7290  opcode(0xFF); /* Opcode FF /1 */
7291  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst));
7292  ins_pipe(ialu_mem_imm);
7293%}
7294
7295instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1)
7296%{
7297  match(Set dst (AddI src0 src1));
7298
7299  ins_cost(110);
7300  format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %}
7301  opcode(0x8D); /* 0x8D /r */
7302  ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
7303  ins_pipe(ialu_reg_reg);
7304%}
7305
7306instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7307%{
7308  match(Set dst (AddL dst src));
7309  effect(KILL cr);
7310
7311  format %{ "addq    $dst, $src\t# long" %}
7312  opcode(0x03);
7313  ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7314  ins_pipe(ialu_reg_reg);
7315%}
7316
7317instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
7318%{
7319  match(Set dst (AddL dst src));
7320  effect(KILL cr);
7321
7322  format %{ "addq    $dst, $src\t# long" %}
7323  opcode(0x81, 0x00); /* /0 id */
7324  ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7325  ins_pipe( ialu_reg );
7326%}
7327
7328instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
7329%{
7330  match(Set dst (AddL dst (LoadL src)));
7331  effect(KILL cr);
7332
7333  ins_cost(125); // XXX
7334  format %{ "addq    $dst, $src\t# long" %}
7335  opcode(0x03);
7336  ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
7337  ins_pipe(ialu_reg_mem);
7338%}
7339
7340instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
7341%{
7342  match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7343  effect(KILL cr);
7344
7345  ins_cost(150); // XXX
7346  format %{ "addq    $dst, $src\t# long" %}
7347  opcode(0x01); /* Opcode 01 /r */
7348  ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7349  ins_pipe(ialu_mem_reg);
7350%}
7351
7352instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
7353%{
7354  match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7355  effect(KILL cr);
7356
7357  ins_cost(125); // XXX
7358  format %{ "addq    $dst, $src\t# long" %}
7359  opcode(0x81); /* Opcode 81 /0 id */
7360  ins_encode(REX_mem_wide(dst),
7361             OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
7362  ins_pipe(ialu_mem_imm);
7363%}
7364
7365instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr)
7366%{
7367  predicate(UseIncDec);
7368  match(Set dst (AddL dst src));
7369  effect(KILL cr);
7370
7371  format %{ "incq    $dst\t# long" %}
7372  opcode(0xFF, 0x00); // FF /0
7373  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7374  ins_pipe(ialu_reg);
7375%}
7376
7377instruct incL_mem(memory dst, immL1 src, rFlagsReg cr)
7378%{
7379  predicate(UseIncDec);
7380  match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7381  effect(KILL cr);
7382
7383  ins_cost(125); // XXX
7384  format %{ "incq    $dst\t# long" %}
7385  opcode(0xFF); /* Opcode FF /0 */
7386  ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst));
7387  ins_pipe(ialu_mem_imm);
7388%}
7389
7390// XXX why does that use AddL
7391instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr)
7392%{
7393  predicate(UseIncDec);
7394  match(Set dst (AddL dst src));
7395  effect(KILL cr);
7396
7397  format %{ "decq    $dst\t# long" %}
7398  opcode(0xFF, 0x01); // FF /1
7399  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7400  ins_pipe(ialu_reg);
7401%}
7402
7403// XXX why does that use AddL
7404instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr)
7405%{
7406  predicate(UseIncDec);
7407  match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7408  effect(KILL cr);
7409
7410  ins_cost(125); // XXX
7411  format %{ "decq    $dst\t# long" %}
7412  opcode(0xFF); /* Opcode FF /1 */
7413  ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst));
7414  ins_pipe(ialu_mem_imm);
7415%}
7416
7417instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1)
7418%{
7419  match(Set dst (AddL src0 src1));
7420
7421  ins_cost(110);
7422  format %{ "leaq    $dst, [$src0 + $src1]\t# long" %}
7423  opcode(0x8D); /* 0x8D /r */
7424  ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
7425  ins_pipe(ialu_reg_reg);
7426%}
7427
7428instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr)
7429%{
7430  match(Set dst (AddP dst src));
7431  effect(KILL cr);
7432
7433  format %{ "addq    $dst, $src\t# ptr" %}
7434  opcode(0x03);
7435  ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7436  ins_pipe(ialu_reg_reg);
7437%}
7438
7439instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr)
7440%{
7441  match(Set dst (AddP dst src));
7442  effect(KILL cr);
7443
7444  format %{ "addq    $dst, $src\t# ptr" %}
7445  opcode(0x81, 0x00); /* /0 id */
7446  ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7447  ins_pipe( ialu_reg );
7448%}
7449
7450// XXX addP mem ops ????
7451
7452instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1)
7453%{
7454  match(Set dst (AddP src0 src1));
7455
7456  ins_cost(110);
7457  format %{ "leaq    $dst, [$src0 + $src1]\t# ptr" %}
7458  opcode(0x8D); /* 0x8D /r */
7459  ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX
7460  ins_pipe(ialu_reg_reg);
7461%}
7462
7463instruct checkCastPP(rRegP dst)
7464%{
7465  match(Set dst (CheckCastPP dst));
7466
7467  size(0);
7468  format %{ "# checkcastPP of $dst" %}
7469  ins_encode(/* empty encoding */);
7470  ins_pipe(empty);
7471%}
7472
7473instruct castPP(rRegP dst)
7474%{
7475  match(Set dst (CastPP dst));
7476
7477  size(0);
7478  format %{ "# castPP of $dst" %}
7479  ins_encode(/* empty encoding */);
7480  ins_pipe(empty);
7481%}
7482
7483instruct castII(rRegI dst)
7484%{
7485  match(Set dst (CastII dst));
7486
7487  size(0);
7488  format %{ "# castII of $dst" %}
7489  ins_encode(/* empty encoding */);
7490  ins_cost(0);
7491  ins_pipe(empty);
7492%}
7493
7494// LoadP-locked same as a regular LoadP when used with compare-swap
7495instruct loadPLocked(rRegP dst, memory mem)
7496%{
7497  match(Set dst (LoadPLocked mem));
7498
7499  ins_cost(125); // XXX
7500  format %{ "movq    $dst, $mem\t# ptr locked" %}
7501  opcode(0x8B);
7502  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
7503  ins_pipe(ialu_reg_mem); // XXX
7504%}
7505
7506// LoadL-locked - same as a regular LoadL when used with compare-swap
7507instruct loadLLocked(rRegL dst, memory mem)
7508%{
7509  match(Set dst (LoadLLocked mem));
7510
7511  ins_cost(125); // XXX
7512  format %{ "movq    $dst, $mem\t# long locked" %}
7513  opcode(0x8B);
7514  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
7515  ins_pipe(ialu_reg_mem); // XXX
7516%}
7517
7518// Conditional-store of the updated heap-top.
7519// Used during allocation of the shared heap.
7520// Sets flags (EQ) on success.  Implemented with a CMPXCHG on Intel.
7521
7522instruct storePConditional(memory heap_top_ptr,
7523                           rax_RegP oldval, rRegP newval,
7524                           rFlagsReg cr)
7525%{
7526  match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
7527
7528  format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
7529            "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
7530  opcode(0x0F, 0xB1);
7531  ins_encode(lock_prefix,
7532             REX_reg_mem_wide(newval, heap_top_ptr),
7533             OpcP, OpcS,
7534             reg_mem(newval, heap_top_ptr));
7535  ins_pipe(pipe_cmpxchg);
7536%}
7537
7538// Conditional-store of an int value.
7539// ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
7540instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
7541%{
7542  match(Set cr (StoreIConditional mem (Binary oldval newval)));
7543  effect(KILL oldval);
7544
7545  format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7546  opcode(0x0F, 0xB1);
7547  ins_encode(lock_prefix,
7548             REX_reg_mem(newval, mem),
7549             OpcP, OpcS,
7550             reg_mem(newval, mem));
7551  ins_pipe(pipe_cmpxchg);
7552%}
7553
7554// Conditional-store of a long value.
7555// ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG.
7556instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
7557%{
7558  match(Set cr (StoreLConditional mem (Binary oldval newval)));
7559  effect(KILL oldval);
7560
7561  format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7562  opcode(0x0F, 0xB1);
7563  ins_encode(lock_prefix,
7564             REX_reg_mem_wide(newval, mem),
7565             OpcP, OpcS,
7566             reg_mem(newval, mem));
7567  ins_pipe(pipe_cmpxchg);
7568%}
7569
7570
7571// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7572instruct compareAndSwapP(rRegI res,
7573                         memory mem_ptr,
7574                         rax_RegP oldval, rRegP newval,
7575                         rFlagsReg cr)
7576%{
7577  match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7578  effect(KILL cr, KILL oldval);
7579
7580  format %{ "cmpxchgq $mem_ptr,$newval\t# "
7581            "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7582            "sete    $res\n\t"
7583            "movzbl  $res, $res" %}
7584  opcode(0x0F, 0xB1);
7585  ins_encode(lock_prefix,
7586             REX_reg_mem_wide(newval, mem_ptr),
7587             OpcP, OpcS,
7588             reg_mem(newval, mem_ptr),
7589             REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7590             REX_reg_breg(res, res), // movzbl
7591             Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7592  ins_pipe( pipe_cmpxchg );
7593%}
7594
7595instruct compareAndSwapL(rRegI res,
7596                         memory mem_ptr,
7597                         rax_RegL oldval, rRegL newval,
7598                         rFlagsReg cr)
7599%{
7600  match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7601  effect(KILL cr, KILL oldval);
7602
7603  format %{ "cmpxchgq $mem_ptr,$newval\t# "
7604            "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7605            "sete    $res\n\t"
7606            "movzbl  $res, $res" %}
7607  opcode(0x0F, 0xB1);
7608  ins_encode(lock_prefix,
7609             REX_reg_mem_wide(newval, mem_ptr),
7610             OpcP, OpcS,
7611             reg_mem(newval, mem_ptr),
7612             REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7613             REX_reg_breg(res, res), // movzbl
7614             Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7615  ins_pipe( pipe_cmpxchg );
7616%}
7617
7618instruct compareAndSwapI(rRegI res,
7619                         memory mem_ptr,
7620                         rax_RegI oldval, rRegI newval,
7621                         rFlagsReg cr)
7622%{
7623  match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
7624  effect(KILL cr, KILL oldval);
7625
7626  format %{ "cmpxchgl $mem_ptr,$newval\t# "
7627            "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7628            "sete    $res\n\t"
7629            "movzbl  $res, $res" %}
7630  opcode(0x0F, 0xB1);
7631  ins_encode(lock_prefix,
7632             REX_reg_mem(newval, mem_ptr),
7633             OpcP, OpcS,
7634             reg_mem(newval, mem_ptr),
7635             REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7636             REX_reg_breg(res, res), // movzbl
7637             Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7638  ins_pipe( pipe_cmpxchg );
7639%}
7640
7641
7642instruct compareAndSwapN(rRegI res,
7643                          memory mem_ptr,
7644                          rax_RegN oldval, rRegN newval,
7645                          rFlagsReg cr) %{
7646  match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7647  effect(KILL cr, KILL oldval);
7648
7649  format %{ "cmpxchgl $mem_ptr,$newval\t# "
7650            "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7651            "sete    $res\n\t"
7652            "movzbl  $res, $res" %}
7653  opcode(0x0F, 0xB1);
7654  ins_encode(lock_prefix,
7655             REX_reg_mem(newval, mem_ptr),
7656             OpcP, OpcS,
7657             reg_mem(newval, mem_ptr),
7658             REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7659             REX_reg_breg(res, res), // movzbl
7660             Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7661  ins_pipe( pipe_cmpxchg );
7662%}
7663
7664//----------Subtraction Instructions-------------------------------------------
7665
7666// Integer Subtraction Instructions
7667instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7668%{
7669  match(Set dst (SubI dst src));
7670  effect(KILL cr);
7671
7672  format %{ "subl    $dst, $src\t# int" %}
7673  opcode(0x2B);
7674  ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
7675  ins_pipe(ialu_reg_reg);
7676%}
7677
7678instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7679%{
7680  match(Set dst (SubI dst src));
7681  effect(KILL cr);
7682
7683  format %{ "subl    $dst, $src\t# int" %}
7684  opcode(0x81, 0x05);  /* Opcode 81 /5 */
7685  ins_encode(OpcSErm(dst, src), Con8or32(src));
7686  ins_pipe(ialu_reg);
7687%}
7688
7689instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
7690%{
7691  match(Set dst (SubI dst (LoadI src)));
7692  effect(KILL cr);
7693
7694  ins_cost(125);
7695  format %{ "subl    $dst, $src\t# int" %}
7696  opcode(0x2B);
7697  ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
7698  ins_pipe(ialu_reg_mem);
7699%}
7700
7701instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
7702%{
7703  match(Set dst (StoreI dst (SubI (LoadI dst) src)));
7704  effect(KILL cr);
7705
7706  ins_cost(150);
7707  format %{ "subl    $dst, $src\t# int" %}
7708  opcode(0x29); /* Opcode 29 /r */
7709  ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
7710  ins_pipe(ialu_mem_reg);
7711%}
7712
7713instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr)
7714%{
7715  match(Set dst (StoreI dst (SubI (LoadI dst) src)));
7716  effect(KILL cr);
7717
7718  ins_cost(125); // XXX
7719  format %{ "subl    $dst, $src\t# int" %}
7720  opcode(0x81); /* Opcode 81 /5 id */
7721  ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
7722  ins_pipe(ialu_mem_imm);
7723%}
7724
7725instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7726%{
7727  match(Set dst (SubL dst src));
7728  effect(KILL cr);
7729
7730  format %{ "subq    $dst, $src\t# long" %}
7731  opcode(0x2B);
7732  ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7733  ins_pipe(ialu_reg_reg);
7734%}
7735
7736instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr)
7737%{
7738  match(Set dst (SubL dst src));
7739  effect(KILL cr);
7740
7741  format %{ "subq    $dst, $src\t# long" %}
7742  opcode(0x81, 0x05);  /* Opcode 81 /5 */
7743  ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7744  ins_pipe(ialu_reg);
7745%}
7746
7747instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
7748%{
7749  match(Set dst (SubL dst (LoadL src)));
7750  effect(KILL cr);
7751
7752  ins_cost(125);
7753  format %{ "subq    $dst, $src\t# long" %}
7754  opcode(0x2B);
7755  ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
7756  ins_pipe(ialu_reg_mem);
7757%}
7758
7759instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
7760%{
7761  match(Set dst (StoreL dst (SubL (LoadL dst) src)));
7762  effect(KILL cr);
7763
7764  ins_cost(150);
7765  format %{ "subq    $dst, $src\t# long" %}
7766  opcode(0x29); /* Opcode 29 /r */
7767  ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7768  ins_pipe(ialu_mem_reg);
7769%}
7770
7771instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
7772%{
7773  match(Set dst (StoreL dst (SubL (LoadL dst) src)));
7774  effect(KILL cr);
7775
7776  ins_cost(125); // XXX
7777  format %{ "subq    $dst, $src\t# long" %}
7778  opcode(0x81); /* Opcode 81 /5 id */
7779  ins_encode(REX_mem_wide(dst),
7780             OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
7781  ins_pipe(ialu_mem_imm);
7782%}
7783
7784// Subtract from a pointer
7785// XXX hmpf???
7786instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr)
7787%{
7788  match(Set dst (AddP dst (SubI zero src)));
7789  effect(KILL cr);
7790
7791  format %{ "subq    $dst, $src\t# ptr - int" %}
7792  opcode(0x2B);
7793  ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7794  ins_pipe(ialu_reg_reg);
7795%}
7796
7797instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr)
7798%{
7799  match(Set dst (SubI zero dst));
7800  effect(KILL cr);
7801
7802  format %{ "negl    $dst\t# int" %}
7803  opcode(0xF7, 0x03);  // Opcode F7 /3
7804  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7805  ins_pipe(ialu_reg);
7806%}
7807
7808instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr)
7809%{
7810  match(Set dst (StoreI dst (SubI zero (LoadI dst))));
7811  effect(KILL cr);
7812
7813  format %{ "negl    $dst\t# int" %}
7814  opcode(0xF7, 0x03);  // Opcode F7 /3
7815  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
7816  ins_pipe(ialu_reg);
7817%}
7818
7819instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr)
7820%{
7821  match(Set dst (SubL zero dst));
7822  effect(KILL cr);
7823
7824  format %{ "negq    $dst\t# long" %}
7825  opcode(0xF7, 0x03);  // Opcode F7 /3
7826  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7827  ins_pipe(ialu_reg);
7828%}
7829
7830instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr)
7831%{
7832  match(Set dst (StoreL dst (SubL zero (LoadL dst))));
7833  effect(KILL cr);
7834
7835  format %{ "negq    $dst\t# long" %}
7836  opcode(0xF7, 0x03);  // Opcode F7 /3
7837  ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
7838  ins_pipe(ialu_reg);
7839%}
7840
7841
7842//----------Multiplication/Division Instructions-------------------------------
7843// Integer Multiplication Instructions
7844// Multiply Register
7845
7846instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7847%{
7848  match(Set dst (MulI dst src));
7849  effect(KILL cr);
7850
7851  ins_cost(300);
7852  format %{ "imull   $dst, $src\t# int" %}
7853  opcode(0x0F, 0xAF);
7854  ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
7855  ins_pipe(ialu_reg_reg_alu0);
7856%}
7857
7858instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr)
7859%{
7860  match(Set dst (MulI src imm));
7861  effect(KILL cr);
7862
7863  ins_cost(300);
7864  format %{ "imull   $dst, $src, $imm\t# int" %}
7865  opcode(0x69); /* 69 /r id */
7866  ins_encode(REX_reg_reg(dst, src),
7867             OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
7868  ins_pipe(ialu_reg_reg_alu0);
7869%}
7870
7871instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr)
7872%{
7873  match(Set dst (MulI dst (LoadI src)));
7874  effect(KILL cr);
7875
7876  ins_cost(350);
7877  format %{ "imull   $dst, $src\t# int" %}
7878  opcode(0x0F, 0xAF);
7879  ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src));
7880  ins_pipe(ialu_reg_mem_alu0);
7881%}
7882
7883instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr)
7884%{
7885  match(Set dst (MulI (LoadI src) imm));
7886  effect(KILL cr);
7887
7888  ins_cost(300);
7889  format %{ "imull   $dst, $src, $imm\t# int" %}
7890  opcode(0x69); /* 69 /r id */
7891  ins_encode(REX_reg_mem(dst, src),
7892             OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
7893  ins_pipe(ialu_reg_mem_alu0);
7894%}
7895
7896instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7897%{
7898  match(Set dst (MulL dst src));
7899  effect(KILL cr);
7900
7901  ins_cost(300);
7902  format %{ "imulq   $dst, $src\t# long" %}
7903  opcode(0x0F, 0xAF);
7904  ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src));
7905  ins_pipe(ialu_reg_reg_alu0);
7906%}
7907
7908instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr)
7909%{
7910  match(Set dst (MulL src imm));
7911  effect(KILL cr);
7912
7913  ins_cost(300);
7914  format %{ "imulq   $dst, $src, $imm\t# long" %}
7915  opcode(0x69); /* 69 /r id */
7916  ins_encode(REX_reg_reg_wide(dst, src),
7917             OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
7918  ins_pipe(ialu_reg_reg_alu0);
7919%}
7920
7921instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr)
7922%{
7923  match(Set dst (MulL dst (LoadL src)));
7924  effect(KILL cr);
7925
7926  ins_cost(350);
7927  format %{ "imulq   $dst, $src\t# long" %}
7928  opcode(0x0F, 0xAF);
7929  ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src));
7930  ins_pipe(ialu_reg_mem_alu0);
7931%}
7932
7933instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr)
7934%{
7935  match(Set dst (MulL (LoadL src) imm));
7936  effect(KILL cr);
7937
7938  ins_cost(300);
7939  format %{ "imulq   $dst, $src, $imm\t# long" %}
7940  opcode(0x69); /* 69 /r id */
7941  ins_encode(REX_reg_mem_wide(dst, src),
7942             OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
7943  ins_pipe(ialu_reg_mem_alu0);
7944%}
7945
7946instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
7947%{
7948  match(Set dst (MulHiL src rax));
7949  effect(USE_KILL rax, KILL cr);
7950
7951  ins_cost(300);
7952  format %{ "imulq   RDX:RAX, RAX, $src\t# mulhi" %}
7953  opcode(0xF7, 0x5); /* Opcode F7 /5 */
7954  ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
7955  ins_pipe(ialu_reg_reg_alu0);
7956%}
7957
7958instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
7959                   rFlagsReg cr)
7960%{
7961  match(Set rax (DivI rax div));
7962  effect(KILL rdx, KILL cr);
7963
7964  ins_cost(30*100+10*100); // XXX
7965  format %{ "cmpl    rax, 0x80000000\t# idiv\n\t"
7966            "jne,s   normal\n\t"
7967            "xorl    rdx, rdx\n\t"
7968            "cmpl    $div, -1\n\t"
7969            "je,s    done\n"
7970    "normal: cdql\n\t"
7971            "idivl   $div\n"
7972    "done:"        %}
7973  opcode(0xF7, 0x7);  /* Opcode F7 /7 */
7974  ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
7975  ins_pipe(ialu_reg_reg_alu0);
7976%}
7977
7978instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
7979                   rFlagsReg cr)
7980%{
7981  match(Set rax (DivL rax div));
7982  effect(KILL rdx, KILL cr);
7983
7984  ins_cost(30*100+10*100); // XXX
7985  format %{ "movq    rdx, 0x8000000000000000\t# ldiv\n\t"
7986            "cmpq    rax, rdx\n\t"
7987            "jne,s   normal\n\t"
7988            "xorl    rdx, rdx\n\t"
7989            "cmpq    $div, -1\n\t"
7990            "je,s    done\n"
7991    "normal: cdqq\n\t"
7992            "idivq   $div\n"
7993    "done:"        %}
7994  opcode(0xF7, 0x7);  /* Opcode F7 /7 */
7995  ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
7996  ins_pipe(ialu_reg_reg_alu0);
7997%}
7998
7999// Integer DIVMOD with Register, both quotient and mod results
8000instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8001                             rFlagsReg cr)
8002%{
8003  match(DivModI rax div);
8004  effect(KILL cr);
8005
8006  ins_cost(30*100+10*100); // XXX
8007  format %{ "cmpl    rax, 0x80000000\t# idiv\n\t"
8008            "jne,s   normal\n\t"
8009            "xorl    rdx, rdx\n\t"
8010            "cmpl    $div, -1\n\t"
8011            "je,s    done\n"
8012    "normal: cdql\n\t"
8013            "idivl   $div\n"
8014    "done:"        %}
8015  opcode(0xF7, 0x7);  /* Opcode F7 /7 */
8016  ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8017  ins_pipe(pipe_slow);
8018%}
8019
8020// Long DIVMOD with Register, both quotient and mod results
8021instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8022                             rFlagsReg cr)
8023%{
8024  match(DivModL rax div);
8025  effect(KILL cr);
8026
8027  ins_cost(30*100+10*100); // XXX
8028  format %{ "movq    rdx, 0x8000000000000000\t# ldiv\n\t"
8029            "cmpq    rax, rdx\n\t"
8030            "jne,s   normal\n\t"
8031            "xorl    rdx, rdx\n\t"
8032            "cmpq    $div, -1\n\t"
8033            "je,s    done\n"
8034    "normal: cdqq\n\t"
8035            "idivq   $div\n"
8036    "done:"        %}
8037  opcode(0xF7, 0x7);  /* Opcode F7 /7 */
8038  ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8039  ins_pipe(pipe_slow);
8040%}
8041
8042//----------- DivL-By-Constant-Expansions--------------------------------------
8043// DivI cases are handled by the compiler
8044
8045// Magic constant, reciprocal of 10
8046instruct loadConL_0x6666666666666667(rRegL dst)
8047%{
8048  effect(DEF dst);
8049
8050  format %{ "movq    $dst, #0x666666666666667\t# Used in div-by-10" %}
8051  ins_encode(load_immL(dst, 0x6666666666666667));
8052  ins_pipe(ialu_reg);
8053%}
8054
8055instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8056%{
8057  effect(DEF dst, USE src, USE_KILL rax, KILL cr);
8058
8059  format %{ "imulq   rdx:rax, rax, $src\t# Used in div-by-10" %}
8060  opcode(0xF7, 0x5); /* Opcode F7 /5 */
8061  ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
8062  ins_pipe(ialu_reg_reg_alu0);
8063%}
8064
8065instruct sarL_rReg_63(rRegL dst, rFlagsReg cr)
8066%{
8067  effect(USE_DEF dst, KILL cr);
8068
8069  format %{ "sarq    $dst, #63\t# Used in div-by-10" %}
8070  opcode(0xC1, 0x7); /* C1 /7 ib */
8071  ins_encode(reg_opc_imm_wide(dst, 0x3F));
8072  ins_pipe(ialu_reg);
8073%}
8074
8075instruct sarL_rReg_2(rRegL dst, rFlagsReg cr)
8076%{
8077  effect(USE_DEF dst, KILL cr);
8078
8079  format %{ "sarq    $dst, #2\t# Used in div-by-10" %}
8080  opcode(0xC1, 0x7); /* C1 /7 ib */
8081  ins_encode(reg_opc_imm_wide(dst, 0x2));
8082  ins_pipe(ialu_reg);
8083%}
8084
8085instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div)
8086%{
8087  match(Set dst (DivL src div));
8088
8089  ins_cost((5+8)*100);
8090  expand %{
8091    rax_RegL rax;                     // Killed temp
8092    rFlagsReg cr;                     // Killed
8093    loadConL_0x6666666666666667(rax); // movq  rax, 0x6666666666666667
8094    mul_hi(dst, src, rax, cr);        // mulq  rdx:rax <= rax * $src
8095    sarL_rReg_63(src, cr);            // sarq  src, 63
8096    sarL_rReg_2(dst, cr);             // sarq  rdx, 2
8097    subL_rReg(dst, src, cr);          // subl  rdx, src
8098  %}
8099%}
8100
8101//-----------------------------------------------------------------------------
8102
8103instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div,
8104                   rFlagsReg cr)
8105%{
8106  match(Set rdx (ModI rax div));
8107  effect(KILL rax, KILL cr);
8108
8109  ins_cost(300); // XXX
8110  format %{ "cmpl    rax, 0x80000000\t# irem\n\t"
8111            "jne,s   normal\n\t"
8112            "xorl    rdx, rdx\n\t"
8113            "cmpl    $div, -1\n\t"
8114            "je,s    done\n"
8115    "normal: cdql\n\t"
8116            "idivl   $div\n"
8117    "done:"        %}
8118  opcode(0xF7, 0x7);  /* Opcode F7 /7 */
8119  ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8120  ins_pipe(ialu_reg_reg_alu0);
8121%}
8122
8123instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div,
8124                   rFlagsReg cr)
8125%{
8126  match(Set rdx (ModL rax div));
8127  effect(KILL rax, KILL cr);
8128
8129  ins_cost(300); // XXX
8130  format %{ "movq    rdx, 0x8000000000000000\t# lrem\n\t"
8131            "cmpq    rax, rdx\n\t"
8132            "jne,s   normal\n\t"
8133            "xorl    rdx, rdx\n\t"
8134            "cmpq    $div, -1\n\t"
8135            "je,s    done\n"
8136    "normal: cdqq\n\t"
8137            "idivq   $div\n"
8138    "done:"        %}
8139  opcode(0xF7, 0x7);  /* Opcode F7 /7 */
8140  ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8141  ins_pipe(ialu_reg_reg_alu0);
8142%}
8143
8144// Integer Shift Instructions
8145// Shift Left by one
8146instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8147%{
8148  match(Set dst (LShiftI dst shift));
8149  effect(KILL cr);
8150
8151  format %{ "sall    $dst, $shift" %}
8152  opcode(0xD1, 0x4); /* D1 /4 */
8153  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8154  ins_pipe(ialu_reg);
8155%}
8156
8157// Shift Left by one
8158instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8159%{
8160  match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8161  effect(KILL cr);
8162
8163  format %{ "sall    $dst, $shift\t" %}
8164  opcode(0xD1, 0x4); /* D1 /4 */
8165  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8166  ins_pipe(ialu_mem_imm);
8167%}
8168
8169// Shift Left by 8-bit immediate
8170instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8171%{
8172  match(Set dst (LShiftI dst shift));
8173  effect(KILL cr);
8174
8175  format %{ "sall    $dst, $shift" %}
8176  opcode(0xC1, 0x4); /* C1 /4 ib */
8177  ins_encode(reg_opc_imm(dst, shift));
8178  ins_pipe(ialu_reg);
8179%}
8180
8181// Shift Left by 8-bit immediate
8182instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8183%{
8184  match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8185  effect(KILL cr);
8186
8187  format %{ "sall    $dst, $shift" %}
8188  opcode(0xC1, 0x4); /* C1 /4 ib */
8189  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8190  ins_pipe(ialu_mem_imm);
8191%}
8192
8193// Shift Left by variable
8194instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8195%{
8196  match(Set dst (LShiftI dst shift));
8197  effect(KILL cr);
8198
8199  format %{ "sall    $dst, $shift" %}
8200  opcode(0xD3, 0x4); /* D3 /4 */
8201  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8202  ins_pipe(ialu_reg_reg);
8203%}
8204
8205// Shift Left by variable
8206instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8207%{
8208  match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8209  effect(KILL cr);
8210
8211  format %{ "sall    $dst, $shift" %}
8212  opcode(0xD3, 0x4); /* D3 /4 */
8213  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8214  ins_pipe(ialu_mem_reg);
8215%}
8216
8217// Arithmetic shift right by one
8218instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8219%{
8220  match(Set dst (RShiftI dst shift));
8221  effect(KILL cr);
8222
8223  format %{ "sarl    $dst, $shift" %}
8224  opcode(0xD1, 0x7); /* D1 /7 */
8225  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8226  ins_pipe(ialu_reg);
8227%}
8228
8229// Arithmetic shift right by one
8230instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8231%{
8232  match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8233  effect(KILL cr);
8234
8235  format %{ "sarl    $dst, $shift" %}
8236  opcode(0xD1, 0x7); /* D1 /7 */
8237  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8238  ins_pipe(ialu_mem_imm);
8239%}
8240
8241// Arithmetic Shift Right by 8-bit immediate
8242instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8243%{
8244  match(Set dst (RShiftI dst shift));
8245  effect(KILL cr);
8246
8247  format %{ "sarl    $dst, $shift" %}
8248  opcode(0xC1, 0x7); /* C1 /7 ib */
8249  ins_encode(reg_opc_imm(dst, shift));
8250  ins_pipe(ialu_mem_imm);
8251%}
8252
8253// Arithmetic Shift Right by 8-bit immediate
8254instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8255%{
8256  match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8257  effect(KILL cr);
8258
8259  format %{ "sarl    $dst, $shift" %}
8260  opcode(0xC1, 0x7); /* C1 /7 ib */
8261  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8262  ins_pipe(ialu_mem_imm);
8263%}
8264
8265// Arithmetic Shift Right by variable
8266instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8267%{
8268  match(Set dst (RShiftI dst shift));
8269  effect(KILL cr);
8270
8271  format %{ "sarl    $dst, $shift" %}
8272  opcode(0xD3, 0x7); /* D3 /7 */
8273  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8274  ins_pipe(ialu_reg_reg);
8275%}
8276
8277// Arithmetic Shift Right by variable
8278instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8279%{
8280  match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8281  effect(KILL cr);
8282
8283  format %{ "sarl    $dst, $shift" %}
8284  opcode(0xD3, 0x7); /* D3 /7 */
8285  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8286  ins_pipe(ialu_mem_reg);
8287%}
8288
8289// Logical shift right by one
8290instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8291%{
8292  match(Set dst (URShiftI dst shift));
8293  effect(KILL cr);
8294
8295  format %{ "shrl    $dst, $shift" %}
8296  opcode(0xD1, 0x5); /* D1 /5 */
8297  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8298  ins_pipe(ialu_reg);
8299%}
8300
8301// Logical shift right by one
8302instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8303%{
8304  match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8305  effect(KILL cr);
8306
8307  format %{ "shrl    $dst, $shift" %}
8308  opcode(0xD1, 0x5); /* D1 /5 */
8309  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8310  ins_pipe(ialu_mem_imm);
8311%}
8312
8313// Logical Shift Right by 8-bit immediate
8314instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8315%{
8316  match(Set dst (URShiftI dst shift));
8317  effect(KILL cr);
8318
8319  format %{ "shrl    $dst, $shift" %}
8320  opcode(0xC1, 0x5); /* C1 /5 ib */
8321  ins_encode(reg_opc_imm(dst, shift));
8322  ins_pipe(ialu_reg);
8323%}
8324
8325// Logical Shift Right by 8-bit immediate
8326instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8327%{
8328  match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8329  effect(KILL cr);
8330
8331  format %{ "shrl    $dst, $shift" %}
8332  opcode(0xC1, 0x5); /* C1 /5 ib */
8333  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8334  ins_pipe(ialu_mem_imm);
8335%}
8336
8337// Logical Shift Right by variable
8338instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8339%{
8340  match(Set dst (URShiftI dst shift));
8341  effect(KILL cr);
8342
8343  format %{ "shrl    $dst, $shift" %}
8344  opcode(0xD3, 0x5); /* D3 /5 */
8345  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8346  ins_pipe(ialu_reg_reg);
8347%}
8348
8349// Logical Shift Right by variable
8350instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8351%{
8352  match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8353  effect(KILL cr);
8354
8355  format %{ "shrl    $dst, $shift" %}
8356  opcode(0xD3, 0x5); /* D3 /5 */
8357  ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8358  ins_pipe(ialu_mem_reg);
8359%}
8360
8361// Long Shift Instructions
8362// Shift Left by one
8363instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8364%{
8365  match(Set dst (LShiftL dst shift));
8366  effect(KILL cr);
8367
8368  format %{ "salq    $dst, $shift" %}
8369  opcode(0xD1, 0x4); /* D1 /4 */
8370  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8371  ins_pipe(ialu_reg);
8372%}
8373
8374// Shift Left by one
8375instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8376%{
8377  match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8378  effect(KILL cr);
8379
8380  format %{ "salq    $dst, $shift" %}
8381  opcode(0xD1, 0x4); /* D1 /4 */
8382  ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8383  ins_pipe(ialu_mem_imm);
8384%}
8385
8386// Shift Left by 8-bit immediate
8387instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8388%{
8389  match(Set dst (LShiftL dst shift));
8390  effect(KILL cr);
8391
8392  format %{ "salq    $dst, $shift" %}
8393  opcode(0xC1, 0x4); /* C1 /4 ib */
8394  ins_encode(reg_opc_imm_wide(dst, shift));
8395  ins_pipe(ialu_reg);
8396%}
8397
8398// Shift Left by 8-bit immediate
8399instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8400%{
8401  match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8402  effect(KILL cr);
8403
8404  format %{ "salq    $dst, $shift" %}
8405  opcode(0xC1, 0x4); /* C1 /4 ib */
8406  ins_encode(REX_mem_wide(dst), OpcP,
8407             RM_opc_mem(secondary, dst), Con8or32(shift));
8408  ins_pipe(ialu_mem_imm);
8409%}
8410
8411// Shift Left by variable
8412instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8413%{
8414  match(Set dst (LShiftL dst shift));
8415  effect(KILL cr);
8416
8417  format %{ "salq    $dst, $shift" %}
8418  opcode(0xD3, 0x4); /* D3 /4 */
8419  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8420  ins_pipe(ialu_reg_reg);
8421%}
8422
8423// Shift Left by variable
8424instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8425%{
8426  match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8427  effect(KILL cr);
8428
8429  format %{ "salq    $dst, $shift" %}
8430  opcode(0xD3, 0x4); /* D3 /4 */
8431  ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8432  ins_pipe(ialu_mem_reg);
8433%}
8434
8435// Arithmetic shift right by one
8436instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8437%{
8438  match(Set dst (RShiftL dst shift));
8439  effect(KILL cr);
8440
8441  format %{ "sarq    $dst, $shift" %}
8442  opcode(0xD1, 0x7); /* D1 /7 */
8443  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8444  ins_pipe(ialu_reg);
8445%}
8446
8447// Arithmetic shift right by one
8448instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8449%{
8450  match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8451  effect(KILL cr);
8452
8453  format %{ "sarq    $dst, $shift" %}
8454  opcode(0xD1, 0x7); /* D1 /7 */
8455  ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8456  ins_pipe(ialu_mem_imm);
8457%}
8458
8459// Arithmetic Shift Right by 8-bit immediate
8460instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8461%{
8462  match(Set dst (RShiftL dst shift));
8463  effect(KILL cr);
8464
8465  format %{ "sarq    $dst, $shift" %}
8466  opcode(0xC1, 0x7); /* C1 /7 ib */
8467  ins_encode(reg_opc_imm_wide(dst, shift));
8468  ins_pipe(ialu_mem_imm);
8469%}
8470
8471// Arithmetic Shift Right by 8-bit immediate
8472instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8473%{
8474  match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8475  effect(KILL cr);
8476
8477  format %{ "sarq    $dst, $shift" %}
8478  opcode(0xC1, 0x7); /* C1 /7 ib */
8479  ins_encode(REX_mem_wide(dst), OpcP,
8480             RM_opc_mem(secondary, dst), Con8or32(shift));
8481  ins_pipe(ialu_mem_imm);
8482%}
8483
8484// Arithmetic Shift Right by variable
8485instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8486%{
8487  match(Set dst (RShiftL dst shift));
8488  effect(KILL cr);
8489
8490  format %{ "sarq    $dst, $shift" %}
8491  opcode(0xD3, 0x7); /* D3 /7 */
8492  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8493  ins_pipe(ialu_reg_reg);
8494%}
8495
8496// Arithmetic Shift Right by variable
8497instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8498%{
8499  match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8500  effect(KILL cr);
8501
8502  format %{ "sarq    $dst, $shift" %}
8503  opcode(0xD3, 0x7); /* D3 /7 */
8504  ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8505  ins_pipe(ialu_mem_reg);
8506%}
8507
8508// Logical shift right by one
8509instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8510%{
8511  match(Set dst (URShiftL dst shift));
8512  effect(KILL cr);
8513
8514  format %{ "shrq    $dst, $shift" %}
8515  opcode(0xD1, 0x5); /* D1 /5 */
8516  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst ));
8517  ins_pipe(ialu_reg);
8518%}
8519
8520// Logical shift right by one
8521instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8522%{
8523  match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8524  effect(KILL cr);
8525
8526  format %{ "shrq    $dst, $shift" %}
8527  opcode(0xD1, 0x5); /* D1 /5 */
8528  ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8529  ins_pipe(ialu_mem_imm);
8530%}
8531
8532// Logical Shift Right by 8-bit immediate
8533instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8534%{
8535  match(Set dst (URShiftL dst shift));
8536  effect(KILL cr);
8537
8538  format %{ "shrq    $dst, $shift" %}
8539  opcode(0xC1, 0x5); /* C1 /5 ib */
8540  ins_encode(reg_opc_imm_wide(dst, shift));
8541  ins_pipe(ialu_reg);
8542%}
8543
8544
8545// Logical Shift Right by 8-bit immediate
8546instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8547%{
8548  match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8549  effect(KILL cr);
8550
8551  format %{ "shrq    $dst, $shift" %}
8552  opcode(0xC1, 0x5); /* C1 /5 ib */
8553  ins_encode(REX_mem_wide(dst), OpcP,
8554             RM_opc_mem(secondary, dst), Con8or32(shift));
8555  ins_pipe(ialu_mem_imm);
8556%}
8557
8558// Logical Shift Right by variable
8559instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8560%{
8561  match(Set dst (URShiftL dst shift));
8562  effect(KILL cr);
8563
8564  format %{ "shrq    $dst, $shift" %}
8565  opcode(0xD3, 0x5); /* D3 /5 */
8566  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8567  ins_pipe(ialu_reg_reg);
8568%}
8569
8570// Logical Shift Right by variable
8571instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8572%{
8573  match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8574  effect(KILL cr);
8575
8576  format %{ "shrq    $dst, $shift" %}
8577  opcode(0xD3, 0x5); /* D3 /5 */
8578  ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8579  ins_pipe(ialu_mem_reg);
8580%}
8581
8582// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
8583// This idiom is used by the compiler for the i2b bytecode.
8584instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour)
8585%{
8586  match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
8587
8588  format %{ "movsbl  $dst, $src\t# i2b" %}
8589  opcode(0x0F, 0xBE);
8590  ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8591  ins_pipe(ialu_reg_reg);
8592%}
8593
8594// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
8595// This idiom is used by the compiler the i2s bytecode.
8596instruct i2s(rRegI dst, rRegI src, immI_16 sixteen)
8597%{
8598  match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
8599
8600  format %{ "movswl  $dst, $src\t# i2s" %}
8601  opcode(0x0F, 0xBF);
8602  ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8603  ins_pipe(ialu_reg_reg);
8604%}
8605
8606// ROL/ROR instructions
8607
8608// ROL expand
8609instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{
8610  effect(KILL cr, USE_DEF dst);
8611
8612  format %{ "roll    $dst" %}
8613  opcode(0xD1, 0x0); /* Opcode  D1 /0 */
8614  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8615  ins_pipe(ialu_reg);
8616%}
8617
8618instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{
8619  effect(USE_DEF dst, USE shift, KILL cr);
8620
8621  format %{ "roll    $dst, $shift" %}
8622  opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
8623  ins_encode( reg_opc_imm(dst, shift) );
8624  ins_pipe(ialu_reg);
8625%}
8626
8627instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
8628%{
8629  effect(USE_DEF dst, USE shift, KILL cr);
8630
8631  format %{ "roll    $dst, $shift" %}
8632  opcode(0xD3, 0x0); /* Opcode D3 /0 */
8633  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8634  ins_pipe(ialu_reg_reg);
8635%}
8636// end of ROL expand
8637
8638// Rotate Left by one
8639instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
8640%{
8641  match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8642
8643  expand %{
8644    rolI_rReg_imm1(dst, cr);
8645  %}
8646%}
8647
8648// Rotate Left by 8-bit immediate
8649instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
8650%{
8651  predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8652  match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8653
8654  expand %{
8655    rolI_rReg_imm8(dst, lshift, cr);
8656  %}
8657%}
8658
8659// Rotate Left by variable
8660instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8661%{
8662  match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift))));
8663
8664  expand %{
8665    rolI_rReg_CL(dst, shift, cr);
8666  %}
8667%}
8668
8669// Rotate Left by variable
8670instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
8671%{
8672  match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift))));
8673
8674  expand %{
8675    rolI_rReg_CL(dst, shift, cr);
8676  %}
8677%}
8678
8679// ROR expand
8680instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr)
8681%{
8682  effect(USE_DEF dst, KILL cr);
8683
8684  format %{ "rorl    $dst" %}
8685  opcode(0xD1, 0x1); /* D1 /1 */
8686  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8687  ins_pipe(ialu_reg);
8688%}
8689
8690instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr)
8691%{
8692  effect(USE_DEF dst, USE shift, KILL cr);
8693
8694  format %{ "rorl    $dst, $shift" %}
8695  opcode(0xC1, 0x1); /* C1 /1 ib */
8696  ins_encode(reg_opc_imm(dst, shift));
8697  ins_pipe(ialu_reg);
8698%}
8699
8700instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
8701%{
8702  effect(USE_DEF dst, USE shift, KILL cr);
8703
8704  format %{ "rorl    $dst, $shift" %}
8705  opcode(0xD3, 0x1); /* D3 /1 */
8706  ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8707  ins_pipe(ialu_reg_reg);
8708%}
8709// end of ROR expand
8710
8711// Rotate Right by one
8712instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
8713%{
8714  match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8715
8716  expand %{
8717    rorI_rReg_imm1(dst, cr);
8718  %}
8719%}
8720
8721// Rotate Right by 8-bit immediate
8722instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
8723%{
8724  predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8725  match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8726
8727  expand %{
8728    rorI_rReg_imm8(dst, rshift, cr);
8729  %}
8730%}
8731
8732// Rotate Right by variable
8733instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8734%{
8735  match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift))));
8736
8737  expand %{
8738    rorI_rReg_CL(dst, shift, cr);
8739  %}
8740%}
8741
8742// Rotate Right by variable
8743instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
8744%{
8745  match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift))));
8746
8747  expand %{
8748    rorI_rReg_CL(dst, shift, cr);
8749  %}
8750%}
8751
8752// for long rotate
8753// ROL expand
8754instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{
8755  effect(USE_DEF dst, KILL cr);
8756
8757  format %{ "rolq    $dst" %}
8758  opcode(0xD1, 0x0); /* Opcode  D1 /0 */
8759  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8760  ins_pipe(ialu_reg);
8761%}
8762
8763instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{
8764  effect(USE_DEF dst, USE shift, KILL cr);
8765
8766  format %{ "rolq    $dst, $shift" %}
8767  opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
8768  ins_encode( reg_opc_imm_wide(dst, shift) );
8769  ins_pipe(ialu_reg);
8770%}
8771
8772instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
8773%{
8774  effect(USE_DEF dst, USE shift, KILL cr);
8775
8776  format %{ "rolq    $dst, $shift" %}
8777  opcode(0xD3, 0x0); /* Opcode D3 /0 */
8778  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8779  ins_pipe(ialu_reg_reg);
8780%}
8781// end of ROL expand
8782
8783// Rotate Left by one
8784instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
8785%{
8786  match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
8787
8788  expand %{
8789    rolL_rReg_imm1(dst, cr);
8790  %}
8791%}
8792
8793// Rotate Left by 8-bit immediate
8794instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
8795%{
8796  predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
8797  match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
8798
8799  expand %{
8800    rolL_rReg_imm8(dst, lshift, cr);
8801  %}
8802%}
8803
8804// Rotate Left by variable
8805instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8806%{
8807  match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift))));
8808
8809  expand %{
8810    rolL_rReg_CL(dst, shift, cr);
8811  %}
8812%}
8813
8814// Rotate Left by variable
8815instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
8816%{
8817  match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift))));
8818
8819  expand %{
8820    rolL_rReg_CL(dst, shift, cr);
8821  %}
8822%}
8823
8824// ROR expand
8825instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr)
8826%{
8827  effect(USE_DEF dst, KILL cr);
8828
8829  format %{ "rorq    $dst" %}
8830  opcode(0xD1, 0x1); /* D1 /1 */
8831  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8832  ins_pipe(ialu_reg);
8833%}
8834
8835instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr)
8836%{
8837  effect(USE_DEF dst, USE shift, KILL cr);
8838
8839  format %{ "rorq    $dst, $shift" %}
8840  opcode(0xC1, 0x1); /* C1 /1 ib */
8841  ins_encode(reg_opc_imm_wide(dst, shift));
8842  ins_pipe(ialu_reg);
8843%}
8844
8845instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
8846%{
8847  effect(USE_DEF dst, USE shift, KILL cr);
8848
8849  format %{ "rorq    $dst, $shift" %}
8850  opcode(0xD3, 0x1); /* D3 /1 */
8851  ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8852  ins_pipe(ialu_reg_reg);
8853%}
8854// end of ROR expand
8855
8856// Rotate Right by one
8857instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
8858%{
8859  match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
8860
8861  expand %{
8862    rorL_rReg_imm1(dst, cr);
8863  %}
8864%}
8865
8866// Rotate Right by 8-bit immediate
8867instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
8868%{
8869  predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
8870  match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
8871
8872  expand %{
8873    rorL_rReg_imm8(dst, rshift, cr);
8874  %}
8875%}
8876
8877// Rotate Right by variable
8878instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8879%{
8880  match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift))));
8881
8882  expand %{
8883    rorL_rReg_CL(dst, shift, cr);
8884  %}
8885%}
8886
8887// Rotate Right by variable
8888instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
8889%{
8890  match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift))));
8891
8892  expand %{
8893    rorL_rReg_CL(dst, shift, cr);
8894  %}
8895%}
8896
8897// Logical Instructions
8898
8899// Integer Logical Instructions
8900
8901// And Instructions
8902// And Register with Register
8903instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8904%{
8905  match(Set dst (AndI dst src));
8906  effect(KILL cr);
8907
8908  format %{ "andl    $dst, $src\t# int" %}
8909  opcode(0x23);
8910  ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8911  ins_pipe(ialu_reg_reg);
8912%}
8913
8914// And Register with Immediate 255
8915instruct andI_rReg_imm255(rRegI dst, immI_255 src)
8916%{
8917  match(Set dst (AndI dst src));
8918
8919  format %{ "movzbl  $dst, $dst\t# int & 0xFF" %}
8920  opcode(0x0F, 0xB6);
8921  ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
8922  ins_pipe(ialu_reg);
8923%}
8924
8925// And Register with Immediate 255 and promote to long
8926instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask)
8927%{
8928  match(Set dst (ConvI2L (AndI src mask)));
8929
8930  format %{ "movzbl  $dst, $src\t# int & 0xFF -> long" %}
8931  opcode(0x0F, 0xB6);
8932  ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8933  ins_pipe(ialu_reg);
8934%}
8935
8936// And Register with Immediate 65535
8937instruct andI_rReg_imm65535(rRegI dst, immI_65535 src)
8938%{
8939  match(Set dst (AndI dst src));
8940
8941  format %{ "movzwl  $dst, $dst\t# int & 0xFFFF" %}
8942  opcode(0x0F, 0xB7);
8943  ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
8944  ins_pipe(ialu_reg);
8945%}
8946
8947// And Register with Immediate 65535 and promote to long
8948instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask)
8949%{
8950  match(Set dst (ConvI2L (AndI src mask)));
8951
8952  format %{ "movzwl  $dst, $src\t# int & 0xFFFF -> long" %}
8953  opcode(0x0F, 0xB7);
8954  ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8955  ins_pipe(ialu_reg);
8956%}
8957
8958// And Register with Immediate
8959instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8960%{
8961  match(Set dst (AndI dst src));
8962  effect(KILL cr);
8963
8964  format %{ "andl    $dst, $src\t# int" %}
8965  opcode(0x81, 0x04); /* Opcode 81 /4 */
8966  ins_encode(OpcSErm(dst, src), Con8or32(src));
8967  ins_pipe(ialu_reg);
8968%}
8969
8970// And Register with Memory
8971instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8972%{
8973  match(Set dst (AndI dst (LoadI src)));
8974  effect(KILL cr);
8975
8976  ins_cost(125);
8977  format %{ "andl    $dst, $src\t# int" %}
8978  opcode(0x23);
8979  ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
8980  ins_pipe(ialu_reg_mem);
8981%}
8982
8983// And Memory with Register
8984instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8985%{
8986  match(Set dst (StoreI dst (AndI (LoadI dst) src)));
8987  effect(KILL cr);
8988
8989  ins_cost(150);
8990  format %{ "andl    $dst, $src\t# int" %}
8991  opcode(0x21); /* Opcode 21 /r */
8992  ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
8993  ins_pipe(ialu_mem_reg);
8994%}
8995
8996// And Memory with Immediate
8997instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr)
8998%{
8999  match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9000  effect(KILL cr);
9001
9002  ins_cost(125);
9003  format %{ "andl    $dst, $src\t# int" %}
9004  opcode(0x81, 0x4); /* Opcode 81 /4 id */
9005  ins_encode(REX_mem(dst), OpcSE(src),
9006             RM_opc_mem(secondary, dst), Con8or32(src));
9007  ins_pipe(ialu_mem_imm);
9008%}
9009
9010// Or Instructions
9011// Or Register with Register
9012instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9013%{
9014  match(Set dst (OrI dst src));
9015  effect(KILL cr);
9016
9017  format %{ "orl     $dst, $src\t# int" %}
9018  opcode(0x0B);
9019  ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9020  ins_pipe(ialu_reg_reg);
9021%}
9022
9023// Or Register with Immediate
9024instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9025%{
9026  match(Set dst (OrI dst src));
9027  effect(KILL cr);
9028
9029  format %{ "orl     $dst, $src\t# int" %}
9030  opcode(0x81, 0x01); /* Opcode 81 /1 id */
9031  ins_encode(OpcSErm(dst, src), Con8or32(src));
9032  ins_pipe(ialu_reg);
9033%}
9034
9035// Or Register with Memory
9036instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9037%{
9038  match(Set dst (OrI dst (LoadI src)));
9039  effect(KILL cr);
9040
9041  ins_cost(125);
9042  format %{ "orl     $dst, $src\t# int" %}
9043  opcode(0x0B);
9044  ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9045  ins_pipe(ialu_reg_mem);
9046%}
9047
9048// Or Memory with Register
9049instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9050%{
9051  match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9052  effect(KILL cr);
9053
9054  ins_cost(150);
9055  format %{ "orl     $dst, $src\t# int" %}
9056  opcode(0x09); /* Opcode 09 /r */
9057  ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9058  ins_pipe(ialu_mem_reg);
9059%}
9060
9061// Or Memory with Immediate
9062instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr)
9063%{
9064  match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9065  effect(KILL cr);
9066
9067  ins_cost(125);
9068  format %{ "orl     $dst, $src\t# int" %}
9069  opcode(0x81, 0x1); /* Opcode 81 /1 id */
9070  ins_encode(REX_mem(dst), OpcSE(src),
9071             RM_opc_mem(secondary, dst), Con8or32(src));
9072  ins_pipe(ialu_mem_imm);
9073%}
9074
9075// Xor Instructions
9076// Xor Register with Register
9077instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9078%{
9079  match(Set dst (XorI dst src));
9080  effect(KILL cr);
9081
9082  format %{ "xorl    $dst, $src\t# int" %}
9083  opcode(0x33);
9084  ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9085  ins_pipe(ialu_reg_reg);
9086%}
9087
9088// Xor Register with Immediate -1
9089instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
9090  match(Set dst (XorI dst imm));
9091
9092  format %{ "not    $dst" %}
9093  ins_encode %{
9094     __ notl($dst$$Register);
9095  %}
9096  ins_pipe(ialu_reg);
9097%}
9098
9099// Xor Register with Immediate
9100instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9101%{
9102  match(Set dst (XorI dst src));
9103  effect(KILL cr);
9104
9105  format %{ "xorl    $dst, $src\t# int" %}
9106  opcode(0x81, 0x06); /* Opcode 81 /6 id */
9107  ins_encode(OpcSErm(dst, src), Con8or32(src));
9108  ins_pipe(ialu_reg);
9109%}
9110
9111// Xor Register with Memory
9112instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9113%{
9114  match(Set dst (XorI dst (LoadI src)));
9115  effect(KILL cr);
9116
9117  ins_cost(125);
9118  format %{ "xorl    $dst, $src\t# int" %}
9119  opcode(0x33);
9120  ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9121  ins_pipe(ialu_reg_mem);
9122%}
9123
9124// Xor Memory with Register
9125instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9126%{
9127  match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9128  effect(KILL cr);
9129
9130  ins_cost(150);
9131  format %{ "xorl    $dst, $src\t# int" %}
9132  opcode(0x31); /* Opcode 31 /r */
9133  ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9134  ins_pipe(ialu_mem_reg);
9135%}
9136
9137// Xor Memory with Immediate
9138instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr)
9139%{
9140  match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9141  effect(KILL cr);
9142
9143  ins_cost(125);
9144  format %{ "xorl    $dst, $src\t# int" %}
9145  opcode(0x81, 0x6); /* Opcode 81 /6 id */
9146  ins_encode(REX_mem(dst), OpcSE(src),
9147             RM_opc_mem(secondary, dst), Con8or32(src));
9148  ins_pipe(ialu_mem_imm);
9149%}
9150
9151
9152// Long Logical Instructions
9153
9154// And Instructions
9155// And Register with Register
9156instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9157%{
9158  match(Set dst (AndL dst src));
9159  effect(KILL cr);
9160
9161  format %{ "andq    $dst, $src\t# long" %}
9162  opcode(0x23);
9163  ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9164  ins_pipe(ialu_reg_reg);
9165%}
9166
9167// And Register with Immediate 255
9168instruct andL_rReg_imm255(rRegL dst, immL_255 src)
9169%{
9170  match(Set dst (AndL dst src));
9171
9172  format %{ "movzbq  $dst, $dst\t# long & 0xFF" %}
9173  opcode(0x0F, 0xB6);
9174  ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9175  ins_pipe(ialu_reg);
9176%}
9177
9178// And Register with Immediate 65535
9179instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
9180%{
9181  match(Set dst (AndL dst src));
9182
9183  format %{ "movzwq  $dst, $dst\t# long & 0xFFFF" %}
9184  opcode(0x0F, 0xB7);
9185  ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9186  ins_pipe(ialu_reg);
9187%}
9188
9189// And Register with Immediate
9190instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9191%{
9192  match(Set dst (AndL dst src));
9193  effect(KILL cr);
9194
9195  format %{ "andq    $dst, $src\t# long" %}
9196  opcode(0x81, 0x04); /* Opcode 81 /4 */
9197  ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9198  ins_pipe(ialu_reg);
9199%}
9200
9201// And Register with Memory
9202instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9203%{
9204  match(Set dst (AndL dst (LoadL src)));
9205  effect(KILL cr);
9206
9207  ins_cost(125);
9208  format %{ "andq    $dst, $src\t# long" %}
9209  opcode(0x23);
9210  ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9211  ins_pipe(ialu_reg_mem);
9212%}
9213
9214// And Memory with Register
9215instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9216%{
9217  match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9218  effect(KILL cr);
9219
9220  ins_cost(150);
9221  format %{ "andq    $dst, $src\t# long" %}
9222  opcode(0x21); /* Opcode 21 /r */
9223  ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9224  ins_pipe(ialu_mem_reg);
9225%}
9226
9227// And Memory with Immediate
9228instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9229%{
9230  match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9231  effect(KILL cr);
9232
9233  ins_cost(125);
9234  format %{ "andq    $dst, $src\t# long" %}
9235  opcode(0x81, 0x4); /* Opcode 81 /4 id */
9236  ins_encode(REX_mem_wide(dst), OpcSE(src),
9237             RM_opc_mem(secondary, dst), Con8or32(src));
9238  ins_pipe(ialu_mem_imm);
9239%}
9240
9241// Or Instructions
9242// Or Register with Register
9243instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9244%{
9245  match(Set dst (OrL dst src));
9246  effect(KILL cr);
9247
9248  format %{ "orq     $dst, $src\t# long" %}
9249  opcode(0x0B);
9250  ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9251  ins_pipe(ialu_reg_reg);
9252%}
9253
9254// Use any_RegP to match R15 (TLS register) without spilling.
9255instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
9256  match(Set dst (OrL dst (CastP2X src)));
9257  effect(KILL cr);
9258
9259  format %{ "orq     $dst, $src\t# long" %}
9260  opcode(0x0B);
9261  ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9262  ins_pipe(ialu_reg_reg);
9263%}
9264
9265
9266// Or Register with Immediate
9267instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9268%{
9269  match(Set dst (OrL dst src));
9270  effect(KILL cr);
9271
9272  format %{ "orq     $dst, $src\t# long" %}
9273  opcode(0x81, 0x01); /* Opcode 81 /1 id */
9274  ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9275  ins_pipe(ialu_reg);
9276%}
9277
9278// Or Register with Memory
9279instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9280%{
9281  match(Set dst (OrL dst (LoadL src)));
9282  effect(KILL cr);
9283
9284  ins_cost(125);
9285  format %{ "orq     $dst, $src\t# long" %}
9286  opcode(0x0B);
9287  ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9288  ins_pipe(ialu_reg_mem);
9289%}
9290
9291// Or Memory with Register
9292instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9293%{
9294  match(Set dst (StoreL dst (OrL (LoadL dst) src)));
9295  effect(KILL cr);
9296
9297  ins_cost(150);
9298  format %{ "orq     $dst, $src\t# long" %}
9299  opcode(0x09); /* Opcode 09 /r */
9300  ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9301  ins_pipe(ialu_mem_reg);
9302%}
9303
9304// Or Memory with Immediate
9305instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9306%{
9307  match(Set dst (StoreL dst (OrL (LoadL dst) src)));
9308  effect(KILL cr);
9309
9310  ins_cost(125);
9311  format %{ "orq     $dst, $src\t# long" %}
9312  opcode(0x81, 0x1); /* Opcode 81 /1 id */
9313  ins_encode(REX_mem_wide(dst), OpcSE(src),
9314             RM_opc_mem(secondary, dst), Con8or32(src));
9315  ins_pipe(ialu_mem_imm);
9316%}
9317
9318// Xor Instructions
9319// Xor Register with Register
9320instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9321%{
9322  match(Set dst (XorL dst src));
9323  effect(KILL cr);
9324
9325  format %{ "xorq    $dst, $src\t# long" %}
9326  opcode(0x33);
9327  ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9328  ins_pipe(ialu_reg_reg);
9329%}
9330
9331// Xor Register with Immediate -1
9332instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
9333  match(Set dst (XorL dst imm));
9334
9335  format %{ "notq   $dst" %}
9336  ins_encode %{
9337     __ notq($dst$$Register);
9338  %}
9339  ins_pipe(ialu_reg);
9340%}
9341
9342// Xor Register with Immediate
9343instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9344%{
9345  match(Set dst (XorL dst src));
9346  effect(KILL cr);
9347
9348  format %{ "xorq    $dst, $src\t# long" %}
9349  opcode(0x81, 0x06); /* Opcode 81 /6 id */
9350  ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9351  ins_pipe(ialu_reg);
9352%}
9353
9354// Xor Register with Memory
9355instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9356%{
9357  match(Set dst (XorL dst (LoadL src)));
9358  effect(KILL cr);
9359
9360  ins_cost(125);
9361  format %{ "xorq    $dst, $src\t# long" %}
9362  opcode(0x33);
9363  ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9364  ins_pipe(ialu_reg_mem);
9365%}
9366
9367// Xor Memory with Register
9368instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9369%{
9370  match(Set dst (StoreL dst (XorL (LoadL dst) src)));
9371  effect(KILL cr);
9372
9373  ins_cost(150);
9374  format %{ "xorq    $dst, $src\t# long" %}
9375  opcode(0x31); /* Opcode 31 /r */
9376  ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9377  ins_pipe(ialu_mem_reg);
9378%}
9379
9380// Xor Memory with Immediate
9381instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9382%{
9383  match(Set dst (StoreL dst (XorL (LoadL dst) src)));
9384  effect(KILL cr);
9385
9386  ins_cost(125);
9387  format %{ "xorq    $dst, $src\t# long" %}
9388  opcode(0x81, 0x6); /* Opcode 81 /6 id */
9389  ins_encode(REX_mem_wide(dst), OpcSE(src),
9390             RM_opc_mem(secondary, dst), Con8or32(src));
9391  ins_pipe(ialu_mem_imm);
9392%}
9393
9394// Convert Int to Boolean
9395instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr)
9396%{
9397  match(Set dst (Conv2B src));
9398  effect(KILL cr);
9399
9400  format %{ "testl   $src, $src\t# ci2b\n\t"
9401            "setnz   $dst\n\t"
9402            "movzbl  $dst, $dst" %}
9403  ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl
9404             setNZ_reg(dst),
9405             REX_reg_breg(dst, dst), // movzbl
9406             Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
9407  ins_pipe(pipe_slow); // XXX
9408%}
9409
9410// Convert Pointer to Boolean
9411instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr)
9412%{
9413  match(Set dst (Conv2B src));
9414  effect(KILL cr);
9415
9416  format %{ "testq   $src, $src\t# cp2b\n\t"
9417            "setnz   $dst\n\t"
9418            "movzbl  $dst, $dst" %}
9419  ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq
9420             setNZ_reg(dst),
9421             REX_reg_breg(dst, dst), // movzbl
9422             Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
9423  ins_pipe(pipe_slow); // XXX
9424%}
9425
9426instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr)
9427%{
9428  match(Set dst (CmpLTMask p q));
9429  effect(KILL cr);
9430
9431  ins_cost(400); // XXX
9432  format %{ "cmpl    $p, $q\t# cmpLTMask\n\t"
9433            "setlt   $dst\n\t"
9434            "movzbl  $dst, $dst\n\t"
9435            "negl    $dst" %}
9436  ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl
9437             setLT_reg(dst),
9438             REX_reg_breg(dst, dst), // movzbl
9439             Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst),
9440             neg_reg(dst));
9441  ins_pipe(pipe_slow);
9442%}
9443
9444instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr)
9445%{
9446  match(Set dst (CmpLTMask dst zero));
9447  effect(KILL cr);
9448
9449  ins_cost(100); // XXX
9450  format %{ "sarl    $dst, #31\t# cmpLTMask0" %}
9451  opcode(0xC1, 0x7);  /* C1 /7 ib */
9452  ins_encode(reg_opc_imm(dst, 0x1F));
9453  ins_pipe(ialu_reg);
9454%}
9455
9456
9457instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr)
9458%{
9459  match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
9460  effect(TEMP tmp, KILL cr);
9461
9462  ins_cost(400); // XXX
9463  format %{ "subl    $p, $q\t# cadd_cmpLTMask1\n\t"
9464            "sbbl    $tmp, $tmp\n\t"
9465            "andl    $tmp, $y\n\t"
9466            "addl    $p, $tmp" %}
9467  ins_encode %{
9468    Register Rp = $p$$Register;
9469    Register Rq = $q$$Register;
9470    Register Ry = $y$$Register;
9471    Register Rt = $tmp$$Register;
9472    __ subl(Rp, Rq);
9473    __ sbbl(Rt, Rt);
9474    __ andl(Rt, Ry);
9475    __ addl(Rp, Rt);
9476  %}
9477  ins_pipe(pipe_cmplt);
9478%}
9479
9480//---------- FP Instructions------------------------------------------------
9481
9482instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
9483%{
9484  match(Set cr (CmpF src1 src2));
9485
9486  ins_cost(145);
9487  format %{ "ucomiss $src1, $src2\n\t"
9488            "jnp,s   exit\n\t"
9489            "pushfq\t# saw NaN, set CF\n\t"
9490            "andq    [rsp], #0xffffff2b\n\t"
9491            "popfq\n"
9492    "exit:" %}
9493  ins_encode %{
9494    __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9495    emit_cmpfp_fixup(_masm);
9496  %}
9497  ins_pipe(pipe_slow);
9498%}
9499
9500instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
9501  match(Set cr (CmpF src1 src2));
9502
9503  ins_cost(100);
9504  format %{ "ucomiss $src1, $src2" %}
9505  ins_encode %{
9506    __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9507  %}
9508  ins_pipe(pipe_slow);
9509%}
9510
9511instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
9512%{
9513  match(Set cr (CmpF src1 (LoadF src2)));
9514
9515  ins_cost(145);
9516  format %{ "ucomiss $src1, $src2\n\t"
9517            "jnp,s   exit\n\t"
9518            "pushfq\t# saw NaN, set CF\n\t"
9519            "andq    [rsp], #0xffffff2b\n\t"
9520            "popfq\n"
9521    "exit:" %}
9522  ins_encode %{
9523    __ ucomiss($src1$$XMMRegister, $src2$$Address);
9524    emit_cmpfp_fixup(_masm);
9525  %}
9526  ins_pipe(pipe_slow);
9527%}
9528
9529instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
9530  match(Set cr (CmpF src1 (LoadF src2)));
9531
9532  ins_cost(100);
9533  format %{ "ucomiss $src1, $src2" %}
9534  ins_encode %{
9535    __ ucomiss($src1$$XMMRegister, $src2$$Address);
9536  %}
9537  ins_pipe(pipe_slow);
9538%}
9539
9540instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
9541  match(Set cr (CmpF src con));
9542
9543  ins_cost(145);
9544  format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
9545            "jnp,s   exit\n\t"
9546            "pushfq\t# saw NaN, set CF\n\t"
9547            "andq    [rsp], #0xffffff2b\n\t"
9548            "popfq\n"
9549    "exit:" %}
9550  ins_encode %{
9551    __ ucomiss($src$$XMMRegister, $constantaddress($con));
9552    emit_cmpfp_fixup(_masm);
9553  %}
9554  ins_pipe(pipe_slow);
9555%}
9556
9557instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
9558  match(Set cr (CmpF src con));
9559  ins_cost(100);
9560  format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
9561  ins_encode %{
9562    __ ucomiss($src$$XMMRegister, $constantaddress($con));
9563  %}
9564  ins_pipe(pipe_slow);
9565%}
9566
9567instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
9568%{
9569  match(Set cr (CmpD src1 src2));
9570
9571  ins_cost(145);
9572  format %{ "ucomisd $src1, $src2\n\t"
9573            "jnp,s   exit\n\t"
9574            "pushfq\t# saw NaN, set CF\n\t"
9575            "andq    [rsp], #0xffffff2b\n\t"
9576            "popfq\n"
9577    "exit:" %}
9578  ins_encode %{
9579    __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9580    emit_cmpfp_fixup(_masm);
9581  %}
9582  ins_pipe(pipe_slow);
9583%}
9584
9585instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
9586  match(Set cr (CmpD src1 src2));
9587
9588  ins_cost(100);
9589  format %{ "ucomisd $src1, $src2 test" %}
9590  ins_encode %{
9591    __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9592  %}
9593  ins_pipe(pipe_slow);
9594%}
9595
9596instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
9597%{
9598  match(Set cr (CmpD src1 (LoadD src2)));
9599
9600  ins_cost(145);
9601  format %{ "ucomisd $src1, $src2\n\t"
9602            "jnp,s   exit\n\t"
9603            "pushfq\t# saw NaN, set CF\n\t"
9604            "andq    [rsp], #0xffffff2b\n\t"
9605            "popfq\n"
9606    "exit:" %}
9607  ins_encode %{
9608    __ ucomisd($src1$$XMMRegister, $src2$$Address);
9609    emit_cmpfp_fixup(_masm);
9610  %}
9611  ins_pipe(pipe_slow);
9612%}
9613
9614instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
9615  match(Set cr (CmpD src1 (LoadD src2)));
9616
9617  ins_cost(100);
9618  format %{ "ucomisd $src1, $src2" %}
9619  ins_encode %{
9620    __ ucomisd($src1$$XMMRegister, $src2$$Address);
9621  %}
9622  ins_pipe(pipe_slow);
9623%}
9624
9625instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
9626  match(Set cr (CmpD src con));
9627
9628  ins_cost(145);
9629  format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
9630            "jnp,s   exit\n\t"
9631            "pushfq\t# saw NaN, set CF\n\t"
9632            "andq    [rsp], #0xffffff2b\n\t"
9633            "popfq\n"
9634    "exit:" %}
9635  ins_encode %{
9636    __ ucomisd($src$$XMMRegister, $constantaddress($con));
9637    emit_cmpfp_fixup(_masm);
9638  %}
9639  ins_pipe(pipe_slow);
9640%}
9641
9642instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
9643  match(Set cr (CmpD src con));
9644  ins_cost(100);
9645  format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
9646  ins_encode %{
9647    __ ucomisd($src$$XMMRegister, $constantaddress($con));
9648  %}
9649  ins_pipe(pipe_slow);
9650%}
9651
9652// Compare into -1,0,1
9653instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
9654%{
9655  match(Set dst (CmpF3 src1 src2));
9656  effect(KILL cr);
9657
9658  ins_cost(275);
9659  format %{ "ucomiss $src1, $src2\n\t"
9660            "movl    $dst, #-1\n\t"
9661            "jp,s    done\n\t"
9662            "jb,s    done\n\t"
9663            "setne   $dst\n\t"
9664            "movzbl  $dst, $dst\n"
9665    "done:" %}
9666  ins_encode %{
9667    __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9668    emit_cmpfp3(_masm, $dst$$Register);
9669  %}
9670  ins_pipe(pipe_slow);
9671%}
9672
9673// Compare into -1,0,1
9674instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
9675%{
9676  match(Set dst (CmpF3 src1 (LoadF src2)));
9677  effect(KILL cr);
9678
9679  ins_cost(275);
9680  format %{ "ucomiss $src1, $src2\n\t"
9681            "movl    $dst, #-1\n\t"
9682            "jp,s    done\n\t"
9683            "jb,s    done\n\t"
9684            "setne   $dst\n\t"
9685            "movzbl  $dst, $dst\n"
9686    "done:" %}
9687  ins_encode %{
9688    __ ucomiss($src1$$XMMRegister, $src2$$Address);
9689    emit_cmpfp3(_masm, $dst$$Register);
9690  %}
9691  ins_pipe(pipe_slow);
9692%}
9693
9694// Compare into -1,0,1
9695instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
9696  match(Set dst (CmpF3 src con));
9697  effect(KILL cr);
9698
9699  ins_cost(275);
9700  format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
9701            "movl    $dst, #-1\n\t"
9702            "jp,s    done\n\t"
9703            "jb,s    done\n\t"
9704            "setne   $dst\n\t"
9705            "movzbl  $dst, $dst\n"
9706    "done:" %}
9707  ins_encode %{
9708    __ ucomiss($src$$XMMRegister, $constantaddress($con));
9709    emit_cmpfp3(_masm, $dst$$Register);
9710  %}
9711  ins_pipe(pipe_slow);
9712%}
9713
9714// Compare into -1,0,1
9715instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
9716%{
9717  match(Set dst (CmpD3 src1 src2));
9718  effect(KILL cr);
9719
9720  ins_cost(275);
9721  format %{ "ucomisd $src1, $src2\n\t"
9722            "movl    $dst, #-1\n\t"
9723            "jp,s    done\n\t"
9724            "jb,s    done\n\t"
9725            "setne   $dst\n\t"
9726            "movzbl  $dst, $dst\n"
9727    "done:" %}
9728  ins_encode %{
9729    __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9730    emit_cmpfp3(_masm, $dst$$Register);
9731  %}
9732  ins_pipe(pipe_slow);
9733%}
9734
9735// Compare into -1,0,1
9736instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
9737%{
9738  match(Set dst (CmpD3 src1 (LoadD src2)));
9739  effect(KILL cr);
9740
9741  ins_cost(275);
9742  format %{ "ucomisd $src1, $src2\n\t"
9743            "movl    $dst, #-1\n\t"
9744            "jp,s    done\n\t"
9745            "jb,s    done\n\t"
9746            "setne   $dst\n\t"
9747            "movzbl  $dst, $dst\n"
9748    "done:" %}
9749  ins_encode %{
9750    __ ucomisd($src1$$XMMRegister, $src2$$Address);
9751    emit_cmpfp3(_masm, $dst$$Register);
9752  %}
9753  ins_pipe(pipe_slow);
9754%}
9755
9756// Compare into -1,0,1
9757instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
9758  match(Set dst (CmpD3 src con));
9759  effect(KILL cr);
9760
9761  ins_cost(275);
9762  format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
9763            "movl    $dst, #-1\n\t"
9764            "jp,s    done\n\t"
9765            "jb,s    done\n\t"
9766            "setne   $dst\n\t"
9767            "movzbl  $dst, $dst\n"
9768    "done:" %}
9769  ins_encode %{
9770    __ ucomisd($src$$XMMRegister, $constantaddress($con));
9771    emit_cmpfp3(_masm, $dst$$Register);
9772  %}
9773  ins_pipe(pipe_slow);
9774%}
9775
9776// -----------Trig and Trancendental Instructions------------------------------
9777instruct cosD_reg(regD dst) %{
9778  match(Set dst (CosD dst));
9779
9780  format %{ "dcos   $dst\n\t" %}
9781  opcode(0xD9, 0xFF);
9782  ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
9783  ins_pipe( pipe_slow );
9784%}
9785
9786instruct sinD_reg(regD dst) %{
9787  match(Set dst (SinD dst));
9788
9789  format %{ "dsin   $dst\n\t" %}
9790  opcode(0xD9, 0xFE);
9791  ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
9792  ins_pipe( pipe_slow );
9793%}
9794
9795instruct tanD_reg(regD dst) %{
9796  match(Set dst (TanD dst));
9797
9798  format %{ "dtan   $dst\n\t" %}
9799  ins_encode( Push_SrcXD(dst),
9800              Opcode(0xD9), Opcode(0xF2),   //fptan
9801              Opcode(0xDD), Opcode(0xD8),   //fstp st
9802              Push_ResultXD(dst) );
9803  ins_pipe( pipe_slow );
9804%}
9805
9806instruct log10D_reg(regD dst) %{
9807  // The source and result Double operands in XMM registers
9808  match(Set dst (Log10D dst));
9809  // fldlg2       ; push log_10(2) on the FPU stack; full 80-bit number
9810  // fyl2x        ; compute log_10(2) * log_2(x)
9811  format %{ "fldlg2\t\t\t#Log10\n\t"
9812            "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t"
9813         %}
9814   ins_encode(Opcode(0xD9), Opcode(0xEC),   // fldlg2
9815              Push_SrcXD(dst),
9816              Opcode(0xD9), Opcode(0xF1),   // fyl2x
9817              Push_ResultXD(dst));
9818
9819  ins_pipe( pipe_slow );
9820%}
9821
9822instruct logD_reg(regD dst) %{
9823  // The source and result Double operands in XMM registers
9824  match(Set dst (LogD dst));
9825  // fldln2       ; push log_e(2) on the FPU stack; full 80-bit number
9826  // fyl2x        ; compute log_e(2) * log_2(x)
9827  format %{ "fldln2\t\t\t#Log_e\n\t"
9828            "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t"
9829         %}
9830  ins_encode( Opcode(0xD9), Opcode(0xED),   // fldln2
9831              Push_SrcXD(dst),
9832              Opcode(0xD9), Opcode(0xF1),   // fyl2x
9833              Push_ResultXD(dst));
9834  ins_pipe( pipe_slow );
9835%}
9836
9837
9838
9839//----------Arithmetic Conversion Instructions---------------------------------
9840
9841instruct roundFloat_nop(regF dst)
9842%{
9843  match(Set dst (RoundFloat dst));
9844
9845  ins_cost(0);
9846  ins_encode();
9847  ins_pipe(empty);
9848%}
9849
9850instruct roundDouble_nop(regD dst)
9851%{
9852  match(Set dst (RoundDouble dst));
9853
9854  ins_cost(0);
9855  ins_encode();
9856  ins_pipe(empty);
9857%}
9858
9859instruct convF2D_reg_reg(regD dst, regF src)
9860%{
9861  match(Set dst (ConvF2D src));
9862
9863  format %{ "cvtss2sd $dst, $src" %}
9864  ins_encode %{
9865    __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister);
9866  %}
9867  ins_pipe(pipe_slow); // XXX
9868%}
9869
9870instruct convF2D_reg_mem(regD dst, memory src)
9871%{
9872  match(Set dst (ConvF2D (LoadF src)));
9873
9874  format %{ "cvtss2sd $dst, $src" %}
9875  ins_encode %{
9876    __ cvtss2sd ($dst$$XMMRegister, $src$$Address);
9877  %}
9878  ins_pipe(pipe_slow); // XXX
9879%}
9880
9881instruct convD2F_reg_reg(regF dst, regD src)
9882%{
9883  match(Set dst (ConvD2F src));
9884
9885  format %{ "cvtsd2ss $dst, $src" %}
9886  ins_encode %{
9887    __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister);
9888  %}
9889  ins_pipe(pipe_slow); // XXX
9890%}
9891
9892instruct convD2F_reg_mem(regF dst, memory src)
9893%{
9894  match(Set dst (ConvD2F (LoadD src)));
9895
9896  format %{ "cvtsd2ss $dst, $src" %}
9897  ins_encode %{
9898    __ cvtsd2ss ($dst$$XMMRegister, $src$$Address);
9899  %}
9900  ins_pipe(pipe_slow); // XXX
9901%}
9902
9903// XXX do mem variants
9904instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
9905%{
9906  match(Set dst (ConvF2I src));
9907  effect(KILL cr);
9908
9909  format %{ "cvttss2sil $dst, $src\t# f2i\n\t"
9910            "cmpl    $dst, #0x80000000\n\t"
9911            "jne,s   done\n\t"
9912            "subq    rsp, #8\n\t"
9913            "movss   [rsp], $src\n\t"
9914            "call    f2i_fixup\n\t"
9915            "popq    $dst\n"
9916    "done:   "%}
9917  ins_encode %{
9918    Label done;
9919    __ cvttss2sil($dst$$Register, $src$$XMMRegister);
9920    __ cmpl($dst$$Register, 0x80000000);
9921    __ jccb(Assembler::notEqual, done);
9922    __ subptr(rsp, 8);
9923    __ movflt(Address(rsp, 0), $src$$XMMRegister);
9924    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup())));
9925    __ pop($dst$$Register);
9926    __ bind(done);
9927  %}
9928  ins_pipe(pipe_slow);
9929%}
9930
9931instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
9932%{
9933  match(Set dst (ConvF2L src));
9934  effect(KILL cr);
9935
9936  format %{ "cvttss2siq $dst, $src\t# f2l\n\t"
9937            "cmpq    $dst, [0x8000000000000000]\n\t"
9938            "jne,s   done\n\t"
9939            "subq    rsp, #8\n\t"
9940            "movss   [rsp], $src\n\t"
9941            "call    f2l_fixup\n\t"
9942            "popq    $dst\n"
9943    "done:   "%}
9944  ins_encode %{
9945    Label done;
9946    __ cvttss2siq($dst$$Register, $src$$XMMRegister);
9947    __ cmp64($dst$$Register,
9948             ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
9949    __ jccb(Assembler::notEqual, done);
9950    __ subptr(rsp, 8);
9951    __ movflt(Address(rsp, 0), $src$$XMMRegister);
9952    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup())));
9953    __ pop($dst$$Register);
9954    __ bind(done);
9955  %}
9956  ins_pipe(pipe_slow);
9957%}
9958
9959instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
9960%{
9961  match(Set dst (ConvD2I src));
9962  effect(KILL cr);
9963
9964  format %{ "cvttsd2sil $dst, $src\t# d2i\n\t"
9965            "cmpl    $dst, #0x80000000\n\t"
9966            "jne,s   done\n\t"
9967            "subq    rsp, #8\n\t"
9968            "movsd   [rsp], $src\n\t"
9969            "call    d2i_fixup\n\t"
9970            "popq    $dst\n"
9971    "done:   "%}
9972  ins_encode %{
9973    Label done;
9974    __ cvttsd2sil($dst$$Register, $src$$XMMRegister);
9975    __ cmpl($dst$$Register, 0x80000000);
9976    __ jccb(Assembler::notEqual, done);
9977    __ subptr(rsp, 8);
9978    __ movdbl(Address(rsp, 0), $src$$XMMRegister);
9979    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup())));
9980    __ pop($dst$$Register);
9981    __ bind(done);
9982  %}
9983  ins_pipe(pipe_slow);
9984%}
9985
9986instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
9987%{
9988  match(Set dst (ConvD2L src));
9989  effect(KILL cr);
9990
9991  format %{ "cvttsd2siq $dst, $src\t# d2l\n\t"
9992            "cmpq    $dst, [0x8000000000000000]\n\t"
9993            "jne,s   done\n\t"
9994            "subq    rsp, #8\n\t"
9995            "movsd   [rsp], $src\n\t"
9996            "call    d2l_fixup\n\t"
9997            "popq    $dst\n"
9998    "done:   "%}
9999  ins_encode %{
10000    Label done;
10001    __ cvttsd2siq($dst$$Register, $src$$XMMRegister);
10002    __ cmp64($dst$$Register,
10003             ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
10004    __ jccb(Assembler::notEqual, done);
10005    __ subptr(rsp, 8);
10006    __ movdbl(Address(rsp, 0), $src$$XMMRegister);
10007    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup())));
10008    __ pop($dst$$Register);
10009    __ bind(done);
10010  %}
10011  ins_pipe(pipe_slow);
10012%}
10013
10014instruct convI2F_reg_reg(regF dst, rRegI src)
10015%{
10016  predicate(!UseXmmI2F);
10017  match(Set dst (ConvI2F src));
10018
10019  format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10020  ins_encode %{
10021    __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
10022  %}
10023  ins_pipe(pipe_slow); // XXX
10024%}
10025
10026instruct convI2F_reg_mem(regF dst, memory src)
10027%{
10028  match(Set dst (ConvI2F (LoadI src)));
10029
10030  format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10031  ins_encode %{
10032    __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address);
10033  %}
10034  ins_pipe(pipe_slow); // XXX
10035%}
10036
10037instruct convI2D_reg_reg(regD dst, rRegI src)
10038%{
10039  predicate(!UseXmmI2D);
10040  match(Set dst (ConvI2D src));
10041
10042  format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10043  ins_encode %{
10044    __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
10045  %}
10046  ins_pipe(pipe_slow); // XXX
10047%}
10048
10049instruct convI2D_reg_mem(regD dst, memory src)
10050%{
10051  match(Set dst (ConvI2D (LoadI src)));
10052
10053  format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10054  ins_encode %{
10055    __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address);
10056  %}
10057  ins_pipe(pipe_slow); // XXX
10058%}
10059
10060instruct convXI2F_reg(regF dst, rRegI src)
10061%{
10062  predicate(UseXmmI2F);
10063  match(Set dst (ConvI2F src));
10064
10065  format %{ "movdl $dst, $src\n\t"
10066            "cvtdq2psl $dst, $dst\t# i2f" %}
10067  ins_encode %{
10068    __ movdl($dst$$XMMRegister, $src$$Register);
10069    __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
10070  %}
10071  ins_pipe(pipe_slow); // XXX
10072%}
10073
10074instruct convXI2D_reg(regD dst, rRegI src)
10075%{
10076  predicate(UseXmmI2D);
10077  match(Set dst (ConvI2D src));
10078
10079  format %{ "movdl $dst, $src\n\t"
10080            "cvtdq2pdl $dst, $dst\t# i2d" %}
10081  ins_encode %{
10082    __ movdl($dst$$XMMRegister, $src$$Register);
10083    __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
10084  %}
10085  ins_pipe(pipe_slow); // XXX
10086%}
10087
10088instruct convL2F_reg_reg(regF dst, rRegL src)
10089%{
10090  match(Set dst (ConvL2F src));
10091
10092  format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10093  ins_encode %{
10094    __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register);
10095  %}
10096  ins_pipe(pipe_slow); // XXX
10097%}
10098
10099instruct convL2F_reg_mem(regF dst, memory src)
10100%{
10101  match(Set dst (ConvL2F (LoadL src)));
10102
10103  format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10104  ins_encode %{
10105    __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address);
10106  %}
10107  ins_pipe(pipe_slow); // XXX
10108%}
10109
10110instruct convL2D_reg_reg(regD dst, rRegL src)
10111%{
10112  match(Set dst (ConvL2D src));
10113
10114  format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10115  ins_encode %{
10116    __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register);
10117  %}
10118  ins_pipe(pipe_slow); // XXX
10119%}
10120
10121instruct convL2D_reg_mem(regD dst, memory src)
10122%{
10123  match(Set dst (ConvL2D (LoadL src)));
10124
10125  format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10126  ins_encode %{
10127    __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address);
10128  %}
10129  ins_pipe(pipe_slow); // XXX
10130%}
10131
10132instruct convI2L_reg_reg(rRegL dst, rRegI src)
10133%{
10134  match(Set dst (ConvI2L src));
10135
10136  ins_cost(125);
10137  format %{ "movslq  $dst, $src\t# i2l" %}
10138  ins_encode %{
10139    __ movslq($dst$$Register, $src$$Register);
10140  %}
10141  ins_pipe(ialu_reg_reg);
10142%}
10143
10144// instruct convI2L_reg_reg_foo(rRegL dst, rRegI src)
10145// %{
10146//   match(Set dst (ConvI2L src));
10147// //   predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 &&
10148// //             _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0);
10149//   predicate(((const TypeNode*) n)->type()->is_long()->_hi ==
10150//             (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi &&
10151//             ((const TypeNode*) n)->type()->is_long()->_lo ==
10152//             (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo);
10153
10154//   format %{ "movl    $dst, $src\t# unsigned i2l" %}
10155//   ins_encode(enc_copy(dst, src));
10156// //   opcode(0x63); // needs REX.W
10157// //   ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
10158//   ins_pipe(ialu_reg_reg);
10159// %}
10160
10161// Zero-extend convert int to long
10162instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
10163%{
10164  match(Set dst (AndL (ConvI2L src) mask));
10165
10166  format %{ "movl    $dst, $src\t# i2l zero-extend\n\t" %}
10167  ins_encode %{
10168    if ($dst$$reg != $src$$reg) {
10169      __ movl($dst$$Register, $src$$Register);
10170    }
10171  %}
10172  ins_pipe(ialu_reg_reg);
10173%}
10174
10175// Zero-extend convert int to long
10176instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
10177%{
10178  match(Set dst (AndL (ConvI2L (LoadI src)) mask));
10179
10180  format %{ "movl    $dst, $src\t# i2l zero-extend\n\t" %}
10181  ins_encode %{
10182    __ movl($dst$$Register, $src$$Address);
10183  %}
10184  ins_pipe(ialu_reg_mem);
10185%}
10186
10187instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
10188%{
10189  match(Set dst (AndL src mask));
10190
10191  format %{ "movl    $dst, $src\t# zero-extend long" %}
10192  ins_encode %{
10193    __ movl($dst$$Register, $src$$Register);
10194  %}
10195  ins_pipe(ialu_reg_reg);
10196%}
10197
10198instruct convL2I_reg_reg(rRegI dst, rRegL src)
10199%{
10200  match(Set dst (ConvL2I src));
10201
10202  format %{ "movl    $dst, $src\t# l2i" %}
10203  ins_encode %{
10204    __ movl($dst$$Register, $src$$Register);
10205  %}
10206  ins_pipe(ialu_reg_reg);
10207%}
10208
10209
10210instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
10211  match(Set dst (MoveF2I src));
10212  effect(DEF dst, USE src);
10213
10214  ins_cost(125);
10215  format %{ "movl    $dst, $src\t# MoveF2I_stack_reg" %}
10216  ins_encode %{
10217    __ movl($dst$$Register, Address(rsp, $src$$disp));
10218  %}
10219  ins_pipe(ialu_reg_mem);
10220%}
10221
10222instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
10223  match(Set dst (MoveI2F src));
10224  effect(DEF dst, USE src);
10225
10226  ins_cost(125);
10227  format %{ "movss   $dst, $src\t# MoveI2F_stack_reg" %}
10228  ins_encode %{
10229    __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
10230  %}
10231  ins_pipe(pipe_slow);
10232%}
10233
10234instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
10235  match(Set dst (MoveD2L src));
10236  effect(DEF dst, USE src);
10237
10238  ins_cost(125);
10239  format %{ "movq    $dst, $src\t# MoveD2L_stack_reg" %}
10240  ins_encode %{
10241    __ movq($dst$$Register, Address(rsp, $src$$disp));
10242  %}
10243  ins_pipe(ialu_reg_mem);
10244%}
10245
10246instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
10247  predicate(!UseXmmLoadAndClearUpper);
10248  match(Set dst (MoveL2D src));
10249  effect(DEF dst, USE src);
10250
10251  ins_cost(125);
10252  format %{ "movlpd  $dst, $src\t# MoveL2D_stack_reg" %}
10253  ins_encode %{
10254    __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10255  %}
10256  ins_pipe(pipe_slow);
10257%}
10258
10259instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
10260  predicate(UseXmmLoadAndClearUpper);
10261  match(Set dst (MoveL2D src));
10262  effect(DEF dst, USE src);
10263
10264  ins_cost(125);
10265  format %{ "movsd   $dst, $src\t# MoveL2D_stack_reg" %}
10266  ins_encode %{
10267    __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10268  %}
10269  ins_pipe(pipe_slow);
10270%}
10271
10272
10273instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
10274  match(Set dst (MoveF2I src));
10275  effect(DEF dst, USE src);
10276
10277  ins_cost(95); // XXX
10278  format %{ "movss   $dst, $src\t# MoveF2I_reg_stack" %}
10279  ins_encode %{
10280    __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
10281  %}
10282  ins_pipe(pipe_slow);
10283%}
10284
10285instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
10286  match(Set dst (MoveI2F src));
10287  effect(DEF dst, USE src);
10288
10289  ins_cost(100);
10290  format %{ "movl    $dst, $src\t# MoveI2F_reg_stack" %}
10291  ins_encode %{
10292    __ movl(Address(rsp, $dst$$disp), $src$$Register);
10293  %}
10294  ins_pipe( ialu_mem_reg );
10295%}
10296
10297instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
10298  match(Set dst (MoveD2L src));
10299  effect(DEF dst, USE src);
10300
10301  ins_cost(95); // XXX
10302  format %{ "movsd   $dst, $src\t# MoveL2D_reg_stack" %}
10303  ins_encode %{
10304    __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
10305  %}
10306  ins_pipe(pipe_slow);
10307%}
10308
10309instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
10310  match(Set dst (MoveL2D src));
10311  effect(DEF dst, USE src);
10312
10313  ins_cost(100);
10314  format %{ "movq    $dst, $src\t# MoveL2D_reg_stack" %}
10315  ins_encode %{
10316    __ movq(Address(rsp, $dst$$disp), $src$$Register);
10317  %}
10318  ins_pipe(ialu_mem_reg);
10319%}
10320
10321instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
10322  match(Set dst (MoveF2I src));
10323  effect(DEF dst, USE src);
10324  ins_cost(85);
10325  format %{ "movd    $dst,$src\t# MoveF2I" %}
10326  ins_encode %{
10327    __ movdl($dst$$Register, $src$$XMMRegister);
10328  %}
10329  ins_pipe( pipe_slow );
10330%}
10331
10332instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
10333  match(Set dst (MoveD2L src));
10334  effect(DEF dst, USE src);
10335  ins_cost(85);
10336  format %{ "movd    $dst,$src\t# MoveD2L" %}
10337  ins_encode %{
10338    __ movdq($dst$$Register, $src$$XMMRegister);
10339  %}
10340  ins_pipe( pipe_slow );
10341%}
10342
10343// The next instructions have long latency and use Int unit. Set high cost.
10344instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
10345  match(Set dst (MoveI2F src));
10346  effect(DEF dst, USE src);
10347  ins_cost(300);
10348  format %{ "movd    $dst,$src\t# MoveI2F" %}
10349  ins_encode %{
10350    __ movdl($dst$$XMMRegister, $src$$Register);
10351  %}
10352  ins_pipe( pipe_slow );
10353%}
10354
10355instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
10356  match(Set dst (MoveL2D src));
10357  effect(DEF dst, USE src);
10358  ins_cost(300);
10359  format %{ "movd    $dst,$src\t# MoveL2D" %}
10360  ins_encode %{
10361     __ movdq($dst$$XMMRegister, $src$$Register);
10362  %}
10363  ins_pipe( pipe_slow );
10364%}
10365
10366// Replicate scalar to packed byte (1 byte) values in xmm
10367instruct Repl8B_reg(regD dst, regD src) %{
10368  match(Set dst (Replicate8B src));
10369  format %{ "MOVDQA  $dst,$src\n\t"
10370            "PUNPCKLBW $dst,$dst\n\t"
10371            "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
10372  ins_encode %{
10373    if ($dst$$reg != $src$$reg) {
10374      __ movdqa($dst$$XMMRegister, $src$$XMMRegister);
10375    }
10376    __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
10377    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10378  %}
10379  ins_pipe( pipe_slow );
10380%}
10381
10382// Replicate scalar to packed byte (1 byte) values in xmm
10383instruct Repl8B_rRegI(regD dst, rRegI src) %{
10384  match(Set dst (Replicate8B src));
10385  format %{ "MOVD    $dst,$src\n\t"
10386            "PUNPCKLBW $dst,$dst\n\t"
10387            "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
10388  ins_encode %{
10389    __ movdl($dst$$XMMRegister, $src$$Register);
10390    __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
10391    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10392  %}
10393  ins_pipe( pipe_slow );
10394%}
10395
10396// Replicate scalar zero to packed byte (1 byte) values in xmm
10397instruct Repl8B_immI0(regD dst, immI0 zero) %{
10398  match(Set dst (Replicate8B zero));
10399  format %{ "PXOR  $dst,$dst\t! replicate8B" %}
10400  ins_encode %{
10401    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10402  %}
10403  ins_pipe( fpu_reg_reg );
10404%}
10405
10406// Replicate scalar to packed shore (2 byte) values in xmm
10407instruct Repl4S_reg(regD dst, regD src) %{
10408  match(Set dst (Replicate4S src));
10409  format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
10410  ins_encode %{
10411    __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
10412  %}
10413  ins_pipe( fpu_reg_reg );
10414%}
10415
10416// Replicate scalar to packed shore (2 byte) values in xmm
10417instruct Repl4S_rRegI(regD dst, rRegI src) %{
10418  match(Set dst (Replicate4S src));
10419  format %{ "MOVD    $dst,$src\n\t"
10420            "PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
10421  ins_encode %{
10422    __ movdl($dst$$XMMRegister, $src$$Register);
10423    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10424  %}
10425  ins_pipe( fpu_reg_reg );
10426%}
10427
10428// Replicate scalar zero to packed short (2 byte) values in xmm
10429instruct Repl4S_immI0(regD dst, immI0 zero) %{
10430  match(Set dst (Replicate4S zero));
10431  format %{ "PXOR  $dst,$dst\t! replicate4S" %}
10432  ins_encode %{
10433    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10434  %}
10435  ins_pipe( fpu_reg_reg );
10436%}
10437
10438// Replicate scalar to packed char (2 byte) values in xmm
10439instruct Repl4C_reg(regD dst, regD src) %{
10440  match(Set dst (Replicate4C src));
10441  format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
10442  ins_encode %{
10443    __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
10444  %}
10445  ins_pipe( fpu_reg_reg );
10446%}
10447
10448// Replicate scalar to packed char (2 byte) values in xmm
10449instruct Repl4C_rRegI(regD dst, rRegI src) %{
10450  match(Set dst (Replicate4C src));
10451  format %{ "MOVD    $dst,$src\n\t"
10452            "PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
10453  ins_encode %{
10454    __ movdl($dst$$XMMRegister, $src$$Register);
10455    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10456  %}
10457  ins_pipe( fpu_reg_reg );
10458%}
10459
10460// Replicate scalar zero to packed char (2 byte) values in xmm
10461instruct Repl4C_immI0(regD dst, immI0 zero) %{
10462  match(Set dst (Replicate4C zero));
10463  format %{ "PXOR  $dst,$dst\t! replicate4C" %}
10464  ins_encode %{
10465    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10466  %}
10467  ins_pipe( fpu_reg_reg );
10468%}
10469
10470// Replicate scalar to packed integer (4 byte) values in xmm
10471instruct Repl2I_reg(regD dst, regD src) %{
10472  match(Set dst (Replicate2I src));
10473  format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
10474  ins_encode %{
10475    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
10476  %}
10477  ins_pipe( fpu_reg_reg );
10478%}
10479
10480// Replicate scalar to packed integer (4 byte) values in xmm
10481instruct Repl2I_rRegI(regD dst, rRegI src) %{
10482  match(Set dst (Replicate2I src));
10483  format %{ "MOVD   $dst,$src\n\t"
10484            "PSHUFD $dst,$dst,0x00\t! replicate2I" %}
10485  ins_encode %{
10486    __ movdl($dst$$XMMRegister, $src$$Register);
10487    __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
10488  %}
10489  ins_pipe( fpu_reg_reg );
10490%}
10491
10492// Replicate scalar zero to packed integer (2 byte) values in xmm
10493instruct Repl2I_immI0(regD dst, immI0 zero) %{
10494  match(Set dst (Replicate2I zero));
10495  format %{ "PXOR  $dst,$dst\t! replicate2I" %}
10496  ins_encode %{
10497    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10498  %}
10499  ins_pipe( fpu_reg_reg );
10500%}
10501
10502// Replicate scalar to packed single precision floating point values in xmm
10503instruct Repl2F_reg(regD dst, regD src) %{
10504  match(Set dst (Replicate2F src));
10505  format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
10506  ins_encode %{
10507    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
10508  %}
10509  ins_pipe( fpu_reg_reg );
10510%}
10511
10512// Replicate scalar to packed single precision floating point values in xmm
10513instruct Repl2F_regF(regD dst, regF src) %{
10514  match(Set dst (Replicate2F src));
10515  format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
10516  ins_encode %{
10517    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
10518  %}
10519  ins_pipe( fpu_reg_reg );
10520%}
10521
10522// Replicate scalar to packed single precision floating point values in xmm
10523instruct Repl2F_immF0(regD dst, immF0 zero) %{
10524  match(Set dst (Replicate2F zero));
10525  format %{ "PXOR  $dst,$dst\t! replicate2F" %}
10526  ins_encode %{
10527    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
10528  %}
10529  ins_pipe( fpu_reg_reg );
10530%}
10531
10532
10533// =======================================================================
10534// fast clearing of an array
10535instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10536                  rFlagsReg cr)
10537%{
10538  match(Set dummy (ClearArray cnt base));
10539  effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10540
10541  format %{ "xorl    rax, rax\t# ClearArray:\n\t"
10542            "rep stosq\t# Store rax to *rdi++ while rcx--" %}
10543  ins_encode(opc_reg_reg(0x33, RAX, RAX), // xorl %eax, %eax
10544             Opcode(0xF3), Opcode(0x48), Opcode(0xAB)); // rep REX_W stos
10545  ins_pipe(pipe_slow);
10546%}
10547
10548instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
10549                        rax_RegI result, regD tmp1, rFlagsReg cr)
10550%{
10551  match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
10552  effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
10553
10554  format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result   // KILL $tmp1" %}
10555  ins_encode %{
10556    __ string_compare($str1$$Register, $str2$$Register,
10557                      $cnt1$$Register, $cnt2$$Register, $result$$Register,
10558                      $tmp1$$XMMRegister);
10559  %}
10560  ins_pipe( pipe_slow );
10561%}
10562
10563// fast search of substring with known size.
10564instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
10565                            rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
10566%{
10567  predicate(UseSSE42Intrinsics);
10568  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
10569  effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
10570
10571  format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result   // KILL $vec, $cnt1, $cnt2, $tmp" %}
10572  ins_encode %{
10573    int icnt2 = (int)$int_cnt2$$constant;
10574    if (icnt2 >= 8) {
10575      // IndexOf for constant substrings with size >= 8 elements
10576      // which don't need to be loaded through stack.
10577      __ string_indexofC8($str1$$Register, $str2$$Register,
10578                          $cnt1$$Register, $cnt2$$Register,
10579                          icnt2, $result$$Register,
10580                          $vec$$XMMRegister, $tmp$$Register);
10581    } else {
10582      // Small strings are loaded through stack if they cross page boundary.
10583      __ string_indexof($str1$$Register, $str2$$Register,
10584                        $cnt1$$Register, $cnt2$$Register,
10585                        icnt2, $result$$Register,
10586                        $vec$$XMMRegister, $tmp$$Register);
10587    }
10588  %}
10589  ins_pipe( pipe_slow );
10590%}
10591
10592instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
10593                        rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
10594%{
10595  predicate(UseSSE42Intrinsics);
10596  match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
10597  effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
10598
10599  format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result   // KILL all" %}
10600  ins_encode %{
10601    __ string_indexof($str1$$Register, $str2$$Register,
10602                      $cnt1$$Register, $cnt2$$Register,
10603                      (-1), $result$$Register,
10604                      $vec$$XMMRegister, $tmp$$Register);
10605  %}
10606  ins_pipe( pipe_slow );
10607%}
10608
10609// fast string equals
10610instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
10611                       regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
10612%{
10613  match(Set result (StrEquals (Binary str1 str2) cnt));
10614  effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
10615
10616  format %{ "String Equals $str1,$str2,$cnt -> $result    // KILL $tmp1, $tmp2, $tmp3" %}
10617  ins_encode %{
10618    __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
10619                          $cnt$$Register, $result$$Register, $tmp3$$Register,
10620                          $tmp1$$XMMRegister, $tmp2$$XMMRegister);
10621  %}
10622  ins_pipe( pipe_slow );
10623%}
10624
10625// fast array equals
10626instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
10627                      regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
10628%{
10629  match(Set result (AryEq ary1 ary2));
10630  effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
10631  //ins_cost(300);
10632
10633  format %{ "Array Equals $ary1,$ary2 -> $result   // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
10634  ins_encode %{
10635    __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
10636                          $tmp3$$Register, $result$$Register, $tmp4$$Register,
10637                          $tmp1$$XMMRegister, $tmp2$$XMMRegister);
10638  %}
10639  ins_pipe( pipe_slow );
10640%}
10641
10642//----------Control Flow Instructions------------------------------------------
10643// Signed compare Instructions
10644
10645// XXX more variants!!
10646instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
10647%{
10648  match(Set cr (CmpI op1 op2));
10649  effect(DEF cr, USE op1, USE op2);
10650
10651  format %{ "cmpl    $op1, $op2" %}
10652  opcode(0x3B);  /* Opcode 3B /r */
10653  ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
10654  ins_pipe(ialu_cr_reg_reg);
10655%}
10656
10657instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
10658%{
10659  match(Set cr (CmpI op1 op2));
10660
10661  format %{ "cmpl    $op1, $op2" %}
10662  opcode(0x81, 0x07); /* Opcode 81 /7 */
10663  ins_encode(OpcSErm(op1, op2), Con8or32(op2));
10664  ins_pipe(ialu_cr_reg_imm);
10665%}
10666
10667instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2)
10668%{
10669  match(Set cr (CmpI op1 (LoadI op2)));
10670
10671  ins_cost(500); // XXX
10672  format %{ "cmpl    $op1, $op2" %}
10673  opcode(0x3B); /* Opcode 3B /r */
10674  ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
10675  ins_pipe(ialu_cr_reg_mem);
10676%}
10677
10678instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero)
10679%{
10680  match(Set cr (CmpI src zero));
10681
10682  format %{ "testl   $src, $src" %}
10683  opcode(0x85);
10684  ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
10685  ins_pipe(ialu_cr_reg_imm);
10686%}
10687
10688instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero)
10689%{
10690  match(Set cr (CmpI (AndI src con) zero));
10691
10692  format %{ "testl   $src, $con" %}
10693  opcode(0xF7, 0x00);
10694  ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con));
10695  ins_pipe(ialu_cr_reg_imm);
10696%}
10697
10698instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero)
10699%{
10700  match(Set cr (CmpI (AndI src (LoadI mem)) zero));
10701
10702  format %{ "testl   $src, $mem" %}
10703  opcode(0x85);
10704  ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
10705  ins_pipe(ialu_cr_reg_mem);
10706%}
10707
10708// Unsigned compare Instructions; really, same as signed except they
10709// produce an rFlagsRegU instead of rFlagsReg.
10710instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2)
10711%{
10712  match(Set cr (CmpU op1 op2));
10713
10714  format %{ "cmpl    $op1, $op2\t# unsigned" %}
10715  opcode(0x3B); /* Opcode 3B /r */
10716  ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
10717  ins_pipe(ialu_cr_reg_reg);
10718%}
10719
10720instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2)
10721%{
10722  match(Set cr (CmpU op1 op2));
10723
10724  format %{ "cmpl    $op1, $op2\t# unsigned" %}
10725  opcode(0x81,0x07); /* Opcode 81 /7 */
10726  ins_encode(OpcSErm(op1, op2), Con8or32(op2));
10727  ins_pipe(ialu_cr_reg_imm);
10728%}
10729
10730instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2)
10731%{
10732  match(Set cr (CmpU op1 (LoadI op2)));
10733
10734  ins_cost(500); // XXX
10735  format %{ "cmpl    $op1, $op2\t# unsigned" %}
10736  opcode(0x3B); /* Opcode 3B /r */
10737  ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
10738  ins_pipe(ialu_cr_reg_mem);
10739%}
10740
10741// // // Cisc-spilled version of cmpU_rReg
10742// //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2)
10743// //%{
10744// //  match(Set cr (CmpU (LoadI op1) op2));
10745// //
10746// //  format %{ "CMPu   $op1,$op2" %}
10747// //  ins_cost(500);
10748// //  opcode(0x39);  /* Opcode 39 /r */
10749// //  ins_encode( OpcP, reg_mem( op1, op2) );
10750// //%}
10751
10752instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero)
10753%{
10754  match(Set cr (CmpU src zero));
10755
10756  format %{ "testl  $src, $src\t# unsigned" %}
10757  opcode(0x85);
10758  ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
10759  ins_pipe(ialu_cr_reg_imm);
10760%}
10761
10762instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2)
10763%{
10764  match(Set cr (CmpP op1 op2));
10765
10766  format %{ "cmpq    $op1, $op2\t# ptr" %}
10767  opcode(0x3B); /* Opcode 3B /r */
10768  ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
10769  ins_pipe(ialu_cr_reg_reg);
10770%}
10771
10772instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
10773%{
10774  match(Set cr (CmpP op1 (LoadP op2)));
10775
10776  ins_cost(500); // XXX
10777  format %{ "cmpq    $op1, $op2\t# ptr" %}
10778  opcode(0x3B); /* Opcode 3B /r */
10779  ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10780  ins_pipe(ialu_cr_reg_mem);
10781%}
10782
10783// // // Cisc-spilled version of cmpP_rReg
10784// //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2)
10785// //%{
10786// //  match(Set cr (CmpP (LoadP op1) op2));
10787// //
10788// //  format %{ "CMPu   $op1,$op2" %}
10789// //  ins_cost(500);
10790// //  opcode(0x39);  /* Opcode 39 /r */
10791// //  ins_encode( OpcP, reg_mem( op1, op2) );
10792// //%}
10793
10794// XXX this is generalized by compP_rReg_mem???
10795// Compare raw pointer (used in out-of-heap check).
10796// Only works because non-oop pointers must be raw pointers
10797// and raw pointers have no anti-dependencies.
10798instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
10799%{
10800  predicate(!n->in(2)->in(2)->bottom_type()->isa_oop_ptr());
10801  match(Set cr (CmpP op1 (LoadP op2)));
10802
10803  format %{ "cmpq    $op1, $op2\t# raw ptr" %}
10804  opcode(0x3B); /* Opcode 3B /r */
10805  ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10806  ins_pipe(ialu_cr_reg_mem);
10807%}
10808
10809// This will generate a signed flags result. This should be OK since
10810// any compare to a zero should be eq/neq.
10811instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero)
10812%{
10813  match(Set cr (CmpP src zero));
10814
10815  format %{ "testq   $src, $src\t# ptr" %}
10816  opcode(0x85);
10817  ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
10818  ins_pipe(ialu_cr_reg_imm);
10819%}
10820
10821// This will generate a signed flags result. This should be OK since
10822// any compare to a zero should be eq/neq.
10823instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
10824%{
10825  predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
10826  match(Set cr (CmpP (LoadP op) zero));
10827
10828  ins_cost(500); // XXX
10829  format %{ "testq   $op, 0xffffffffffffffff\t# ptr" %}
10830  opcode(0xF7); /* Opcode F7 /0 */
10831  ins_encode(REX_mem_wide(op),
10832             OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
10833  ins_pipe(ialu_cr_reg_imm);
10834%}
10835
10836instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
10837%{
10838  predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL));
10839  match(Set cr (CmpP (LoadP mem) zero));
10840
10841  format %{ "cmpq    R12, $mem\t# ptr (R12_heapbase==0)" %}
10842  ins_encode %{
10843    __ cmpq(r12, $mem$$Address);
10844  %}
10845  ins_pipe(ialu_cr_reg_mem);
10846%}
10847
10848instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
10849%{
10850  match(Set cr (CmpN op1 op2));
10851
10852  format %{ "cmpl    $op1, $op2\t# compressed ptr" %}
10853  ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %}
10854  ins_pipe(ialu_cr_reg_reg);
10855%}
10856
10857instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
10858%{
10859  match(Set cr (CmpN src (LoadN mem)));
10860
10861  format %{ "cmpl    $src, $mem\t# compressed ptr" %}
10862  ins_encode %{
10863    __ cmpl($src$$Register, $mem$$Address);
10864  %}
10865  ins_pipe(ialu_cr_reg_mem);
10866%}
10867
10868instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{
10869  match(Set cr (CmpN op1 op2));
10870
10871  format %{ "cmpl    $op1, $op2\t# compressed ptr" %}
10872  ins_encode %{
10873    __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant);
10874  %}
10875  ins_pipe(ialu_cr_reg_imm);
10876%}
10877
10878instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src)
10879%{
10880  match(Set cr (CmpN src (LoadN mem)));
10881
10882  format %{ "cmpl    $mem, $src\t# compressed ptr" %}
10883  ins_encode %{
10884    __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
10885  %}
10886  ins_pipe(ialu_cr_reg_mem);
10887%}
10888
10889instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
10890  match(Set cr (CmpN src zero));
10891
10892  format %{ "testl   $src, $src\t# compressed ptr" %}
10893  ins_encode %{ __ testl($src$$Register, $src$$Register); %}
10894  ins_pipe(ialu_cr_reg_imm);
10895%}
10896
10897instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
10898%{
10899  predicate(Universe::narrow_oop_base() != NULL);
10900  match(Set cr (CmpN (LoadN mem) zero));
10901
10902  ins_cost(500); // XXX
10903  format %{ "testl   $mem, 0xffffffff\t# compressed ptr" %}
10904  ins_encode %{
10905    __ cmpl($mem$$Address, (int)0xFFFFFFFF);
10906  %}
10907  ins_pipe(ialu_cr_reg_mem);
10908%}
10909
10910instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
10911%{
10912  predicate(Universe::narrow_oop_base() == NULL);
10913  match(Set cr (CmpN (LoadN mem) zero));
10914
10915  format %{ "cmpl    R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
10916  ins_encode %{
10917    __ cmpl(r12, $mem$$Address);
10918  %}
10919  ins_pipe(ialu_cr_reg_mem);
10920%}
10921
10922// Yanked all unsigned pointer compare operations.
10923// Pointer compares are done with CmpP which is already unsigned.
10924
10925instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
10926%{
10927  match(Set cr (CmpL op1 op2));
10928
10929  format %{ "cmpq    $op1, $op2" %}
10930  opcode(0x3B);  /* Opcode 3B /r */
10931  ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
10932  ins_pipe(ialu_cr_reg_reg);
10933%}
10934
10935instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
10936%{
10937  match(Set cr (CmpL op1 op2));
10938
10939  format %{ "cmpq    $op1, $op2" %}
10940  opcode(0x81, 0x07); /* Opcode 81 /7 */
10941  ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2));
10942  ins_pipe(ialu_cr_reg_imm);
10943%}
10944
10945instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2)
10946%{
10947  match(Set cr (CmpL op1 (LoadL op2)));
10948
10949  format %{ "cmpq    $op1, $op2" %}
10950  opcode(0x3B); /* Opcode 3B /r */
10951  ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10952  ins_pipe(ialu_cr_reg_mem);
10953%}
10954
10955instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero)
10956%{
10957  match(Set cr (CmpL src zero));
10958
10959  format %{ "testq   $src, $src" %}
10960  opcode(0x85);
10961  ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
10962  ins_pipe(ialu_cr_reg_imm);
10963%}
10964
10965instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero)
10966%{
10967  match(Set cr (CmpL (AndL src con) zero));
10968
10969  format %{ "testq   $src, $con\t# long" %}
10970  opcode(0xF7, 0x00);
10971  ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con));
10972  ins_pipe(ialu_cr_reg_imm);
10973%}
10974
10975instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero)
10976%{
10977  match(Set cr (CmpL (AndL src (LoadL mem)) zero));
10978
10979  format %{ "testq   $src, $mem" %}
10980  opcode(0x85);
10981  ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
10982  ins_pipe(ialu_cr_reg_mem);
10983%}
10984
10985// Manifest a CmpL result in an integer register.  Very painful.
10986// This is the test to avoid.
10987instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
10988%{
10989  match(Set dst (CmpL3 src1 src2));
10990  effect(KILL flags);
10991
10992  ins_cost(275); // XXX
10993  format %{ "cmpq    $src1, $src2\t# CmpL3\n\t"
10994            "movl    $dst, -1\n\t"
10995            "jl,s    done\n\t"
10996            "setne   $dst\n\t"
10997            "movzbl  $dst, $dst\n\t"
10998    "done:" %}
10999  ins_encode(cmpl3_flag(src1, src2, dst));
11000  ins_pipe(pipe_slow);
11001%}
11002
11003//----------Max and Min--------------------------------------------------------
11004// Min Instructions
11005
11006instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr)
11007%{
11008  effect(USE_DEF dst, USE src, USE cr);
11009
11010  format %{ "cmovlgt $dst, $src\t# min" %}
11011  opcode(0x0F, 0x4F);
11012  ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
11013  ins_pipe(pipe_cmov_reg);
11014%}
11015
11016
11017instruct minI_rReg(rRegI dst, rRegI src)
11018%{
11019  match(Set dst (MinI dst src));
11020
11021  ins_cost(200);
11022  expand %{
11023    rFlagsReg cr;
11024    compI_rReg(cr, dst, src);
11025    cmovI_reg_g(dst, src, cr);
11026  %}
11027%}
11028
11029instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr)
11030%{
11031  effect(USE_DEF dst, USE src, USE cr);
11032
11033  format %{ "cmovllt $dst, $src\t# max" %}
11034  opcode(0x0F, 0x4C);
11035  ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
11036  ins_pipe(pipe_cmov_reg);
11037%}
11038
11039
11040instruct maxI_rReg(rRegI dst, rRegI src)
11041%{
11042  match(Set dst (MaxI dst src));
11043
11044  ins_cost(200);
11045  expand %{
11046    rFlagsReg cr;
11047    compI_rReg(cr, dst, src);
11048    cmovI_reg_l(dst, src, cr);
11049  %}
11050%}
11051
11052// ============================================================================
11053// Branch Instructions
11054
11055// Jump Direct - Label defines a relative address from JMP+1
11056instruct jmpDir(label labl)
11057%{
11058  match(Goto);
11059  effect(USE labl);
11060
11061  ins_cost(300);
11062  format %{ "jmp     $labl" %}
11063  size(5);
11064  ins_encode %{
11065    Label* L = $labl$$label;
11066    __ jmp(*L, false); // Always long jump
11067  %}
11068  ins_pipe(pipe_jmp);
11069%}
11070
11071// Jump Direct Conditional - Label defines a relative address from Jcc+1
11072instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl)
11073%{
11074  match(If cop cr);
11075  effect(USE labl);
11076
11077  ins_cost(300);
11078  format %{ "j$cop     $labl" %}
11079  size(6);
11080  ins_encode %{
11081    Label* L = $labl$$label;
11082    __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11083  %}
11084  ins_pipe(pipe_jcc);
11085%}
11086
11087// Jump Direct Conditional - Label defines a relative address from Jcc+1
11088instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
11089%{
11090  match(CountedLoopEnd cop cr);
11091  effect(USE labl);
11092
11093  ins_cost(300);
11094  format %{ "j$cop     $labl\t# loop end" %}
11095  size(6);
11096  ins_encode %{
11097    Label* L = $labl$$label;
11098    __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11099  %}
11100  ins_pipe(pipe_jcc);
11101%}
11102
11103// Jump Direct Conditional - Label defines a relative address from Jcc+1
11104instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11105  match(CountedLoopEnd cop cmp);
11106  effect(USE labl);
11107
11108  ins_cost(300);
11109  format %{ "j$cop,u   $labl\t# loop end" %}
11110  size(6);
11111  ins_encode %{
11112    Label* L = $labl$$label;
11113    __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11114  %}
11115  ins_pipe(pipe_jcc);
11116%}
11117
11118instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11119  match(CountedLoopEnd cop cmp);
11120  effect(USE labl);
11121
11122  ins_cost(200);
11123  format %{ "j$cop,u   $labl\t# loop end" %}
11124  size(6);
11125  ins_encode %{
11126    Label* L = $labl$$label;
11127    __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11128  %}
11129  ins_pipe(pipe_jcc);
11130%}
11131
11132// Jump Direct Conditional - using unsigned comparison
11133instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11134  match(If cop cmp);
11135  effect(USE labl);
11136
11137  ins_cost(300);
11138  format %{ "j$cop,u  $labl" %}
11139  size(6);
11140  ins_encode %{
11141    Label* L = $labl$$label;
11142    __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11143  %}
11144  ins_pipe(pipe_jcc);
11145%}
11146
11147instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11148  match(If cop cmp);
11149  effect(USE labl);
11150
11151  ins_cost(200);
11152  format %{ "j$cop,u  $labl" %}
11153  size(6);
11154  ins_encode %{
11155    Label* L = $labl$$label;
11156    __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11157  %}
11158  ins_pipe(pipe_jcc);
11159%}
11160
11161instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
11162  match(If cop cmp);
11163  effect(USE labl);
11164
11165  ins_cost(200);
11166  format %{ $$template
11167    if ($cop$$cmpcode == Assembler::notEqual) {
11168      $$emit$$"jp,u   $labl\n\t"
11169      $$emit$$"j$cop,u   $labl"
11170    } else {
11171      $$emit$$"jp,u   done\n\t"
11172      $$emit$$"j$cop,u   $labl\n\t"
11173      $$emit$$"done:"
11174    }
11175  %}
11176  ins_encode %{
11177    Label* l = $labl$$label;
11178    if ($cop$$cmpcode == Assembler::notEqual) {
11179      __ jcc(Assembler::parity, *l, false);
11180      __ jcc(Assembler::notEqual, *l, false);
11181    } else if ($cop$$cmpcode == Assembler::equal) {
11182      Label done;
11183      __ jccb(Assembler::parity, done);
11184      __ jcc(Assembler::equal, *l, false);
11185      __ bind(done);
11186    } else {
11187       ShouldNotReachHere();
11188    }
11189  %}
11190  ins_pipe(pipe_jcc);
11191%}
11192
11193// ============================================================================
11194// The 2nd slow-half of a subtype check.  Scan the subklass's 2ndary
11195// superklass array for an instance of the superklass.  Set a hidden
11196// internal cache on a hit (cache is checked with exposed code in
11197// gen_subtype_check()).  Return NZ for a miss or zero for a hit.  The
11198// encoding ALSO sets flags.
11199
11200instruct partialSubtypeCheck(rdi_RegP result,
11201                             rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
11202                             rFlagsReg cr)
11203%{
11204  match(Set result (PartialSubtypeCheck sub super));
11205  effect(KILL rcx, KILL cr);
11206
11207  ins_cost(1100);  // slightly larger than the next version
11208  format %{ "movq    rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
11209            "movl    rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t"
11210            "addq    rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t"
11211            "repne   scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t"
11212            "jne,s   miss\t\t# Missed: rdi not-zero\n\t"
11213            "movq    [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
11214            "xorq    $result, $result\t\t Hit: rdi zero\n\t"
11215    "miss:\t" %}
11216
11217  opcode(0x1); // Force a XOR of RDI
11218  ins_encode(enc_PartialSubtypeCheck());
11219  ins_pipe(pipe_slow);
11220%}
11221
11222instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr,
11223                                     rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
11224                                     immP0 zero,
11225                                     rdi_RegP result)
11226%{
11227  match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
11228  effect(KILL rcx, KILL result);
11229
11230  ins_cost(1000);
11231  format %{ "movq    rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
11232            "movl    rcx, [rdi + arrayOopDesc::length_offset_in_bytes()]\t# length to scan\n\t"
11233            "addq    rdi, arrayOopDex::base_offset_in_bytes(T_OBJECT)\t# Skip to start of data; set NZ in case count is zero\n\t"
11234            "repne   scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t"
11235            "jne,s   miss\t\t# Missed: flags nz\n\t"
11236            "movq    [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
11237    "miss:\t" %}
11238
11239  opcode(0x0); // No need to XOR RDI
11240  ins_encode(enc_PartialSubtypeCheck());
11241  ins_pipe(pipe_slow);
11242%}
11243
11244// ============================================================================
11245// Branch Instructions -- short offset versions
11246//
11247// These instructions are used to replace jumps of a long offset (the default
11248// match) with jumps of a shorter offset.  These instructions are all tagged
11249// with the ins_short_branch attribute, which causes the ADLC to suppress the
11250// match rules in general matching.  Instead, the ADLC generates a conversion
11251// method in the MachNode which can be used to do in-place replacement of the
11252// long variant with the shorter variant.  The compiler will determine if a
11253// branch can be taken by the is_short_branch_offset() predicate in the machine
11254// specific code section of the file.
11255
11256// Jump Direct - Label defines a relative address from JMP+1
11257instruct jmpDir_short(label labl) %{
11258  match(Goto);
11259  effect(USE labl);
11260
11261  ins_cost(300);
11262  format %{ "jmp,s   $labl" %}
11263  size(2);
11264  ins_encode %{
11265    Label* L = $labl$$label;
11266    __ jmpb(*L);
11267  %}
11268  ins_pipe(pipe_jmp);
11269  ins_short_branch(1);
11270%}
11271
11272// Jump Direct Conditional - Label defines a relative address from Jcc+1
11273instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
11274  match(If cop cr);
11275  effect(USE labl);
11276
11277  ins_cost(300);
11278  format %{ "j$cop,s   $labl" %}
11279  size(2);
11280  ins_encode %{
11281    Label* L = $labl$$label;
11282    __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11283  %}
11284  ins_pipe(pipe_jcc);
11285  ins_short_branch(1);
11286%}
11287
11288// Jump Direct Conditional - Label defines a relative address from Jcc+1
11289instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
11290  match(CountedLoopEnd cop cr);
11291  effect(USE labl);
11292
11293  ins_cost(300);
11294  format %{ "j$cop,s   $labl\t# loop end" %}
11295  size(2);
11296  ins_encode %{
11297    Label* L = $labl$$label;
11298    __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11299  %}
11300  ins_pipe(pipe_jcc);
11301  ins_short_branch(1);
11302%}
11303
11304// Jump Direct Conditional - Label defines a relative address from Jcc+1
11305instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11306  match(CountedLoopEnd cop cmp);
11307  effect(USE labl);
11308
11309  ins_cost(300);
11310  format %{ "j$cop,us  $labl\t# loop end" %}
11311  size(2);
11312  ins_encode %{
11313    Label* L = $labl$$label;
11314    __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11315  %}
11316  ins_pipe(pipe_jcc);
11317  ins_short_branch(1);
11318%}
11319
11320instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11321  match(CountedLoopEnd cop cmp);
11322  effect(USE labl);
11323
11324  ins_cost(300);
11325  format %{ "j$cop,us  $labl\t# loop end" %}
11326  size(2);
11327  ins_encode %{
11328    Label* L = $labl$$label;
11329    __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11330  %}
11331  ins_pipe(pipe_jcc);
11332  ins_short_branch(1);
11333%}
11334
11335// Jump Direct Conditional - using unsigned comparison
11336instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11337  match(If cop cmp);
11338  effect(USE labl);
11339
11340  ins_cost(300);
11341  format %{ "j$cop,us  $labl" %}
11342  size(2);
11343  ins_encode %{
11344    Label* L = $labl$$label;
11345    __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11346  %}
11347  ins_pipe(pipe_jcc);
11348  ins_short_branch(1);
11349%}
11350
11351instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11352  match(If cop cmp);
11353  effect(USE labl);
11354
11355  ins_cost(300);
11356  format %{ "j$cop,us  $labl" %}
11357  size(2);
11358  ins_encode %{
11359    Label* L = $labl$$label;
11360    __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11361  %}
11362  ins_pipe(pipe_jcc);
11363  ins_short_branch(1);
11364%}
11365
11366instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
11367  match(If cop cmp);
11368  effect(USE labl);
11369
11370  ins_cost(300);
11371  format %{ $$template
11372    if ($cop$$cmpcode == Assembler::notEqual) {
11373      $$emit$$"jp,u,s   $labl\n\t"
11374      $$emit$$"j$cop,u,s   $labl"
11375    } else {
11376      $$emit$$"jp,u,s   done\n\t"
11377      $$emit$$"j$cop,u,s  $labl\n\t"
11378      $$emit$$"done:"
11379    }
11380  %}
11381  size(4);
11382  ins_encode %{
11383    Label* l = $labl$$label;
11384    if ($cop$$cmpcode == Assembler::notEqual) {
11385      __ jccb(Assembler::parity, *l);
11386      __ jccb(Assembler::notEqual, *l);
11387    } else if ($cop$$cmpcode == Assembler::equal) {
11388      Label done;
11389      __ jccb(Assembler::parity, done);
11390      __ jccb(Assembler::equal, *l);
11391      __ bind(done);
11392    } else {
11393       ShouldNotReachHere();
11394    }
11395  %}
11396  ins_pipe(pipe_jcc);
11397  ins_short_branch(1);
11398%}
11399
11400// ============================================================================
11401// inlined locking and unlocking
11402
11403instruct cmpFastLock(rFlagsReg cr,
11404                     rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr)
11405%{
11406  match(Set cr (FastLock object box));
11407  effect(TEMP tmp, TEMP scr, USE_KILL box);
11408
11409  ins_cost(300);
11410  format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
11411  ins_encode(Fast_Lock(object, box, tmp, scr));
11412  ins_pipe(pipe_slow);
11413%}
11414
11415instruct cmpFastUnlock(rFlagsReg cr,
11416                       rRegP object, rax_RegP box, rRegP tmp)
11417%{
11418  match(Set cr (FastUnlock object box));
11419  effect(TEMP tmp, USE_KILL box);
11420
11421  ins_cost(300);
11422  format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
11423  ins_encode(Fast_Unlock(object, box, tmp));
11424  ins_pipe(pipe_slow);
11425%}
11426
11427
11428// ============================================================================
11429// Safepoint Instructions
11430instruct safePoint_poll(rFlagsReg cr)
11431%{
11432  predicate(!Assembler::is_polling_page_far());
11433  match(SafePoint);
11434  effect(KILL cr);
11435
11436  format %{ "testl  rax, [rip + #offset_to_poll_page]\t"
11437            "# Safepoint: poll for GC" %}
11438  ins_cost(125);
11439  ins_encode %{
11440    AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type);
11441    __ testl(rax, addr);
11442  %}
11443  ins_pipe(ialu_reg_mem);
11444%}
11445
11446instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
11447%{
11448  predicate(Assembler::is_polling_page_far());
11449  match(SafePoint poll);
11450  effect(KILL cr, USE poll);
11451
11452  format %{ "testl  rax, [$poll]\t"
11453            "# Safepoint: poll for GC" %}
11454  ins_cost(125);
11455  ins_encode %{
11456    __ relocate(relocInfo::poll_type);
11457    __ testl(rax, Address($poll$$Register, 0));
11458  %}
11459  ins_pipe(ialu_reg_mem);
11460%}
11461
11462// ============================================================================
11463// Procedure Call/Return Instructions
11464// Call Java Static Instruction
11465// Note: If this code changes, the corresponding ret_addr_offset() and
11466//       compute_padding() functions will have to be adjusted.
11467instruct CallStaticJavaDirect(method meth) %{
11468  match(CallStaticJava);
11469  predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke());
11470  effect(USE meth);
11471
11472  ins_cost(300);
11473  format %{ "call,static " %}
11474  opcode(0xE8); /* E8 cd */
11475  ins_encode(Java_Static_Call(meth), call_epilog);
11476  ins_pipe(pipe_slow);
11477  ins_alignment(4);
11478%}
11479
11480// Call Java Static Instruction (method handle version)
11481// Note: If this code changes, the corresponding ret_addr_offset() and
11482//       compute_padding() functions will have to be adjusted.
11483instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{
11484  match(CallStaticJava);
11485  predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke());
11486  effect(USE meth);
11487  // RBP is saved by all callees (for interpreter stack correction).
11488  // We use it here for a similar purpose, in {preserve,restore}_SP.
11489
11490  ins_cost(300);
11491  format %{ "call,static/MethodHandle " %}
11492  opcode(0xE8); /* E8 cd */
11493  ins_encode(preserve_SP,
11494             Java_Static_Call(meth),
11495             restore_SP,
11496             call_epilog);
11497  ins_pipe(pipe_slow);
11498  ins_alignment(4);
11499%}
11500
11501// Call Java Dynamic Instruction
11502// Note: If this code changes, the corresponding ret_addr_offset() and
11503//       compute_padding() functions will have to be adjusted.
11504instruct CallDynamicJavaDirect(method meth)
11505%{
11506  match(CallDynamicJava);
11507  effect(USE meth);
11508
11509  ins_cost(300);
11510  format %{ "movq    rax, #Universe::non_oop_word()\n\t"
11511            "call,dynamic " %}
11512  opcode(0xE8); /* E8 cd */
11513  ins_encode(Java_Dynamic_Call(meth), call_epilog);
11514  ins_pipe(pipe_slow);
11515  ins_alignment(4);
11516%}
11517
11518// Call Runtime Instruction
11519instruct CallRuntimeDirect(method meth)
11520%{
11521  match(CallRuntime);
11522  effect(USE meth);
11523
11524  ins_cost(300);
11525  format %{ "call,runtime " %}
11526  opcode(0xE8); /* E8 cd */
11527  ins_encode(Java_To_Runtime(meth));
11528  ins_pipe(pipe_slow);
11529%}
11530
11531// Call runtime without safepoint
11532instruct CallLeafDirect(method meth)
11533%{
11534  match(CallLeaf);
11535  effect(USE meth);
11536
11537  ins_cost(300);
11538  format %{ "call_leaf,runtime " %}
11539  opcode(0xE8); /* E8 cd */
11540  ins_encode(Java_To_Runtime(meth));
11541  ins_pipe(pipe_slow);
11542%}
11543
11544// Call runtime without safepoint
11545instruct CallLeafNoFPDirect(method meth)
11546%{
11547  match(CallLeafNoFP);
11548  effect(USE meth);
11549
11550  ins_cost(300);
11551  format %{ "call_leaf_nofp,runtime " %}
11552  opcode(0xE8); /* E8 cd */
11553  ins_encode(Java_To_Runtime(meth));
11554  ins_pipe(pipe_slow);
11555%}
11556
11557// Return Instruction
11558// Remove the return address & jump to it.
11559// Notice: We always emit a nop after a ret to make sure there is room
11560// for safepoint patching
11561instruct Ret()
11562%{
11563  match(Return);
11564
11565  format %{ "ret" %}
11566  opcode(0xC3);
11567  ins_encode(OpcP);
11568  ins_pipe(pipe_jmp);
11569%}
11570
11571// Tail Call; Jump from runtime stub to Java code.
11572// Also known as an 'interprocedural jump'.
11573// Target of jump will eventually return to caller.
11574// TailJump below removes the return address.
11575instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop)
11576%{
11577  match(TailCall jump_target method_oop);
11578
11579  ins_cost(300);
11580  format %{ "jmp     $jump_target\t# rbx holds method oop" %}
11581  opcode(0xFF, 0x4); /* Opcode FF /4 */
11582  ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target));
11583  ins_pipe(pipe_jmp);
11584%}
11585
11586// Tail Jump; remove the return address; jump to target.
11587// TailCall above leaves the return address around.
11588instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop)
11589%{
11590  match(TailJump jump_target ex_oop);
11591
11592  ins_cost(300);
11593  format %{ "popq    rdx\t# pop return address\n\t"
11594            "jmp     $jump_target" %}
11595  opcode(0xFF, 0x4); /* Opcode FF /4 */
11596  ins_encode(Opcode(0x5a), // popq rdx
11597             REX_reg(jump_target), OpcP, reg_opc(jump_target));
11598  ins_pipe(pipe_jmp);
11599%}
11600
11601// Create exception oop: created by stack-crawling runtime code.
11602// Created exception is now available to this handler, and is setup
11603// just prior to jumping to this handler.  No code emitted.
11604instruct CreateException(rax_RegP ex_oop)
11605%{
11606  match(Set ex_oop (CreateEx));
11607
11608  size(0);
11609  // use the following format syntax
11610  format %{ "# exception oop is in rax; no code emitted" %}
11611  ins_encode();
11612  ins_pipe(empty);
11613%}
11614
11615// Rethrow exception:
11616// The exception oop will come in the first argument position.
11617// Then JUMP (not call) to the rethrow stub code.
11618instruct RethrowException()
11619%{
11620  match(Rethrow);
11621
11622  // use the following format syntax
11623  format %{ "jmp     rethrow_stub" %}
11624  ins_encode(enc_rethrow);
11625  ins_pipe(pipe_jmp);
11626%}
11627
11628
11629// ============================================================================
11630// This name is KNOWN by the ADLC and cannot be changed.
11631// The ADLC forces a 'TypeRawPtr::BOTTOM' output type
11632// for this guy.
11633instruct tlsLoadP(r15_RegP dst) %{
11634  match(Set dst (ThreadLocal));
11635  effect(DEF dst);
11636
11637  size(0);
11638  format %{ "# TLS is in R15" %}
11639  ins_encode( /*empty encoding*/ );
11640  ins_pipe(ialu_reg_reg);
11641%}
11642
11643
11644//----------PEEPHOLE RULES-----------------------------------------------------
11645// These must follow all instruction definitions as they use the names
11646// defined in the instructions definitions.
11647//
11648// peepmatch ( root_instr_name [preceding_instruction]* );
11649//
11650// peepconstraint %{
11651// (instruction_number.operand_name relational_op instruction_number.operand_name
11652//  [, ...] );
11653// // instruction numbers are zero-based using left to right order in peepmatch
11654//
11655// peepreplace ( instr_name  ( [instruction_number.operand_name]* ) );
11656// // provide an instruction_number.operand_name for each operand that appears
11657// // in the replacement instruction's match rule
11658//
11659// ---------VM FLAGS---------------------------------------------------------
11660//
11661// All peephole optimizations can be turned off using -XX:-OptoPeephole
11662//
11663// Each peephole rule is given an identifying number starting with zero and
11664// increasing by one in the order seen by the parser.  An individual peephole
11665// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11666// on the command-line.
11667//
11668// ---------CURRENT LIMITATIONS----------------------------------------------
11669//
11670// Only match adjacent instructions in same basic block
11671// Only equality constraints
11672// Only constraints between operands, not (0.dest_reg == RAX_enc)
11673// Only one replacement instruction
11674//
11675// ---------EXAMPLE----------------------------------------------------------
11676//
11677// // pertinent parts of existing instructions in architecture description
11678// instruct movI(rRegI dst, rRegI src)
11679// %{
11680//   match(Set dst (CopyI src));
11681// %}
11682//
11683// instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
11684// %{
11685//   match(Set dst (AddI dst src));
11686//   effect(KILL cr);
11687// %}
11688//
11689// // Change (inc mov) to lea
11690// peephole %{
11691//   // increment preceeded by register-register move
11692//   peepmatch ( incI_rReg movI );
11693//   // require that the destination register of the increment
11694//   // match the destination register of the move
11695//   peepconstraint ( 0.dst == 1.dst );
11696//   // construct a replacement instruction that sets
11697//   // the destination to ( move's source register + one )
11698//   peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) );
11699// %}
11700//
11701
11702// Implementation no longer uses movX instructions since
11703// machine-independent system no longer uses CopyX nodes.
11704//
11705// peephole
11706// %{
11707//   peepmatch (incI_rReg movI);
11708//   peepconstraint (0.dst == 1.dst);
11709//   peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11710// %}
11711
11712// peephole
11713// %{
11714//   peepmatch (decI_rReg movI);
11715//   peepconstraint (0.dst == 1.dst);
11716//   peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11717// %}
11718
11719// peephole
11720// %{
11721//   peepmatch (addI_rReg_imm movI);
11722//   peepconstraint (0.dst == 1.dst);
11723//   peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11724// %}
11725
11726// peephole
11727// %{
11728//   peepmatch (incL_rReg movL);
11729//   peepconstraint (0.dst == 1.dst);
11730//   peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11731// %}
11732
11733// peephole
11734// %{
11735//   peepmatch (decL_rReg movL);
11736//   peepconstraint (0.dst == 1.dst);
11737//   peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11738// %}
11739
11740// peephole
11741// %{
11742//   peepmatch (addL_rReg_imm movL);
11743//   peepconstraint (0.dst == 1.dst);
11744//   peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11745// %}
11746
11747// peephole
11748// %{
11749//   peepmatch (addP_rReg_imm movP);
11750//   peepconstraint (0.dst == 1.dst);
11751//   peepreplace (leaP_rReg_imm(0.dst 1.src 0.src));
11752// %}
11753
11754// // Change load of spilled value to only a spill
11755// instruct storeI(memory mem, rRegI src)
11756// %{
11757//   match(Set mem (StoreI mem src));
11758// %}
11759//
11760// instruct loadI(rRegI dst, memory mem)
11761// %{
11762//   match(Set dst (LoadI mem));
11763// %}
11764//
11765
11766peephole
11767%{
11768  peepmatch (loadI storeI);
11769  peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
11770  peepreplace (storeI(1.mem 1.mem 1.src));
11771%}
11772
11773peephole
11774%{
11775  peepmatch (loadL storeL);
11776  peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
11777  peepreplace (storeL(1.mem 1.mem 1.src));
11778%}
11779
11780//----------SMARTSPILL RULES---------------------------------------------------
11781// These must follow all instruction definitions as they use the names
11782// defined in the instructions definitions.
11783