Fri, 25 Jan 2013 10:04:08 -0500
8000692: Remove old KERNEL code
Summary: Removed depreciated kernel VM source code from hotspot VM
Reviewed-by: dholmes, acorn
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 //
25 // AMD64 Architecture Description File
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.
32 register %{
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.
62 // General Registers
63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when
64 // used as byte registers)
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.
70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg());
71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next());
73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg());
74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next());
76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg());
77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next());
79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg());
80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next());
82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg());
83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next());
85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code
86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg());
87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next());
89 #ifdef _WIN64
91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg());
92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next());
94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg());
95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next());
97 #else
99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg());
100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next());
102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg());
103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next());
105 #endif
107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg());
108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next());
110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg());
111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next());
113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg());
114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next());
116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg());
117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next());
119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg());
120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next());
122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg());
123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next());
125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg());
126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next());
128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg());
129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next());
132 // Floating Point Registers
134 // Specify priority of register selection within phases of register
135 // allocation. Highest priority is first. A useful heuristic is to
136 // give registers a low priority when they are required by machine
137 // instructions, like EAX and EDX on I486, and choose no-save registers
138 // before save-on-call, & save-on-call before save-on-entry. Registers
139 // which participate in fixed calling sequences should come last.
140 // Registers which are used as pairs must fall on an even boundary.
142 alloc_class chunk0(R10, R10_H,
143 R11, R11_H,
144 R8, R8_H,
145 R9, R9_H,
146 R12, R12_H,
147 RCX, RCX_H,
148 RBX, RBX_H,
149 RDI, RDI_H,
150 RDX, RDX_H,
151 RSI, RSI_H,
152 RAX, RAX_H,
153 RBP, RBP_H,
154 R13, R13_H,
155 R14, R14_H,
156 R15, R15_H,
157 RSP, RSP_H);
160 //----------Architecture Description Register Classes--------------------------
161 // Several register classes are automatically defined based upon information in
162 // this architecture description.
163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ )
164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ )
165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
167 //
169 // Class for all pointer registers (including RSP)
170 reg_class any_reg(RAX, RAX_H,
171 RDX, RDX_H,
172 RBP, RBP_H,
173 RDI, RDI_H,
174 RSI, RSI_H,
175 RCX, RCX_H,
176 RBX, RBX_H,
177 RSP, RSP_H,
178 R8, R8_H,
179 R9, R9_H,
180 R10, R10_H,
181 R11, R11_H,
182 R12, R12_H,
183 R13, R13_H,
184 R14, R14_H,
185 R15, R15_H);
187 // Class for all pointer registers except RSP
188 reg_class ptr_reg(RAX, RAX_H,
189 RDX, RDX_H,
190 RBP, RBP_H,
191 RDI, RDI_H,
192 RSI, RSI_H,
193 RCX, RCX_H,
194 RBX, RBX_H,
195 R8, R8_H,
196 R9, R9_H,
197 R10, R10_H,
198 R11, R11_H,
199 R13, R13_H,
200 R14, R14_H);
202 // Class for all pointer registers except RAX and RSP
203 reg_class ptr_no_rax_reg(RDX, RDX_H,
204 RBP, RBP_H,
205 RDI, RDI_H,
206 RSI, RSI_H,
207 RCX, RCX_H,
208 RBX, RBX_H,
209 R8, R8_H,
210 R9, R9_H,
211 R10, R10_H,
212 R11, R11_H,
213 R13, R13_H,
214 R14, R14_H);
216 reg_class ptr_no_rbp_reg(RDX, RDX_H,
217 RAX, RAX_H,
218 RDI, RDI_H,
219 RSI, RSI_H,
220 RCX, RCX_H,
221 RBX, RBX_H,
222 R8, R8_H,
223 R9, R9_H,
224 R10, R10_H,
225 R11, R11_H,
226 R13, R13_H,
227 R14, R14_H);
229 // Class for all pointer registers except RAX, RBX and RSP
230 reg_class ptr_no_rax_rbx_reg(RDX, RDX_H,
231 RBP, RBP_H,
232 RDI, RDI_H,
233 RSI, RSI_H,
234 RCX, RCX_H,
235 R8, R8_H,
236 R9, R9_H,
237 R10, R10_H,
238 R11, R11_H,
239 R13, R13_H,
240 R14, R14_H);
242 // Singleton class for RAX pointer register
243 reg_class ptr_rax_reg(RAX, RAX_H);
245 // Singleton class for RBX pointer register
246 reg_class ptr_rbx_reg(RBX, RBX_H);
248 // Singleton class for RSI pointer register
249 reg_class ptr_rsi_reg(RSI, RSI_H);
251 // Singleton class for RDI pointer register
252 reg_class ptr_rdi_reg(RDI, RDI_H);
254 // Singleton class for RBP pointer register
255 reg_class ptr_rbp_reg(RBP, RBP_H);
257 // Singleton class for stack pointer
258 reg_class ptr_rsp_reg(RSP, RSP_H);
260 // Singleton class for TLS pointer
261 reg_class ptr_r15_reg(R15, R15_H);
263 // Class for all long registers (except RSP)
264 reg_class long_reg(RAX, RAX_H,
265 RDX, RDX_H,
266 RBP, RBP_H,
267 RDI, RDI_H,
268 RSI, RSI_H,
269 RCX, RCX_H,
270 RBX, RBX_H,
271 R8, R8_H,
272 R9, R9_H,
273 R10, R10_H,
274 R11, R11_H,
275 R13, R13_H,
276 R14, R14_H);
278 // Class for all long registers except RAX, RDX (and RSP)
279 reg_class long_no_rax_rdx_reg(RBP, RBP_H,
280 RDI, RDI_H,
281 RSI, RSI_H,
282 RCX, RCX_H,
283 RBX, RBX_H,
284 R8, R8_H,
285 R9, R9_H,
286 R10, R10_H,
287 R11, R11_H,
288 R13, R13_H,
289 R14, R14_H);
291 // Class for all long registers except RCX (and RSP)
292 reg_class long_no_rcx_reg(RBP, RBP_H,
293 RDI, RDI_H,
294 RSI, RSI_H,
295 RAX, RAX_H,
296 RDX, RDX_H,
297 RBX, RBX_H,
298 R8, R8_H,
299 R9, R9_H,
300 R10, R10_H,
301 R11, R11_H,
302 R13, R13_H,
303 R14, R14_H);
305 // Class for all long registers except RAX (and RSP)
306 reg_class long_no_rax_reg(RBP, RBP_H,
307 RDX, RDX_H,
308 RDI, RDI_H,
309 RSI, RSI_H,
310 RCX, RCX_H,
311 RBX, RBX_H,
312 R8, R8_H,
313 R9, R9_H,
314 R10, R10_H,
315 R11, R11_H,
316 R13, R13_H,
317 R14, R14_H);
319 // Singleton class for RAX long register
320 reg_class long_rax_reg(RAX, RAX_H);
322 // Singleton class for RCX long register
323 reg_class long_rcx_reg(RCX, RCX_H);
325 // Singleton class for RDX long register
326 reg_class long_rdx_reg(RDX, RDX_H);
328 // Class for all int registers (except RSP)
329 reg_class int_reg(RAX,
330 RDX,
331 RBP,
332 RDI,
333 RSI,
334 RCX,
335 RBX,
336 R8,
337 R9,
338 R10,
339 R11,
340 R13,
341 R14);
343 // Class for all int registers except RCX (and RSP)
344 reg_class int_no_rcx_reg(RAX,
345 RDX,
346 RBP,
347 RDI,
348 RSI,
349 RBX,
350 R8,
351 R9,
352 R10,
353 R11,
354 R13,
355 R14);
357 // Class for all int registers except RAX, RDX (and RSP)
358 reg_class int_no_rax_rdx_reg(RBP,
359 RDI,
360 RSI,
361 RCX,
362 RBX,
363 R8,
364 R9,
365 R10,
366 R11,
367 R13,
368 R14);
370 // Singleton class for RAX int register
371 reg_class int_rax_reg(RAX);
373 // Singleton class for RBX int register
374 reg_class int_rbx_reg(RBX);
376 // Singleton class for RCX int register
377 reg_class int_rcx_reg(RCX);
379 // Singleton class for RCX int register
380 reg_class int_rdx_reg(RDX);
382 // Singleton class for RCX int register
383 reg_class int_rdi_reg(RDI);
385 // Singleton class for instruction pointer
386 // reg_class ip_reg(RIP);
388 %}
390 //----------SOURCE BLOCK-------------------------------------------------------
391 // This is a block of C++ code which provides values, functions, and
392 // definitions necessary in the rest of the architecture description
393 source %{
394 #define RELOC_IMM64 Assembler::imm_operand
395 #define RELOC_DISP32 Assembler::disp32_operand
397 #define __ _masm.
399 static int preserve_SP_size() {
400 return 3; // rex.w, op, rm(reg/reg)
401 }
403 // !!!!! Special hack to get all types of calls to specify the byte offset
404 // from the start of the call to the point where the return address
405 // will point.
406 int MachCallStaticJavaNode::ret_addr_offset()
407 {
408 int offset = 5; // 5 bytes from start of call to where return address points
409 if (_method_handle_invoke)
410 offset += preserve_SP_size();
411 return offset;
412 }
414 int MachCallDynamicJavaNode::ret_addr_offset()
415 {
416 return 15; // 15 bytes from start of call to where return address points
417 }
419 // In os_cpu .ad file
420 // int MachCallRuntimeNode::ret_addr_offset()
422 // Indicate if the safepoint node needs the polling page as an input,
423 // it does if the polling page is more than disp32 away.
424 bool SafePointNode::needs_polling_address_input()
425 {
426 return Assembler::is_polling_page_far();
427 }
429 //
430 // Compute padding required for nodes which need alignment
431 //
433 // The address of the call instruction needs to be 4-byte aligned to
434 // ensure that it does not span a cache line so that it can be patched.
435 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
436 {
437 current_offset += 1; // skip call opcode byte
438 return round_to(current_offset, alignment_required()) - current_offset;
439 }
441 // The address of the call instruction needs to be 4-byte aligned to
442 // ensure that it does not span a cache line so that it can be patched.
443 int CallStaticJavaHandleNode::compute_padding(int current_offset) const
444 {
445 current_offset += preserve_SP_size(); // skip mov rbp, rsp
446 current_offset += 1; // skip call opcode byte
447 return round_to(current_offset, alignment_required()) - current_offset;
448 }
450 // The address of the call instruction needs to be 4-byte aligned to
451 // ensure that it does not span a cache line so that it can be patched.
452 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
453 {
454 current_offset += 11; // skip movq instruction + call opcode byte
455 return round_to(current_offset, alignment_required()) - current_offset;
456 }
458 // EMIT_RM()
459 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
460 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
461 cbuf.insts()->emit_int8(c);
462 }
464 // EMIT_CC()
465 void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
466 unsigned char c = (unsigned char) (f1 | f2);
467 cbuf.insts()->emit_int8(c);
468 }
470 // EMIT_OPCODE()
471 void emit_opcode(CodeBuffer &cbuf, int code) {
472 cbuf.insts()->emit_int8((unsigned char) code);
473 }
475 // EMIT_OPCODE() w/ relocation information
476 void emit_opcode(CodeBuffer &cbuf,
477 int code, relocInfo::relocType reloc, int offset, int format)
478 {
479 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format);
480 emit_opcode(cbuf, code);
481 }
483 // EMIT_D8()
484 void emit_d8(CodeBuffer &cbuf, int d8) {
485 cbuf.insts()->emit_int8((unsigned char) d8);
486 }
488 // EMIT_D16()
489 void emit_d16(CodeBuffer &cbuf, int d16) {
490 cbuf.insts()->emit_int16(d16);
491 }
493 // EMIT_D32()
494 void emit_d32(CodeBuffer &cbuf, int d32) {
495 cbuf.insts()->emit_int32(d32);
496 }
498 // EMIT_D64()
499 void emit_d64(CodeBuffer &cbuf, int64_t d64) {
500 cbuf.insts()->emit_int64(d64);
501 }
503 // emit 32 bit value and construct relocation entry from relocInfo::relocType
504 void emit_d32_reloc(CodeBuffer& cbuf,
505 int d32,
506 relocInfo::relocType reloc,
507 int format)
508 {
509 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
510 cbuf.relocate(cbuf.insts_mark(), reloc, format);
511 cbuf.insts()->emit_int32(d32);
512 }
514 // emit 32 bit value and construct relocation entry from RelocationHolder
515 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) {
516 #ifdef ASSERT
517 if (rspec.reloc()->type() == relocInfo::oop_type &&
518 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
519 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop");
520 assert(oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
521 }
522 #endif
523 cbuf.relocate(cbuf.insts_mark(), rspec, format);
524 cbuf.insts()->emit_int32(d32);
525 }
527 void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
528 address next_ip = cbuf.insts_end() + 4;
529 emit_d32_reloc(cbuf, (int) (addr - next_ip),
530 external_word_Relocation::spec(addr),
531 RELOC_DISP32);
532 }
535 // emit 64 bit value and construct relocation entry from relocInfo::relocType
536 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) {
537 cbuf.relocate(cbuf.insts_mark(), reloc, format);
538 cbuf.insts()->emit_int64(d64);
539 }
541 // emit 64 bit value and construct relocation entry from RelocationHolder
542 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) {
543 #ifdef ASSERT
544 if (rspec.reloc()->type() == relocInfo::oop_type &&
545 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
546 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop");
547 assert(oop(d64)->is_oop() && (ScavengeRootsInCode || !oop(d64)->is_scavengable()),
548 "cannot embed scavengable oops in code");
549 }
550 #endif
551 cbuf.relocate(cbuf.insts_mark(), rspec, format);
552 cbuf.insts()->emit_int64(d64);
553 }
555 // Access stack slot for load or store
556 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp)
557 {
558 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src])
559 if (-0x80 <= disp && disp < 0x80) {
560 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte
561 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
562 emit_d8(cbuf, disp); // Displacement // R/M byte
563 } else {
564 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte
565 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
566 emit_d32(cbuf, disp); // Displacement // R/M byte
567 }
568 }
570 // rRegI ereg, memory mem) %{ // emit_reg_mem
571 void encode_RegMem(CodeBuffer &cbuf,
572 int reg,
573 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc)
574 {
575 assert(disp_reloc == relocInfo::none, "cannot have disp");
576 int regenc = reg & 7;
577 int baseenc = base & 7;
578 int indexenc = index & 7;
580 // There is no index & no scale, use form without SIB byte
581 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) {
582 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
583 if (disp == 0 && base != RBP_enc && base != R13_enc) {
584 emit_rm(cbuf, 0x0, regenc, baseenc); // *
585 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
586 // If 8-bit displacement, mode 0x1
587 emit_rm(cbuf, 0x1, regenc, baseenc); // *
588 emit_d8(cbuf, disp);
589 } else {
590 // If 32-bit displacement
591 if (base == -1) { // Special flag for absolute address
592 emit_rm(cbuf, 0x0, regenc, 0x5); // *
593 if (disp_reloc != relocInfo::none) {
594 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
595 } else {
596 emit_d32(cbuf, disp);
597 }
598 } else {
599 // Normal base + offset
600 emit_rm(cbuf, 0x2, regenc, baseenc); // *
601 if (disp_reloc != relocInfo::none) {
602 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
603 } else {
604 emit_d32(cbuf, disp);
605 }
606 }
607 }
608 } else {
609 // Else, encode with the SIB byte
610 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
611 if (disp == 0 && base != RBP_enc && base != R13_enc) {
612 // If no displacement
613 emit_rm(cbuf, 0x0, regenc, 0x4); // *
614 emit_rm(cbuf, scale, indexenc, baseenc);
615 } else {
616 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
617 // If 8-bit displacement, mode 0x1
618 emit_rm(cbuf, 0x1, regenc, 0x4); // *
619 emit_rm(cbuf, scale, indexenc, baseenc);
620 emit_d8(cbuf, disp);
621 } else {
622 // If 32-bit displacement
623 if (base == 0x04 ) {
624 emit_rm(cbuf, 0x2, regenc, 0x4);
625 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
626 } else {
627 emit_rm(cbuf, 0x2, regenc, 0x4);
628 emit_rm(cbuf, scale, indexenc, baseenc); // *
629 }
630 if (disp_reloc != relocInfo::none) {
631 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
632 } else {
633 emit_d32(cbuf, disp);
634 }
635 }
636 }
637 }
638 }
640 // This could be in MacroAssembler but it's fairly C2 specific
641 void emit_cmpfp_fixup(MacroAssembler& _masm) {
642 Label exit;
643 __ jccb(Assembler::noParity, exit);
644 __ pushf();
645 //
646 // comiss/ucomiss instructions set ZF,PF,CF flags and
647 // zero OF,AF,SF for NaN values.
648 // Fixup flags by zeroing ZF,PF so that compare of NaN
649 // values returns 'less than' result (CF is set).
650 // Leave the rest of flags unchanged.
651 //
652 // 7 6 5 4 3 2 1 0
653 // |S|Z|r|A|r|P|r|C| (r - reserved bit)
654 // 0 0 1 0 1 0 1 1 (0x2B)
655 //
656 __ andq(Address(rsp, 0), 0xffffff2b);
657 __ popf();
658 __ bind(exit);
659 }
661 void emit_cmpfp3(MacroAssembler& _masm, Register dst) {
662 Label done;
663 __ movl(dst, -1);
664 __ jcc(Assembler::parity, done);
665 __ jcc(Assembler::below, done);
666 __ setb(Assembler::notEqual, dst);
667 __ movzbl(dst, dst);
668 __ bind(done);
669 }
672 //=============================================================================
673 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
675 int Compile::ConstantTable::calculate_table_base_offset() const {
676 return 0; // absolute addressing, no offset
677 }
679 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
680 // Empty encoding
681 }
683 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
684 return 0;
685 }
687 #ifndef PRODUCT
688 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
689 st->print("# MachConstantBaseNode (empty encoding)");
690 }
691 #endif
694 //=============================================================================
695 #ifndef PRODUCT
696 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
697 Compile* C = ra_->C;
699 int framesize = C->frame_slots() << LogBytesPerInt;
700 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
701 // Remove wordSize for return addr which is already pushed.
702 framesize -= wordSize;
704 if (C->need_stack_bang(framesize)) {
705 framesize -= wordSize;
706 st->print("# stack bang");
707 st->print("\n\t");
708 st->print("pushq rbp\t# Save rbp");
709 if (framesize) {
710 st->print("\n\t");
711 st->print("subq rsp, #%d\t# Create frame",framesize);
712 }
713 } else {
714 st->print("subq rsp, #%d\t# Create frame",framesize);
715 st->print("\n\t");
716 framesize -= wordSize;
717 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
718 }
720 if (VerifyStackAtCalls) {
721 st->print("\n\t");
722 framesize -= wordSize;
723 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize);
724 #ifdef ASSERT
725 st->print("\n\t");
726 st->print("# stack alignment check");
727 #endif
728 }
729 st->cr();
730 }
731 #endif
733 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
734 Compile* C = ra_->C;
735 MacroAssembler _masm(&cbuf);
737 int framesize = C->frame_slots() << LogBytesPerInt;
739 __ verified_entry(framesize, C->need_stack_bang(framesize), false);
741 C->set_frame_complete(cbuf.insts_size());
743 if (C->has_mach_constant_base_node()) {
744 // NOTE: We set the table base offset here because users might be
745 // emitted before MachConstantBaseNode.
746 Compile::ConstantTable& constant_table = C->constant_table();
747 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
748 }
749 }
751 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
752 {
753 return MachNode::size(ra_); // too many variables; just compute it
754 // the hard way
755 }
757 int MachPrologNode::reloc() const
758 {
759 return 0; // a large enough number
760 }
762 //=============================================================================
763 #ifndef PRODUCT
764 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
765 {
766 Compile* C = ra_->C;
767 int framesize = C->frame_slots() << LogBytesPerInt;
768 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
769 // Remove word for return adr already pushed
770 // and RBP
771 framesize -= 2*wordSize;
773 if (framesize) {
774 st->print_cr("addq rsp, %d\t# Destroy frame", framesize);
775 st->print("\t");
776 }
778 st->print_cr("popq rbp");
779 if (do_polling() && C->is_method_compilation()) {
780 st->print("\t");
781 if (Assembler::is_polling_page_far()) {
782 st->print_cr("movq rscratch1, #polling_page_address\n\t"
783 "testl rax, [rscratch1]\t"
784 "# Safepoint: poll for GC");
785 } else {
786 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t"
787 "# Safepoint: poll for GC");
788 }
789 }
790 }
791 #endif
793 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
794 {
795 Compile* C = ra_->C;
796 int framesize = C->frame_slots() << LogBytesPerInt;
797 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
798 // Remove word for return adr already pushed
799 // and RBP
800 framesize -= 2*wordSize;
802 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here
804 if (framesize) {
805 emit_opcode(cbuf, Assembler::REX_W);
806 if (framesize < 0x80) {
807 emit_opcode(cbuf, 0x83); // addq rsp, #framesize
808 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
809 emit_d8(cbuf, framesize);
810 } else {
811 emit_opcode(cbuf, 0x81); // addq rsp, #framesize
812 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
813 emit_d32(cbuf, framesize);
814 }
815 }
817 // popq rbp
818 emit_opcode(cbuf, 0x58 | RBP_enc);
820 if (do_polling() && C->is_method_compilation()) {
821 MacroAssembler _masm(&cbuf);
822 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
823 if (Assembler::is_polling_page_far()) {
824 __ lea(rscratch1, polling_page);
825 __ relocate(relocInfo::poll_return_type);
826 __ testl(rax, Address(rscratch1, 0));
827 } else {
828 __ testl(rax, polling_page);
829 }
830 }
831 }
833 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
834 {
835 return MachNode::size(ra_); // too many variables; just compute it
836 // the hard way
837 }
839 int MachEpilogNode::reloc() const
840 {
841 return 2; // a large enough number
842 }
844 const Pipeline* MachEpilogNode::pipeline() const
845 {
846 return MachNode::pipeline_class();
847 }
849 int MachEpilogNode::safepoint_offset() const
850 {
851 return 0;
852 }
854 //=============================================================================
856 enum RC {
857 rc_bad,
858 rc_int,
859 rc_float,
860 rc_stack
861 };
863 static enum RC rc_class(OptoReg::Name reg)
864 {
865 if( !OptoReg::is_valid(reg) ) return rc_bad;
867 if (OptoReg::is_stack(reg)) return rc_stack;
869 VMReg r = OptoReg::as_VMReg(reg);
871 if (r->is_Register()) return rc_int;
873 assert(r->is_XMMRegister(), "must be");
874 return rc_float;
875 }
877 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad.
878 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
879 int src_hi, int dst_hi, uint ireg, outputStream* st);
881 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
882 int stack_offset, int reg, uint ireg, outputStream* st);
884 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
885 int dst_offset, uint ireg, outputStream* st) {
886 if (cbuf) {
887 MacroAssembler _masm(cbuf);
888 switch (ireg) {
889 case Op_VecS:
890 __ movq(Address(rsp, -8), rax);
891 __ movl(rax, Address(rsp, src_offset));
892 __ movl(Address(rsp, dst_offset), rax);
893 __ movq(rax, Address(rsp, -8));
894 break;
895 case Op_VecD:
896 __ pushq(Address(rsp, src_offset));
897 __ popq (Address(rsp, dst_offset));
898 break;
899 case Op_VecX:
900 __ pushq(Address(rsp, src_offset));
901 __ popq (Address(rsp, dst_offset));
902 __ pushq(Address(rsp, src_offset+8));
903 __ popq (Address(rsp, dst_offset+8));
904 break;
905 case Op_VecY:
906 __ vmovdqu(Address(rsp, -32), xmm0);
907 __ vmovdqu(xmm0, Address(rsp, src_offset));
908 __ vmovdqu(Address(rsp, dst_offset), xmm0);
909 __ vmovdqu(xmm0, Address(rsp, -32));
910 break;
911 default:
912 ShouldNotReachHere();
913 }
914 #ifndef PRODUCT
915 } else {
916 switch (ireg) {
917 case Op_VecS:
918 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
919 "movl rax, [rsp + #%d]\n\t"
920 "movl [rsp + #%d], rax\n\t"
921 "movq rax, [rsp - #8]",
922 src_offset, dst_offset);
923 break;
924 case Op_VecD:
925 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
926 "popq [rsp + #%d]",
927 src_offset, dst_offset);
928 break;
929 case Op_VecX:
930 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t"
931 "popq [rsp + #%d]\n\t"
932 "pushq [rsp + #%d]\n\t"
933 "popq [rsp + #%d]",
934 src_offset, dst_offset, src_offset+8, dst_offset+8);
935 break;
936 case Op_VecY:
937 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
938 "vmovdqu xmm0, [rsp + #%d]\n\t"
939 "vmovdqu [rsp + #%d], xmm0\n\t"
940 "vmovdqu xmm0, [rsp - #32]",
941 src_offset, dst_offset);
942 break;
943 default:
944 ShouldNotReachHere();
945 }
946 #endif
947 }
948 }
950 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
951 PhaseRegAlloc* ra_,
952 bool do_size,
953 outputStream* st) const {
954 assert(cbuf != NULL || st != NULL, "sanity");
955 // Get registers to move
956 OptoReg::Name src_second = ra_->get_reg_second(in(1));
957 OptoReg::Name src_first = ra_->get_reg_first(in(1));
958 OptoReg::Name dst_second = ra_->get_reg_second(this);
959 OptoReg::Name dst_first = ra_->get_reg_first(this);
961 enum RC src_second_rc = rc_class(src_second);
962 enum RC src_first_rc = rc_class(src_first);
963 enum RC dst_second_rc = rc_class(dst_second);
964 enum RC dst_first_rc = rc_class(dst_first);
966 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
967 "must move at least 1 register" );
969 if (src_first == dst_first && src_second == dst_second) {
970 // Self copy, no move
971 return 0;
972 }
973 if (bottom_type()->isa_vect() != NULL) {
974 uint ireg = ideal_reg();
975 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
976 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
977 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
978 // mem -> mem
979 int src_offset = ra_->reg2offset(src_first);
980 int dst_offset = ra_->reg2offset(dst_first);
981 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st);
982 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) {
983 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st);
984 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) {
985 int stack_offset = ra_->reg2offset(dst_first);
986 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st);
987 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) {
988 int stack_offset = ra_->reg2offset(src_first);
989 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st);
990 } else {
991 ShouldNotReachHere();
992 }
993 return 0;
994 }
995 if (src_first_rc == rc_stack) {
996 // mem ->
997 if (dst_first_rc == rc_stack) {
998 // mem -> mem
999 assert(src_second != dst_first, "overlap");
1000 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1001 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1002 // 64-bit
1003 int src_offset = ra_->reg2offset(src_first);
1004 int dst_offset = ra_->reg2offset(dst_first);
1005 if (cbuf) {
1006 MacroAssembler _masm(cbuf);
1007 __ pushq(Address(rsp, src_offset));
1008 __ popq (Address(rsp, dst_offset));
1009 #ifndef PRODUCT
1010 } else {
1011 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1012 "popq [rsp + #%d]",
1013 src_offset, dst_offset);
1014 #endif
1015 }
1016 } else {
1017 // 32-bit
1018 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1019 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1020 // No pushl/popl, so:
1021 int src_offset = ra_->reg2offset(src_first);
1022 int dst_offset = ra_->reg2offset(dst_first);
1023 if (cbuf) {
1024 MacroAssembler _masm(cbuf);
1025 __ movq(Address(rsp, -8), rax);
1026 __ movl(rax, Address(rsp, src_offset));
1027 __ movl(Address(rsp, dst_offset), rax);
1028 __ movq(rax, Address(rsp, -8));
1029 #ifndef PRODUCT
1030 } else {
1031 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1032 "movl rax, [rsp + #%d]\n\t"
1033 "movl [rsp + #%d], rax\n\t"
1034 "movq rax, [rsp - #8]",
1035 src_offset, dst_offset);
1036 #endif
1037 }
1038 }
1039 return 0;
1040 } else if (dst_first_rc == rc_int) {
1041 // mem -> gpr
1042 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1043 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1044 // 64-bit
1045 int offset = ra_->reg2offset(src_first);
1046 if (cbuf) {
1047 MacroAssembler _masm(cbuf);
1048 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1049 #ifndef PRODUCT
1050 } else {
1051 st->print("movq %s, [rsp + #%d]\t# spill",
1052 Matcher::regName[dst_first],
1053 offset);
1054 #endif
1055 }
1056 } else {
1057 // 32-bit
1058 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1059 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1060 int offset = ra_->reg2offset(src_first);
1061 if (cbuf) {
1062 MacroAssembler _masm(cbuf);
1063 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1064 #ifndef PRODUCT
1065 } else {
1066 st->print("movl %s, [rsp + #%d]\t# spill",
1067 Matcher::regName[dst_first],
1068 offset);
1069 #endif
1070 }
1071 }
1072 return 0;
1073 } else if (dst_first_rc == rc_float) {
1074 // mem-> xmm
1075 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1076 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1077 // 64-bit
1078 int offset = ra_->reg2offset(src_first);
1079 if (cbuf) {
1080 MacroAssembler _masm(cbuf);
1081 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1082 #ifndef PRODUCT
1083 } else {
1084 st->print("%s %s, [rsp + #%d]\t# spill",
1085 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1086 Matcher::regName[dst_first],
1087 offset);
1088 #endif
1089 }
1090 } else {
1091 // 32-bit
1092 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1093 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1094 int offset = ra_->reg2offset(src_first);
1095 if (cbuf) {
1096 MacroAssembler _masm(cbuf);
1097 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1098 #ifndef PRODUCT
1099 } else {
1100 st->print("movss %s, [rsp + #%d]\t# spill",
1101 Matcher::regName[dst_first],
1102 offset);
1103 #endif
1104 }
1105 }
1106 return 0;
1107 }
1108 } else if (src_first_rc == rc_int) {
1109 // gpr ->
1110 if (dst_first_rc == rc_stack) {
1111 // gpr -> mem
1112 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1113 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1114 // 64-bit
1115 int offset = ra_->reg2offset(dst_first);
1116 if (cbuf) {
1117 MacroAssembler _masm(cbuf);
1118 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
1119 #ifndef PRODUCT
1120 } else {
1121 st->print("movq [rsp + #%d], %s\t# spill",
1122 offset,
1123 Matcher::regName[src_first]);
1124 #endif
1125 }
1126 } else {
1127 // 32-bit
1128 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1129 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1130 int offset = ra_->reg2offset(dst_first);
1131 if (cbuf) {
1132 MacroAssembler _masm(cbuf);
1133 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
1134 #ifndef PRODUCT
1135 } else {
1136 st->print("movl [rsp + #%d], %s\t# spill",
1137 offset,
1138 Matcher::regName[src_first]);
1139 #endif
1140 }
1141 }
1142 return 0;
1143 } else if (dst_first_rc == rc_int) {
1144 // gpr -> gpr
1145 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1146 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1147 // 64-bit
1148 if (cbuf) {
1149 MacroAssembler _masm(cbuf);
1150 __ movq(as_Register(Matcher::_regEncode[dst_first]),
1151 as_Register(Matcher::_regEncode[src_first]));
1152 #ifndef PRODUCT
1153 } else {
1154 st->print("movq %s, %s\t# spill",
1155 Matcher::regName[dst_first],
1156 Matcher::regName[src_first]);
1157 #endif
1158 }
1159 return 0;
1160 } else {
1161 // 32-bit
1162 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1163 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1164 if (cbuf) {
1165 MacroAssembler _masm(cbuf);
1166 __ movl(as_Register(Matcher::_regEncode[dst_first]),
1167 as_Register(Matcher::_regEncode[src_first]));
1168 #ifndef PRODUCT
1169 } else {
1170 st->print("movl %s, %s\t# spill",
1171 Matcher::regName[dst_first],
1172 Matcher::regName[src_first]);
1173 #endif
1174 }
1175 return 0;
1176 }
1177 } else if (dst_first_rc == rc_float) {
1178 // gpr -> xmm
1179 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1180 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1181 // 64-bit
1182 if (cbuf) {
1183 MacroAssembler _masm(cbuf);
1184 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1185 #ifndef PRODUCT
1186 } else {
1187 st->print("movdq %s, %s\t# spill",
1188 Matcher::regName[dst_first],
1189 Matcher::regName[src_first]);
1190 #endif
1191 }
1192 } else {
1193 // 32-bit
1194 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1195 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1196 if (cbuf) {
1197 MacroAssembler _masm(cbuf);
1198 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1199 #ifndef PRODUCT
1200 } else {
1201 st->print("movdl %s, %s\t# spill",
1202 Matcher::regName[dst_first],
1203 Matcher::regName[src_first]);
1204 #endif
1205 }
1206 }
1207 return 0;
1208 }
1209 } else if (src_first_rc == rc_float) {
1210 // xmm ->
1211 if (dst_first_rc == rc_stack) {
1212 // xmm -> mem
1213 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1214 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1215 // 64-bit
1216 int offset = ra_->reg2offset(dst_first);
1217 if (cbuf) {
1218 MacroAssembler _masm(cbuf);
1219 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1220 #ifndef PRODUCT
1221 } else {
1222 st->print("movsd [rsp + #%d], %s\t# spill",
1223 offset,
1224 Matcher::regName[src_first]);
1225 #endif
1226 }
1227 } else {
1228 // 32-bit
1229 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1230 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1231 int offset = ra_->reg2offset(dst_first);
1232 if (cbuf) {
1233 MacroAssembler _masm(cbuf);
1234 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1235 #ifndef PRODUCT
1236 } else {
1237 st->print("movss [rsp + #%d], %s\t# spill",
1238 offset,
1239 Matcher::regName[src_first]);
1240 #endif
1241 }
1242 }
1243 return 0;
1244 } else if (dst_first_rc == rc_int) {
1245 // xmm -> gpr
1246 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1247 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1248 // 64-bit
1249 if (cbuf) {
1250 MacroAssembler _masm(cbuf);
1251 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1252 #ifndef PRODUCT
1253 } else {
1254 st->print("movdq %s, %s\t# spill",
1255 Matcher::regName[dst_first],
1256 Matcher::regName[src_first]);
1257 #endif
1258 }
1259 } else {
1260 // 32-bit
1261 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1262 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1263 if (cbuf) {
1264 MacroAssembler _masm(cbuf);
1265 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1266 #ifndef PRODUCT
1267 } else {
1268 st->print("movdl %s, %s\t# spill",
1269 Matcher::regName[dst_first],
1270 Matcher::regName[src_first]);
1271 #endif
1272 }
1273 }
1274 return 0;
1275 } else if (dst_first_rc == rc_float) {
1276 // xmm -> xmm
1277 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1278 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1279 // 64-bit
1280 if (cbuf) {
1281 MacroAssembler _masm(cbuf);
1282 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1283 #ifndef PRODUCT
1284 } else {
1285 st->print("%s %s, %s\t# spill",
1286 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
1287 Matcher::regName[dst_first],
1288 Matcher::regName[src_first]);
1289 #endif
1290 }
1291 } else {
1292 // 32-bit
1293 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1294 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1295 if (cbuf) {
1296 MacroAssembler _masm(cbuf);
1297 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1298 #ifndef PRODUCT
1299 } else {
1300 st->print("%s %s, %s\t# spill",
1301 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1302 Matcher::regName[dst_first],
1303 Matcher::regName[src_first]);
1304 #endif
1305 }
1306 }
1307 return 0;
1308 }
1309 }
1311 assert(0," foo ");
1312 Unimplemented();
1313 return 0;
1314 }
1316 #ifndef PRODUCT
1317 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const {
1318 implementation(NULL, ra_, false, st);
1319 }
1320 #endif
1322 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1323 implementation(&cbuf, ra_, false, NULL);
1324 }
1326 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1327 return MachNode::size(ra_);
1328 }
1330 //=============================================================================
1331 #ifndef PRODUCT
1332 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1333 {
1334 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1335 int reg = ra_->get_reg_first(this);
1336 st->print("leaq %s, [rsp + #%d]\t# box lock",
1337 Matcher::regName[reg], offset);
1338 }
1339 #endif
1341 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1342 {
1343 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1344 int reg = ra_->get_encode(this);
1345 if (offset >= 0x80) {
1346 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1347 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1348 emit_rm(cbuf, 0x2, reg & 7, 0x04);
1349 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1350 emit_d32(cbuf, offset);
1351 } else {
1352 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1353 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1354 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1355 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1356 emit_d8(cbuf, offset);
1357 }
1358 }
1360 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1361 {
1362 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1363 return (offset < 0x80) ? 5 : 8; // REX
1364 }
1366 //=============================================================================
1368 // emit call stub, compiled java to interpreter
1369 void emit_java_to_interp(CodeBuffer& cbuf)
1370 {
1371 // Stub is fixed up when the corresponding call is converted from
1372 // calling compiled code to calling interpreted code.
1373 // movq rbx, 0
1374 // jmp -5 # to self
1376 address mark = cbuf.insts_mark(); // get mark within main instrs section
1378 // Note that the code buffer's insts_mark is always relative to insts.
1379 // That's why we must use the macroassembler to generate a stub.
1380 MacroAssembler _masm(&cbuf);
1382 address base =
1383 __ start_a_stub(Compile::MAX_stubs_size);
1384 if (base == NULL) return; // CodeBuffer::expand failed
1385 // static stub relocation stores the instruction address of the call
1386 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM64);
1387 // static stub relocation also tags the Method* in the code-stream.
1388 __ mov_metadata(rbx, (Metadata*) NULL); // method is zapped till fixup time
1389 // This is recognized as unresolved by relocs/nativeinst/ic code
1390 __ jump(RuntimeAddress(__ pc()));
1392 // Update current stubs pointer and restore insts_end.
1393 __ end_a_stub();
1394 }
1396 // size of call stub, compiled java to interpretor
1397 uint size_java_to_interp()
1398 {
1399 return 15; // movq (1+1+8); jmp (1+4)
1400 }
1402 // relocation entries for call stub, compiled java to interpretor
1403 uint reloc_java_to_interp()
1404 {
1405 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call
1406 }
1408 //=============================================================================
1409 #ifndef PRODUCT
1410 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1411 {
1412 if (UseCompressedKlassPointers) {
1413 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1414 if (Universe::narrow_klass_shift() != 0) {
1415 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1416 }
1417 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1418 } else {
1419 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1420 "# Inline cache check");
1421 }
1422 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1423 st->print_cr("\tnop\t# nops to align entry point");
1424 }
1425 #endif
1427 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1428 {
1429 MacroAssembler masm(&cbuf);
1430 uint insts_size = cbuf.insts_size();
1431 if (UseCompressedKlassPointers) {
1432 masm.load_klass(rscratch1, j_rarg0);
1433 masm.cmpptr(rax, rscratch1);
1434 } else {
1435 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1436 }
1438 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1440 /* WARNING these NOPs are critical so that verified entry point is properly
1441 4 bytes aligned for patching by NativeJump::patch_verified_entry() */
1442 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
1443 if (OptoBreakpoint) {
1444 // Leave space for int3
1445 nops_cnt -= 1;
1446 }
1447 nops_cnt &= 0x3; // Do not add nops if code is aligned.
1448 if (nops_cnt > 0)
1449 masm.nop(nops_cnt);
1450 }
1452 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1453 {
1454 return MachNode::size(ra_); // too many variables; just compute it
1455 // the hard way
1456 }
1459 //=============================================================================
1460 uint size_exception_handler()
1461 {
1462 // NativeCall instruction size is the same as NativeJump.
1463 // Note that this value is also credited (in output.cpp) to
1464 // the size of the code section.
1465 return NativeJump::instruction_size;
1466 }
1468 // Emit exception handler code.
1469 int emit_exception_handler(CodeBuffer& cbuf)
1470 {
1472 // Note that the code buffer's insts_mark is always relative to insts.
1473 // That's why we must use the macroassembler to generate a handler.
1474 MacroAssembler _masm(&cbuf);
1475 address base =
1476 __ start_a_stub(size_exception_handler());
1477 if (base == NULL) return 0; // CodeBuffer::expand failed
1478 int offset = __ offset();
1479 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
1480 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
1481 __ end_a_stub();
1482 return offset;
1483 }
1485 uint size_deopt_handler()
1486 {
1487 // three 5 byte instructions
1488 return 15;
1489 }
1491 // Emit deopt handler code.
1492 int emit_deopt_handler(CodeBuffer& cbuf)
1493 {
1495 // Note that the code buffer's insts_mark is always relative to insts.
1496 // That's why we must use the macroassembler to generate a handler.
1497 MacroAssembler _masm(&cbuf);
1498 address base =
1499 __ start_a_stub(size_deopt_handler());
1500 if (base == NULL) return 0; // CodeBuffer::expand failed
1501 int offset = __ offset();
1502 address the_pc = (address) __ pc();
1503 Label next;
1504 // push a "the_pc" on the stack without destroying any registers
1505 // as they all may be live.
1507 // push address of "next"
1508 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
1509 __ bind(next);
1510 // adjust it so it matches "the_pc"
1511 __ subptr(Address(rsp, 0), __ offset() - offset);
1512 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1513 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1514 __ end_a_stub();
1515 return offset;
1516 }
1518 int Matcher::regnum_to_fpu_offset(int regnum)
1519 {
1520 return regnum - 32; // The FP registers are in the second chunk
1521 }
1523 // This is UltraSparc specific, true just means we have fast l2f conversion
1524 const bool Matcher::convL2FSupported(void) {
1525 return true;
1526 }
1528 // Is this branch offset short enough that a short branch can be used?
1529 //
1530 // NOTE: If the platform does not provide any short branch variants, then
1531 // this method should return false for offset 0.
1532 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1533 // The passed offset is relative to address of the branch.
1534 // On 86 a branch displacement is calculated relative to address
1535 // of a next instruction.
1536 offset -= br_size;
1538 // the short version of jmpConUCF2 contains multiple branches,
1539 // making the reach slightly less
1540 if (rule == jmpConUCF2_rule)
1541 return (-126 <= offset && offset <= 125);
1542 return (-128 <= offset && offset <= 127);
1543 }
1545 const bool Matcher::isSimpleConstant64(jlong value) {
1546 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1547 //return value == (int) value; // Cf. storeImmL and immL32.
1549 // Probably always true, even if a temp register is required.
1550 return true;
1551 }
1553 // The ecx parameter to rep stosq for the ClearArray node is in words.
1554 const bool Matcher::init_array_count_is_in_bytes = false;
1556 // Threshold size for cleararray.
1557 const int Matcher::init_array_short_size = 8 * BytesPerLong;
1559 // No additional cost for CMOVL.
1560 const int Matcher::long_cmove_cost() { return 0; }
1562 // No CMOVF/CMOVD with SSE2
1563 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1565 // Should the Matcher clone shifts on addressing modes, expecting them
1566 // to be subsumed into complex addressing expressions or compute them
1567 // into registers? True for Intel but false for most RISCs
1568 const bool Matcher::clone_shift_expressions = true;
1570 // Do we need to mask the count passed to shift instructions or does
1571 // the cpu only look at the lower 5/6 bits anyway?
1572 const bool Matcher::need_masked_shift_count = false;
1574 bool Matcher::narrow_oop_use_complex_address() {
1575 assert(UseCompressedOops, "only for compressed oops code");
1576 return (LogMinObjAlignmentInBytes <= 3);
1577 }
1579 bool Matcher::narrow_klass_use_complex_address() {
1580 assert(UseCompressedKlassPointers, "only for compressed klass code");
1581 return (LogKlassAlignmentInBytes <= 3);
1582 }
1584 // Is it better to copy float constants, or load them directly from
1585 // memory? Intel can load a float constant from a direct address,
1586 // requiring no extra registers. Most RISCs will have to materialize
1587 // an address into a register first, so they would do better to copy
1588 // the constant from stack.
1589 const bool Matcher::rematerialize_float_constants = true; // XXX
1591 // If CPU can load and store mis-aligned doubles directly then no
1592 // fixup is needed. Else we split the double into 2 integer pieces
1593 // and move it piece-by-piece. Only happens when passing doubles into
1594 // C code as the Java calling convention forces doubles to be aligned.
1595 const bool Matcher::misaligned_doubles_ok = true;
1597 // No-op on amd64
1598 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {}
1600 // Advertise here if the CPU requires explicit rounding operations to
1601 // implement the UseStrictFP mode.
1602 const bool Matcher::strict_fp_requires_explicit_rounding = true;
1604 // Are floats conerted to double when stored to stack during deoptimization?
1605 // On x64 it is stored without convertion so we can use normal access.
1606 bool Matcher::float_in_double() { return false; }
1608 // Do ints take an entire long register or just half?
1609 const bool Matcher::int_in_long = true;
1611 // Return whether or not this register is ever used as an argument.
1612 // This function is used on startup to build the trampoline stubs in
1613 // generateOptoStub. Registers not mentioned will be killed by the VM
1614 // call in the trampoline, and arguments in those registers not be
1615 // available to the callee.
1616 bool Matcher::can_be_java_arg(int reg)
1617 {
1618 return
1619 reg == RDI_num || reg == RDI_H_num ||
1620 reg == RSI_num || reg == RSI_H_num ||
1621 reg == RDX_num || reg == RDX_H_num ||
1622 reg == RCX_num || reg == RCX_H_num ||
1623 reg == R8_num || reg == R8_H_num ||
1624 reg == R9_num || reg == R9_H_num ||
1625 reg == R12_num || reg == R12_H_num ||
1626 reg == XMM0_num || reg == XMM0b_num ||
1627 reg == XMM1_num || reg == XMM1b_num ||
1628 reg == XMM2_num || reg == XMM2b_num ||
1629 reg == XMM3_num || reg == XMM3b_num ||
1630 reg == XMM4_num || reg == XMM4b_num ||
1631 reg == XMM5_num || reg == XMM5b_num ||
1632 reg == XMM6_num || reg == XMM6b_num ||
1633 reg == XMM7_num || reg == XMM7b_num;
1634 }
1636 bool Matcher::is_spillable_arg(int reg)
1637 {
1638 return can_be_java_arg(reg);
1639 }
1641 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1642 // In 64 bit mode a code which use multiply when
1643 // devisor is constant is faster than hardware
1644 // DIV instruction (it uses MulHiL).
1645 return false;
1646 }
1648 // Register for DIVI projection of divmodI
1649 RegMask Matcher::divI_proj_mask() {
1650 return INT_RAX_REG_mask();
1651 }
1653 // Register for MODI projection of divmodI
1654 RegMask Matcher::modI_proj_mask() {
1655 return INT_RDX_REG_mask();
1656 }
1658 // Register for DIVL projection of divmodL
1659 RegMask Matcher::divL_proj_mask() {
1660 return LONG_RAX_REG_mask();
1661 }
1663 // Register for MODL projection of divmodL
1664 RegMask Matcher::modL_proj_mask() {
1665 return LONG_RDX_REG_mask();
1666 }
1668 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1669 return PTR_RBP_REG_mask();
1670 }
1672 static Address build_address(int b, int i, int s, int d) {
1673 Register index = as_Register(i);
1674 Address::ScaleFactor scale = (Address::ScaleFactor)s;
1675 if (index == rsp) {
1676 index = noreg;
1677 scale = Address::no_scale;
1678 }
1679 Address addr(as_Register(b), index, scale, d);
1680 return addr;
1681 }
1683 %}
1685 //----------ENCODING BLOCK-----------------------------------------------------
1686 // This block specifies the encoding classes used by the compiler to
1687 // output byte streams. Encoding classes are parameterized macros
1688 // used by Machine Instruction Nodes in order to generate the bit
1689 // encoding of the instruction. Operands specify their base encoding
1690 // interface with the interface keyword. There are currently
1691 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
1692 // COND_INTER. REG_INTER causes an operand to generate a function
1693 // which returns its register number when queried. CONST_INTER causes
1694 // an operand to generate a function which returns the value of the
1695 // constant when queried. MEMORY_INTER causes an operand to generate
1696 // four functions which return the Base Register, the Index Register,
1697 // the Scale Value, and the Offset Value of the operand when queried.
1698 // COND_INTER causes an operand to generate six functions which return
1699 // the encoding code (ie - encoding bits for the instruction)
1700 // associated with each basic boolean condition for a conditional
1701 // instruction.
1702 //
1703 // Instructions specify two basic values for encoding. Again, a
1704 // function is available to check if the constant displacement is an
1705 // oop. They use the ins_encode keyword to specify their encoding
1706 // classes (which must be a sequence of enc_class names, and their
1707 // parameters, specified in the encoding block), and they use the
1708 // opcode keyword to specify, in order, their primary, secondary, and
1709 // tertiary opcode. Only the opcode sections which a particular
1710 // instruction needs for encoding need to be specified.
1711 encode %{
1712 // Build emit functions for each basic byte or larger field in the
1713 // intel encoding scheme (opcode, rm, sib, immediate), and call them
1714 // from C++ code in the enc_class source block. Emit functions will
1715 // live in the main source block for now. In future, we can
1716 // generalize this by adding a syntax that specifies the sizes of
1717 // fields in an order, so that the adlc can build the emit functions
1718 // automagically
1720 // Emit primary opcode
1721 enc_class OpcP
1722 %{
1723 emit_opcode(cbuf, $primary);
1724 %}
1726 // Emit secondary opcode
1727 enc_class OpcS
1728 %{
1729 emit_opcode(cbuf, $secondary);
1730 %}
1732 // Emit tertiary opcode
1733 enc_class OpcT
1734 %{
1735 emit_opcode(cbuf, $tertiary);
1736 %}
1738 // Emit opcode directly
1739 enc_class Opcode(immI d8)
1740 %{
1741 emit_opcode(cbuf, $d8$$constant);
1742 %}
1744 // Emit size prefix
1745 enc_class SizePrefix
1746 %{
1747 emit_opcode(cbuf, 0x66);
1748 %}
1750 enc_class reg(rRegI reg)
1751 %{
1752 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
1753 %}
1755 enc_class reg_reg(rRegI dst, rRegI src)
1756 %{
1757 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1758 %}
1760 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
1761 %{
1762 emit_opcode(cbuf, $opcode$$constant);
1763 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1764 %}
1766 enc_class cdql_enc(no_rax_rdx_RegI div)
1767 %{
1768 // Full implementation of Java idiv and irem; checks for
1769 // special case as described in JVM spec., p.243 & p.271.
1770 //
1771 // normal case special case
1772 //
1773 // input : rax: dividend min_int
1774 // reg: divisor -1
1775 //
1776 // output: rax: quotient (= rax idiv reg) min_int
1777 // rdx: remainder (= rax irem reg) 0
1778 //
1779 // Code sequnce:
1780 //
1781 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax
1782 // 5: 75 07/08 jne e <normal>
1783 // 7: 33 d2 xor %edx,%edx
1784 // [div >= 8 -> offset + 1]
1785 // [REX_B]
1786 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div
1787 // c: 74 03/04 je 11 <done>
1788 // 000000000000000e <normal>:
1789 // e: 99 cltd
1790 // [div >= 8 -> offset + 1]
1791 // [REX_B]
1792 // f: f7 f9 idiv $div
1793 // 0000000000000011 <done>:
1795 // cmp $0x80000000,%eax
1796 emit_opcode(cbuf, 0x3d);
1797 emit_d8(cbuf, 0x00);
1798 emit_d8(cbuf, 0x00);
1799 emit_d8(cbuf, 0x00);
1800 emit_d8(cbuf, 0x80);
1802 // jne e <normal>
1803 emit_opcode(cbuf, 0x75);
1804 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08);
1806 // xor %edx,%edx
1807 emit_opcode(cbuf, 0x33);
1808 emit_d8(cbuf, 0xD2);
1810 // cmp $0xffffffffffffffff,%ecx
1811 if ($div$$reg >= 8) {
1812 emit_opcode(cbuf, Assembler::REX_B);
1813 }
1814 emit_opcode(cbuf, 0x83);
1815 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
1816 emit_d8(cbuf, 0xFF);
1818 // je 11 <done>
1819 emit_opcode(cbuf, 0x74);
1820 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04);
1822 // <normal>
1823 // cltd
1824 emit_opcode(cbuf, 0x99);
1826 // idivl (note: must be emitted by the user of this rule)
1827 // <done>
1828 %}
1830 enc_class cdqq_enc(no_rax_rdx_RegL div)
1831 %{
1832 // Full implementation of Java ldiv and lrem; checks for
1833 // special case as described in JVM spec., p.243 & p.271.
1834 //
1835 // normal case special case
1836 //
1837 // input : rax: dividend min_long
1838 // reg: divisor -1
1839 //
1840 // output: rax: quotient (= rax idiv reg) min_long
1841 // rdx: remainder (= rax irem reg) 0
1842 //
1843 // Code sequnce:
1844 //
1845 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx
1846 // 7: 00 00 80
1847 // a: 48 39 d0 cmp %rdx,%rax
1848 // d: 75 08 jne 17 <normal>
1849 // f: 33 d2 xor %edx,%edx
1850 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div
1851 // 15: 74 05 je 1c <done>
1852 // 0000000000000017 <normal>:
1853 // 17: 48 99 cqto
1854 // 19: 48 f7 f9 idiv $div
1855 // 000000000000001c <done>:
1857 // mov $0x8000000000000000,%rdx
1858 emit_opcode(cbuf, Assembler::REX_W);
1859 emit_opcode(cbuf, 0xBA);
1860 emit_d8(cbuf, 0x00);
1861 emit_d8(cbuf, 0x00);
1862 emit_d8(cbuf, 0x00);
1863 emit_d8(cbuf, 0x00);
1864 emit_d8(cbuf, 0x00);
1865 emit_d8(cbuf, 0x00);
1866 emit_d8(cbuf, 0x00);
1867 emit_d8(cbuf, 0x80);
1869 // cmp %rdx,%rax
1870 emit_opcode(cbuf, Assembler::REX_W);
1871 emit_opcode(cbuf, 0x39);
1872 emit_d8(cbuf, 0xD0);
1874 // jne 17 <normal>
1875 emit_opcode(cbuf, 0x75);
1876 emit_d8(cbuf, 0x08);
1878 // xor %edx,%edx
1879 emit_opcode(cbuf, 0x33);
1880 emit_d8(cbuf, 0xD2);
1882 // cmp $0xffffffffffffffff,$div
1883 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB);
1884 emit_opcode(cbuf, 0x83);
1885 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
1886 emit_d8(cbuf, 0xFF);
1888 // je 1e <done>
1889 emit_opcode(cbuf, 0x74);
1890 emit_d8(cbuf, 0x05);
1892 // <normal>
1893 // cqto
1894 emit_opcode(cbuf, Assembler::REX_W);
1895 emit_opcode(cbuf, 0x99);
1897 // idivq (note: must be emitted by the user of this rule)
1898 // <done>
1899 %}
1901 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
1902 enc_class OpcSE(immI imm)
1903 %{
1904 // Emit primary opcode and set sign-extend bit
1905 // Check for 8-bit immediate, and set sign extend bit in opcode
1906 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1907 emit_opcode(cbuf, $primary | 0x02);
1908 } else {
1909 // 32-bit immediate
1910 emit_opcode(cbuf, $primary);
1911 }
1912 %}
1914 enc_class OpcSErm(rRegI dst, immI imm)
1915 %{
1916 // OpcSEr/m
1917 int dstenc = $dst$$reg;
1918 if (dstenc >= 8) {
1919 emit_opcode(cbuf, Assembler::REX_B);
1920 dstenc -= 8;
1921 }
1922 // Emit primary opcode and set sign-extend bit
1923 // Check for 8-bit immediate, and set sign extend bit in opcode
1924 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1925 emit_opcode(cbuf, $primary | 0x02);
1926 } else {
1927 // 32-bit immediate
1928 emit_opcode(cbuf, $primary);
1929 }
1930 // Emit r/m byte with secondary opcode, after primary opcode.
1931 emit_rm(cbuf, 0x3, $secondary, dstenc);
1932 %}
1934 enc_class OpcSErm_wide(rRegL dst, immI imm)
1935 %{
1936 // OpcSEr/m
1937 int dstenc = $dst$$reg;
1938 if (dstenc < 8) {
1939 emit_opcode(cbuf, Assembler::REX_W);
1940 } else {
1941 emit_opcode(cbuf, Assembler::REX_WB);
1942 dstenc -= 8;
1943 }
1944 // Emit primary opcode and set sign-extend bit
1945 // Check for 8-bit immediate, and set sign extend bit in opcode
1946 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1947 emit_opcode(cbuf, $primary | 0x02);
1948 } else {
1949 // 32-bit immediate
1950 emit_opcode(cbuf, $primary);
1951 }
1952 // Emit r/m byte with secondary opcode, after primary opcode.
1953 emit_rm(cbuf, 0x3, $secondary, dstenc);
1954 %}
1956 enc_class Con8or32(immI imm)
1957 %{
1958 // Check for 8-bit immediate, and set sign extend bit in opcode
1959 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1960 $$$emit8$imm$$constant;
1961 } else {
1962 // 32-bit immediate
1963 $$$emit32$imm$$constant;
1964 }
1965 %}
1967 enc_class opc2_reg(rRegI dst)
1968 %{
1969 // BSWAP
1970 emit_cc(cbuf, $secondary, $dst$$reg);
1971 %}
1973 enc_class opc3_reg(rRegI dst)
1974 %{
1975 // BSWAP
1976 emit_cc(cbuf, $tertiary, $dst$$reg);
1977 %}
1979 enc_class reg_opc(rRegI div)
1980 %{
1981 // INC, DEC, IDIV, IMOD, JMP indirect, ...
1982 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
1983 %}
1985 enc_class enc_cmov(cmpOp cop)
1986 %{
1987 // CMOV
1988 $$$emit8$primary;
1989 emit_cc(cbuf, $secondary, $cop$$cmpcode);
1990 %}
1992 enc_class enc_PartialSubtypeCheck()
1993 %{
1994 Register Rrdi = as_Register(RDI_enc); // result register
1995 Register Rrax = as_Register(RAX_enc); // super class
1996 Register Rrcx = as_Register(RCX_enc); // killed
1997 Register Rrsi = as_Register(RSI_enc); // sub class
1998 Label miss;
1999 const bool set_cond_codes = true;
2001 MacroAssembler _masm(&cbuf);
2002 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
2003 NULL, &miss,
2004 /*set_cond_codes:*/ true);
2005 if ($primary) {
2006 __ xorptr(Rrdi, Rrdi);
2007 }
2008 __ bind(miss);
2009 %}
2011 enc_class Java_To_Interpreter(method meth)
2012 %{
2013 // CALL Java_To_Interpreter
2014 // This is the instruction starting address for relocation info.
2015 cbuf.set_insts_mark();
2016 $$$emit8$primary;
2017 // CALL directly to the runtime
2018 emit_d32_reloc(cbuf,
2019 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2020 runtime_call_Relocation::spec(),
2021 RELOC_DISP32);
2022 %}
2024 enc_class Java_Static_Call(method meth)
2025 %{
2026 // JAVA STATIC CALL
2027 // CALL to fixup routine. Fixup routine uses ScopeDesc info to
2028 // determine who we intended to call.
2029 cbuf.set_insts_mark();
2030 $$$emit8$primary;
2032 if (!_method) {
2033 emit_d32_reloc(cbuf,
2034 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2035 runtime_call_Relocation::spec(),
2036 RELOC_DISP32);
2037 } else if (_optimized_virtual) {
2038 emit_d32_reloc(cbuf,
2039 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2040 opt_virtual_call_Relocation::spec(),
2041 RELOC_DISP32);
2042 } else {
2043 emit_d32_reloc(cbuf,
2044 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2045 static_call_Relocation::spec(),
2046 RELOC_DISP32);
2047 }
2048 if (_method) {
2049 // Emit stub for static call
2050 emit_java_to_interp(cbuf);
2051 }
2052 %}
2054 enc_class Java_Dynamic_Call(method meth) %{
2055 MacroAssembler _masm(&cbuf);
2056 __ ic_call((address)$meth$$method);
2057 %}
2059 enc_class Java_Compiled_Call(method meth)
2060 %{
2061 // JAVA COMPILED CALL
2062 int disp = in_bytes(Method:: from_compiled_offset());
2064 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
2065 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
2067 // callq *disp(%rax)
2068 cbuf.set_insts_mark();
2069 $$$emit8$primary;
2070 if (disp < 0x80) {
2071 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
2072 emit_d8(cbuf, disp); // Displacement
2073 } else {
2074 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte
2075 emit_d32(cbuf, disp); // Displacement
2076 }
2077 %}
2079 enc_class reg_opc_imm(rRegI dst, immI8 shift)
2080 %{
2081 // SAL, SAR, SHR
2082 int dstenc = $dst$$reg;
2083 if (dstenc >= 8) {
2084 emit_opcode(cbuf, Assembler::REX_B);
2085 dstenc -= 8;
2086 }
2087 $$$emit8$primary;
2088 emit_rm(cbuf, 0x3, $secondary, dstenc);
2089 $$$emit8$shift$$constant;
2090 %}
2092 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift)
2093 %{
2094 // SAL, SAR, SHR
2095 int dstenc = $dst$$reg;
2096 if (dstenc < 8) {
2097 emit_opcode(cbuf, Assembler::REX_W);
2098 } else {
2099 emit_opcode(cbuf, Assembler::REX_WB);
2100 dstenc -= 8;
2101 }
2102 $$$emit8$primary;
2103 emit_rm(cbuf, 0x3, $secondary, dstenc);
2104 $$$emit8$shift$$constant;
2105 %}
2107 enc_class load_immI(rRegI dst, immI src)
2108 %{
2109 int dstenc = $dst$$reg;
2110 if (dstenc >= 8) {
2111 emit_opcode(cbuf, Assembler::REX_B);
2112 dstenc -= 8;
2113 }
2114 emit_opcode(cbuf, 0xB8 | dstenc);
2115 $$$emit32$src$$constant;
2116 %}
2118 enc_class load_immL(rRegL dst, immL src)
2119 %{
2120 int dstenc = $dst$$reg;
2121 if (dstenc < 8) {
2122 emit_opcode(cbuf, Assembler::REX_W);
2123 } else {
2124 emit_opcode(cbuf, Assembler::REX_WB);
2125 dstenc -= 8;
2126 }
2127 emit_opcode(cbuf, 0xB8 | dstenc);
2128 emit_d64(cbuf, $src$$constant);
2129 %}
2131 enc_class load_immUL32(rRegL dst, immUL32 src)
2132 %{
2133 // same as load_immI, but this time we care about zeroes in the high word
2134 int dstenc = $dst$$reg;
2135 if (dstenc >= 8) {
2136 emit_opcode(cbuf, Assembler::REX_B);
2137 dstenc -= 8;
2138 }
2139 emit_opcode(cbuf, 0xB8 | dstenc);
2140 $$$emit32$src$$constant;
2141 %}
2143 enc_class load_immL32(rRegL dst, immL32 src)
2144 %{
2145 int dstenc = $dst$$reg;
2146 if (dstenc < 8) {
2147 emit_opcode(cbuf, Assembler::REX_W);
2148 } else {
2149 emit_opcode(cbuf, Assembler::REX_WB);
2150 dstenc -= 8;
2151 }
2152 emit_opcode(cbuf, 0xC7);
2153 emit_rm(cbuf, 0x03, 0x00, dstenc);
2154 $$$emit32$src$$constant;
2155 %}
2157 enc_class load_immP31(rRegP dst, immP32 src)
2158 %{
2159 // same as load_immI, but this time we care about zeroes in the high word
2160 int dstenc = $dst$$reg;
2161 if (dstenc >= 8) {
2162 emit_opcode(cbuf, Assembler::REX_B);
2163 dstenc -= 8;
2164 }
2165 emit_opcode(cbuf, 0xB8 | dstenc);
2166 $$$emit32$src$$constant;
2167 %}
2169 enc_class load_immP(rRegP dst, immP src)
2170 %{
2171 int dstenc = $dst$$reg;
2172 if (dstenc < 8) {
2173 emit_opcode(cbuf, Assembler::REX_W);
2174 } else {
2175 emit_opcode(cbuf, Assembler::REX_WB);
2176 dstenc -= 8;
2177 }
2178 emit_opcode(cbuf, 0xB8 | dstenc);
2179 // This next line should be generated from ADLC
2180 if ($src->constant_reloc() != relocInfo::none) {
2181 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64);
2182 } else {
2183 emit_d64(cbuf, $src$$constant);
2184 }
2185 %}
2187 enc_class Con32(immI src)
2188 %{
2189 // Output immediate
2190 $$$emit32$src$$constant;
2191 %}
2193 enc_class Con64(immL src)
2194 %{
2195 // Output immediate
2196 emit_d64($src$$constant);
2197 %}
2199 enc_class Con32F_as_bits(immF src)
2200 %{
2201 // Output Float immediate bits
2202 jfloat jf = $src$$constant;
2203 jint jf_as_bits = jint_cast(jf);
2204 emit_d32(cbuf, jf_as_bits);
2205 %}
2207 enc_class Con16(immI src)
2208 %{
2209 // Output immediate
2210 $$$emit16$src$$constant;
2211 %}
2213 // How is this different from Con32??? XXX
2214 enc_class Con_d32(immI src)
2215 %{
2216 emit_d32(cbuf,$src$$constant);
2217 %}
2219 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
2220 // Output immediate memory reference
2221 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2222 emit_d32(cbuf, 0x00);
2223 %}
2225 enc_class lock_prefix()
2226 %{
2227 if (os::is_MP()) {
2228 emit_opcode(cbuf, 0xF0); // lock
2229 }
2230 %}
2232 enc_class REX_mem(memory mem)
2233 %{
2234 if ($mem$$base >= 8) {
2235 if ($mem$$index < 8) {
2236 emit_opcode(cbuf, Assembler::REX_B);
2237 } else {
2238 emit_opcode(cbuf, Assembler::REX_XB);
2239 }
2240 } else {
2241 if ($mem$$index >= 8) {
2242 emit_opcode(cbuf, Assembler::REX_X);
2243 }
2244 }
2245 %}
2247 enc_class REX_mem_wide(memory mem)
2248 %{
2249 if ($mem$$base >= 8) {
2250 if ($mem$$index < 8) {
2251 emit_opcode(cbuf, Assembler::REX_WB);
2252 } else {
2253 emit_opcode(cbuf, Assembler::REX_WXB);
2254 }
2255 } else {
2256 if ($mem$$index < 8) {
2257 emit_opcode(cbuf, Assembler::REX_W);
2258 } else {
2259 emit_opcode(cbuf, Assembler::REX_WX);
2260 }
2261 }
2262 %}
2264 // for byte regs
2265 enc_class REX_breg(rRegI reg)
2266 %{
2267 if ($reg$$reg >= 4) {
2268 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2269 }
2270 %}
2272 // for byte regs
2273 enc_class REX_reg_breg(rRegI dst, rRegI src)
2274 %{
2275 if ($dst$$reg < 8) {
2276 if ($src$$reg >= 4) {
2277 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2278 }
2279 } else {
2280 if ($src$$reg < 8) {
2281 emit_opcode(cbuf, Assembler::REX_R);
2282 } else {
2283 emit_opcode(cbuf, Assembler::REX_RB);
2284 }
2285 }
2286 %}
2288 // for byte regs
2289 enc_class REX_breg_mem(rRegI reg, memory mem)
2290 %{
2291 if ($reg$$reg < 8) {
2292 if ($mem$$base < 8) {
2293 if ($mem$$index >= 8) {
2294 emit_opcode(cbuf, Assembler::REX_X);
2295 } else if ($reg$$reg >= 4) {
2296 emit_opcode(cbuf, Assembler::REX);
2297 }
2298 } else {
2299 if ($mem$$index < 8) {
2300 emit_opcode(cbuf, Assembler::REX_B);
2301 } else {
2302 emit_opcode(cbuf, Assembler::REX_XB);
2303 }
2304 }
2305 } else {
2306 if ($mem$$base < 8) {
2307 if ($mem$$index < 8) {
2308 emit_opcode(cbuf, Assembler::REX_R);
2309 } else {
2310 emit_opcode(cbuf, Assembler::REX_RX);
2311 }
2312 } else {
2313 if ($mem$$index < 8) {
2314 emit_opcode(cbuf, Assembler::REX_RB);
2315 } else {
2316 emit_opcode(cbuf, Assembler::REX_RXB);
2317 }
2318 }
2319 }
2320 %}
2322 enc_class REX_reg(rRegI reg)
2323 %{
2324 if ($reg$$reg >= 8) {
2325 emit_opcode(cbuf, Assembler::REX_B);
2326 }
2327 %}
2329 enc_class REX_reg_wide(rRegI reg)
2330 %{
2331 if ($reg$$reg < 8) {
2332 emit_opcode(cbuf, Assembler::REX_W);
2333 } else {
2334 emit_opcode(cbuf, Assembler::REX_WB);
2335 }
2336 %}
2338 enc_class REX_reg_reg(rRegI dst, rRegI src)
2339 %{
2340 if ($dst$$reg < 8) {
2341 if ($src$$reg >= 8) {
2342 emit_opcode(cbuf, Assembler::REX_B);
2343 }
2344 } else {
2345 if ($src$$reg < 8) {
2346 emit_opcode(cbuf, Assembler::REX_R);
2347 } else {
2348 emit_opcode(cbuf, Assembler::REX_RB);
2349 }
2350 }
2351 %}
2353 enc_class REX_reg_reg_wide(rRegI dst, rRegI src)
2354 %{
2355 if ($dst$$reg < 8) {
2356 if ($src$$reg < 8) {
2357 emit_opcode(cbuf, Assembler::REX_W);
2358 } else {
2359 emit_opcode(cbuf, Assembler::REX_WB);
2360 }
2361 } else {
2362 if ($src$$reg < 8) {
2363 emit_opcode(cbuf, Assembler::REX_WR);
2364 } else {
2365 emit_opcode(cbuf, Assembler::REX_WRB);
2366 }
2367 }
2368 %}
2370 enc_class REX_reg_mem(rRegI reg, memory mem)
2371 %{
2372 if ($reg$$reg < 8) {
2373 if ($mem$$base < 8) {
2374 if ($mem$$index >= 8) {
2375 emit_opcode(cbuf, Assembler::REX_X);
2376 }
2377 } else {
2378 if ($mem$$index < 8) {
2379 emit_opcode(cbuf, Assembler::REX_B);
2380 } else {
2381 emit_opcode(cbuf, Assembler::REX_XB);
2382 }
2383 }
2384 } else {
2385 if ($mem$$base < 8) {
2386 if ($mem$$index < 8) {
2387 emit_opcode(cbuf, Assembler::REX_R);
2388 } else {
2389 emit_opcode(cbuf, Assembler::REX_RX);
2390 }
2391 } else {
2392 if ($mem$$index < 8) {
2393 emit_opcode(cbuf, Assembler::REX_RB);
2394 } else {
2395 emit_opcode(cbuf, Assembler::REX_RXB);
2396 }
2397 }
2398 }
2399 %}
2401 enc_class REX_reg_mem_wide(rRegL reg, memory mem)
2402 %{
2403 if ($reg$$reg < 8) {
2404 if ($mem$$base < 8) {
2405 if ($mem$$index < 8) {
2406 emit_opcode(cbuf, Assembler::REX_W);
2407 } else {
2408 emit_opcode(cbuf, Assembler::REX_WX);
2409 }
2410 } else {
2411 if ($mem$$index < 8) {
2412 emit_opcode(cbuf, Assembler::REX_WB);
2413 } else {
2414 emit_opcode(cbuf, Assembler::REX_WXB);
2415 }
2416 }
2417 } else {
2418 if ($mem$$base < 8) {
2419 if ($mem$$index < 8) {
2420 emit_opcode(cbuf, Assembler::REX_WR);
2421 } else {
2422 emit_opcode(cbuf, Assembler::REX_WRX);
2423 }
2424 } else {
2425 if ($mem$$index < 8) {
2426 emit_opcode(cbuf, Assembler::REX_WRB);
2427 } else {
2428 emit_opcode(cbuf, Assembler::REX_WRXB);
2429 }
2430 }
2431 }
2432 %}
2434 enc_class reg_mem(rRegI ereg, memory mem)
2435 %{
2436 // High registers handle in encode_RegMem
2437 int reg = $ereg$$reg;
2438 int base = $mem$$base;
2439 int index = $mem$$index;
2440 int scale = $mem$$scale;
2441 int disp = $mem$$disp;
2442 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2444 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc);
2445 %}
2447 enc_class RM_opc_mem(immI rm_opcode, memory mem)
2448 %{
2449 int rm_byte_opcode = $rm_opcode$$constant;
2451 // High registers handle in encode_RegMem
2452 int base = $mem$$base;
2453 int index = $mem$$index;
2454 int scale = $mem$$scale;
2455 int displace = $mem$$disp;
2457 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when
2458 // working with static
2459 // globals
2460 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace,
2461 disp_reloc);
2462 %}
2464 enc_class reg_lea(rRegI dst, rRegI src0, immI src1)
2465 %{
2466 int reg_encoding = $dst$$reg;
2467 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
2468 int index = 0x04; // 0x04 indicates no index
2469 int scale = 0x00; // 0x00 indicates no scale
2470 int displace = $src1$$constant; // 0x00 indicates no displacement
2471 relocInfo::relocType disp_reloc = relocInfo::none;
2472 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace,
2473 disp_reloc);
2474 %}
2476 enc_class neg_reg(rRegI dst)
2477 %{
2478 int dstenc = $dst$$reg;
2479 if (dstenc >= 8) {
2480 emit_opcode(cbuf, Assembler::REX_B);
2481 dstenc -= 8;
2482 }
2483 // NEG $dst
2484 emit_opcode(cbuf, 0xF7);
2485 emit_rm(cbuf, 0x3, 0x03, dstenc);
2486 %}
2488 enc_class neg_reg_wide(rRegI dst)
2489 %{
2490 int dstenc = $dst$$reg;
2491 if (dstenc < 8) {
2492 emit_opcode(cbuf, Assembler::REX_W);
2493 } else {
2494 emit_opcode(cbuf, Assembler::REX_WB);
2495 dstenc -= 8;
2496 }
2497 // NEG $dst
2498 emit_opcode(cbuf, 0xF7);
2499 emit_rm(cbuf, 0x3, 0x03, dstenc);
2500 %}
2502 enc_class setLT_reg(rRegI dst)
2503 %{
2504 int dstenc = $dst$$reg;
2505 if (dstenc >= 8) {
2506 emit_opcode(cbuf, Assembler::REX_B);
2507 dstenc -= 8;
2508 } else if (dstenc >= 4) {
2509 emit_opcode(cbuf, Assembler::REX);
2510 }
2511 // SETLT $dst
2512 emit_opcode(cbuf, 0x0F);
2513 emit_opcode(cbuf, 0x9C);
2514 emit_rm(cbuf, 0x3, 0x0, dstenc);
2515 %}
2517 enc_class setNZ_reg(rRegI dst)
2518 %{
2519 int dstenc = $dst$$reg;
2520 if (dstenc >= 8) {
2521 emit_opcode(cbuf, Assembler::REX_B);
2522 dstenc -= 8;
2523 } else if (dstenc >= 4) {
2524 emit_opcode(cbuf, Assembler::REX);
2525 }
2526 // SETNZ $dst
2527 emit_opcode(cbuf, 0x0F);
2528 emit_opcode(cbuf, 0x95);
2529 emit_rm(cbuf, 0x3, 0x0, dstenc);
2530 %}
2533 // Compare the lonogs and set -1, 0, or 1 into dst
2534 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst)
2535 %{
2536 int src1enc = $src1$$reg;
2537 int src2enc = $src2$$reg;
2538 int dstenc = $dst$$reg;
2540 // cmpq $src1, $src2
2541 if (src1enc < 8) {
2542 if (src2enc < 8) {
2543 emit_opcode(cbuf, Assembler::REX_W);
2544 } else {
2545 emit_opcode(cbuf, Assembler::REX_WB);
2546 }
2547 } else {
2548 if (src2enc < 8) {
2549 emit_opcode(cbuf, Assembler::REX_WR);
2550 } else {
2551 emit_opcode(cbuf, Assembler::REX_WRB);
2552 }
2553 }
2554 emit_opcode(cbuf, 0x3B);
2555 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7);
2557 // movl $dst, -1
2558 if (dstenc >= 8) {
2559 emit_opcode(cbuf, Assembler::REX_B);
2560 }
2561 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
2562 emit_d32(cbuf, -1);
2564 // jl,s done
2565 emit_opcode(cbuf, 0x7C);
2566 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
2568 // setne $dst
2569 if (dstenc >= 4) {
2570 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
2571 }
2572 emit_opcode(cbuf, 0x0F);
2573 emit_opcode(cbuf, 0x95);
2574 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
2576 // movzbl $dst, $dst
2577 if (dstenc >= 4) {
2578 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
2579 }
2580 emit_opcode(cbuf, 0x0F);
2581 emit_opcode(cbuf, 0xB6);
2582 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
2583 %}
2585 enc_class Push_ResultXD(regD dst) %{
2586 MacroAssembler _masm(&cbuf);
2587 __ fstp_d(Address(rsp, 0));
2588 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
2589 __ addptr(rsp, 8);
2590 %}
2592 enc_class Push_SrcXD(regD src) %{
2593 MacroAssembler _masm(&cbuf);
2594 __ subptr(rsp, 8);
2595 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
2596 __ fld_d(Address(rsp, 0));
2597 %}
2600 // obj: object to lock
2601 // box: box address (header location) -- killed
2602 // tmp: rax -- killed
2603 // scr: rbx -- killed
2604 //
2605 // What follows is a direct transliteration of fast_lock() and fast_unlock()
2606 // from i486.ad. See that file for comments.
2607 // TODO: where possible switch from movq (r, 0) to movl(r,0) and
2608 // use the shorter encoding. (Movl clears the high-order 32-bits).
2611 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr)
2612 %{
2613 Register objReg = as_Register((int)$obj$$reg);
2614 Register boxReg = as_Register((int)$box$$reg);
2615 Register tmpReg = as_Register($tmp$$reg);
2616 Register scrReg = as_Register($scr$$reg);
2617 MacroAssembler masm(&cbuf);
2619 // Verify uniqueness of register assignments -- necessary but not sufficient
2620 assert (objReg != boxReg && objReg != tmpReg &&
2621 objReg != scrReg && tmpReg != scrReg, "invariant") ;
2623 if (_counters != NULL) {
2624 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr()));
2625 }
2626 if (EmitSync & 1) {
2627 // Without cast to int32_t a movptr will destroy r10 which is typically obj
2628 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
2629 masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
2630 } else
2631 if (EmitSync & 2) {
2632 Label DONE_LABEL;
2633 if (UseBiasedLocking) {
2634 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument.
2635 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
2636 }
2637 // QQQ was movl...
2638 masm.movptr(tmpReg, 0x1);
2639 masm.orptr(tmpReg, Address(objReg, 0));
2640 masm.movptr(Address(boxReg, 0), tmpReg);
2641 if (os::is_MP()) {
2642 masm.lock();
2643 }
2644 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
2645 masm.jcc(Assembler::equal, DONE_LABEL);
2647 // Recursive locking
2648 masm.subptr(tmpReg, rsp);
2649 masm.andptr(tmpReg, 7 - os::vm_page_size());
2650 masm.movptr(Address(boxReg, 0), tmpReg);
2652 masm.bind(DONE_LABEL);
2653 masm.nop(); // avoid branch to branch
2654 } else {
2655 Label DONE_LABEL, IsInflated, Egress;
2657 masm.movptr(tmpReg, Address(objReg, 0)) ;
2658 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased
2659 masm.jcc (Assembler::notZero, IsInflated) ;
2661 // it's stack-locked, biased or neutral
2662 // TODO: optimize markword triage order to reduce the number of
2663 // conditional branches in the most common cases.
2664 // Beware -- there's a subtle invariant that fetch of the markword
2665 // at [FETCH], below, will never observe a biased encoding (*101b).
2666 // If this invariant is not held we'll suffer exclusion (safety) failure.
2668 if (UseBiasedLocking && !UseOptoBiasInlining) {
2669 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
2670 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH]
2671 }
2673 // was q will it destroy high?
2674 masm.orl (tmpReg, 1) ;
2675 masm.movptr(Address(boxReg, 0), tmpReg) ;
2676 if (os::is_MP()) { masm.lock(); }
2677 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
2678 if (_counters != NULL) {
2679 masm.cond_inc32(Assembler::equal,
2680 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
2681 }
2682 masm.jcc (Assembler::equal, DONE_LABEL);
2684 // Recursive locking
2685 masm.subptr(tmpReg, rsp);
2686 masm.andptr(tmpReg, 7 - os::vm_page_size());
2687 masm.movptr(Address(boxReg, 0), tmpReg);
2688 if (_counters != NULL) {
2689 masm.cond_inc32(Assembler::equal,
2690 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
2691 }
2692 masm.jmp (DONE_LABEL) ;
2694 masm.bind (IsInflated) ;
2695 // It's inflated
2697 // TODO: someday avoid the ST-before-CAS penalty by
2698 // relocating (deferring) the following ST.
2699 // We should also think about trying a CAS without having
2700 // fetched _owner. If the CAS is successful we may
2701 // avoid an RTO->RTS upgrade on the $line.
2702 // Without cast to int32_t a movptr will destroy r10 which is typically obj
2703 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
2705 masm.mov (boxReg, tmpReg) ;
2706 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
2707 masm.testptr(tmpReg, tmpReg) ;
2708 masm.jcc (Assembler::notZero, DONE_LABEL) ;
2710 // It's inflated and appears unlocked
2711 if (os::is_MP()) { masm.lock(); }
2712 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
2713 // Intentional fall-through into DONE_LABEL ...
2715 masm.bind (DONE_LABEL) ;
2716 masm.nop () ; // avoid jmp to jmp
2717 }
2718 %}
2720 // obj: object to unlock
2721 // box: box address (displaced header location), killed
2722 // RBX: killed tmp; cannot be obj nor box
2723 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp)
2724 %{
2726 Register objReg = as_Register($obj$$reg);
2727 Register boxReg = as_Register($box$$reg);
2728 Register tmpReg = as_Register($tmp$$reg);
2729 MacroAssembler masm(&cbuf);
2731 if (EmitSync & 4) {
2732 masm.cmpptr(rsp, 0) ;
2733 } else
2734 if (EmitSync & 8) {
2735 Label DONE_LABEL;
2736 if (UseBiasedLocking) {
2737 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
2738 }
2740 // Check whether the displaced header is 0
2741 //(=> recursive unlock)
2742 masm.movptr(tmpReg, Address(boxReg, 0));
2743 masm.testptr(tmpReg, tmpReg);
2744 masm.jcc(Assembler::zero, DONE_LABEL);
2746 // If not recursive lock, reset the header to displaced header
2747 if (os::is_MP()) {
2748 masm.lock();
2749 }
2750 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
2751 masm.bind(DONE_LABEL);
2752 masm.nop(); // avoid branch to branch
2753 } else {
2754 Label DONE_LABEL, Stacked, CheckSucc ;
2756 if (UseBiasedLocking && !UseOptoBiasInlining) {
2757 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
2758 }
2760 masm.movptr(tmpReg, Address(objReg, 0)) ;
2761 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
2762 masm.jcc (Assembler::zero, DONE_LABEL) ;
2763 masm.testl (tmpReg, 0x02) ;
2764 masm.jcc (Assembler::zero, Stacked) ;
2766 // It's inflated
2767 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
2768 masm.xorptr(boxReg, r15_thread) ;
2769 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
2770 masm.jcc (Assembler::notZero, DONE_LABEL) ;
2771 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
2772 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
2773 masm.jcc (Assembler::notZero, CheckSucc) ;
2774 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
2775 masm.jmp (DONE_LABEL) ;
2777 if ((EmitSync & 65536) == 0) {
2778 Label LSuccess, LGoSlowPath ;
2779 masm.bind (CheckSucc) ;
2780 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
2781 masm.jcc (Assembler::zero, LGoSlowPath) ;
2783 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the
2784 // the explicit ST;MEMBAR combination, but masm doesn't currently support
2785 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc
2786 // are all faster when the write buffer is populated.
2787 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
2788 if (os::is_MP()) {
2789 masm.lock () ; masm.addl (Address(rsp, 0), 0) ;
2790 }
2791 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
2792 masm.jcc (Assembler::notZero, LSuccess) ;
2794 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX
2795 if (os::is_MP()) { masm.lock(); }
2796 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2));
2797 masm.jcc (Assembler::notEqual, LSuccess) ;
2798 // Intentional fall-through into slow-path
2800 masm.bind (LGoSlowPath) ;
2801 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure
2802 masm.jmp (DONE_LABEL) ;
2804 masm.bind (LSuccess) ;
2805 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success
2806 masm.jmp (DONE_LABEL) ;
2807 }
2809 masm.bind (Stacked) ;
2810 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch
2811 if (os::is_MP()) { masm.lock(); }
2812 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
2814 if (EmitSync & 65536) {
2815 masm.bind (CheckSucc) ;
2816 }
2817 masm.bind(DONE_LABEL);
2818 if (EmitSync & 32768) {
2819 masm.nop(); // avoid branch to branch
2820 }
2821 }
2822 %}
2825 enc_class enc_rethrow()
2826 %{
2827 cbuf.set_insts_mark();
2828 emit_opcode(cbuf, 0xE9); // jmp entry
2829 emit_d32_reloc(cbuf,
2830 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
2831 runtime_call_Relocation::spec(),
2832 RELOC_DISP32);
2833 %}
2835 %}
2839 //----------FRAME--------------------------------------------------------------
2840 // Definition of frame structure and management information.
2841 //
2842 // S T A C K L A Y O U T Allocators stack-slot number
2843 // | (to get allocators register number
2844 // G Owned by | | v add OptoReg::stack0())
2845 // r CALLER | |
2846 // o | +--------+ pad to even-align allocators stack-slot
2847 // w V | pad0 | numbers; owned by CALLER
2848 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
2849 // h ^ | in | 5
2850 // | | args | 4 Holes in incoming args owned by SELF
2851 // | | | | 3
2852 // | | +--------+
2853 // V | | old out| Empty on Intel, window on Sparc
2854 // | old |preserve| Must be even aligned.
2855 // | SP-+--------+----> Matcher::_old_SP, even aligned
2856 // | | in | 3 area for Intel ret address
2857 // Owned by |preserve| Empty on Sparc.
2858 // SELF +--------+
2859 // | | pad2 | 2 pad to align old SP
2860 // | +--------+ 1
2861 // | | locks | 0
2862 // | +--------+----> OptoReg::stack0(), even aligned
2863 // | | pad1 | 11 pad to align new SP
2864 // | +--------+
2865 // | | | 10
2866 // | | spills | 9 spills
2867 // V | | 8 (pad0 slot for callee)
2868 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
2869 // ^ | out | 7
2870 // | | args | 6 Holes in outgoing args owned by CALLEE
2871 // Owned by +--------+
2872 // CALLEE | new out| 6 Empty on Intel, window on Sparc
2873 // | new |preserve| Must be even-aligned.
2874 // | SP-+--------+----> Matcher::_new_SP, even aligned
2875 // | | |
2876 //
2877 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
2878 // known from SELF's arguments and the Java calling convention.
2879 // Region 6-7 is determined per call site.
2880 // Note 2: If the calling convention leaves holes in the incoming argument
2881 // area, those holes are owned by SELF. Holes in the outgoing area
2882 // are owned by the CALLEE. Holes should not be nessecary in the
2883 // incoming area, as the Java calling convention is completely under
2884 // the control of the AD file. Doubles can be sorted and packed to
2885 // avoid holes. Holes in the outgoing arguments may be nessecary for
2886 // varargs C calling conventions.
2887 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
2888 // even aligned with pad0 as needed.
2889 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
2890 // region 6-11 is even aligned; it may be padded out more so that
2891 // the region from SP to FP meets the minimum stack alignment.
2892 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
2893 // alignment. Region 11, pad1, may be dynamically extended so that
2894 // SP meets the minimum alignment.
2896 frame
2897 %{
2898 // What direction does stack grow in (assumed to be same for C & Java)
2899 stack_direction(TOWARDS_LOW);
2901 // These three registers define part of the calling convention
2902 // between compiled code and the interpreter.
2903 inline_cache_reg(RAX); // Inline Cache Register
2904 interpreter_method_oop_reg(RBX); // Method Oop Register when
2905 // calling interpreter
2907 // Optional: name the operand used by cisc-spilling to access
2908 // [stack_pointer + offset]
2909 cisc_spilling_operand_name(indOffset32);
2911 // Number of stack slots consumed by locking an object
2912 sync_stack_slots(2);
2914 // Compiled code's Frame Pointer
2915 frame_pointer(RSP);
2917 // Interpreter stores its frame pointer in a register which is
2918 // stored to the stack by I2CAdaptors.
2919 // I2CAdaptors convert from interpreted java to compiled java.
2920 interpreter_frame_pointer(RBP);
2922 // Stack alignment requirement
2923 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
2925 // Number of stack slots between incoming argument block and the start of
2926 // a new frame. The PROLOG must add this many slots to the stack. The
2927 // EPILOG must remove this many slots. amd64 needs two slots for
2928 // return address.
2929 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls);
2931 // Number of outgoing stack slots killed above the out_preserve_stack_slots
2932 // for calls to C. Supports the var-args backing area for register parms.
2933 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
2935 // The after-PROLOG location of the return address. Location of
2936 // return address specifies a type (REG or STACK) and a number
2937 // representing the register number (i.e. - use a register name) or
2938 // stack slot.
2939 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
2940 // Otherwise, it is above the locks and verification slot and alignment word
2941 return_addr(STACK - 2 +
2942 round_to((Compile::current()->in_preserve_stack_slots() +
2943 Compile::current()->fixed_slots()),
2944 stack_alignment_in_slots()));
2946 // Body of function which returns an integer array locating
2947 // arguments either in registers or in stack slots. Passed an array
2948 // of ideal registers called "sig" and a "length" count. Stack-slot
2949 // offsets are based on outgoing arguments, i.e. a CALLER setting up
2950 // arguments for a CALLEE. Incoming stack arguments are
2951 // automatically biased by the preserve_stack_slots field above.
2953 calling_convention
2954 %{
2955 // No difference between ingoing/outgoing just pass false
2956 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
2957 %}
2959 c_calling_convention
2960 %{
2961 // This is obviously always outgoing
2962 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length);
2963 %}
2965 // Location of compiled Java return values. Same as C for now.
2966 return_value
2967 %{
2968 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
2969 "only return normal values");
2971 static const int lo[Op_RegL + 1] = {
2972 0,
2973 0,
2974 RAX_num, // Op_RegN
2975 RAX_num, // Op_RegI
2976 RAX_num, // Op_RegP
2977 XMM0_num, // Op_RegF
2978 XMM0_num, // Op_RegD
2979 RAX_num // Op_RegL
2980 };
2981 static const int hi[Op_RegL + 1] = {
2982 0,
2983 0,
2984 OptoReg::Bad, // Op_RegN
2985 OptoReg::Bad, // Op_RegI
2986 RAX_H_num, // Op_RegP
2987 OptoReg::Bad, // Op_RegF
2988 XMM0b_num, // Op_RegD
2989 RAX_H_num // Op_RegL
2990 };
2991 // Excluded flags and vector registers.
2992 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type");
2993 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
2994 %}
2995 %}
2997 //----------ATTRIBUTES---------------------------------------------------------
2998 //----------Operand Attributes-------------------------------------------------
2999 op_attrib op_cost(0); // Required cost attribute
3001 //----------Instruction Attributes---------------------------------------------
3002 ins_attrib ins_cost(100); // Required cost attribute
3003 ins_attrib ins_size(8); // Required size attribute (in bits)
3004 ins_attrib ins_short_branch(0); // Required flag: is this instruction
3005 // a non-matching short branch variant
3006 // of some long branch?
3007 ins_attrib ins_alignment(1); // Required alignment attribute (must
3008 // be a power of 2) specifies the
3009 // alignment that some part of the
3010 // instruction (not necessarily the
3011 // start) requires. If > 1, a
3012 // compute_padding() function must be
3013 // provided for the instruction
3015 //----------OPERANDS-----------------------------------------------------------
3016 // Operand definitions must precede instruction definitions for correct parsing
3017 // in the ADLC because operands constitute user defined types which are used in
3018 // instruction definitions.
3020 //----------Simple Operands----------------------------------------------------
3021 // Immediate Operands
3022 // Integer Immediate
3023 operand immI()
3024 %{
3025 match(ConI);
3027 op_cost(10);
3028 format %{ %}
3029 interface(CONST_INTER);
3030 %}
3032 // Constant for test vs zero
3033 operand immI0()
3034 %{
3035 predicate(n->get_int() == 0);
3036 match(ConI);
3038 op_cost(0);
3039 format %{ %}
3040 interface(CONST_INTER);
3041 %}
3043 // Constant for increment
3044 operand immI1()
3045 %{
3046 predicate(n->get_int() == 1);
3047 match(ConI);
3049 op_cost(0);
3050 format %{ %}
3051 interface(CONST_INTER);
3052 %}
3054 // Constant for decrement
3055 operand immI_M1()
3056 %{
3057 predicate(n->get_int() == -1);
3058 match(ConI);
3060 op_cost(0);
3061 format %{ %}
3062 interface(CONST_INTER);
3063 %}
3065 // Valid scale values for addressing modes
3066 operand immI2()
3067 %{
3068 predicate(0 <= n->get_int() && (n->get_int() <= 3));
3069 match(ConI);
3071 format %{ %}
3072 interface(CONST_INTER);
3073 %}
3075 operand immI8()
3076 %{
3077 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80));
3078 match(ConI);
3080 op_cost(5);
3081 format %{ %}
3082 interface(CONST_INTER);
3083 %}
3085 operand immI16()
3086 %{
3087 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
3088 match(ConI);
3090 op_cost(10);
3091 format %{ %}
3092 interface(CONST_INTER);
3093 %}
3095 // Constant for long shifts
3096 operand immI_32()
3097 %{
3098 predicate( n->get_int() == 32 );
3099 match(ConI);
3101 op_cost(0);
3102 format %{ %}
3103 interface(CONST_INTER);
3104 %}
3106 // Constant for long shifts
3107 operand immI_64()
3108 %{
3109 predicate( n->get_int() == 64 );
3110 match(ConI);
3112 op_cost(0);
3113 format %{ %}
3114 interface(CONST_INTER);
3115 %}
3117 // Pointer Immediate
3118 operand immP()
3119 %{
3120 match(ConP);
3122 op_cost(10);
3123 format %{ %}
3124 interface(CONST_INTER);
3125 %}
3127 // NULL Pointer Immediate
3128 operand immP0()
3129 %{
3130 predicate(n->get_ptr() == 0);
3131 match(ConP);
3133 op_cost(5);
3134 format %{ %}
3135 interface(CONST_INTER);
3136 %}
3138 // Pointer Immediate
3139 operand immN() %{
3140 match(ConN);
3142 op_cost(10);
3143 format %{ %}
3144 interface(CONST_INTER);
3145 %}
3147 operand immNKlass() %{
3148 match(ConNKlass);
3150 op_cost(10);
3151 format %{ %}
3152 interface(CONST_INTER);
3153 %}
3155 // NULL Pointer Immediate
3156 operand immN0() %{
3157 predicate(n->get_narrowcon() == 0);
3158 match(ConN);
3160 op_cost(5);
3161 format %{ %}
3162 interface(CONST_INTER);
3163 %}
3165 operand immP31()
3166 %{
3167 predicate(n->as_Type()->type()->reloc() == relocInfo::none
3168 && (n->get_ptr() >> 31) == 0);
3169 match(ConP);
3171 op_cost(5);
3172 format %{ %}
3173 interface(CONST_INTER);
3174 %}
3177 // Long Immediate
3178 operand immL()
3179 %{
3180 match(ConL);
3182 op_cost(20);
3183 format %{ %}
3184 interface(CONST_INTER);
3185 %}
3187 // Long Immediate 8-bit
3188 operand immL8()
3189 %{
3190 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3191 match(ConL);
3193 op_cost(5);
3194 format %{ %}
3195 interface(CONST_INTER);
3196 %}
3198 // Long Immediate 32-bit unsigned
3199 operand immUL32()
3200 %{
3201 predicate(n->get_long() == (unsigned int) (n->get_long()));
3202 match(ConL);
3204 op_cost(10);
3205 format %{ %}
3206 interface(CONST_INTER);
3207 %}
3209 // Long Immediate 32-bit signed
3210 operand immL32()
3211 %{
3212 predicate(n->get_long() == (int) (n->get_long()));
3213 match(ConL);
3215 op_cost(15);
3216 format %{ %}
3217 interface(CONST_INTER);
3218 %}
3220 // Long Immediate zero
3221 operand immL0()
3222 %{
3223 predicate(n->get_long() == 0L);
3224 match(ConL);
3226 op_cost(10);
3227 format %{ %}
3228 interface(CONST_INTER);
3229 %}
3231 // Constant for increment
3232 operand immL1()
3233 %{
3234 predicate(n->get_long() == 1);
3235 match(ConL);
3237 format %{ %}
3238 interface(CONST_INTER);
3239 %}
3241 // Constant for decrement
3242 operand immL_M1()
3243 %{
3244 predicate(n->get_long() == -1);
3245 match(ConL);
3247 format %{ %}
3248 interface(CONST_INTER);
3249 %}
3251 // Long Immediate: the value 10
3252 operand immL10()
3253 %{
3254 predicate(n->get_long() == 10);
3255 match(ConL);
3257 format %{ %}
3258 interface(CONST_INTER);
3259 %}
3261 // Long immediate from 0 to 127.
3262 // Used for a shorter form of long mul by 10.
3263 operand immL_127()
3264 %{
3265 predicate(0 <= n->get_long() && n->get_long() < 0x80);
3266 match(ConL);
3268 op_cost(10);
3269 format %{ %}
3270 interface(CONST_INTER);
3271 %}
3273 // Long Immediate: low 32-bit mask
3274 operand immL_32bits()
3275 %{
3276 predicate(n->get_long() == 0xFFFFFFFFL);
3277 match(ConL);
3278 op_cost(20);
3280 format %{ %}
3281 interface(CONST_INTER);
3282 %}
3284 // Float Immediate zero
3285 operand immF0()
3286 %{
3287 predicate(jint_cast(n->getf()) == 0);
3288 match(ConF);
3290 op_cost(5);
3291 format %{ %}
3292 interface(CONST_INTER);
3293 %}
3295 // Float Immediate
3296 operand immF()
3297 %{
3298 match(ConF);
3300 op_cost(15);
3301 format %{ %}
3302 interface(CONST_INTER);
3303 %}
3305 // Double Immediate zero
3306 operand immD0()
3307 %{
3308 predicate(jlong_cast(n->getd()) == 0);
3309 match(ConD);
3311 op_cost(5);
3312 format %{ %}
3313 interface(CONST_INTER);
3314 %}
3316 // Double Immediate
3317 operand immD()
3318 %{
3319 match(ConD);
3321 op_cost(15);
3322 format %{ %}
3323 interface(CONST_INTER);
3324 %}
3326 // Immediates for special shifts (sign extend)
3328 // Constants for increment
3329 operand immI_16()
3330 %{
3331 predicate(n->get_int() == 16);
3332 match(ConI);
3334 format %{ %}
3335 interface(CONST_INTER);
3336 %}
3338 operand immI_24()
3339 %{
3340 predicate(n->get_int() == 24);
3341 match(ConI);
3343 format %{ %}
3344 interface(CONST_INTER);
3345 %}
3347 // Constant for byte-wide masking
3348 operand immI_255()
3349 %{
3350 predicate(n->get_int() == 255);
3351 match(ConI);
3353 format %{ %}
3354 interface(CONST_INTER);
3355 %}
3357 // Constant for short-wide masking
3358 operand immI_65535()
3359 %{
3360 predicate(n->get_int() == 65535);
3361 match(ConI);
3363 format %{ %}
3364 interface(CONST_INTER);
3365 %}
3367 // Constant for byte-wide masking
3368 operand immL_255()
3369 %{
3370 predicate(n->get_long() == 255);
3371 match(ConL);
3373 format %{ %}
3374 interface(CONST_INTER);
3375 %}
3377 // Constant for short-wide masking
3378 operand immL_65535()
3379 %{
3380 predicate(n->get_long() == 65535);
3381 match(ConL);
3383 format %{ %}
3384 interface(CONST_INTER);
3385 %}
3387 // Register Operands
3388 // Integer Register
3389 operand rRegI()
3390 %{
3391 constraint(ALLOC_IN_RC(int_reg));
3392 match(RegI);
3394 match(rax_RegI);
3395 match(rbx_RegI);
3396 match(rcx_RegI);
3397 match(rdx_RegI);
3398 match(rdi_RegI);
3400 format %{ %}
3401 interface(REG_INTER);
3402 %}
3404 // Special Registers
3405 operand rax_RegI()
3406 %{
3407 constraint(ALLOC_IN_RC(int_rax_reg));
3408 match(RegI);
3409 match(rRegI);
3411 format %{ "RAX" %}
3412 interface(REG_INTER);
3413 %}
3415 // Special Registers
3416 operand rbx_RegI()
3417 %{
3418 constraint(ALLOC_IN_RC(int_rbx_reg));
3419 match(RegI);
3420 match(rRegI);
3422 format %{ "RBX" %}
3423 interface(REG_INTER);
3424 %}
3426 operand rcx_RegI()
3427 %{
3428 constraint(ALLOC_IN_RC(int_rcx_reg));
3429 match(RegI);
3430 match(rRegI);
3432 format %{ "RCX" %}
3433 interface(REG_INTER);
3434 %}
3436 operand rdx_RegI()
3437 %{
3438 constraint(ALLOC_IN_RC(int_rdx_reg));
3439 match(RegI);
3440 match(rRegI);
3442 format %{ "RDX" %}
3443 interface(REG_INTER);
3444 %}
3446 operand rdi_RegI()
3447 %{
3448 constraint(ALLOC_IN_RC(int_rdi_reg));
3449 match(RegI);
3450 match(rRegI);
3452 format %{ "RDI" %}
3453 interface(REG_INTER);
3454 %}
3456 operand no_rcx_RegI()
3457 %{
3458 constraint(ALLOC_IN_RC(int_no_rcx_reg));
3459 match(RegI);
3460 match(rax_RegI);
3461 match(rbx_RegI);
3462 match(rdx_RegI);
3463 match(rdi_RegI);
3465 format %{ %}
3466 interface(REG_INTER);
3467 %}
3469 operand no_rax_rdx_RegI()
3470 %{
3471 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg));
3472 match(RegI);
3473 match(rbx_RegI);
3474 match(rcx_RegI);
3475 match(rdi_RegI);
3477 format %{ %}
3478 interface(REG_INTER);
3479 %}
3481 // Pointer Register
3482 operand any_RegP()
3483 %{
3484 constraint(ALLOC_IN_RC(any_reg));
3485 match(RegP);
3486 match(rax_RegP);
3487 match(rbx_RegP);
3488 match(rdi_RegP);
3489 match(rsi_RegP);
3490 match(rbp_RegP);
3491 match(r15_RegP);
3492 match(rRegP);
3494 format %{ %}
3495 interface(REG_INTER);
3496 %}
3498 operand rRegP()
3499 %{
3500 constraint(ALLOC_IN_RC(ptr_reg));
3501 match(RegP);
3502 match(rax_RegP);
3503 match(rbx_RegP);
3504 match(rdi_RegP);
3505 match(rsi_RegP);
3506 match(rbp_RegP);
3507 match(r15_RegP); // See Q&A below about r15_RegP.
3509 format %{ %}
3510 interface(REG_INTER);
3511 %}
3513 operand rRegN() %{
3514 constraint(ALLOC_IN_RC(int_reg));
3515 match(RegN);
3517 format %{ %}
3518 interface(REG_INTER);
3519 %}
3521 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
3522 // Answer: Operand match rules govern the DFA as it processes instruction inputs.
3523 // It's fine for an instruction input which expects rRegP to match a r15_RegP.
3524 // The output of an instruction is controlled by the allocator, which respects
3525 // register class masks, not match rules. Unless an instruction mentions
3526 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered
3527 // by the allocator as an input.
3529 operand no_rax_RegP()
3530 %{
3531 constraint(ALLOC_IN_RC(ptr_no_rax_reg));
3532 match(RegP);
3533 match(rbx_RegP);
3534 match(rsi_RegP);
3535 match(rdi_RegP);
3537 format %{ %}
3538 interface(REG_INTER);
3539 %}
3541 operand no_rbp_RegP()
3542 %{
3543 constraint(ALLOC_IN_RC(ptr_no_rbp_reg));
3544 match(RegP);
3545 match(rbx_RegP);
3546 match(rsi_RegP);
3547 match(rdi_RegP);
3549 format %{ %}
3550 interface(REG_INTER);
3551 %}
3553 operand no_rax_rbx_RegP()
3554 %{
3555 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg));
3556 match(RegP);
3557 match(rsi_RegP);
3558 match(rdi_RegP);
3560 format %{ %}
3561 interface(REG_INTER);
3562 %}
3564 // Special Registers
3565 // Return a pointer value
3566 operand rax_RegP()
3567 %{
3568 constraint(ALLOC_IN_RC(ptr_rax_reg));
3569 match(RegP);
3570 match(rRegP);
3572 format %{ %}
3573 interface(REG_INTER);
3574 %}
3576 // Special Registers
3577 // Return a compressed pointer value
3578 operand rax_RegN()
3579 %{
3580 constraint(ALLOC_IN_RC(int_rax_reg));
3581 match(RegN);
3582 match(rRegN);
3584 format %{ %}
3585 interface(REG_INTER);
3586 %}
3588 // Used in AtomicAdd
3589 operand rbx_RegP()
3590 %{
3591 constraint(ALLOC_IN_RC(ptr_rbx_reg));
3592 match(RegP);
3593 match(rRegP);
3595 format %{ %}
3596 interface(REG_INTER);
3597 %}
3599 operand rsi_RegP()
3600 %{
3601 constraint(ALLOC_IN_RC(ptr_rsi_reg));
3602 match(RegP);
3603 match(rRegP);
3605 format %{ %}
3606 interface(REG_INTER);
3607 %}
3609 // Used in rep stosq
3610 operand rdi_RegP()
3611 %{
3612 constraint(ALLOC_IN_RC(ptr_rdi_reg));
3613 match(RegP);
3614 match(rRegP);
3616 format %{ %}
3617 interface(REG_INTER);
3618 %}
3620 operand rbp_RegP()
3621 %{
3622 constraint(ALLOC_IN_RC(ptr_rbp_reg));
3623 match(RegP);
3624 match(rRegP);
3626 format %{ %}
3627 interface(REG_INTER);
3628 %}
3630 operand r15_RegP()
3631 %{
3632 constraint(ALLOC_IN_RC(ptr_r15_reg));
3633 match(RegP);
3634 match(rRegP);
3636 format %{ %}
3637 interface(REG_INTER);
3638 %}
3640 operand rRegL()
3641 %{
3642 constraint(ALLOC_IN_RC(long_reg));
3643 match(RegL);
3644 match(rax_RegL);
3645 match(rdx_RegL);
3647 format %{ %}
3648 interface(REG_INTER);
3649 %}
3651 // Special Registers
3652 operand no_rax_rdx_RegL()
3653 %{
3654 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3655 match(RegL);
3656 match(rRegL);
3658 format %{ %}
3659 interface(REG_INTER);
3660 %}
3662 operand no_rax_RegL()
3663 %{
3664 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3665 match(RegL);
3666 match(rRegL);
3667 match(rdx_RegL);
3669 format %{ %}
3670 interface(REG_INTER);
3671 %}
3673 operand no_rcx_RegL()
3674 %{
3675 constraint(ALLOC_IN_RC(long_no_rcx_reg));
3676 match(RegL);
3677 match(rRegL);
3679 format %{ %}
3680 interface(REG_INTER);
3681 %}
3683 operand rax_RegL()
3684 %{
3685 constraint(ALLOC_IN_RC(long_rax_reg));
3686 match(RegL);
3687 match(rRegL);
3689 format %{ "RAX" %}
3690 interface(REG_INTER);
3691 %}
3693 operand rcx_RegL()
3694 %{
3695 constraint(ALLOC_IN_RC(long_rcx_reg));
3696 match(RegL);
3697 match(rRegL);
3699 format %{ %}
3700 interface(REG_INTER);
3701 %}
3703 operand rdx_RegL()
3704 %{
3705 constraint(ALLOC_IN_RC(long_rdx_reg));
3706 match(RegL);
3707 match(rRegL);
3709 format %{ %}
3710 interface(REG_INTER);
3711 %}
3713 // Flags register, used as output of compare instructions
3714 operand rFlagsReg()
3715 %{
3716 constraint(ALLOC_IN_RC(int_flags));
3717 match(RegFlags);
3719 format %{ "RFLAGS" %}
3720 interface(REG_INTER);
3721 %}
3723 // Flags register, used as output of FLOATING POINT compare instructions
3724 operand rFlagsRegU()
3725 %{
3726 constraint(ALLOC_IN_RC(int_flags));
3727 match(RegFlags);
3729 format %{ "RFLAGS_U" %}
3730 interface(REG_INTER);
3731 %}
3733 operand rFlagsRegUCF() %{
3734 constraint(ALLOC_IN_RC(int_flags));
3735 match(RegFlags);
3736 predicate(false);
3738 format %{ "RFLAGS_U_CF" %}
3739 interface(REG_INTER);
3740 %}
3742 // Float register operands
3743 operand regF()
3744 %{
3745 constraint(ALLOC_IN_RC(float_reg));
3746 match(RegF);
3748 format %{ %}
3749 interface(REG_INTER);
3750 %}
3752 // Double register operands
3753 operand regD()
3754 %{
3755 constraint(ALLOC_IN_RC(double_reg));
3756 match(RegD);
3758 format %{ %}
3759 interface(REG_INTER);
3760 %}
3762 //----------Memory Operands----------------------------------------------------
3763 // Direct Memory Operand
3764 // operand direct(immP addr)
3765 // %{
3766 // match(addr);
3768 // format %{ "[$addr]" %}
3769 // interface(MEMORY_INTER) %{
3770 // base(0xFFFFFFFF);
3771 // index(0x4);
3772 // scale(0x0);
3773 // disp($addr);
3774 // %}
3775 // %}
3777 // Indirect Memory Operand
3778 operand indirect(any_RegP reg)
3779 %{
3780 constraint(ALLOC_IN_RC(ptr_reg));
3781 match(reg);
3783 format %{ "[$reg]" %}
3784 interface(MEMORY_INTER) %{
3785 base($reg);
3786 index(0x4);
3787 scale(0x0);
3788 disp(0x0);
3789 %}
3790 %}
3792 // Indirect Memory Plus Short Offset Operand
3793 operand indOffset8(any_RegP reg, immL8 off)
3794 %{
3795 constraint(ALLOC_IN_RC(ptr_reg));
3796 match(AddP reg off);
3798 format %{ "[$reg + $off (8-bit)]" %}
3799 interface(MEMORY_INTER) %{
3800 base($reg);
3801 index(0x4);
3802 scale(0x0);
3803 disp($off);
3804 %}
3805 %}
3807 // Indirect Memory Plus Long Offset Operand
3808 operand indOffset32(any_RegP reg, immL32 off)
3809 %{
3810 constraint(ALLOC_IN_RC(ptr_reg));
3811 match(AddP reg off);
3813 format %{ "[$reg + $off (32-bit)]" %}
3814 interface(MEMORY_INTER) %{
3815 base($reg);
3816 index(0x4);
3817 scale(0x0);
3818 disp($off);
3819 %}
3820 %}
3822 // Indirect Memory Plus Index Register Plus Offset Operand
3823 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off)
3824 %{
3825 constraint(ALLOC_IN_RC(ptr_reg));
3826 match(AddP (AddP reg lreg) off);
3828 op_cost(10);
3829 format %{"[$reg + $off + $lreg]" %}
3830 interface(MEMORY_INTER) %{
3831 base($reg);
3832 index($lreg);
3833 scale(0x0);
3834 disp($off);
3835 %}
3836 %}
3838 // Indirect Memory Plus Index Register Plus Offset Operand
3839 operand indIndex(any_RegP reg, rRegL lreg)
3840 %{
3841 constraint(ALLOC_IN_RC(ptr_reg));
3842 match(AddP reg lreg);
3844 op_cost(10);
3845 format %{"[$reg + $lreg]" %}
3846 interface(MEMORY_INTER) %{
3847 base($reg);
3848 index($lreg);
3849 scale(0x0);
3850 disp(0x0);
3851 %}
3852 %}
3854 // Indirect Memory Times Scale Plus Index Register
3855 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale)
3856 %{
3857 constraint(ALLOC_IN_RC(ptr_reg));
3858 match(AddP reg (LShiftL lreg scale));
3860 op_cost(10);
3861 format %{"[$reg + $lreg << $scale]" %}
3862 interface(MEMORY_INTER) %{
3863 base($reg);
3864 index($lreg);
3865 scale($scale);
3866 disp(0x0);
3867 %}
3868 %}
3870 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
3871 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
3872 %{
3873 constraint(ALLOC_IN_RC(ptr_reg));
3874 match(AddP (AddP reg (LShiftL lreg scale)) off);
3876 op_cost(10);
3877 format %{"[$reg + $off + $lreg << $scale]" %}
3878 interface(MEMORY_INTER) %{
3879 base($reg);
3880 index($lreg);
3881 scale($scale);
3882 disp($off);
3883 %}
3884 %}
3886 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
3887 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale)
3888 %{
3889 constraint(ALLOC_IN_RC(ptr_reg));
3890 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
3891 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off);
3893 op_cost(10);
3894 format %{"[$reg + $off + $idx << $scale]" %}
3895 interface(MEMORY_INTER) %{
3896 base($reg);
3897 index($idx);
3898 scale($scale);
3899 disp($off);
3900 %}
3901 %}
3903 // Indirect Narrow Oop Plus Offset Operand
3904 // Note: x86 architecture doesn't support "scale * index + offset" without a base
3905 // we can't free r12 even with Universe::narrow_oop_base() == NULL.
3906 operand indCompressedOopOffset(rRegN reg, immL32 off) %{
3907 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8));
3908 constraint(ALLOC_IN_RC(ptr_reg));
3909 match(AddP (DecodeN reg) off);
3911 op_cost(10);
3912 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
3913 interface(MEMORY_INTER) %{
3914 base(0xc); // R12
3915 index($reg);
3916 scale(0x3);
3917 disp($off);
3918 %}
3919 %}
3921 // Indirect Memory Operand
3922 operand indirectNarrow(rRegN reg)
3923 %{
3924 predicate(Universe::narrow_oop_shift() == 0);
3925 constraint(ALLOC_IN_RC(ptr_reg));
3926 match(DecodeN reg);
3928 format %{ "[$reg]" %}
3929 interface(MEMORY_INTER) %{
3930 base($reg);
3931 index(0x4);
3932 scale(0x0);
3933 disp(0x0);
3934 %}
3935 %}
3937 // Indirect Memory Plus Short Offset Operand
3938 operand indOffset8Narrow(rRegN reg, immL8 off)
3939 %{
3940 predicate(Universe::narrow_oop_shift() == 0);
3941 constraint(ALLOC_IN_RC(ptr_reg));
3942 match(AddP (DecodeN reg) off);
3944 format %{ "[$reg + $off (8-bit)]" %}
3945 interface(MEMORY_INTER) %{
3946 base($reg);
3947 index(0x4);
3948 scale(0x0);
3949 disp($off);
3950 %}
3951 %}
3953 // Indirect Memory Plus Long Offset Operand
3954 operand indOffset32Narrow(rRegN reg, immL32 off)
3955 %{
3956 predicate(Universe::narrow_oop_shift() == 0);
3957 constraint(ALLOC_IN_RC(ptr_reg));
3958 match(AddP (DecodeN reg) off);
3960 format %{ "[$reg + $off (32-bit)]" %}
3961 interface(MEMORY_INTER) %{
3962 base($reg);
3963 index(0x4);
3964 scale(0x0);
3965 disp($off);
3966 %}
3967 %}
3969 // Indirect Memory Plus Index Register Plus Offset Operand
3970 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off)
3971 %{
3972 predicate(Universe::narrow_oop_shift() == 0);
3973 constraint(ALLOC_IN_RC(ptr_reg));
3974 match(AddP (AddP (DecodeN reg) lreg) off);
3976 op_cost(10);
3977 format %{"[$reg + $off + $lreg]" %}
3978 interface(MEMORY_INTER) %{
3979 base($reg);
3980 index($lreg);
3981 scale(0x0);
3982 disp($off);
3983 %}
3984 %}
3986 // Indirect Memory Plus Index Register Plus Offset Operand
3987 operand indIndexNarrow(rRegN reg, rRegL lreg)
3988 %{
3989 predicate(Universe::narrow_oop_shift() == 0);
3990 constraint(ALLOC_IN_RC(ptr_reg));
3991 match(AddP (DecodeN reg) lreg);
3993 op_cost(10);
3994 format %{"[$reg + $lreg]" %}
3995 interface(MEMORY_INTER) %{
3996 base($reg);
3997 index($lreg);
3998 scale(0x0);
3999 disp(0x0);
4000 %}
4001 %}
4003 // Indirect Memory Times Scale Plus Index Register
4004 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale)
4005 %{
4006 predicate(Universe::narrow_oop_shift() == 0);
4007 constraint(ALLOC_IN_RC(ptr_reg));
4008 match(AddP (DecodeN reg) (LShiftL lreg scale));
4010 op_cost(10);
4011 format %{"[$reg + $lreg << $scale]" %}
4012 interface(MEMORY_INTER) %{
4013 base($reg);
4014 index($lreg);
4015 scale($scale);
4016 disp(0x0);
4017 %}
4018 %}
4020 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
4021 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
4022 %{
4023 predicate(Universe::narrow_oop_shift() == 0);
4024 constraint(ALLOC_IN_RC(ptr_reg));
4025 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
4027 op_cost(10);
4028 format %{"[$reg + $off + $lreg << $scale]" %}
4029 interface(MEMORY_INTER) %{
4030 base($reg);
4031 index($lreg);
4032 scale($scale);
4033 disp($off);
4034 %}
4035 %}
4037 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
4038 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4039 %{
4040 constraint(ALLOC_IN_RC(ptr_reg));
4041 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4042 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
4044 op_cost(10);
4045 format %{"[$reg + $off + $idx << $scale]" %}
4046 interface(MEMORY_INTER) %{
4047 base($reg);
4048 index($idx);
4049 scale($scale);
4050 disp($off);
4051 %}
4052 %}
4054 operand indirectNarrowKlass(rRegN reg)
4055 %{
4056 predicate(Universe::narrow_klass_shift() == 0);
4057 constraint(ALLOC_IN_RC(ptr_reg));
4058 match(DecodeNKlass reg);
4060 format %{ "[$reg]" %}
4061 interface(MEMORY_INTER) %{
4062 base($reg);
4063 index(0x4);
4064 scale(0x0);
4065 disp(0x0);
4066 %}
4067 %}
4069 operand indOffset8NarrowKlass(rRegN reg, immL8 off)
4070 %{
4071 predicate(Universe::narrow_klass_shift() == 0);
4072 constraint(ALLOC_IN_RC(ptr_reg));
4073 match(AddP (DecodeNKlass reg) off);
4075 format %{ "[$reg + $off (8-bit)]" %}
4076 interface(MEMORY_INTER) %{
4077 base($reg);
4078 index(0x4);
4079 scale(0x0);
4080 disp($off);
4081 %}
4082 %}
4084 operand indOffset32NarrowKlass(rRegN reg, immL32 off)
4085 %{
4086 predicate(Universe::narrow_klass_shift() == 0);
4087 constraint(ALLOC_IN_RC(ptr_reg));
4088 match(AddP (DecodeNKlass reg) off);
4090 format %{ "[$reg + $off (32-bit)]" %}
4091 interface(MEMORY_INTER) %{
4092 base($reg);
4093 index(0x4);
4094 scale(0x0);
4095 disp($off);
4096 %}
4097 %}
4099 operand indIndexOffsetNarrowKlass(rRegN reg, rRegL lreg, immL32 off)
4100 %{
4101 predicate(Universe::narrow_klass_shift() == 0);
4102 constraint(ALLOC_IN_RC(ptr_reg));
4103 match(AddP (AddP (DecodeNKlass reg) lreg) off);
4105 op_cost(10);
4106 format %{"[$reg + $off + $lreg]" %}
4107 interface(MEMORY_INTER) %{
4108 base($reg);
4109 index($lreg);
4110 scale(0x0);
4111 disp($off);
4112 %}
4113 %}
4115 operand indIndexNarrowKlass(rRegN reg, rRegL lreg)
4116 %{
4117 predicate(Universe::narrow_klass_shift() == 0);
4118 constraint(ALLOC_IN_RC(ptr_reg));
4119 match(AddP (DecodeNKlass reg) lreg);
4121 op_cost(10);
4122 format %{"[$reg + $lreg]" %}
4123 interface(MEMORY_INTER) %{
4124 base($reg);
4125 index($lreg);
4126 scale(0x0);
4127 disp(0x0);
4128 %}
4129 %}
4131 operand indIndexScaleNarrowKlass(rRegN reg, rRegL lreg, immI2 scale)
4132 %{
4133 predicate(Universe::narrow_klass_shift() == 0);
4134 constraint(ALLOC_IN_RC(ptr_reg));
4135 match(AddP (DecodeNKlass reg) (LShiftL lreg scale));
4137 op_cost(10);
4138 format %{"[$reg + $lreg << $scale]" %}
4139 interface(MEMORY_INTER) %{
4140 base($reg);
4141 index($lreg);
4142 scale($scale);
4143 disp(0x0);
4144 %}
4145 %}
4147 operand indIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
4148 %{
4149 predicate(Universe::narrow_klass_shift() == 0);
4150 constraint(ALLOC_IN_RC(ptr_reg));
4151 match(AddP (AddP (DecodeNKlass reg) (LShiftL lreg scale)) off);
4153 op_cost(10);
4154 format %{"[$reg + $off + $lreg << $scale]" %}
4155 interface(MEMORY_INTER) %{
4156 base($reg);
4157 index($lreg);
4158 scale($scale);
4159 disp($off);
4160 %}
4161 %}
4163 operand indCompressedKlassOffset(rRegN reg, immL32 off) %{
4164 predicate(UseCompressedKlassPointers && (Universe::narrow_klass_shift() == Address::times_8));
4165 constraint(ALLOC_IN_RC(ptr_reg));
4166 match(AddP (DecodeNKlass reg) off);
4168 op_cost(10);
4169 format %{"[R12 + $reg << 3 + $off] (compressed klass addressing)" %}
4170 interface(MEMORY_INTER) %{
4171 base(0xc); // R12
4172 index($reg);
4173 scale(0x3);
4174 disp($off);
4175 %}
4176 %}
4178 operand indPosIndexScaleOffsetNarrowKlass(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4179 %{
4180 constraint(ALLOC_IN_RC(ptr_reg));
4181 predicate(Universe::narrow_klass_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4182 match(AddP (AddP (DecodeNKlass reg) (LShiftL (ConvI2L idx) scale)) off);
4184 op_cost(10);
4185 format %{"[$reg + $off + $idx << $scale]" %}
4186 interface(MEMORY_INTER) %{
4187 base($reg);
4188 index($idx);
4189 scale($scale);
4190 disp($off);
4191 %}
4192 %}
4194 //----------Special Memory Operands--------------------------------------------
4195 // Stack Slot Operand - This operand is used for loading and storing temporary
4196 // values on the stack where a match requires a value to
4197 // flow through memory.
4198 operand stackSlotP(sRegP reg)
4199 %{
4200 constraint(ALLOC_IN_RC(stack_slots));
4201 // No match rule because this operand is only generated in matching
4203 format %{ "[$reg]" %}
4204 interface(MEMORY_INTER) %{
4205 base(0x4); // RSP
4206 index(0x4); // No Index
4207 scale(0x0); // No Scale
4208 disp($reg); // Stack Offset
4209 %}
4210 %}
4212 operand stackSlotI(sRegI reg)
4213 %{
4214 constraint(ALLOC_IN_RC(stack_slots));
4215 // No match rule because this operand is only generated in matching
4217 format %{ "[$reg]" %}
4218 interface(MEMORY_INTER) %{
4219 base(0x4); // RSP
4220 index(0x4); // No Index
4221 scale(0x0); // No Scale
4222 disp($reg); // Stack Offset
4223 %}
4224 %}
4226 operand stackSlotF(sRegF reg)
4227 %{
4228 constraint(ALLOC_IN_RC(stack_slots));
4229 // No match rule because this operand is only generated in matching
4231 format %{ "[$reg]" %}
4232 interface(MEMORY_INTER) %{
4233 base(0x4); // RSP
4234 index(0x4); // No Index
4235 scale(0x0); // No Scale
4236 disp($reg); // Stack Offset
4237 %}
4238 %}
4240 operand stackSlotD(sRegD reg)
4241 %{
4242 constraint(ALLOC_IN_RC(stack_slots));
4243 // No match rule because this operand is only generated in matching
4245 format %{ "[$reg]" %}
4246 interface(MEMORY_INTER) %{
4247 base(0x4); // RSP
4248 index(0x4); // No Index
4249 scale(0x0); // No Scale
4250 disp($reg); // Stack Offset
4251 %}
4252 %}
4253 operand stackSlotL(sRegL reg)
4254 %{
4255 constraint(ALLOC_IN_RC(stack_slots));
4256 // No match rule because this operand is only generated in matching
4258 format %{ "[$reg]" %}
4259 interface(MEMORY_INTER) %{
4260 base(0x4); // RSP
4261 index(0x4); // No Index
4262 scale(0x0); // No Scale
4263 disp($reg); // Stack Offset
4264 %}
4265 %}
4267 //----------Conditional Branch Operands----------------------------------------
4268 // Comparison Op - This is the operation of the comparison, and is limited to
4269 // the following set of codes:
4270 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
4271 //
4272 // Other attributes of the comparison, such as unsignedness, are specified
4273 // by the comparison instruction that sets a condition code flags register.
4274 // That result is represented by a flags operand whose subtype is appropriate
4275 // to the unsignedness (etc.) of the comparison.
4276 //
4277 // Later, the instruction which matches both the Comparison Op (a Bool) and
4278 // the flags (produced by the Cmp) specifies the coding of the comparison op
4279 // by matching a specific subtype of Bool operand below, such as cmpOpU.
4281 // Comparision Code
4282 operand cmpOp()
4283 %{
4284 match(Bool);
4286 format %{ "" %}
4287 interface(COND_INTER) %{
4288 equal(0x4, "e");
4289 not_equal(0x5, "ne");
4290 less(0xC, "l");
4291 greater_equal(0xD, "ge");
4292 less_equal(0xE, "le");
4293 greater(0xF, "g");
4294 %}
4295 %}
4297 // Comparison Code, unsigned compare. Used by FP also, with
4298 // C2 (unordered) turned into GT or LT already. The other bits
4299 // C0 and C3 are turned into Carry & Zero flags.
4300 operand cmpOpU()
4301 %{
4302 match(Bool);
4304 format %{ "" %}
4305 interface(COND_INTER) %{
4306 equal(0x4, "e");
4307 not_equal(0x5, "ne");
4308 less(0x2, "b");
4309 greater_equal(0x3, "nb");
4310 less_equal(0x6, "be");
4311 greater(0x7, "nbe");
4312 %}
4313 %}
4316 // Floating comparisons that don't require any fixup for the unordered case
4317 operand cmpOpUCF() %{
4318 match(Bool);
4319 predicate(n->as_Bool()->_test._test == BoolTest::lt ||
4320 n->as_Bool()->_test._test == BoolTest::ge ||
4321 n->as_Bool()->_test._test == BoolTest::le ||
4322 n->as_Bool()->_test._test == BoolTest::gt);
4323 format %{ "" %}
4324 interface(COND_INTER) %{
4325 equal(0x4, "e");
4326 not_equal(0x5, "ne");
4327 less(0x2, "b");
4328 greater_equal(0x3, "nb");
4329 less_equal(0x6, "be");
4330 greater(0x7, "nbe");
4331 %}
4332 %}
4335 // Floating comparisons that can be fixed up with extra conditional jumps
4336 operand cmpOpUCF2() %{
4337 match(Bool);
4338 predicate(n->as_Bool()->_test._test == BoolTest::ne ||
4339 n->as_Bool()->_test._test == BoolTest::eq);
4340 format %{ "" %}
4341 interface(COND_INTER) %{
4342 equal(0x4, "e");
4343 not_equal(0x5, "ne");
4344 less(0x2, "b");
4345 greater_equal(0x3, "nb");
4346 less_equal(0x6, "be");
4347 greater(0x7, "nbe");
4348 %}
4349 %}
4352 //----------OPERAND CLASSES----------------------------------------------------
4353 // Operand Classes are groups of operands that are used as to simplify
4354 // instruction definitions by not requiring the AD writer to specify separate
4355 // instructions for every form of operand when the instruction accepts
4356 // multiple operand types with the same basic encoding and format. The classic
4357 // case of this is memory operands.
4359 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
4360 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
4361 indCompressedOopOffset,
4362 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
4363 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
4364 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow,
4365 indCompressedKlassOffset,
4366 indirectNarrowKlass, indOffset8NarrowKlass, indOffset32NarrowKlass,
4367 indIndexOffsetNarrowKlass, indIndexNarrowKlass, indIndexScaleNarrowKlass,
4368 indIndexScaleOffsetNarrowKlass, indPosIndexScaleOffsetNarrowKlass);
4370 //----------PIPELINE-----------------------------------------------------------
4371 // Rules which define the behavior of the target architectures pipeline.
4372 pipeline %{
4374 //----------ATTRIBUTES---------------------------------------------------------
4375 attributes %{
4376 variable_size_instructions; // Fixed size instructions
4377 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
4378 instruction_unit_size = 1; // An instruction is 1 bytes long
4379 instruction_fetch_unit_size = 16; // The processor fetches one line
4380 instruction_fetch_units = 1; // of 16 bytes
4382 // List of nop instructions
4383 nops( MachNop );
4384 %}
4386 //----------RESOURCES----------------------------------------------------------
4387 // Resources are the functional units available to the machine
4389 // Generic P2/P3 pipeline
4390 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of
4391 // 3 instructions decoded per cycle.
4392 // 2 load/store ops per cycle, 1 branch, 1 FPU,
4393 // 3 ALU op, only ALU0 handles mul instructions.
4394 resources( D0, D1, D2, DECODE = D0 | D1 | D2,
4395 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2,
4396 BR, FPU,
4397 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2);
4399 //----------PIPELINE DESCRIPTION-----------------------------------------------
4400 // Pipeline Description specifies the stages in the machine's pipeline
4402 // Generic P2/P3 pipeline
4403 pipe_desc(S0, S1, S2, S3, S4, S5);
4405 //----------PIPELINE CLASSES---------------------------------------------------
4406 // Pipeline Classes describe the stages in which input and output are
4407 // referenced by the hardware pipeline.
4409 // Naming convention: ialu or fpu
4410 // Then: _reg
4411 // Then: _reg if there is a 2nd register
4412 // Then: _long if it's a pair of instructions implementing a long
4413 // Then: _fat if it requires the big decoder
4414 // Or: _mem if it requires the big decoder and a memory unit.
4416 // Integer ALU reg operation
4417 pipe_class ialu_reg(rRegI dst)
4418 %{
4419 single_instruction;
4420 dst : S4(write);
4421 dst : S3(read);
4422 DECODE : S0; // any decoder
4423 ALU : S3; // any alu
4424 %}
4426 // Long ALU reg operation
4427 pipe_class ialu_reg_long(rRegL dst)
4428 %{
4429 instruction_count(2);
4430 dst : S4(write);
4431 dst : S3(read);
4432 DECODE : S0(2); // any 2 decoders
4433 ALU : S3(2); // both alus
4434 %}
4436 // Integer ALU reg operation using big decoder
4437 pipe_class ialu_reg_fat(rRegI dst)
4438 %{
4439 single_instruction;
4440 dst : S4(write);
4441 dst : S3(read);
4442 D0 : S0; // big decoder only
4443 ALU : S3; // any alu
4444 %}
4446 // Long ALU reg operation using big decoder
4447 pipe_class ialu_reg_long_fat(rRegL dst)
4448 %{
4449 instruction_count(2);
4450 dst : S4(write);
4451 dst : S3(read);
4452 D0 : S0(2); // big decoder only; twice
4453 ALU : S3(2); // any 2 alus
4454 %}
4456 // Integer ALU reg-reg operation
4457 pipe_class ialu_reg_reg(rRegI dst, rRegI src)
4458 %{
4459 single_instruction;
4460 dst : S4(write);
4461 src : S3(read);
4462 DECODE : S0; // any decoder
4463 ALU : S3; // any alu
4464 %}
4466 // Long ALU reg-reg operation
4467 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src)
4468 %{
4469 instruction_count(2);
4470 dst : S4(write);
4471 src : S3(read);
4472 DECODE : S0(2); // any 2 decoders
4473 ALU : S3(2); // both alus
4474 %}
4476 // Integer ALU reg-reg operation
4477 pipe_class ialu_reg_reg_fat(rRegI dst, memory src)
4478 %{
4479 single_instruction;
4480 dst : S4(write);
4481 src : S3(read);
4482 D0 : S0; // big decoder only
4483 ALU : S3; // any alu
4484 %}
4486 // Long ALU reg-reg operation
4487 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src)
4488 %{
4489 instruction_count(2);
4490 dst : S4(write);
4491 src : S3(read);
4492 D0 : S0(2); // big decoder only; twice
4493 ALU : S3(2); // both alus
4494 %}
4496 // Integer ALU reg-mem operation
4497 pipe_class ialu_reg_mem(rRegI dst, memory mem)
4498 %{
4499 single_instruction;
4500 dst : S5(write);
4501 mem : S3(read);
4502 D0 : S0; // big decoder only
4503 ALU : S4; // any alu
4504 MEM : S3; // any mem
4505 %}
4507 // Integer mem operation (prefetch)
4508 pipe_class ialu_mem(memory mem)
4509 %{
4510 single_instruction;
4511 mem : S3(read);
4512 D0 : S0; // big decoder only
4513 MEM : S3; // any mem
4514 %}
4516 // Integer Store to Memory
4517 pipe_class ialu_mem_reg(memory mem, rRegI src)
4518 %{
4519 single_instruction;
4520 mem : S3(read);
4521 src : S5(read);
4522 D0 : S0; // big decoder only
4523 ALU : S4; // any alu
4524 MEM : S3;
4525 %}
4527 // // Long Store to Memory
4528 // pipe_class ialu_mem_long_reg(memory mem, rRegL src)
4529 // %{
4530 // instruction_count(2);
4531 // mem : S3(read);
4532 // src : S5(read);
4533 // D0 : S0(2); // big decoder only; twice
4534 // ALU : S4(2); // any 2 alus
4535 // MEM : S3(2); // Both mems
4536 // %}
4538 // Integer Store to Memory
4539 pipe_class ialu_mem_imm(memory mem)
4540 %{
4541 single_instruction;
4542 mem : S3(read);
4543 D0 : S0; // big decoder only
4544 ALU : S4; // any alu
4545 MEM : S3;
4546 %}
4548 // Integer ALU0 reg-reg operation
4549 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src)
4550 %{
4551 single_instruction;
4552 dst : S4(write);
4553 src : S3(read);
4554 D0 : S0; // Big decoder only
4555 ALU0 : S3; // only alu0
4556 %}
4558 // Integer ALU0 reg-mem operation
4559 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem)
4560 %{
4561 single_instruction;
4562 dst : S5(write);
4563 mem : S3(read);
4564 D0 : S0; // big decoder only
4565 ALU0 : S4; // ALU0 only
4566 MEM : S3; // any mem
4567 %}
4569 // Integer ALU reg-reg operation
4570 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2)
4571 %{
4572 single_instruction;
4573 cr : S4(write);
4574 src1 : S3(read);
4575 src2 : S3(read);
4576 DECODE : S0; // any decoder
4577 ALU : S3; // any alu
4578 %}
4580 // Integer ALU reg-imm operation
4581 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1)
4582 %{
4583 single_instruction;
4584 cr : S4(write);
4585 src1 : S3(read);
4586 DECODE : S0; // any decoder
4587 ALU : S3; // any alu
4588 %}
4590 // Integer ALU reg-mem operation
4591 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2)
4592 %{
4593 single_instruction;
4594 cr : S4(write);
4595 src1 : S3(read);
4596 src2 : S3(read);
4597 D0 : S0; // big decoder only
4598 ALU : S4; // any alu
4599 MEM : S3;
4600 %}
4602 // Conditional move reg-reg
4603 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y)
4604 %{
4605 instruction_count(4);
4606 y : S4(read);
4607 q : S3(read);
4608 p : S3(read);
4609 DECODE : S0(4); // any decoder
4610 %}
4612 // Conditional move reg-reg
4613 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr)
4614 %{
4615 single_instruction;
4616 dst : S4(write);
4617 src : S3(read);
4618 cr : S3(read);
4619 DECODE : S0; // any decoder
4620 %}
4622 // Conditional move reg-mem
4623 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src)
4624 %{
4625 single_instruction;
4626 dst : S4(write);
4627 src : S3(read);
4628 cr : S3(read);
4629 DECODE : S0; // any decoder
4630 MEM : S3;
4631 %}
4633 // Conditional move reg-reg long
4634 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src)
4635 %{
4636 single_instruction;
4637 dst : S4(write);
4638 src : S3(read);
4639 cr : S3(read);
4640 DECODE : S0(2); // any 2 decoders
4641 %}
4643 // XXX
4644 // // Conditional move double reg-reg
4645 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src)
4646 // %{
4647 // single_instruction;
4648 // dst : S4(write);
4649 // src : S3(read);
4650 // cr : S3(read);
4651 // DECODE : S0; // any decoder
4652 // %}
4654 // Float reg-reg operation
4655 pipe_class fpu_reg(regD dst)
4656 %{
4657 instruction_count(2);
4658 dst : S3(read);
4659 DECODE : S0(2); // any 2 decoders
4660 FPU : S3;
4661 %}
4663 // Float reg-reg operation
4664 pipe_class fpu_reg_reg(regD dst, regD src)
4665 %{
4666 instruction_count(2);
4667 dst : S4(write);
4668 src : S3(read);
4669 DECODE : S0(2); // any 2 decoders
4670 FPU : S3;
4671 %}
4673 // Float reg-reg operation
4674 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2)
4675 %{
4676 instruction_count(3);
4677 dst : S4(write);
4678 src1 : S3(read);
4679 src2 : S3(read);
4680 DECODE : S0(3); // any 3 decoders
4681 FPU : S3(2);
4682 %}
4684 // Float reg-reg operation
4685 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3)
4686 %{
4687 instruction_count(4);
4688 dst : S4(write);
4689 src1 : S3(read);
4690 src2 : S3(read);
4691 src3 : S3(read);
4692 DECODE : S0(4); // any 3 decoders
4693 FPU : S3(2);
4694 %}
4696 // Float reg-reg operation
4697 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3)
4698 %{
4699 instruction_count(4);
4700 dst : S4(write);
4701 src1 : S3(read);
4702 src2 : S3(read);
4703 src3 : S3(read);
4704 DECODE : S1(3); // any 3 decoders
4705 D0 : S0; // Big decoder only
4706 FPU : S3(2);
4707 MEM : S3;
4708 %}
4710 // Float reg-mem operation
4711 pipe_class fpu_reg_mem(regD dst, memory mem)
4712 %{
4713 instruction_count(2);
4714 dst : S5(write);
4715 mem : S3(read);
4716 D0 : S0; // big decoder only
4717 DECODE : S1; // any decoder for FPU POP
4718 FPU : S4;
4719 MEM : S3; // any mem
4720 %}
4722 // Float reg-mem operation
4723 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem)
4724 %{
4725 instruction_count(3);
4726 dst : S5(write);
4727 src1 : S3(read);
4728 mem : S3(read);
4729 D0 : S0; // big decoder only
4730 DECODE : S1(2); // any decoder for FPU POP
4731 FPU : S4;
4732 MEM : S3; // any mem
4733 %}
4735 // Float mem-reg operation
4736 pipe_class fpu_mem_reg(memory mem, regD src)
4737 %{
4738 instruction_count(2);
4739 src : S5(read);
4740 mem : S3(read);
4741 DECODE : S0; // any decoder for FPU PUSH
4742 D0 : S1; // big decoder only
4743 FPU : S4;
4744 MEM : S3; // any mem
4745 %}
4747 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2)
4748 %{
4749 instruction_count(3);
4750 src1 : S3(read);
4751 src2 : S3(read);
4752 mem : S3(read);
4753 DECODE : S0(2); // any decoder for FPU PUSH
4754 D0 : S1; // big decoder only
4755 FPU : S4;
4756 MEM : S3; // any mem
4757 %}
4759 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2)
4760 %{
4761 instruction_count(3);
4762 src1 : S3(read);
4763 src2 : S3(read);
4764 mem : S4(read);
4765 DECODE : S0; // any decoder for FPU PUSH
4766 D0 : S0(2); // big decoder only
4767 FPU : S4;
4768 MEM : S3(2); // any mem
4769 %}
4771 pipe_class fpu_mem_mem(memory dst, memory src1)
4772 %{
4773 instruction_count(2);
4774 src1 : S3(read);
4775 dst : S4(read);
4776 D0 : S0(2); // big decoder only
4777 MEM : S3(2); // any mem
4778 %}
4780 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2)
4781 %{
4782 instruction_count(3);
4783 src1 : S3(read);
4784 src2 : S3(read);
4785 dst : S4(read);
4786 D0 : S0(3); // big decoder only
4787 FPU : S4;
4788 MEM : S3(3); // any mem
4789 %}
4791 pipe_class fpu_mem_reg_con(memory mem, regD src1)
4792 %{
4793 instruction_count(3);
4794 src1 : S4(read);
4795 mem : S4(read);
4796 DECODE : S0; // any decoder for FPU PUSH
4797 D0 : S0(2); // big decoder only
4798 FPU : S4;
4799 MEM : S3(2); // any mem
4800 %}
4802 // Float load constant
4803 pipe_class fpu_reg_con(regD dst)
4804 %{
4805 instruction_count(2);
4806 dst : S5(write);
4807 D0 : S0; // big decoder only for the load
4808 DECODE : S1; // any decoder for FPU POP
4809 FPU : S4;
4810 MEM : S3; // any mem
4811 %}
4813 // Float load constant
4814 pipe_class fpu_reg_reg_con(regD dst, regD src)
4815 %{
4816 instruction_count(3);
4817 dst : S5(write);
4818 src : S3(read);
4819 D0 : S0; // big decoder only for the load
4820 DECODE : S1(2); // any decoder for FPU POP
4821 FPU : S4;
4822 MEM : S3; // any mem
4823 %}
4825 // UnConditional branch
4826 pipe_class pipe_jmp(label labl)
4827 %{
4828 single_instruction;
4829 BR : S3;
4830 %}
4832 // Conditional branch
4833 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl)
4834 %{
4835 single_instruction;
4836 cr : S1(read);
4837 BR : S3;
4838 %}
4840 // Allocation idiom
4841 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr)
4842 %{
4843 instruction_count(1); force_serialization;
4844 fixed_latency(6);
4845 heap_ptr : S3(read);
4846 DECODE : S0(3);
4847 D0 : S2;
4848 MEM : S3;
4849 ALU : S3(2);
4850 dst : S5(write);
4851 BR : S5;
4852 %}
4854 // Generic big/slow expanded idiom
4855 pipe_class pipe_slow()
4856 %{
4857 instruction_count(10); multiple_bundles; force_serialization;
4858 fixed_latency(100);
4859 D0 : S0(2);
4860 MEM : S3(2);
4861 %}
4863 // The real do-nothing guy
4864 pipe_class empty()
4865 %{
4866 instruction_count(0);
4867 %}
4869 // Define the class for the Nop node
4870 define
4871 %{
4872 MachNop = empty;
4873 %}
4875 %}
4877 //----------INSTRUCTIONS-------------------------------------------------------
4878 //
4879 // match -- States which machine-independent subtree may be replaced
4880 // by this instruction.
4881 // ins_cost -- The estimated cost of this instruction is used by instruction
4882 // selection to identify a minimum cost tree of machine
4883 // instructions that matches a tree of machine-independent
4884 // instructions.
4885 // format -- A string providing the disassembly for this instruction.
4886 // The value of an instruction's operand may be inserted
4887 // by referring to it with a '$' prefix.
4888 // opcode -- Three instruction opcodes may be provided. These are referred
4889 // to within an encode class as $primary, $secondary, and $tertiary
4890 // rrspectively. The primary opcode is commonly used to
4891 // indicate the type of machine instruction, while secondary
4892 // and tertiary are often used for prefix options or addressing
4893 // modes.
4894 // ins_encode -- A list of encode classes with parameters. The encode class
4895 // name must have been defined in an 'enc_class' specification
4896 // in the encode section of the architecture description.
4899 //----------Load/Store/Move Instructions---------------------------------------
4900 //----------Load Instructions--------------------------------------------------
4902 // Load Byte (8 bit signed)
4903 instruct loadB(rRegI dst, memory mem)
4904 %{
4905 match(Set dst (LoadB mem));
4907 ins_cost(125);
4908 format %{ "movsbl $dst, $mem\t# byte" %}
4910 ins_encode %{
4911 __ movsbl($dst$$Register, $mem$$Address);
4912 %}
4914 ins_pipe(ialu_reg_mem);
4915 %}
4917 // Load Byte (8 bit signed) into Long Register
4918 instruct loadB2L(rRegL dst, memory mem)
4919 %{
4920 match(Set dst (ConvI2L (LoadB mem)));
4922 ins_cost(125);
4923 format %{ "movsbq $dst, $mem\t# byte -> long" %}
4925 ins_encode %{
4926 __ movsbq($dst$$Register, $mem$$Address);
4927 %}
4929 ins_pipe(ialu_reg_mem);
4930 %}
4932 // Load Unsigned Byte (8 bit UNsigned)
4933 instruct loadUB(rRegI dst, memory mem)
4934 %{
4935 match(Set dst (LoadUB mem));
4937 ins_cost(125);
4938 format %{ "movzbl $dst, $mem\t# ubyte" %}
4940 ins_encode %{
4941 __ movzbl($dst$$Register, $mem$$Address);
4942 %}
4944 ins_pipe(ialu_reg_mem);
4945 %}
4947 // Load Unsigned Byte (8 bit UNsigned) into Long Register
4948 instruct loadUB2L(rRegL dst, memory mem)
4949 %{
4950 match(Set dst (ConvI2L (LoadUB mem)));
4952 ins_cost(125);
4953 format %{ "movzbq $dst, $mem\t# ubyte -> long" %}
4955 ins_encode %{
4956 __ movzbq($dst$$Register, $mem$$Address);
4957 %}
4959 ins_pipe(ialu_reg_mem);
4960 %}
4962 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register
4963 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{
4964 match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
4965 effect(KILL cr);
4967 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t"
4968 "andl $dst, $mask" %}
4969 ins_encode %{
4970 Register Rdst = $dst$$Register;
4971 __ movzbq(Rdst, $mem$$Address);
4972 __ andl(Rdst, $mask$$constant);
4973 %}
4974 ins_pipe(ialu_reg_mem);
4975 %}
4977 // Load Short (16 bit signed)
4978 instruct loadS(rRegI dst, memory mem)
4979 %{
4980 match(Set dst (LoadS mem));
4982 ins_cost(125);
4983 format %{ "movswl $dst, $mem\t# short" %}
4985 ins_encode %{
4986 __ movswl($dst$$Register, $mem$$Address);
4987 %}
4989 ins_pipe(ialu_reg_mem);
4990 %}
4992 // Load Short (16 bit signed) to Byte (8 bit signed)
4993 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4994 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
4996 ins_cost(125);
4997 format %{ "movsbl $dst, $mem\t# short -> byte" %}
4998 ins_encode %{
4999 __ movsbl($dst$$Register, $mem$$Address);
5000 %}
5001 ins_pipe(ialu_reg_mem);
5002 %}
5004 // Load Short (16 bit signed) into Long Register
5005 instruct loadS2L(rRegL dst, memory mem)
5006 %{
5007 match(Set dst (ConvI2L (LoadS mem)));
5009 ins_cost(125);
5010 format %{ "movswq $dst, $mem\t# short -> long" %}
5012 ins_encode %{
5013 __ movswq($dst$$Register, $mem$$Address);
5014 %}
5016 ins_pipe(ialu_reg_mem);
5017 %}
5019 // Load Unsigned Short/Char (16 bit UNsigned)
5020 instruct loadUS(rRegI dst, memory mem)
5021 %{
5022 match(Set dst (LoadUS mem));
5024 ins_cost(125);
5025 format %{ "movzwl $dst, $mem\t# ushort/char" %}
5027 ins_encode %{
5028 __ movzwl($dst$$Register, $mem$$Address);
5029 %}
5031 ins_pipe(ialu_reg_mem);
5032 %}
5034 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
5035 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
5036 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
5038 ins_cost(125);
5039 format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
5040 ins_encode %{
5041 __ movsbl($dst$$Register, $mem$$Address);
5042 %}
5043 ins_pipe(ialu_reg_mem);
5044 %}
5046 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
5047 instruct loadUS2L(rRegL dst, memory mem)
5048 %{
5049 match(Set dst (ConvI2L (LoadUS mem)));
5051 ins_cost(125);
5052 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %}
5054 ins_encode %{
5055 __ movzwq($dst$$Register, $mem$$Address);
5056 %}
5058 ins_pipe(ialu_reg_mem);
5059 %}
5061 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register
5062 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
5063 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
5065 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %}
5066 ins_encode %{
5067 __ movzbq($dst$$Register, $mem$$Address);
5068 %}
5069 ins_pipe(ialu_reg_mem);
5070 %}
5072 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register
5073 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{
5074 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
5075 effect(KILL cr);
5077 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t"
5078 "andl $dst, $mask" %}
5079 ins_encode %{
5080 Register Rdst = $dst$$Register;
5081 __ movzwq(Rdst, $mem$$Address);
5082 __ andl(Rdst, $mask$$constant);
5083 %}
5084 ins_pipe(ialu_reg_mem);
5085 %}
5087 // Load Integer
5088 instruct loadI(rRegI dst, memory mem)
5089 %{
5090 match(Set dst (LoadI mem));
5092 ins_cost(125);
5093 format %{ "movl $dst, $mem\t# int" %}
5095 ins_encode %{
5096 __ movl($dst$$Register, $mem$$Address);
5097 %}
5099 ins_pipe(ialu_reg_mem);
5100 %}
5102 // Load Integer (32 bit signed) to Byte (8 bit signed)
5103 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
5104 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
5106 ins_cost(125);
5107 format %{ "movsbl $dst, $mem\t# int -> byte" %}
5108 ins_encode %{
5109 __ movsbl($dst$$Register, $mem$$Address);
5110 %}
5111 ins_pipe(ialu_reg_mem);
5112 %}
5114 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
5115 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
5116 match(Set dst (AndI (LoadI mem) mask));
5118 ins_cost(125);
5119 format %{ "movzbl $dst, $mem\t# int -> ubyte" %}
5120 ins_encode %{
5121 __ movzbl($dst$$Register, $mem$$Address);
5122 %}
5123 ins_pipe(ialu_reg_mem);
5124 %}
5126 // Load Integer (32 bit signed) to Short (16 bit signed)
5127 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
5128 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
5130 ins_cost(125);
5131 format %{ "movswl $dst, $mem\t# int -> short" %}
5132 ins_encode %{
5133 __ movswl($dst$$Register, $mem$$Address);
5134 %}
5135 ins_pipe(ialu_reg_mem);
5136 %}
5138 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
5139 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
5140 match(Set dst (AndI (LoadI mem) mask));
5142 ins_cost(125);
5143 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %}
5144 ins_encode %{
5145 __ movzwl($dst$$Register, $mem$$Address);
5146 %}
5147 ins_pipe(ialu_reg_mem);
5148 %}
5150 // Load Integer into Long Register
5151 instruct loadI2L(rRegL dst, memory mem)
5152 %{
5153 match(Set dst (ConvI2L (LoadI mem)));
5155 ins_cost(125);
5156 format %{ "movslq $dst, $mem\t# int -> long" %}
5158 ins_encode %{
5159 __ movslq($dst$$Register, $mem$$Address);
5160 %}
5162 ins_pipe(ialu_reg_mem);
5163 %}
5165 // Load Integer with mask 0xFF into Long Register
5166 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
5167 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5169 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %}
5170 ins_encode %{
5171 __ movzbq($dst$$Register, $mem$$Address);
5172 %}
5173 ins_pipe(ialu_reg_mem);
5174 %}
5176 // Load Integer with mask 0xFFFF into Long Register
5177 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{
5178 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5180 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %}
5181 ins_encode %{
5182 __ movzwq($dst$$Register, $mem$$Address);
5183 %}
5184 ins_pipe(ialu_reg_mem);
5185 %}
5187 // Load Integer with a 32-bit mask into Long Register
5188 instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
5189 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5190 effect(KILL cr);
5192 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t"
5193 "andl $dst, $mask" %}
5194 ins_encode %{
5195 Register Rdst = $dst$$Register;
5196 __ movl(Rdst, $mem$$Address);
5197 __ andl(Rdst, $mask$$constant);
5198 %}
5199 ins_pipe(ialu_reg_mem);
5200 %}
5202 // Load Unsigned Integer into Long Register
5203 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask)
5204 %{
5205 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5207 ins_cost(125);
5208 format %{ "movl $dst, $mem\t# uint -> long" %}
5210 ins_encode %{
5211 __ movl($dst$$Register, $mem$$Address);
5212 %}
5214 ins_pipe(ialu_reg_mem);
5215 %}
5217 // Load Long
5218 instruct loadL(rRegL dst, memory mem)
5219 %{
5220 match(Set dst (LoadL mem));
5222 ins_cost(125);
5223 format %{ "movq $dst, $mem\t# long" %}
5225 ins_encode %{
5226 __ movq($dst$$Register, $mem$$Address);
5227 %}
5229 ins_pipe(ialu_reg_mem); // XXX
5230 %}
5232 // Load Range
5233 instruct loadRange(rRegI dst, memory mem)
5234 %{
5235 match(Set dst (LoadRange mem));
5237 ins_cost(125); // XXX
5238 format %{ "movl $dst, $mem\t# range" %}
5239 opcode(0x8B);
5240 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem));
5241 ins_pipe(ialu_reg_mem);
5242 %}
5244 // Load Pointer
5245 instruct loadP(rRegP dst, memory mem)
5246 %{
5247 match(Set dst (LoadP mem));
5249 ins_cost(125); // XXX
5250 format %{ "movq $dst, $mem\t# ptr" %}
5251 opcode(0x8B);
5252 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5253 ins_pipe(ialu_reg_mem); // XXX
5254 %}
5256 // Load Compressed Pointer
5257 instruct loadN(rRegN dst, memory mem)
5258 %{
5259 match(Set dst (LoadN mem));
5261 ins_cost(125); // XXX
5262 format %{ "movl $dst, $mem\t# compressed ptr" %}
5263 ins_encode %{
5264 __ movl($dst$$Register, $mem$$Address);
5265 %}
5266 ins_pipe(ialu_reg_mem); // XXX
5267 %}
5270 // Load Klass Pointer
5271 instruct loadKlass(rRegP dst, memory mem)
5272 %{
5273 match(Set dst (LoadKlass mem));
5275 ins_cost(125); // XXX
5276 format %{ "movq $dst, $mem\t# class" %}
5277 opcode(0x8B);
5278 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5279 ins_pipe(ialu_reg_mem); // XXX
5280 %}
5282 // Load narrow Klass Pointer
5283 instruct loadNKlass(rRegN dst, memory mem)
5284 %{
5285 match(Set dst (LoadNKlass mem));
5287 ins_cost(125); // XXX
5288 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
5289 ins_encode %{
5290 __ movl($dst$$Register, $mem$$Address);
5291 %}
5292 ins_pipe(ialu_reg_mem); // XXX
5293 %}
5295 // Load Float
5296 instruct loadF(regF dst, memory mem)
5297 %{
5298 match(Set dst (LoadF mem));
5300 ins_cost(145); // XXX
5301 format %{ "movss $dst, $mem\t# float" %}
5302 ins_encode %{
5303 __ movflt($dst$$XMMRegister, $mem$$Address);
5304 %}
5305 ins_pipe(pipe_slow); // XXX
5306 %}
5308 // Load Double
5309 instruct loadD_partial(regD dst, memory mem)
5310 %{
5311 predicate(!UseXmmLoadAndClearUpper);
5312 match(Set dst (LoadD mem));
5314 ins_cost(145); // XXX
5315 format %{ "movlpd $dst, $mem\t# double" %}
5316 ins_encode %{
5317 __ movdbl($dst$$XMMRegister, $mem$$Address);
5318 %}
5319 ins_pipe(pipe_slow); // XXX
5320 %}
5322 instruct loadD(regD dst, memory mem)
5323 %{
5324 predicate(UseXmmLoadAndClearUpper);
5325 match(Set dst (LoadD mem));
5327 ins_cost(145); // XXX
5328 format %{ "movsd $dst, $mem\t# double" %}
5329 ins_encode %{
5330 __ movdbl($dst$$XMMRegister, $mem$$Address);
5331 %}
5332 ins_pipe(pipe_slow); // XXX
5333 %}
5335 // Load Effective Address
5336 instruct leaP8(rRegP dst, indOffset8 mem)
5337 %{
5338 match(Set dst mem);
5340 ins_cost(110); // XXX
5341 format %{ "leaq $dst, $mem\t# ptr 8" %}
5342 opcode(0x8D);
5343 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5344 ins_pipe(ialu_reg_reg_fat);
5345 %}
5347 instruct leaP32(rRegP dst, indOffset32 mem)
5348 %{
5349 match(Set dst mem);
5351 ins_cost(110);
5352 format %{ "leaq $dst, $mem\t# ptr 32" %}
5353 opcode(0x8D);
5354 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5355 ins_pipe(ialu_reg_reg_fat);
5356 %}
5358 // instruct leaPIdx(rRegP dst, indIndex mem)
5359 // %{
5360 // match(Set dst mem);
5362 // ins_cost(110);
5363 // format %{ "leaq $dst, $mem\t# ptr idx" %}
5364 // opcode(0x8D);
5365 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5366 // ins_pipe(ialu_reg_reg_fat);
5367 // %}
5369 instruct leaPIdxOff(rRegP dst, indIndexOffset mem)
5370 %{
5371 match(Set dst mem);
5373 ins_cost(110);
5374 format %{ "leaq $dst, $mem\t# ptr idxoff" %}
5375 opcode(0x8D);
5376 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5377 ins_pipe(ialu_reg_reg_fat);
5378 %}
5380 instruct leaPIdxScale(rRegP dst, indIndexScale mem)
5381 %{
5382 match(Set dst mem);
5384 ins_cost(110);
5385 format %{ "leaq $dst, $mem\t# ptr idxscale" %}
5386 opcode(0x8D);
5387 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5388 ins_pipe(ialu_reg_reg_fat);
5389 %}
5391 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem)
5392 %{
5393 match(Set dst mem);
5395 ins_cost(110);
5396 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %}
5397 opcode(0x8D);
5398 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5399 ins_pipe(ialu_reg_reg_fat);
5400 %}
5402 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem)
5403 %{
5404 match(Set dst mem);
5406 ins_cost(110);
5407 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %}
5408 opcode(0x8D);
5409 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5410 ins_pipe(ialu_reg_reg_fat);
5411 %}
5413 // Load Effective Address which uses Narrow (32-bits) oop
5414 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem)
5415 %{
5416 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0));
5417 match(Set dst mem);
5419 ins_cost(110);
5420 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %}
5421 opcode(0x8D);
5422 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5423 ins_pipe(ialu_reg_reg_fat);
5424 %}
5426 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem)
5427 %{
5428 predicate(Universe::narrow_oop_shift() == 0);
5429 match(Set dst mem);
5431 ins_cost(110); // XXX
5432 format %{ "leaq $dst, $mem\t# ptr off8narrow" %}
5433 opcode(0x8D);
5434 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5435 ins_pipe(ialu_reg_reg_fat);
5436 %}
5438 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem)
5439 %{
5440 predicate(Universe::narrow_oop_shift() == 0);
5441 match(Set dst mem);
5443 ins_cost(110);
5444 format %{ "leaq $dst, $mem\t# ptr off32narrow" %}
5445 opcode(0x8D);
5446 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5447 ins_pipe(ialu_reg_reg_fat);
5448 %}
5450 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem)
5451 %{
5452 predicate(Universe::narrow_oop_shift() == 0);
5453 match(Set dst mem);
5455 ins_cost(110);
5456 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %}
5457 opcode(0x8D);
5458 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5459 ins_pipe(ialu_reg_reg_fat);
5460 %}
5462 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem)
5463 %{
5464 predicate(Universe::narrow_oop_shift() == 0);
5465 match(Set dst mem);
5467 ins_cost(110);
5468 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %}
5469 opcode(0x8D);
5470 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5471 ins_pipe(ialu_reg_reg_fat);
5472 %}
5474 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem)
5475 %{
5476 predicate(Universe::narrow_oop_shift() == 0);
5477 match(Set dst mem);
5479 ins_cost(110);
5480 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %}
5481 opcode(0x8D);
5482 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5483 ins_pipe(ialu_reg_reg_fat);
5484 %}
5486 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem)
5487 %{
5488 predicate(Universe::narrow_oop_shift() == 0);
5489 match(Set dst mem);
5491 ins_cost(110);
5492 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %}
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 %}
5498 instruct loadConI(rRegI dst, immI src)
5499 %{
5500 match(Set dst src);
5502 format %{ "movl $dst, $src\t# int" %}
5503 ins_encode(load_immI(dst, src));
5504 ins_pipe(ialu_reg_fat); // XXX
5505 %}
5507 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr)
5508 %{
5509 match(Set dst src);
5510 effect(KILL cr);
5512 ins_cost(50);
5513 format %{ "xorl $dst, $dst\t# int" %}
5514 opcode(0x33); /* + rd */
5515 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5516 ins_pipe(ialu_reg);
5517 %}
5519 instruct loadConL(rRegL dst, immL src)
5520 %{
5521 match(Set dst src);
5523 ins_cost(150);
5524 format %{ "movq $dst, $src\t# long" %}
5525 ins_encode(load_immL(dst, src));
5526 ins_pipe(ialu_reg);
5527 %}
5529 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr)
5530 %{
5531 match(Set dst src);
5532 effect(KILL cr);
5534 ins_cost(50);
5535 format %{ "xorl $dst, $dst\t# long" %}
5536 opcode(0x33); /* + rd */
5537 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5538 ins_pipe(ialu_reg); // XXX
5539 %}
5541 instruct loadConUL32(rRegL dst, immUL32 src)
5542 %{
5543 match(Set dst src);
5545 ins_cost(60);
5546 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %}
5547 ins_encode(load_immUL32(dst, src));
5548 ins_pipe(ialu_reg);
5549 %}
5551 instruct loadConL32(rRegL dst, immL32 src)
5552 %{
5553 match(Set dst src);
5555 ins_cost(70);
5556 format %{ "movq $dst, $src\t# long (32-bit)" %}
5557 ins_encode(load_immL32(dst, src));
5558 ins_pipe(ialu_reg);
5559 %}
5561 instruct loadConP(rRegP dst, immP con) %{
5562 match(Set dst con);
5564 format %{ "movq $dst, $con\t# ptr" %}
5565 ins_encode(load_immP(dst, con));
5566 ins_pipe(ialu_reg_fat); // XXX
5567 %}
5569 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
5570 %{
5571 match(Set dst src);
5572 effect(KILL cr);
5574 ins_cost(50);
5575 format %{ "xorl $dst, $dst\t# ptr" %}
5576 opcode(0x33); /* + rd */
5577 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5578 ins_pipe(ialu_reg);
5579 %}
5581 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
5582 %{
5583 match(Set dst src);
5584 effect(KILL cr);
5586 ins_cost(60);
5587 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %}
5588 ins_encode(load_immP31(dst, src));
5589 ins_pipe(ialu_reg);
5590 %}
5592 instruct loadConF(regF dst, immF con) %{
5593 match(Set dst con);
5594 ins_cost(125);
5595 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
5596 ins_encode %{
5597 __ movflt($dst$$XMMRegister, $constantaddress($con));
5598 %}
5599 ins_pipe(pipe_slow);
5600 %}
5602 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
5603 match(Set dst src);
5604 effect(KILL cr);
5605 format %{ "xorq $dst, $src\t# compressed NULL ptr" %}
5606 ins_encode %{
5607 __ xorq($dst$$Register, $dst$$Register);
5608 %}
5609 ins_pipe(ialu_reg);
5610 %}
5612 instruct loadConN(rRegN dst, immN src) %{
5613 match(Set dst src);
5615 ins_cost(125);
5616 format %{ "movl $dst, $src\t# compressed ptr" %}
5617 ins_encode %{
5618 address con = (address)$src$$constant;
5619 if (con == NULL) {
5620 ShouldNotReachHere();
5621 } else {
5622 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
5623 }
5624 %}
5625 ins_pipe(ialu_reg_fat); // XXX
5626 %}
5628 instruct loadConNKlass(rRegN dst, immNKlass src) %{
5629 match(Set dst src);
5631 ins_cost(125);
5632 format %{ "movl $dst, $src\t# compressed klass ptr" %}
5633 ins_encode %{
5634 address con = (address)$src$$constant;
5635 if (con == NULL) {
5636 ShouldNotReachHere();
5637 } else {
5638 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant);
5639 }
5640 %}
5641 ins_pipe(ialu_reg_fat); // XXX
5642 %}
5644 instruct loadConF0(regF dst, immF0 src)
5645 %{
5646 match(Set dst src);
5647 ins_cost(100);
5649 format %{ "xorps $dst, $dst\t# float 0.0" %}
5650 ins_encode %{
5651 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
5652 %}
5653 ins_pipe(pipe_slow);
5654 %}
5656 // Use the same format since predicate() can not be used here.
5657 instruct loadConD(regD dst, immD con) %{
5658 match(Set dst con);
5659 ins_cost(125);
5660 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
5661 ins_encode %{
5662 __ movdbl($dst$$XMMRegister, $constantaddress($con));
5663 %}
5664 ins_pipe(pipe_slow);
5665 %}
5667 instruct loadConD0(regD dst, immD0 src)
5668 %{
5669 match(Set dst src);
5670 ins_cost(100);
5672 format %{ "xorpd $dst, $dst\t# double 0.0" %}
5673 ins_encode %{
5674 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
5675 %}
5676 ins_pipe(pipe_slow);
5677 %}
5679 instruct loadSSI(rRegI dst, stackSlotI src)
5680 %{
5681 match(Set dst src);
5683 ins_cost(125);
5684 format %{ "movl $dst, $src\t# int stk" %}
5685 opcode(0x8B);
5686 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
5687 ins_pipe(ialu_reg_mem);
5688 %}
5690 instruct loadSSL(rRegL dst, stackSlotL src)
5691 %{
5692 match(Set dst src);
5694 ins_cost(125);
5695 format %{ "movq $dst, $src\t# long stk" %}
5696 opcode(0x8B);
5697 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5698 ins_pipe(ialu_reg_mem);
5699 %}
5701 instruct loadSSP(rRegP dst, stackSlotP src)
5702 %{
5703 match(Set dst src);
5705 ins_cost(125);
5706 format %{ "movq $dst, $src\t# ptr stk" %}
5707 opcode(0x8B);
5708 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5709 ins_pipe(ialu_reg_mem);
5710 %}
5712 instruct loadSSF(regF dst, stackSlotF src)
5713 %{
5714 match(Set dst src);
5716 ins_cost(125);
5717 format %{ "movss $dst, $src\t# float stk" %}
5718 ins_encode %{
5719 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
5720 %}
5721 ins_pipe(pipe_slow); // XXX
5722 %}
5724 // Use the same format since predicate() can not be used here.
5725 instruct loadSSD(regD dst, stackSlotD src)
5726 %{
5727 match(Set dst src);
5729 ins_cost(125);
5730 format %{ "movsd $dst, $src\t# double stk" %}
5731 ins_encode %{
5732 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
5733 %}
5734 ins_pipe(pipe_slow); // XXX
5735 %}
5737 // Prefetch instructions.
5738 // Must be safe to execute with invalid address (cannot fault).
5740 instruct prefetchr( memory mem ) %{
5741 predicate(ReadPrefetchInstr==3);
5742 match(PrefetchRead mem);
5743 ins_cost(125);
5745 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %}
5746 ins_encode %{
5747 __ prefetchr($mem$$Address);
5748 %}
5749 ins_pipe(ialu_mem);
5750 %}
5752 instruct prefetchrNTA( memory mem ) %{
5753 predicate(ReadPrefetchInstr==0);
5754 match(PrefetchRead mem);
5755 ins_cost(125);
5757 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %}
5758 ins_encode %{
5759 __ prefetchnta($mem$$Address);
5760 %}
5761 ins_pipe(ialu_mem);
5762 %}
5764 instruct prefetchrT0( memory mem ) %{
5765 predicate(ReadPrefetchInstr==1);
5766 match(PrefetchRead mem);
5767 ins_cost(125);
5769 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %}
5770 ins_encode %{
5771 __ prefetcht0($mem$$Address);
5772 %}
5773 ins_pipe(ialu_mem);
5774 %}
5776 instruct prefetchrT2( memory mem ) %{
5777 predicate(ReadPrefetchInstr==2);
5778 match(PrefetchRead mem);
5779 ins_cost(125);
5781 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %}
5782 ins_encode %{
5783 __ prefetcht2($mem$$Address);
5784 %}
5785 ins_pipe(ialu_mem);
5786 %}
5788 instruct prefetchwNTA( memory mem ) %{
5789 match(PrefetchWrite mem);
5790 ins_cost(125);
5792 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %}
5793 ins_encode %{
5794 __ prefetchnta($mem$$Address);
5795 %}
5796 ins_pipe(ialu_mem);
5797 %}
5799 // Prefetch instructions for allocation.
5801 instruct prefetchAlloc( memory mem ) %{
5802 predicate(AllocatePrefetchInstr==3);
5803 match(PrefetchAllocation mem);
5804 ins_cost(125);
5806 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %}
5807 ins_encode %{
5808 __ prefetchw($mem$$Address);
5809 %}
5810 ins_pipe(ialu_mem);
5811 %}
5813 instruct prefetchAllocNTA( memory mem ) %{
5814 predicate(AllocatePrefetchInstr==0);
5815 match(PrefetchAllocation mem);
5816 ins_cost(125);
5818 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %}
5819 ins_encode %{
5820 __ prefetchnta($mem$$Address);
5821 %}
5822 ins_pipe(ialu_mem);
5823 %}
5825 instruct prefetchAllocT0( memory mem ) %{
5826 predicate(AllocatePrefetchInstr==1);
5827 match(PrefetchAllocation mem);
5828 ins_cost(125);
5830 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %}
5831 ins_encode %{
5832 __ prefetcht0($mem$$Address);
5833 %}
5834 ins_pipe(ialu_mem);
5835 %}
5837 instruct prefetchAllocT2( memory mem ) %{
5838 predicate(AllocatePrefetchInstr==2);
5839 match(PrefetchAllocation mem);
5840 ins_cost(125);
5842 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %}
5843 ins_encode %{
5844 __ prefetcht2($mem$$Address);
5845 %}
5846 ins_pipe(ialu_mem);
5847 %}
5849 //----------Store Instructions-------------------------------------------------
5851 // Store Byte
5852 instruct storeB(memory mem, rRegI src)
5853 %{
5854 match(Set mem (StoreB mem src));
5856 ins_cost(125); // XXX
5857 format %{ "movb $mem, $src\t# byte" %}
5858 opcode(0x88);
5859 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem));
5860 ins_pipe(ialu_mem_reg);
5861 %}
5863 // Store Char/Short
5864 instruct storeC(memory mem, rRegI src)
5865 %{
5866 match(Set mem (StoreC mem src));
5868 ins_cost(125); // XXX
5869 format %{ "movw $mem, $src\t# char/short" %}
5870 opcode(0x89);
5871 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
5872 ins_pipe(ialu_mem_reg);
5873 %}
5875 // Store Integer
5876 instruct storeI(memory mem, rRegI src)
5877 %{
5878 match(Set mem (StoreI mem src));
5880 ins_cost(125); // XXX
5881 format %{ "movl $mem, $src\t# int" %}
5882 opcode(0x89);
5883 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
5884 ins_pipe(ialu_mem_reg);
5885 %}
5887 // Store Long
5888 instruct storeL(memory mem, rRegL src)
5889 %{
5890 match(Set mem (StoreL mem src));
5892 ins_cost(125); // XXX
5893 format %{ "movq $mem, $src\t# long" %}
5894 opcode(0x89);
5895 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5896 ins_pipe(ialu_mem_reg); // XXX
5897 %}
5899 // Store Pointer
5900 instruct storeP(memory mem, any_RegP src)
5901 %{
5902 match(Set mem (StoreP mem src));
5904 ins_cost(125); // XXX
5905 format %{ "movq $mem, $src\t# ptr" %}
5906 opcode(0x89);
5907 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5908 ins_pipe(ialu_mem_reg);
5909 %}
5911 instruct storeImmP0(memory mem, immP0 zero)
5912 %{
5913 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5914 match(Set mem (StoreP mem zero));
5916 ins_cost(125); // XXX
5917 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
5918 ins_encode %{
5919 __ movq($mem$$Address, r12);
5920 %}
5921 ins_pipe(ialu_mem_reg);
5922 %}
5924 // Store NULL Pointer, mark word, or other simple pointer constant.
5925 instruct storeImmP(memory mem, immP31 src)
5926 %{
5927 match(Set mem (StoreP mem src));
5929 ins_cost(150); // XXX
5930 format %{ "movq $mem, $src\t# ptr" %}
5931 opcode(0xC7); /* C7 /0 */
5932 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5933 ins_pipe(ialu_mem_imm);
5934 %}
5936 // Store Compressed Pointer
5937 instruct storeN(memory mem, rRegN src)
5938 %{
5939 match(Set mem (StoreN mem src));
5941 ins_cost(125); // XXX
5942 format %{ "movl $mem, $src\t# compressed ptr" %}
5943 ins_encode %{
5944 __ movl($mem$$Address, $src$$Register);
5945 %}
5946 ins_pipe(ialu_mem_reg);
5947 %}
5949 instruct storeNKlass(memory mem, rRegN src)
5950 %{
5951 match(Set mem (StoreNKlass mem src));
5953 ins_cost(125); // XXX
5954 format %{ "movl $mem, $src\t# compressed klass ptr" %}
5955 ins_encode %{
5956 __ movl($mem$$Address, $src$$Register);
5957 %}
5958 ins_pipe(ialu_mem_reg);
5959 %}
5961 instruct storeImmN0(memory mem, immN0 zero)
5962 %{
5963 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL);
5964 match(Set mem (StoreN mem zero));
5966 ins_cost(125); // XXX
5967 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
5968 ins_encode %{
5969 __ movl($mem$$Address, r12);
5970 %}
5971 ins_pipe(ialu_mem_reg);
5972 %}
5974 instruct storeImmN(memory mem, immN src)
5975 %{
5976 match(Set mem (StoreN mem src));
5978 ins_cost(150); // XXX
5979 format %{ "movl $mem, $src\t# compressed ptr" %}
5980 ins_encode %{
5981 address con = (address)$src$$constant;
5982 if (con == NULL) {
5983 __ movl($mem$$Address, (int32_t)0);
5984 } else {
5985 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant);
5986 }
5987 %}
5988 ins_pipe(ialu_mem_imm);
5989 %}
5991 instruct storeImmNKlass(memory mem, immNKlass src)
5992 %{
5993 match(Set mem (StoreNKlass mem src));
5995 ins_cost(150); // XXX
5996 format %{ "movl $mem, $src\t# compressed klass ptr" %}
5997 ins_encode %{
5998 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant);
5999 %}
6000 ins_pipe(ialu_mem_imm);
6001 %}
6003 // Store Integer Immediate
6004 instruct storeImmI0(memory mem, immI0 zero)
6005 %{
6006 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6007 match(Set mem (StoreI mem zero));
6009 ins_cost(125); // XXX
6010 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
6011 ins_encode %{
6012 __ movl($mem$$Address, r12);
6013 %}
6014 ins_pipe(ialu_mem_reg);
6015 %}
6017 instruct storeImmI(memory mem, immI src)
6018 %{
6019 match(Set mem (StoreI mem src));
6021 ins_cost(150);
6022 format %{ "movl $mem, $src\t# int" %}
6023 opcode(0xC7); /* C7 /0 */
6024 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6025 ins_pipe(ialu_mem_imm);
6026 %}
6028 // Store Long Immediate
6029 instruct storeImmL0(memory mem, immL0 zero)
6030 %{
6031 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6032 match(Set mem (StoreL mem zero));
6034 ins_cost(125); // XXX
6035 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
6036 ins_encode %{
6037 __ movq($mem$$Address, r12);
6038 %}
6039 ins_pipe(ialu_mem_reg);
6040 %}
6042 instruct storeImmL(memory mem, immL32 src)
6043 %{
6044 match(Set mem (StoreL mem src));
6046 ins_cost(150);
6047 format %{ "movq $mem, $src\t# long" %}
6048 opcode(0xC7); /* C7 /0 */
6049 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
6050 ins_pipe(ialu_mem_imm);
6051 %}
6053 // Store Short/Char Immediate
6054 instruct storeImmC0(memory mem, immI0 zero)
6055 %{
6056 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6057 match(Set mem (StoreC mem zero));
6059 ins_cost(125); // XXX
6060 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
6061 ins_encode %{
6062 __ movw($mem$$Address, r12);
6063 %}
6064 ins_pipe(ialu_mem_reg);
6065 %}
6067 instruct storeImmI16(memory mem, immI16 src)
6068 %{
6069 predicate(UseStoreImmI16);
6070 match(Set mem (StoreC mem src));
6072 ins_cost(150);
6073 format %{ "movw $mem, $src\t# short/char" %}
6074 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */
6075 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src));
6076 ins_pipe(ialu_mem_imm);
6077 %}
6079 // Store Byte Immediate
6080 instruct storeImmB0(memory mem, immI0 zero)
6081 %{
6082 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6083 match(Set mem (StoreB mem zero));
6085 ins_cost(125); // XXX
6086 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
6087 ins_encode %{
6088 __ movb($mem$$Address, r12);
6089 %}
6090 ins_pipe(ialu_mem_reg);
6091 %}
6093 instruct storeImmB(memory mem, immI8 src)
6094 %{
6095 match(Set mem (StoreB mem src));
6097 ins_cost(150); // XXX
6098 format %{ "movb $mem, $src\t# byte" %}
6099 opcode(0xC6); /* C6 /0 */
6100 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6101 ins_pipe(ialu_mem_imm);
6102 %}
6104 // Store CMS card-mark Immediate
6105 instruct storeImmCM0_reg(memory mem, immI0 zero)
6106 %{
6107 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6108 match(Set mem (StoreCM mem zero));
6110 ins_cost(125); // XXX
6111 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
6112 ins_encode %{
6113 __ movb($mem$$Address, r12);
6114 %}
6115 ins_pipe(ialu_mem_reg);
6116 %}
6118 instruct storeImmCM0(memory mem, immI0 src)
6119 %{
6120 match(Set mem (StoreCM mem src));
6122 ins_cost(150); // XXX
6123 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
6124 opcode(0xC6); /* C6 /0 */
6125 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
6126 ins_pipe(ialu_mem_imm);
6127 %}
6129 // Store Float
6130 instruct storeF(memory mem, regF src)
6131 %{
6132 match(Set mem (StoreF mem src));
6134 ins_cost(95); // XXX
6135 format %{ "movss $mem, $src\t# float" %}
6136 ins_encode %{
6137 __ movflt($mem$$Address, $src$$XMMRegister);
6138 %}
6139 ins_pipe(pipe_slow); // XXX
6140 %}
6142 // Store immediate Float value (it is faster than store from XMM register)
6143 instruct storeF0(memory mem, immF0 zero)
6144 %{
6145 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6146 match(Set mem (StoreF mem zero));
6148 ins_cost(25); // XXX
6149 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
6150 ins_encode %{
6151 __ movl($mem$$Address, r12);
6152 %}
6153 ins_pipe(ialu_mem_reg);
6154 %}
6156 instruct storeF_imm(memory mem, immF src)
6157 %{
6158 match(Set mem (StoreF mem src));
6160 ins_cost(50);
6161 format %{ "movl $mem, $src\t# float" %}
6162 opcode(0xC7); /* C7 /0 */
6163 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6164 ins_pipe(ialu_mem_imm);
6165 %}
6167 // Store Double
6168 instruct storeD(memory mem, regD src)
6169 %{
6170 match(Set mem (StoreD mem src));
6172 ins_cost(95); // XXX
6173 format %{ "movsd $mem, $src\t# double" %}
6174 ins_encode %{
6175 __ movdbl($mem$$Address, $src$$XMMRegister);
6176 %}
6177 ins_pipe(pipe_slow); // XXX
6178 %}
6180 // Store immediate double 0.0 (it is faster than store from XMM register)
6181 instruct storeD0_imm(memory mem, immD0 src)
6182 %{
6183 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
6184 match(Set mem (StoreD mem src));
6186 ins_cost(50);
6187 format %{ "movq $mem, $src\t# double 0." %}
6188 opcode(0xC7); /* C7 /0 */
6189 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6190 ins_pipe(ialu_mem_imm);
6191 %}
6193 instruct storeD0(memory mem, immD0 zero)
6194 %{
6195 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6196 match(Set mem (StoreD mem zero));
6198 ins_cost(25); // XXX
6199 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
6200 ins_encode %{
6201 __ movq($mem$$Address, r12);
6202 %}
6203 ins_pipe(ialu_mem_reg);
6204 %}
6206 instruct storeSSI(stackSlotI dst, rRegI src)
6207 %{
6208 match(Set dst src);
6210 ins_cost(100);
6211 format %{ "movl $dst, $src\t# int stk" %}
6212 opcode(0x89);
6213 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
6214 ins_pipe( ialu_mem_reg );
6215 %}
6217 instruct storeSSL(stackSlotL dst, rRegL src)
6218 %{
6219 match(Set dst src);
6221 ins_cost(100);
6222 format %{ "movq $dst, $src\t# long stk" %}
6223 opcode(0x89);
6224 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6225 ins_pipe(ialu_mem_reg);
6226 %}
6228 instruct storeSSP(stackSlotP dst, rRegP src)
6229 %{
6230 match(Set dst src);
6232 ins_cost(100);
6233 format %{ "movq $dst, $src\t# ptr stk" %}
6234 opcode(0x89);
6235 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6236 ins_pipe(ialu_mem_reg);
6237 %}
6239 instruct storeSSF(stackSlotF dst, regF src)
6240 %{
6241 match(Set dst src);
6243 ins_cost(95); // XXX
6244 format %{ "movss $dst, $src\t# float stk" %}
6245 ins_encode %{
6246 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
6247 %}
6248 ins_pipe(pipe_slow); // XXX
6249 %}
6251 instruct storeSSD(stackSlotD dst, regD src)
6252 %{
6253 match(Set dst src);
6255 ins_cost(95); // XXX
6256 format %{ "movsd $dst, $src\t# double stk" %}
6257 ins_encode %{
6258 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
6259 %}
6260 ins_pipe(pipe_slow); // XXX
6261 %}
6263 //----------BSWAP Instructions-------------------------------------------------
6264 instruct bytes_reverse_int(rRegI dst) %{
6265 match(Set dst (ReverseBytesI dst));
6267 format %{ "bswapl $dst" %}
6268 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */
6269 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) );
6270 ins_pipe( ialu_reg );
6271 %}
6273 instruct bytes_reverse_long(rRegL dst) %{
6274 match(Set dst (ReverseBytesL dst));
6276 format %{ "bswapq $dst" %}
6277 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */
6278 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) );
6279 ins_pipe( ialu_reg);
6280 %}
6282 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{
6283 match(Set dst (ReverseBytesUS dst));
6284 effect(KILL cr);
6286 format %{ "bswapl $dst\n\t"
6287 "shrl $dst,16\n\t" %}
6288 ins_encode %{
6289 __ bswapl($dst$$Register);
6290 __ shrl($dst$$Register, 16);
6291 %}
6292 ins_pipe( ialu_reg );
6293 %}
6295 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{
6296 match(Set dst (ReverseBytesS dst));
6297 effect(KILL cr);
6299 format %{ "bswapl $dst\n\t"
6300 "sar $dst,16\n\t" %}
6301 ins_encode %{
6302 __ bswapl($dst$$Register);
6303 __ sarl($dst$$Register, 16);
6304 %}
6305 ins_pipe( ialu_reg );
6306 %}
6308 //---------- Zeros Count Instructions ------------------------------------------
6310 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6311 predicate(UseCountLeadingZerosInstruction);
6312 match(Set dst (CountLeadingZerosI src));
6313 effect(KILL cr);
6315 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %}
6316 ins_encode %{
6317 __ lzcntl($dst$$Register, $src$$Register);
6318 %}
6319 ins_pipe(ialu_reg);
6320 %}
6322 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{
6323 predicate(!UseCountLeadingZerosInstruction);
6324 match(Set dst (CountLeadingZerosI src));
6325 effect(KILL cr);
6327 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t"
6328 "jnz skip\n\t"
6329 "movl $dst, -1\n"
6330 "skip:\n\t"
6331 "negl $dst\n\t"
6332 "addl $dst, 31" %}
6333 ins_encode %{
6334 Register Rdst = $dst$$Register;
6335 Register Rsrc = $src$$Register;
6336 Label skip;
6337 __ bsrl(Rdst, Rsrc);
6338 __ jccb(Assembler::notZero, skip);
6339 __ movl(Rdst, -1);
6340 __ bind(skip);
6341 __ negl(Rdst);
6342 __ addl(Rdst, BitsPerInt - 1);
6343 %}
6344 ins_pipe(ialu_reg);
6345 %}
6347 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6348 predicate(UseCountLeadingZerosInstruction);
6349 match(Set dst (CountLeadingZerosL src));
6350 effect(KILL cr);
6352 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %}
6353 ins_encode %{
6354 __ lzcntq($dst$$Register, $src$$Register);
6355 %}
6356 ins_pipe(ialu_reg);
6357 %}
6359 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{
6360 predicate(!UseCountLeadingZerosInstruction);
6361 match(Set dst (CountLeadingZerosL src));
6362 effect(KILL cr);
6364 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t"
6365 "jnz skip\n\t"
6366 "movl $dst, -1\n"
6367 "skip:\n\t"
6368 "negl $dst\n\t"
6369 "addl $dst, 63" %}
6370 ins_encode %{
6371 Register Rdst = $dst$$Register;
6372 Register Rsrc = $src$$Register;
6373 Label skip;
6374 __ bsrq(Rdst, Rsrc);
6375 __ jccb(Assembler::notZero, skip);
6376 __ movl(Rdst, -1);
6377 __ bind(skip);
6378 __ negl(Rdst);
6379 __ addl(Rdst, BitsPerLong - 1);
6380 %}
6381 ins_pipe(ialu_reg);
6382 %}
6384 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6385 match(Set dst (CountTrailingZerosI src));
6386 effect(KILL cr);
6388 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t"
6389 "jnz done\n\t"
6390 "movl $dst, 32\n"
6391 "done:" %}
6392 ins_encode %{
6393 Register Rdst = $dst$$Register;
6394 Label done;
6395 __ bsfl(Rdst, $src$$Register);
6396 __ jccb(Assembler::notZero, done);
6397 __ movl(Rdst, BitsPerInt);
6398 __ bind(done);
6399 %}
6400 ins_pipe(ialu_reg);
6401 %}
6403 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6404 match(Set dst (CountTrailingZerosL src));
6405 effect(KILL cr);
6407 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t"
6408 "jnz done\n\t"
6409 "movl $dst, 64\n"
6410 "done:" %}
6411 ins_encode %{
6412 Register Rdst = $dst$$Register;
6413 Label done;
6414 __ bsfq(Rdst, $src$$Register);
6415 __ jccb(Assembler::notZero, done);
6416 __ movl(Rdst, BitsPerLong);
6417 __ bind(done);
6418 %}
6419 ins_pipe(ialu_reg);
6420 %}
6423 //---------- Population Count Instructions -------------------------------------
6425 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{
6426 predicate(UsePopCountInstruction);
6427 match(Set dst (PopCountI src));
6428 effect(KILL cr);
6430 format %{ "popcnt $dst, $src" %}
6431 ins_encode %{
6432 __ popcntl($dst$$Register, $src$$Register);
6433 %}
6434 ins_pipe(ialu_reg);
6435 %}
6437 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{
6438 predicate(UsePopCountInstruction);
6439 match(Set dst (PopCountI (LoadI mem)));
6440 effect(KILL cr);
6442 format %{ "popcnt $dst, $mem" %}
6443 ins_encode %{
6444 __ popcntl($dst$$Register, $mem$$Address);
6445 %}
6446 ins_pipe(ialu_reg);
6447 %}
6449 // Note: Long.bitCount(long) returns an int.
6450 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{
6451 predicate(UsePopCountInstruction);
6452 match(Set dst (PopCountL src));
6453 effect(KILL cr);
6455 format %{ "popcnt $dst, $src" %}
6456 ins_encode %{
6457 __ popcntq($dst$$Register, $src$$Register);
6458 %}
6459 ins_pipe(ialu_reg);
6460 %}
6462 // Note: Long.bitCount(long) returns an int.
6463 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{
6464 predicate(UsePopCountInstruction);
6465 match(Set dst (PopCountL (LoadL mem)));
6466 effect(KILL cr);
6468 format %{ "popcnt $dst, $mem" %}
6469 ins_encode %{
6470 __ popcntq($dst$$Register, $mem$$Address);
6471 %}
6472 ins_pipe(ialu_reg);
6473 %}
6476 //----------MemBar Instructions-----------------------------------------------
6477 // Memory barrier flavors
6479 instruct membar_acquire()
6480 %{
6481 match(MemBarAcquire);
6482 ins_cost(0);
6484 size(0);
6485 format %{ "MEMBAR-acquire ! (empty encoding)" %}
6486 ins_encode();
6487 ins_pipe(empty);
6488 %}
6490 instruct membar_acquire_lock()
6491 %{
6492 match(MemBarAcquireLock);
6493 ins_cost(0);
6495 size(0);
6496 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %}
6497 ins_encode();
6498 ins_pipe(empty);
6499 %}
6501 instruct membar_release()
6502 %{
6503 match(MemBarRelease);
6504 ins_cost(0);
6506 size(0);
6507 format %{ "MEMBAR-release ! (empty encoding)" %}
6508 ins_encode();
6509 ins_pipe(empty);
6510 %}
6512 instruct membar_release_lock()
6513 %{
6514 match(MemBarReleaseLock);
6515 ins_cost(0);
6517 size(0);
6518 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
6519 ins_encode();
6520 ins_pipe(empty);
6521 %}
6523 instruct membar_volatile(rFlagsReg cr) %{
6524 match(MemBarVolatile);
6525 effect(KILL cr);
6526 ins_cost(400);
6528 format %{
6529 $$template
6530 if (os::is_MP()) {
6531 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
6532 } else {
6533 $$emit$$"MEMBAR-volatile ! (empty encoding)"
6534 }
6535 %}
6536 ins_encode %{
6537 __ membar(Assembler::StoreLoad);
6538 %}
6539 ins_pipe(pipe_slow);
6540 %}
6542 instruct unnecessary_membar_volatile()
6543 %{
6544 match(MemBarVolatile);
6545 predicate(Matcher::post_store_load_barrier(n));
6546 ins_cost(0);
6548 size(0);
6549 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
6550 ins_encode();
6551 ins_pipe(empty);
6552 %}
6554 instruct membar_storestore() %{
6555 match(MemBarStoreStore);
6556 ins_cost(0);
6558 size(0);
6559 format %{ "MEMBAR-storestore (empty encoding)" %}
6560 ins_encode( );
6561 ins_pipe(empty);
6562 %}
6564 //----------Move Instructions--------------------------------------------------
6566 instruct castX2P(rRegP dst, rRegL src)
6567 %{
6568 match(Set dst (CastX2P src));
6570 format %{ "movq $dst, $src\t# long->ptr" %}
6571 ins_encode %{
6572 if ($dst$$reg != $src$$reg) {
6573 __ movptr($dst$$Register, $src$$Register);
6574 }
6575 %}
6576 ins_pipe(ialu_reg_reg); // XXX
6577 %}
6579 instruct castP2X(rRegL dst, rRegP src)
6580 %{
6581 match(Set dst (CastP2X src));
6583 format %{ "movq $dst, $src\t# ptr -> long" %}
6584 ins_encode %{
6585 if ($dst$$reg != $src$$reg) {
6586 __ movptr($dst$$Register, $src$$Register);
6587 }
6588 %}
6589 ins_pipe(ialu_reg_reg); // XXX
6590 %}
6592 // Convert oop into int for vectors alignment masking
6593 instruct convP2I(rRegI dst, rRegP src)
6594 %{
6595 match(Set dst (ConvL2I (CastP2X src)));
6597 format %{ "movl $dst, $src\t# ptr -> int" %}
6598 ins_encode %{
6599 __ movl($dst$$Register, $src$$Register);
6600 %}
6601 ins_pipe(ialu_reg_reg); // XXX
6602 %}
6604 // Convert compressed oop into int for vectors alignment masking
6605 // in case of 32bit oops (heap < 4Gb).
6606 instruct convN2I(rRegI dst, rRegN src)
6607 %{
6608 predicate(Universe::narrow_oop_shift() == 0);
6609 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6611 format %{ "movl $dst, $src\t# compressed ptr -> int" %}
6612 ins_encode %{
6613 __ movl($dst$$Register, $src$$Register);
6614 %}
6615 ins_pipe(ialu_reg_reg); // XXX
6616 %}
6618 // Convert oop pointer into compressed form
6619 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
6620 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
6621 match(Set dst (EncodeP src));
6622 effect(KILL cr);
6623 format %{ "encode_heap_oop $dst,$src" %}
6624 ins_encode %{
6625 Register s = $src$$Register;
6626 Register d = $dst$$Register;
6627 if (s != d) {
6628 __ movq(d, s);
6629 }
6630 __ encode_heap_oop(d);
6631 %}
6632 ins_pipe(ialu_reg_long);
6633 %}
6635 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6636 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
6637 match(Set dst (EncodeP src));
6638 effect(KILL cr);
6639 format %{ "encode_heap_oop_not_null $dst,$src" %}
6640 ins_encode %{
6641 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
6642 %}
6643 ins_pipe(ialu_reg_long);
6644 %}
6646 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
6647 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
6648 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
6649 match(Set dst (DecodeN src));
6650 effect(KILL cr);
6651 format %{ "decode_heap_oop $dst,$src" %}
6652 ins_encode %{
6653 Register s = $src$$Register;
6654 Register d = $dst$$Register;
6655 if (s != d) {
6656 __ movq(d, s);
6657 }
6658 __ decode_heap_oop(d);
6659 %}
6660 ins_pipe(ialu_reg_long);
6661 %}
6663 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6664 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
6665 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
6666 match(Set dst (DecodeN src));
6667 effect(KILL cr);
6668 format %{ "decode_heap_oop_not_null $dst,$src" %}
6669 ins_encode %{
6670 Register s = $src$$Register;
6671 Register d = $dst$$Register;
6672 if (s != d) {
6673 __ decode_heap_oop_not_null(d, s);
6674 } else {
6675 __ decode_heap_oop_not_null(d);
6676 }
6677 %}
6678 ins_pipe(ialu_reg_long);
6679 %}
6681 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6682 match(Set dst (EncodePKlass src));
6683 effect(KILL cr);
6684 format %{ "encode_heap_oop_not_null $dst,$src" %}
6685 ins_encode %{
6686 __ encode_klass_not_null($dst$$Register, $src$$Register);
6687 %}
6688 ins_pipe(ialu_reg_long);
6689 %}
6691 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6692 match(Set dst (DecodeNKlass src));
6693 effect(KILL cr);
6694 format %{ "decode_heap_oop_not_null $dst,$src" %}
6695 ins_encode %{
6696 Register s = $src$$Register;
6697 Register d = $dst$$Register;
6698 if (s != d) {
6699 __ decode_klass_not_null(d, s);
6700 } else {
6701 __ decode_klass_not_null(d);
6702 }
6703 %}
6704 ins_pipe(ialu_reg_long);
6705 %}
6708 //----------Conditional Move---------------------------------------------------
6709 // Jump
6710 // dummy instruction for generating temp registers
6711 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
6712 match(Jump (LShiftL switch_val shift));
6713 ins_cost(350);
6714 predicate(false);
6715 effect(TEMP dest);
6717 format %{ "leaq $dest, [$constantaddress]\n\t"
6718 "jmp [$dest + $switch_val << $shift]\n\t" %}
6719 ins_encode %{
6720 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6721 // to do that and the compiler is using that register as one it can allocate.
6722 // So we build it all by hand.
6723 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
6724 // ArrayAddress dispatch(table, index);
6725 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
6726 __ lea($dest$$Register, $constantaddress);
6727 __ jmp(dispatch);
6728 %}
6729 ins_pipe(pipe_jmp);
6730 %}
6732 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
6733 match(Jump (AddL (LShiftL switch_val shift) offset));
6734 ins_cost(350);
6735 effect(TEMP dest);
6737 format %{ "leaq $dest, [$constantaddress]\n\t"
6738 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %}
6739 ins_encode %{
6740 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6741 // to do that and the compiler is using that register as one it can allocate.
6742 // So we build it all by hand.
6743 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6744 // ArrayAddress dispatch(table, index);
6745 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6746 __ lea($dest$$Register, $constantaddress);
6747 __ jmp(dispatch);
6748 %}
6749 ins_pipe(pipe_jmp);
6750 %}
6752 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
6753 match(Jump switch_val);
6754 ins_cost(350);
6755 effect(TEMP dest);
6757 format %{ "leaq $dest, [$constantaddress]\n\t"
6758 "jmp [$dest + $switch_val]\n\t" %}
6759 ins_encode %{
6760 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6761 // to do that and the compiler is using that register as one it can allocate.
6762 // So we build it all by hand.
6763 // Address index(noreg, switch_reg, Address::times_1);
6764 // ArrayAddress dispatch(table, index);
6765 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1);
6766 __ lea($dest$$Register, $constantaddress);
6767 __ jmp(dispatch);
6768 %}
6769 ins_pipe(pipe_jmp);
6770 %}
6772 // Conditional move
6773 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
6774 %{
6775 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6777 ins_cost(200); // XXX
6778 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
6779 opcode(0x0F, 0x40);
6780 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6781 ins_pipe(pipe_cmov_reg);
6782 %}
6784 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
6785 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6787 ins_cost(200); // XXX
6788 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
6789 opcode(0x0F, 0x40);
6790 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6791 ins_pipe(pipe_cmov_reg);
6792 %}
6794 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
6795 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6796 ins_cost(200);
6797 expand %{
6798 cmovI_regU(cop, cr, dst, src);
6799 %}
6800 %}
6802 // Conditional move
6803 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
6804 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6806 ins_cost(250); // XXX
6807 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
6808 opcode(0x0F, 0x40);
6809 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
6810 ins_pipe(pipe_cmov_mem);
6811 %}
6813 // Conditional move
6814 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
6815 %{
6816 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6818 ins_cost(250); // XXX
6819 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
6820 opcode(0x0F, 0x40);
6821 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
6822 ins_pipe(pipe_cmov_mem);
6823 %}
6825 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
6826 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6827 ins_cost(250);
6828 expand %{
6829 cmovI_memU(cop, cr, dst, src);
6830 %}
6831 %}
6833 // Conditional move
6834 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
6835 %{
6836 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6838 ins_cost(200); // XXX
6839 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
6840 opcode(0x0F, 0x40);
6841 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6842 ins_pipe(pipe_cmov_reg);
6843 %}
6845 // Conditional move
6846 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
6847 %{
6848 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6850 ins_cost(200); // XXX
6851 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
6852 opcode(0x0F, 0x40);
6853 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6854 ins_pipe(pipe_cmov_reg);
6855 %}
6857 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
6858 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6859 ins_cost(200);
6860 expand %{
6861 cmovN_regU(cop, cr, dst, src);
6862 %}
6863 %}
6865 // Conditional move
6866 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
6867 %{
6868 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6870 ins_cost(200); // XXX
6871 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %}
6872 opcode(0x0F, 0x40);
6873 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6874 ins_pipe(pipe_cmov_reg); // XXX
6875 %}
6877 // Conditional move
6878 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
6879 %{
6880 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6882 ins_cost(200); // XXX
6883 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %}
6884 opcode(0x0F, 0x40);
6885 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6886 ins_pipe(pipe_cmov_reg); // XXX
6887 %}
6889 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
6890 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6891 ins_cost(200);
6892 expand %{
6893 cmovP_regU(cop, cr, dst, src);
6894 %}
6895 %}
6897 // DISABLED: Requires the ADLC to emit a bottom_type call that
6898 // correctly meets the two pointer arguments; one is an incoming
6899 // register but the other is a memory operand. ALSO appears to
6900 // be buggy with implicit null checks.
6901 //
6902 //// Conditional move
6903 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src)
6904 //%{
6905 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
6906 // ins_cost(250);
6907 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
6908 // opcode(0x0F,0x40);
6909 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
6910 // ins_pipe( pipe_cmov_mem );
6911 //%}
6912 //
6913 //// Conditional move
6914 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src)
6915 //%{
6916 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
6917 // ins_cost(250);
6918 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
6919 // opcode(0x0F,0x40);
6920 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
6921 // ins_pipe( pipe_cmov_mem );
6922 //%}
6924 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src)
6925 %{
6926 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
6928 ins_cost(200); // XXX
6929 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
6930 opcode(0x0F, 0x40);
6931 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6932 ins_pipe(pipe_cmov_reg); // XXX
6933 %}
6935 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src)
6936 %{
6937 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
6939 ins_cost(200); // XXX
6940 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
6941 opcode(0x0F, 0x40);
6942 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
6943 ins_pipe(pipe_cmov_mem); // XXX
6944 %}
6946 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src)
6947 %{
6948 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
6950 ins_cost(200); // XXX
6951 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
6952 opcode(0x0F, 0x40);
6953 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6954 ins_pipe(pipe_cmov_reg); // XXX
6955 %}
6957 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
6958 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
6959 ins_cost(200);
6960 expand %{
6961 cmovL_regU(cop, cr, dst, src);
6962 %}
6963 %}
6965 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
6966 %{
6967 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
6969 ins_cost(200); // XXX
6970 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
6971 opcode(0x0F, 0x40);
6972 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
6973 ins_pipe(pipe_cmov_mem); // XXX
6974 %}
6976 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
6977 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
6978 ins_cost(200);
6979 expand %{
6980 cmovL_memU(cop, cr, dst, src);
6981 %}
6982 %}
6984 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
6985 %{
6986 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
6988 ins_cost(200); // XXX
6989 format %{ "jn$cop skip\t# signed cmove float\n\t"
6990 "movss $dst, $src\n"
6991 "skip:" %}
6992 ins_encode %{
6993 Label Lskip;
6994 // Invert sense of branch from sense of CMOV
6995 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
6996 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
6997 __ bind(Lskip);
6998 %}
6999 ins_pipe(pipe_slow);
7000 %}
7002 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
7003 // %{
7004 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src))));
7006 // ins_cost(200); // XXX
7007 // format %{ "jn$cop skip\t# signed cmove float\n\t"
7008 // "movss $dst, $src\n"
7009 // "skip:" %}
7010 // ins_encode(enc_cmovf_mem_branch(cop, dst, src));
7011 // ins_pipe(pipe_slow);
7012 // %}
7014 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
7015 %{
7016 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7018 ins_cost(200); // XXX
7019 format %{ "jn$cop skip\t# unsigned cmove float\n\t"
7020 "movss $dst, $src\n"
7021 "skip:" %}
7022 ins_encode %{
7023 Label Lskip;
7024 // Invert sense of branch from sense of CMOV
7025 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7026 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
7027 __ bind(Lskip);
7028 %}
7029 ins_pipe(pipe_slow);
7030 %}
7032 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
7033 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
7034 ins_cost(200);
7035 expand %{
7036 cmovF_regU(cop, cr, dst, src);
7037 %}
7038 %}
7040 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
7041 %{
7042 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7044 ins_cost(200); // XXX
7045 format %{ "jn$cop skip\t# signed cmove double\n\t"
7046 "movsd $dst, $src\n"
7047 "skip:" %}
7048 ins_encode %{
7049 Label Lskip;
7050 // Invert sense of branch from sense of CMOV
7051 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7052 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7053 __ bind(Lskip);
7054 %}
7055 ins_pipe(pipe_slow);
7056 %}
7058 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
7059 %{
7060 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7062 ins_cost(200); // XXX
7063 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
7064 "movsd $dst, $src\n"
7065 "skip:" %}
7066 ins_encode %{
7067 Label Lskip;
7068 // Invert sense of branch from sense of CMOV
7069 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7070 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
7071 __ bind(Lskip);
7072 %}
7073 ins_pipe(pipe_slow);
7074 %}
7076 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
7077 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
7078 ins_cost(200);
7079 expand %{
7080 cmovD_regU(cop, cr, dst, src);
7081 %}
7082 %}
7084 //----------Arithmetic Instructions--------------------------------------------
7085 //----------Addition Instructions----------------------------------------------
7087 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7088 %{
7089 match(Set dst (AddI dst src));
7090 effect(KILL cr);
7092 format %{ "addl $dst, $src\t# int" %}
7093 opcode(0x03);
7094 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
7095 ins_pipe(ialu_reg_reg);
7096 %}
7098 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7099 %{
7100 match(Set dst (AddI dst src));
7101 effect(KILL cr);
7103 format %{ "addl $dst, $src\t# int" %}
7104 opcode(0x81, 0x00); /* /0 id */
7105 ins_encode(OpcSErm(dst, src), Con8or32(src));
7106 ins_pipe( ialu_reg );
7107 %}
7109 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
7110 %{
7111 match(Set dst (AddI dst (LoadI src)));
7112 effect(KILL cr);
7114 ins_cost(125); // XXX
7115 format %{ "addl $dst, $src\t# int" %}
7116 opcode(0x03);
7117 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
7118 ins_pipe(ialu_reg_mem);
7119 %}
7121 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
7122 %{
7123 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7124 effect(KILL cr);
7126 ins_cost(150); // XXX
7127 format %{ "addl $dst, $src\t# int" %}
7128 opcode(0x01); /* Opcode 01 /r */
7129 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
7130 ins_pipe(ialu_mem_reg);
7131 %}
7133 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr)
7134 %{
7135 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7136 effect(KILL cr);
7138 ins_cost(125); // XXX
7139 format %{ "addl $dst, $src\t# int" %}
7140 opcode(0x81); /* Opcode 81 /0 id */
7141 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
7142 ins_pipe(ialu_mem_imm);
7143 %}
7145 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
7146 %{
7147 predicate(UseIncDec);
7148 match(Set dst (AddI dst src));
7149 effect(KILL cr);
7151 format %{ "incl $dst\t# int" %}
7152 opcode(0xFF, 0x00); // FF /0
7153 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7154 ins_pipe(ialu_reg);
7155 %}
7157 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr)
7158 %{
7159 predicate(UseIncDec);
7160 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7161 effect(KILL cr);
7163 ins_cost(125); // XXX
7164 format %{ "incl $dst\t# int" %}
7165 opcode(0xFF); /* Opcode FF /0 */
7166 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst));
7167 ins_pipe(ialu_mem_imm);
7168 %}
7170 // XXX why does that use AddI
7171 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr)
7172 %{
7173 predicate(UseIncDec);
7174 match(Set dst (AddI dst src));
7175 effect(KILL cr);
7177 format %{ "decl $dst\t# int" %}
7178 opcode(0xFF, 0x01); // FF /1
7179 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7180 ins_pipe(ialu_reg);
7181 %}
7183 // XXX why does that use AddI
7184 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr)
7185 %{
7186 predicate(UseIncDec);
7187 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7188 effect(KILL cr);
7190 ins_cost(125); // XXX
7191 format %{ "decl $dst\t# int" %}
7192 opcode(0xFF); /* Opcode FF /1 */
7193 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst));
7194 ins_pipe(ialu_mem_imm);
7195 %}
7197 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1)
7198 %{
7199 match(Set dst (AddI src0 src1));
7201 ins_cost(110);
7202 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %}
7203 opcode(0x8D); /* 0x8D /r */
7204 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
7205 ins_pipe(ialu_reg_reg);
7206 %}
7208 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7209 %{
7210 match(Set dst (AddL dst src));
7211 effect(KILL cr);
7213 format %{ "addq $dst, $src\t# long" %}
7214 opcode(0x03);
7215 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7216 ins_pipe(ialu_reg_reg);
7217 %}
7219 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
7220 %{
7221 match(Set dst (AddL dst src));
7222 effect(KILL cr);
7224 format %{ "addq $dst, $src\t# long" %}
7225 opcode(0x81, 0x00); /* /0 id */
7226 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7227 ins_pipe( ialu_reg );
7228 %}
7230 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
7231 %{
7232 match(Set dst (AddL dst (LoadL src)));
7233 effect(KILL cr);
7235 ins_cost(125); // XXX
7236 format %{ "addq $dst, $src\t# long" %}
7237 opcode(0x03);
7238 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
7239 ins_pipe(ialu_reg_mem);
7240 %}
7242 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
7243 %{
7244 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7245 effect(KILL cr);
7247 ins_cost(150); // XXX
7248 format %{ "addq $dst, $src\t# long" %}
7249 opcode(0x01); /* Opcode 01 /r */
7250 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7251 ins_pipe(ialu_mem_reg);
7252 %}
7254 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
7255 %{
7256 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7257 effect(KILL cr);
7259 ins_cost(125); // XXX
7260 format %{ "addq $dst, $src\t# long" %}
7261 opcode(0x81); /* Opcode 81 /0 id */
7262 ins_encode(REX_mem_wide(dst),
7263 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
7264 ins_pipe(ialu_mem_imm);
7265 %}
7267 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr)
7268 %{
7269 predicate(UseIncDec);
7270 match(Set dst (AddL dst src));
7271 effect(KILL cr);
7273 format %{ "incq $dst\t# long" %}
7274 opcode(0xFF, 0x00); // FF /0
7275 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7276 ins_pipe(ialu_reg);
7277 %}
7279 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr)
7280 %{
7281 predicate(UseIncDec);
7282 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7283 effect(KILL cr);
7285 ins_cost(125); // XXX
7286 format %{ "incq $dst\t# long" %}
7287 opcode(0xFF); /* Opcode FF /0 */
7288 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst));
7289 ins_pipe(ialu_mem_imm);
7290 %}
7292 // XXX why does that use AddL
7293 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr)
7294 %{
7295 predicate(UseIncDec);
7296 match(Set dst (AddL dst src));
7297 effect(KILL cr);
7299 format %{ "decq $dst\t# long" %}
7300 opcode(0xFF, 0x01); // FF /1
7301 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7302 ins_pipe(ialu_reg);
7303 %}
7305 // XXX why does that use AddL
7306 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr)
7307 %{
7308 predicate(UseIncDec);
7309 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7310 effect(KILL cr);
7312 ins_cost(125); // XXX
7313 format %{ "decq $dst\t# long" %}
7314 opcode(0xFF); /* Opcode FF /1 */
7315 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst));
7316 ins_pipe(ialu_mem_imm);
7317 %}
7319 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1)
7320 %{
7321 match(Set dst (AddL src0 src1));
7323 ins_cost(110);
7324 format %{ "leaq $dst, [$src0 + $src1]\t# long" %}
7325 opcode(0x8D); /* 0x8D /r */
7326 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
7327 ins_pipe(ialu_reg_reg);
7328 %}
7330 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr)
7331 %{
7332 match(Set dst (AddP dst src));
7333 effect(KILL cr);
7335 format %{ "addq $dst, $src\t# ptr" %}
7336 opcode(0x03);
7337 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7338 ins_pipe(ialu_reg_reg);
7339 %}
7341 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr)
7342 %{
7343 match(Set dst (AddP dst src));
7344 effect(KILL cr);
7346 format %{ "addq $dst, $src\t# ptr" %}
7347 opcode(0x81, 0x00); /* /0 id */
7348 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7349 ins_pipe( ialu_reg );
7350 %}
7352 // XXX addP mem ops ????
7354 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1)
7355 %{
7356 match(Set dst (AddP src0 src1));
7358 ins_cost(110);
7359 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %}
7360 opcode(0x8D); /* 0x8D /r */
7361 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX
7362 ins_pipe(ialu_reg_reg);
7363 %}
7365 instruct checkCastPP(rRegP dst)
7366 %{
7367 match(Set dst (CheckCastPP dst));
7369 size(0);
7370 format %{ "# checkcastPP of $dst" %}
7371 ins_encode(/* empty encoding */);
7372 ins_pipe(empty);
7373 %}
7375 instruct castPP(rRegP dst)
7376 %{
7377 match(Set dst (CastPP dst));
7379 size(0);
7380 format %{ "# castPP of $dst" %}
7381 ins_encode(/* empty encoding */);
7382 ins_pipe(empty);
7383 %}
7385 instruct castII(rRegI dst)
7386 %{
7387 match(Set dst (CastII dst));
7389 size(0);
7390 format %{ "# castII of $dst" %}
7391 ins_encode(/* empty encoding */);
7392 ins_cost(0);
7393 ins_pipe(empty);
7394 %}
7396 // LoadP-locked same as a regular LoadP when used with compare-swap
7397 instruct loadPLocked(rRegP dst, memory mem)
7398 %{
7399 match(Set dst (LoadPLocked mem));
7401 ins_cost(125); // XXX
7402 format %{ "movq $dst, $mem\t# ptr locked" %}
7403 opcode(0x8B);
7404 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
7405 ins_pipe(ialu_reg_mem); // XXX
7406 %}
7408 // Conditional-store of the updated heap-top.
7409 // Used during allocation of the shared heap.
7410 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
7412 instruct storePConditional(memory heap_top_ptr,
7413 rax_RegP oldval, rRegP newval,
7414 rFlagsReg cr)
7415 %{
7416 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
7418 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
7419 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
7420 opcode(0x0F, 0xB1);
7421 ins_encode(lock_prefix,
7422 REX_reg_mem_wide(newval, heap_top_ptr),
7423 OpcP, OpcS,
7424 reg_mem(newval, heap_top_ptr));
7425 ins_pipe(pipe_cmpxchg);
7426 %}
7428 // Conditional-store of an int value.
7429 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
7430 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
7431 %{
7432 match(Set cr (StoreIConditional mem (Binary oldval newval)));
7433 effect(KILL oldval);
7435 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7436 opcode(0x0F, 0xB1);
7437 ins_encode(lock_prefix,
7438 REX_reg_mem(newval, mem),
7439 OpcP, OpcS,
7440 reg_mem(newval, mem));
7441 ins_pipe(pipe_cmpxchg);
7442 %}
7444 // Conditional-store of a long value.
7445 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
7446 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
7447 %{
7448 match(Set cr (StoreLConditional mem (Binary oldval newval)));
7449 effect(KILL oldval);
7451 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7452 opcode(0x0F, 0xB1);
7453 ins_encode(lock_prefix,
7454 REX_reg_mem_wide(newval, mem),
7455 OpcP, OpcS,
7456 reg_mem(newval, mem));
7457 ins_pipe(pipe_cmpxchg);
7458 %}
7461 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7462 instruct compareAndSwapP(rRegI res,
7463 memory mem_ptr,
7464 rax_RegP oldval, rRegP newval,
7465 rFlagsReg cr)
7466 %{
7467 predicate(VM_Version::supports_cx8());
7468 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7469 effect(KILL cr, KILL oldval);
7471 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7472 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7473 "sete $res\n\t"
7474 "movzbl $res, $res" %}
7475 opcode(0x0F, 0xB1);
7476 ins_encode(lock_prefix,
7477 REX_reg_mem_wide(newval, mem_ptr),
7478 OpcP, OpcS,
7479 reg_mem(newval, mem_ptr),
7480 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7481 REX_reg_breg(res, res), // movzbl
7482 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7483 ins_pipe( pipe_cmpxchg );
7484 %}
7486 instruct compareAndSwapL(rRegI res,
7487 memory mem_ptr,
7488 rax_RegL oldval, rRegL newval,
7489 rFlagsReg cr)
7490 %{
7491 predicate(VM_Version::supports_cx8());
7492 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7493 effect(KILL cr, KILL oldval);
7495 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7496 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7497 "sete $res\n\t"
7498 "movzbl $res, $res" %}
7499 opcode(0x0F, 0xB1);
7500 ins_encode(lock_prefix,
7501 REX_reg_mem_wide(newval, mem_ptr),
7502 OpcP, OpcS,
7503 reg_mem(newval, mem_ptr),
7504 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7505 REX_reg_breg(res, res), // movzbl
7506 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7507 ins_pipe( pipe_cmpxchg );
7508 %}
7510 instruct compareAndSwapI(rRegI res,
7511 memory mem_ptr,
7512 rax_RegI oldval, rRegI newval,
7513 rFlagsReg cr)
7514 %{
7515 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
7516 effect(KILL cr, KILL oldval);
7518 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7519 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7520 "sete $res\n\t"
7521 "movzbl $res, $res" %}
7522 opcode(0x0F, 0xB1);
7523 ins_encode(lock_prefix,
7524 REX_reg_mem(newval, mem_ptr),
7525 OpcP, OpcS,
7526 reg_mem(newval, mem_ptr),
7527 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7528 REX_reg_breg(res, res), // movzbl
7529 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7530 ins_pipe( pipe_cmpxchg );
7531 %}
7534 instruct compareAndSwapN(rRegI res,
7535 memory mem_ptr,
7536 rax_RegN oldval, rRegN newval,
7537 rFlagsReg cr) %{
7538 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7539 effect(KILL cr, KILL oldval);
7541 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7542 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7543 "sete $res\n\t"
7544 "movzbl $res, $res" %}
7545 opcode(0x0F, 0xB1);
7546 ins_encode(lock_prefix,
7547 REX_reg_mem(newval, mem_ptr),
7548 OpcP, OpcS,
7549 reg_mem(newval, mem_ptr),
7550 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7551 REX_reg_breg(res, res), // movzbl
7552 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7553 ins_pipe( pipe_cmpxchg );
7554 %}
7556 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
7557 predicate(n->as_LoadStore()->result_not_used());
7558 match(Set dummy (GetAndAddI mem add));
7559 effect(KILL cr);
7560 format %{ "ADDL [$mem],$add" %}
7561 ins_encode %{
7562 if (os::is_MP()) { __ lock(); }
7563 __ addl($mem$$Address, $add$$constant);
7564 %}
7565 ins_pipe( pipe_cmpxchg );
7566 %}
7568 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{
7569 match(Set newval (GetAndAddI mem newval));
7570 effect(KILL cr);
7571 format %{ "XADDL [$mem],$newval" %}
7572 ins_encode %{
7573 if (os::is_MP()) { __ lock(); }
7574 __ xaddl($mem$$Address, $newval$$Register);
7575 %}
7576 ins_pipe( pipe_cmpxchg );
7577 %}
7579 instruct xaddL_no_res( memory mem, Universe dummy, immL add, rFlagsReg cr) %{
7580 predicate(n->as_LoadStore()->result_not_used());
7581 match(Set dummy (GetAndAddL mem add));
7582 effect(KILL cr);
7583 format %{ "ADDQ [$mem],$add" %}
7584 ins_encode %{
7585 if (os::is_MP()) { __ lock(); }
7586 __ addq($mem$$Address, $add$$constant);
7587 %}
7588 ins_pipe( pipe_cmpxchg );
7589 %}
7591 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{
7592 match(Set newval (GetAndAddL mem newval));
7593 effect(KILL cr);
7594 format %{ "XADDQ [$mem],$newval" %}
7595 ins_encode %{
7596 if (os::is_MP()) { __ lock(); }
7597 __ xaddq($mem$$Address, $newval$$Register);
7598 %}
7599 ins_pipe( pipe_cmpxchg );
7600 %}
7602 instruct xchgI( memory mem, rRegI newval) %{
7603 match(Set newval (GetAndSetI mem newval));
7604 format %{ "XCHGL $newval,[$mem]" %}
7605 ins_encode %{
7606 __ xchgl($newval$$Register, $mem$$Address);
7607 %}
7608 ins_pipe( pipe_cmpxchg );
7609 %}
7611 instruct xchgL( memory mem, rRegL newval) %{
7612 match(Set newval (GetAndSetL mem newval));
7613 format %{ "XCHGL $newval,[$mem]" %}
7614 ins_encode %{
7615 __ xchgq($newval$$Register, $mem$$Address);
7616 %}
7617 ins_pipe( pipe_cmpxchg );
7618 %}
7620 instruct xchgP( memory mem, rRegP newval) %{
7621 match(Set newval (GetAndSetP mem newval));
7622 format %{ "XCHGQ $newval,[$mem]" %}
7623 ins_encode %{
7624 __ xchgq($newval$$Register, $mem$$Address);
7625 %}
7626 ins_pipe( pipe_cmpxchg );
7627 %}
7629 instruct xchgN( memory mem, rRegN newval) %{
7630 match(Set newval (GetAndSetN mem newval));
7631 format %{ "XCHGL $newval,$mem]" %}
7632 ins_encode %{
7633 __ xchgl($newval$$Register, $mem$$Address);
7634 %}
7635 ins_pipe( pipe_cmpxchg );
7636 %}
7638 //----------Subtraction Instructions-------------------------------------------
7640 // Integer Subtraction Instructions
7641 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7642 %{
7643 match(Set dst (SubI dst src));
7644 effect(KILL cr);
7646 format %{ "subl $dst, $src\t# int" %}
7647 opcode(0x2B);
7648 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
7649 ins_pipe(ialu_reg_reg);
7650 %}
7652 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7653 %{
7654 match(Set dst (SubI dst src));
7655 effect(KILL cr);
7657 format %{ "subl $dst, $src\t# int" %}
7658 opcode(0x81, 0x05); /* Opcode 81 /5 */
7659 ins_encode(OpcSErm(dst, src), Con8or32(src));
7660 ins_pipe(ialu_reg);
7661 %}
7663 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
7664 %{
7665 match(Set dst (SubI dst (LoadI src)));
7666 effect(KILL cr);
7668 ins_cost(125);
7669 format %{ "subl $dst, $src\t# int" %}
7670 opcode(0x2B);
7671 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
7672 ins_pipe(ialu_reg_mem);
7673 %}
7675 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
7676 %{
7677 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
7678 effect(KILL cr);
7680 ins_cost(150);
7681 format %{ "subl $dst, $src\t# int" %}
7682 opcode(0x29); /* Opcode 29 /r */
7683 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
7684 ins_pipe(ialu_mem_reg);
7685 %}
7687 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr)
7688 %{
7689 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
7690 effect(KILL cr);
7692 ins_cost(125); // XXX
7693 format %{ "subl $dst, $src\t# int" %}
7694 opcode(0x81); /* Opcode 81 /5 id */
7695 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
7696 ins_pipe(ialu_mem_imm);
7697 %}
7699 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7700 %{
7701 match(Set dst (SubL dst src));
7702 effect(KILL cr);
7704 format %{ "subq $dst, $src\t# long" %}
7705 opcode(0x2B);
7706 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7707 ins_pipe(ialu_reg_reg);
7708 %}
7710 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr)
7711 %{
7712 match(Set dst (SubL dst src));
7713 effect(KILL cr);
7715 format %{ "subq $dst, $src\t# long" %}
7716 opcode(0x81, 0x05); /* Opcode 81 /5 */
7717 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7718 ins_pipe(ialu_reg);
7719 %}
7721 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
7722 %{
7723 match(Set dst (SubL dst (LoadL src)));
7724 effect(KILL cr);
7726 ins_cost(125);
7727 format %{ "subq $dst, $src\t# long" %}
7728 opcode(0x2B);
7729 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
7730 ins_pipe(ialu_reg_mem);
7731 %}
7733 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
7734 %{
7735 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
7736 effect(KILL cr);
7738 ins_cost(150);
7739 format %{ "subq $dst, $src\t# long" %}
7740 opcode(0x29); /* Opcode 29 /r */
7741 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7742 ins_pipe(ialu_mem_reg);
7743 %}
7745 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
7746 %{
7747 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
7748 effect(KILL cr);
7750 ins_cost(125); // XXX
7751 format %{ "subq $dst, $src\t# long" %}
7752 opcode(0x81); /* Opcode 81 /5 id */
7753 ins_encode(REX_mem_wide(dst),
7754 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
7755 ins_pipe(ialu_mem_imm);
7756 %}
7758 // Subtract from a pointer
7759 // XXX hmpf???
7760 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr)
7761 %{
7762 match(Set dst (AddP dst (SubI zero src)));
7763 effect(KILL cr);
7765 format %{ "subq $dst, $src\t# ptr - int" %}
7766 opcode(0x2B);
7767 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7768 ins_pipe(ialu_reg_reg);
7769 %}
7771 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr)
7772 %{
7773 match(Set dst (SubI zero dst));
7774 effect(KILL cr);
7776 format %{ "negl $dst\t# int" %}
7777 opcode(0xF7, 0x03); // Opcode F7 /3
7778 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7779 ins_pipe(ialu_reg);
7780 %}
7782 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr)
7783 %{
7784 match(Set dst (StoreI dst (SubI zero (LoadI dst))));
7785 effect(KILL cr);
7787 format %{ "negl $dst\t# int" %}
7788 opcode(0xF7, 0x03); // Opcode F7 /3
7789 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
7790 ins_pipe(ialu_reg);
7791 %}
7793 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr)
7794 %{
7795 match(Set dst (SubL zero dst));
7796 effect(KILL cr);
7798 format %{ "negq $dst\t# long" %}
7799 opcode(0xF7, 0x03); // Opcode F7 /3
7800 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7801 ins_pipe(ialu_reg);
7802 %}
7804 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr)
7805 %{
7806 match(Set dst (StoreL dst (SubL zero (LoadL dst))));
7807 effect(KILL cr);
7809 format %{ "negq $dst\t# long" %}
7810 opcode(0xF7, 0x03); // Opcode F7 /3
7811 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
7812 ins_pipe(ialu_reg);
7813 %}
7816 //----------Multiplication/Division Instructions-------------------------------
7817 // Integer Multiplication Instructions
7818 // Multiply Register
7820 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7821 %{
7822 match(Set dst (MulI dst src));
7823 effect(KILL cr);
7825 ins_cost(300);
7826 format %{ "imull $dst, $src\t# int" %}
7827 opcode(0x0F, 0xAF);
7828 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
7829 ins_pipe(ialu_reg_reg_alu0);
7830 %}
7832 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr)
7833 %{
7834 match(Set dst (MulI src imm));
7835 effect(KILL cr);
7837 ins_cost(300);
7838 format %{ "imull $dst, $src, $imm\t# int" %}
7839 opcode(0x69); /* 69 /r id */
7840 ins_encode(REX_reg_reg(dst, src),
7841 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
7842 ins_pipe(ialu_reg_reg_alu0);
7843 %}
7845 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr)
7846 %{
7847 match(Set dst (MulI dst (LoadI src)));
7848 effect(KILL cr);
7850 ins_cost(350);
7851 format %{ "imull $dst, $src\t# int" %}
7852 opcode(0x0F, 0xAF);
7853 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src));
7854 ins_pipe(ialu_reg_mem_alu0);
7855 %}
7857 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr)
7858 %{
7859 match(Set dst (MulI (LoadI src) imm));
7860 effect(KILL cr);
7862 ins_cost(300);
7863 format %{ "imull $dst, $src, $imm\t# int" %}
7864 opcode(0x69); /* 69 /r id */
7865 ins_encode(REX_reg_mem(dst, src),
7866 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
7867 ins_pipe(ialu_reg_mem_alu0);
7868 %}
7870 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7871 %{
7872 match(Set dst (MulL dst src));
7873 effect(KILL cr);
7875 ins_cost(300);
7876 format %{ "imulq $dst, $src\t# long" %}
7877 opcode(0x0F, 0xAF);
7878 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src));
7879 ins_pipe(ialu_reg_reg_alu0);
7880 %}
7882 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr)
7883 %{
7884 match(Set dst (MulL src imm));
7885 effect(KILL cr);
7887 ins_cost(300);
7888 format %{ "imulq $dst, $src, $imm\t# long" %}
7889 opcode(0x69); /* 69 /r id */
7890 ins_encode(REX_reg_reg_wide(dst, src),
7891 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
7892 ins_pipe(ialu_reg_reg_alu0);
7893 %}
7895 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr)
7896 %{
7897 match(Set dst (MulL dst (LoadL src)));
7898 effect(KILL cr);
7900 ins_cost(350);
7901 format %{ "imulq $dst, $src\t# long" %}
7902 opcode(0x0F, 0xAF);
7903 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src));
7904 ins_pipe(ialu_reg_mem_alu0);
7905 %}
7907 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr)
7908 %{
7909 match(Set dst (MulL (LoadL src) imm));
7910 effect(KILL cr);
7912 ins_cost(300);
7913 format %{ "imulq $dst, $src, $imm\t# long" %}
7914 opcode(0x69); /* 69 /r id */
7915 ins_encode(REX_reg_mem_wide(dst, src),
7916 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
7917 ins_pipe(ialu_reg_mem_alu0);
7918 %}
7920 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
7921 %{
7922 match(Set dst (MulHiL src rax));
7923 effect(USE_KILL rax, KILL cr);
7925 ins_cost(300);
7926 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %}
7927 opcode(0xF7, 0x5); /* Opcode F7 /5 */
7928 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
7929 ins_pipe(ialu_reg_reg_alu0);
7930 %}
7932 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
7933 rFlagsReg cr)
7934 %{
7935 match(Set rax (DivI rax div));
7936 effect(KILL rdx, KILL cr);
7938 ins_cost(30*100+10*100); // XXX
7939 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
7940 "jne,s normal\n\t"
7941 "xorl rdx, rdx\n\t"
7942 "cmpl $div, -1\n\t"
7943 "je,s done\n"
7944 "normal: cdql\n\t"
7945 "idivl $div\n"
7946 "done:" %}
7947 opcode(0xF7, 0x7); /* Opcode F7 /7 */
7948 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
7949 ins_pipe(ialu_reg_reg_alu0);
7950 %}
7952 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
7953 rFlagsReg cr)
7954 %{
7955 match(Set rax (DivL rax div));
7956 effect(KILL rdx, KILL cr);
7958 ins_cost(30*100+10*100); // XXX
7959 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
7960 "cmpq rax, rdx\n\t"
7961 "jne,s normal\n\t"
7962 "xorl rdx, rdx\n\t"
7963 "cmpq $div, -1\n\t"
7964 "je,s done\n"
7965 "normal: cdqq\n\t"
7966 "idivq $div\n"
7967 "done:" %}
7968 opcode(0xF7, 0x7); /* Opcode F7 /7 */
7969 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
7970 ins_pipe(ialu_reg_reg_alu0);
7971 %}
7973 // Integer DIVMOD with Register, both quotient and mod results
7974 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
7975 rFlagsReg cr)
7976 %{
7977 match(DivModI rax div);
7978 effect(KILL cr);
7980 ins_cost(30*100+10*100); // XXX
7981 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
7982 "jne,s normal\n\t"
7983 "xorl rdx, rdx\n\t"
7984 "cmpl $div, -1\n\t"
7985 "je,s done\n"
7986 "normal: cdql\n\t"
7987 "idivl $div\n"
7988 "done:" %}
7989 opcode(0xF7, 0x7); /* Opcode F7 /7 */
7990 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
7991 ins_pipe(pipe_slow);
7992 %}
7994 // Long DIVMOD with Register, both quotient and mod results
7995 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
7996 rFlagsReg cr)
7997 %{
7998 match(DivModL rax div);
7999 effect(KILL cr);
8001 ins_cost(30*100+10*100); // XXX
8002 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8003 "cmpq rax, rdx\n\t"
8004 "jne,s normal\n\t"
8005 "xorl rdx, rdx\n\t"
8006 "cmpq $div, -1\n\t"
8007 "je,s done\n"
8008 "normal: cdqq\n\t"
8009 "idivq $div\n"
8010 "done:" %}
8011 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8012 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8013 ins_pipe(pipe_slow);
8014 %}
8016 //----------- DivL-By-Constant-Expansions--------------------------------------
8017 // DivI cases are handled by the compiler
8019 // Magic constant, reciprocal of 10
8020 instruct loadConL_0x6666666666666667(rRegL dst)
8021 %{
8022 effect(DEF dst);
8024 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %}
8025 ins_encode(load_immL(dst, 0x6666666666666667));
8026 ins_pipe(ialu_reg);
8027 %}
8029 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8030 %{
8031 effect(DEF dst, USE src, USE_KILL rax, KILL cr);
8033 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %}
8034 opcode(0xF7, 0x5); /* Opcode F7 /5 */
8035 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
8036 ins_pipe(ialu_reg_reg_alu0);
8037 %}
8039 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr)
8040 %{
8041 effect(USE_DEF dst, KILL cr);
8043 format %{ "sarq $dst, #63\t# Used in div-by-10" %}
8044 opcode(0xC1, 0x7); /* C1 /7 ib */
8045 ins_encode(reg_opc_imm_wide(dst, 0x3F));
8046 ins_pipe(ialu_reg);
8047 %}
8049 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr)
8050 %{
8051 effect(USE_DEF dst, KILL cr);
8053 format %{ "sarq $dst, #2\t# Used in div-by-10" %}
8054 opcode(0xC1, 0x7); /* C1 /7 ib */
8055 ins_encode(reg_opc_imm_wide(dst, 0x2));
8056 ins_pipe(ialu_reg);
8057 %}
8059 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div)
8060 %{
8061 match(Set dst (DivL src div));
8063 ins_cost((5+8)*100);
8064 expand %{
8065 rax_RegL rax; // Killed temp
8066 rFlagsReg cr; // Killed
8067 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667
8068 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src
8069 sarL_rReg_63(src, cr); // sarq src, 63
8070 sarL_rReg_2(dst, cr); // sarq rdx, 2
8071 subL_rReg(dst, src, cr); // subl rdx, src
8072 %}
8073 %}
8075 //-----------------------------------------------------------------------------
8077 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div,
8078 rFlagsReg cr)
8079 %{
8080 match(Set rdx (ModI rax div));
8081 effect(KILL rax, KILL cr);
8083 ins_cost(300); // XXX
8084 format %{ "cmpl rax, 0x80000000\t# irem\n\t"
8085 "jne,s normal\n\t"
8086 "xorl rdx, rdx\n\t"
8087 "cmpl $div, -1\n\t"
8088 "je,s done\n"
8089 "normal: cdql\n\t"
8090 "idivl $div\n"
8091 "done:" %}
8092 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8093 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8094 ins_pipe(ialu_reg_reg_alu0);
8095 %}
8097 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div,
8098 rFlagsReg cr)
8099 %{
8100 match(Set rdx (ModL rax div));
8101 effect(KILL rax, KILL cr);
8103 ins_cost(300); // XXX
8104 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t"
8105 "cmpq rax, rdx\n\t"
8106 "jne,s normal\n\t"
8107 "xorl rdx, rdx\n\t"
8108 "cmpq $div, -1\n\t"
8109 "je,s done\n"
8110 "normal: cdqq\n\t"
8111 "idivq $div\n"
8112 "done:" %}
8113 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8114 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8115 ins_pipe(ialu_reg_reg_alu0);
8116 %}
8118 // Integer Shift Instructions
8119 // Shift Left by one
8120 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8121 %{
8122 match(Set dst (LShiftI dst shift));
8123 effect(KILL cr);
8125 format %{ "sall $dst, $shift" %}
8126 opcode(0xD1, 0x4); /* D1 /4 */
8127 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8128 ins_pipe(ialu_reg);
8129 %}
8131 // Shift Left by one
8132 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8133 %{
8134 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8135 effect(KILL cr);
8137 format %{ "sall $dst, $shift\t" %}
8138 opcode(0xD1, 0x4); /* D1 /4 */
8139 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8140 ins_pipe(ialu_mem_imm);
8141 %}
8143 // Shift Left by 8-bit immediate
8144 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8145 %{
8146 match(Set dst (LShiftI dst shift));
8147 effect(KILL cr);
8149 format %{ "sall $dst, $shift" %}
8150 opcode(0xC1, 0x4); /* C1 /4 ib */
8151 ins_encode(reg_opc_imm(dst, shift));
8152 ins_pipe(ialu_reg);
8153 %}
8155 // Shift Left by 8-bit immediate
8156 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8157 %{
8158 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8159 effect(KILL cr);
8161 format %{ "sall $dst, $shift" %}
8162 opcode(0xC1, 0x4); /* C1 /4 ib */
8163 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8164 ins_pipe(ialu_mem_imm);
8165 %}
8167 // Shift Left by variable
8168 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8169 %{
8170 match(Set dst (LShiftI dst shift));
8171 effect(KILL cr);
8173 format %{ "sall $dst, $shift" %}
8174 opcode(0xD3, 0x4); /* D3 /4 */
8175 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8176 ins_pipe(ialu_reg_reg);
8177 %}
8179 // Shift Left by variable
8180 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8181 %{
8182 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8183 effect(KILL cr);
8185 format %{ "sall $dst, $shift" %}
8186 opcode(0xD3, 0x4); /* D3 /4 */
8187 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8188 ins_pipe(ialu_mem_reg);
8189 %}
8191 // Arithmetic shift right by one
8192 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8193 %{
8194 match(Set dst (RShiftI dst shift));
8195 effect(KILL cr);
8197 format %{ "sarl $dst, $shift" %}
8198 opcode(0xD1, 0x7); /* D1 /7 */
8199 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8200 ins_pipe(ialu_reg);
8201 %}
8203 // Arithmetic shift right by one
8204 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8205 %{
8206 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8207 effect(KILL cr);
8209 format %{ "sarl $dst, $shift" %}
8210 opcode(0xD1, 0x7); /* D1 /7 */
8211 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8212 ins_pipe(ialu_mem_imm);
8213 %}
8215 // Arithmetic Shift Right by 8-bit immediate
8216 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8217 %{
8218 match(Set dst (RShiftI dst shift));
8219 effect(KILL cr);
8221 format %{ "sarl $dst, $shift" %}
8222 opcode(0xC1, 0x7); /* C1 /7 ib */
8223 ins_encode(reg_opc_imm(dst, shift));
8224 ins_pipe(ialu_mem_imm);
8225 %}
8227 // Arithmetic Shift Right by 8-bit immediate
8228 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8229 %{
8230 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8231 effect(KILL cr);
8233 format %{ "sarl $dst, $shift" %}
8234 opcode(0xC1, 0x7); /* C1 /7 ib */
8235 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8236 ins_pipe(ialu_mem_imm);
8237 %}
8239 // Arithmetic Shift Right by variable
8240 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8241 %{
8242 match(Set dst (RShiftI dst shift));
8243 effect(KILL cr);
8245 format %{ "sarl $dst, $shift" %}
8246 opcode(0xD3, 0x7); /* D3 /7 */
8247 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8248 ins_pipe(ialu_reg_reg);
8249 %}
8251 // Arithmetic Shift Right by variable
8252 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8253 %{
8254 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8255 effect(KILL cr);
8257 format %{ "sarl $dst, $shift" %}
8258 opcode(0xD3, 0x7); /* D3 /7 */
8259 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8260 ins_pipe(ialu_mem_reg);
8261 %}
8263 // Logical shift right by one
8264 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8265 %{
8266 match(Set dst (URShiftI dst shift));
8267 effect(KILL cr);
8269 format %{ "shrl $dst, $shift" %}
8270 opcode(0xD1, 0x5); /* D1 /5 */
8271 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8272 ins_pipe(ialu_reg);
8273 %}
8275 // Logical shift right by one
8276 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8277 %{
8278 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8279 effect(KILL cr);
8281 format %{ "shrl $dst, $shift" %}
8282 opcode(0xD1, 0x5); /* D1 /5 */
8283 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8284 ins_pipe(ialu_mem_imm);
8285 %}
8287 // Logical Shift Right by 8-bit immediate
8288 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8289 %{
8290 match(Set dst (URShiftI dst shift));
8291 effect(KILL cr);
8293 format %{ "shrl $dst, $shift" %}
8294 opcode(0xC1, 0x5); /* C1 /5 ib */
8295 ins_encode(reg_opc_imm(dst, shift));
8296 ins_pipe(ialu_reg);
8297 %}
8299 // Logical Shift Right by 8-bit immediate
8300 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8301 %{
8302 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8303 effect(KILL cr);
8305 format %{ "shrl $dst, $shift" %}
8306 opcode(0xC1, 0x5); /* C1 /5 ib */
8307 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8308 ins_pipe(ialu_mem_imm);
8309 %}
8311 // Logical Shift Right by variable
8312 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8313 %{
8314 match(Set dst (URShiftI dst shift));
8315 effect(KILL cr);
8317 format %{ "shrl $dst, $shift" %}
8318 opcode(0xD3, 0x5); /* D3 /5 */
8319 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8320 ins_pipe(ialu_reg_reg);
8321 %}
8323 // Logical Shift Right by variable
8324 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8325 %{
8326 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8327 effect(KILL cr);
8329 format %{ "shrl $dst, $shift" %}
8330 opcode(0xD3, 0x5); /* D3 /5 */
8331 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8332 ins_pipe(ialu_mem_reg);
8333 %}
8335 // Long Shift Instructions
8336 // Shift Left by one
8337 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8338 %{
8339 match(Set dst (LShiftL dst shift));
8340 effect(KILL cr);
8342 format %{ "salq $dst, $shift" %}
8343 opcode(0xD1, 0x4); /* D1 /4 */
8344 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8345 ins_pipe(ialu_reg);
8346 %}
8348 // Shift Left by one
8349 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8350 %{
8351 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8352 effect(KILL cr);
8354 format %{ "salq $dst, $shift" %}
8355 opcode(0xD1, 0x4); /* D1 /4 */
8356 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8357 ins_pipe(ialu_mem_imm);
8358 %}
8360 // Shift Left by 8-bit immediate
8361 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8362 %{
8363 match(Set dst (LShiftL dst shift));
8364 effect(KILL cr);
8366 format %{ "salq $dst, $shift" %}
8367 opcode(0xC1, 0x4); /* C1 /4 ib */
8368 ins_encode(reg_opc_imm_wide(dst, shift));
8369 ins_pipe(ialu_reg);
8370 %}
8372 // Shift Left by 8-bit immediate
8373 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8374 %{
8375 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8376 effect(KILL cr);
8378 format %{ "salq $dst, $shift" %}
8379 opcode(0xC1, 0x4); /* C1 /4 ib */
8380 ins_encode(REX_mem_wide(dst), OpcP,
8381 RM_opc_mem(secondary, dst), Con8or32(shift));
8382 ins_pipe(ialu_mem_imm);
8383 %}
8385 // Shift Left by variable
8386 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8387 %{
8388 match(Set dst (LShiftL dst shift));
8389 effect(KILL cr);
8391 format %{ "salq $dst, $shift" %}
8392 opcode(0xD3, 0x4); /* D3 /4 */
8393 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8394 ins_pipe(ialu_reg_reg);
8395 %}
8397 // Shift Left by variable
8398 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8399 %{
8400 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8401 effect(KILL cr);
8403 format %{ "salq $dst, $shift" %}
8404 opcode(0xD3, 0x4); /* D3 /4 */
8405 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8406 ins_pipe(ialu_mem_reg);
8407 %}
8409 // Arithmetic shift right by one
8410 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8411 %{
8412 match(Set dst (RShiftL dst shift));
8413 effect(KILL cr);
8415 format %{ "sarq $dst, $shift" %}
8416 opcode(0xD1, 0x7); /* D1 /7 */
8417 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8418 ins_pipe(ialu_reg);
8419 %}
8421 // Arithmetic shift right by one
8422 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8423 %{
8424 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8425 effect(KILL cr);
8427 format %{ "sarq $dst, $shift" %}
8428 opcode(0xD1, 0x7); /* D1 /7 */
8429 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8430 ins_pipe(ialu_mem_imm);
8431 %}
8433 // Arithmetic Shift Right by 8-bit immediate
8434 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8435 %{
8436 match(Set dst (RShiftL dst shift));
8437 effect(KILL cr);
8439 format %{ "sarq $dst, $shift" %}
8440 opcode(0xC1, 0x7); /* C1 /7 ib */
8441 ins_encode(reg_opc_imm_wide(dst, shift));
8442 ins_pipe(ialu_mem_imm);
8443 %}
8445 // Arithmetic Shift Right by 8-bit immediate
8446 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8447 %{
8448 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8449 effect(KILL cr);
8451 format %{ "sarq $dst, $shift" %}
8452 opcode(0xC1, 0x7); /* C1 /7 ib */
8453 ins_encode(REX_mem_wide(dst), OpcP,
8454 RM_opc_mem(secondary, dst), Con8or32(shift));
8455 ins_pipe(ialu_mem_imm);
8456 %}
8458 // Arithmetic Shift Right by variable
8459 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8460 %{
8461 match(Set dst (RShiftL dst shift));
8462 effect(KILL cr);
8464 format %{ "sarq $dst, $shift" %}
8465 opcode(0xD3, 0x7); /* D3 /7 */
8466 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8467 ins_pipe(ialu_reg_reg);
8468 %}
8470 // Arithmetic Shift Right by variable
8471 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8472 %{
8473 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8474 effect(KILL cr);
8476 format %{ "sarq $dst, $shift" %}
8477 opcode(0xD3, 0x7); /* D3 /7 */
8478 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8479 ins_pipe(ialu_mem_reg);
8480 %}
8482 // Logical shift right by one
8483 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8484 %{
8485 match(Set dst (URShiftL dst shift));
8486 effect(KILL cr);
8488 format %{ "shrq $dst, $shift" %}
8489 opcode(0xD1, 0x5); /* D1 /5 */
8490 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst ));
8491 ins_pipe(ialu_reg);
8492 %}
8494 // Logical shift right by one
8495 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8496 %{
8497 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8498 effect(KILL cr);
8500 format %{ "shrq $dst, $shift" %}
8501 opcode(0xD1, 0x5); /* D1 /5 */
8502 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8503 ins_pipe(ialu_mem_imm);
8504 %}
8506 // Logical Shift Right by 8-bit immediate
8507 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8508 %{
8509 match(Set dst (URShiftL dst shift));
8510 effect(KILL cr);
8512 format %{ "shrq $dst, $shift" %}
8513 opcode(0xC1, 0x5); /* C1 /5 ib */
8514 ins_encode(reg_opc_imm_wide(dst, shift));
8515 ins_pipe(ialu_reg);
8516 %}
8519 // Logical Shift Right by 8-bit immediate
8520 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8521 %{
8522 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8523 effect(KILL cr);
8525 format %{ "shrq $dst, $shift" %}
8526 opcode(0xC1, 0x5); /* C1 /5 ib */
8527 ins_encode(REX_mem_wide(dst), OpcP,
8528 RM_opc_mem(secondary, dst), Con8or32(shift));
8529 ins_pipe(ialu_mem_imm);
8530 %}
8532 // Logical Shift Right by variable
8533 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8534 %{
8535 match(Set dst (URShiftL dst shift));
8536 effect(KILL cr);
8538 format %{ "shrq $dst, $shift" %}
8539 opcode(0xD3, 0x5); /* D3 /5 */
8540 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8541 ins_pipe(ialu_reg_reg);
8542 %}
8544 // Logical Shift Right by variable
8545 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8546 %{
8547 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8548 effect(KILL cr);
8550 format %{ "shrq $dst, $shift" %}
8551 opcode(0xD3, 0x5); /* D3 /5 */
8552 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8553 ins_pipe(ialu_mem_reg);
8554 %}
8556 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
8557 // This idiom is used by the compiler for the i2b bytecode.
8558 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour)
8559 %{
8560 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
8562 format %{ "movsbl $dst, $src\t# i2b" %}
8563 opcode(0x0F, 0xBE);
8564 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8565 ins_pipe(ialu_reg_reg);
8566 %}
8568 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
8569 // This idiom is used by the compiler the i2s bytecode.
8570 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen)
8571 %{
8572 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
8574 format %{ "movswl $dst, $src\t# i2s" %}
8575 opcode(0x0F, 0xBF);
8576 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8577 ins_pipe(ialu_reg_reg);
8578 %}
8580 // ROL/ROR instructions
8582 // ROL expand
8583 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{
8584 effect(KILL cr, USE_DEF dst);
8586 format %{ "roll $dst" %}
8587 opcode(0xD1, 0x0); /* Opcode D1 /0 */
8588 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8589 ins_pipe(ialu_reg);
8590 %}
8592 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{
8593 effect(USE_DEF dst, USE shift, KILL cr);
8595 format %{ "roll $dst, $shift" %}
8596 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
8597 ins_encode( reg_opc_imm(dst, shift) );
8598 ins_pipe(ialu_reg);
8599 %}
8601 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
8602 %{
8603 effect(USE_DEF dst, USE shift, KILL cr);
8605 format %{ "roll $dst, $shift" %}
8606 opcode(0xD3, 0x0); /* Opcode D3 /0 */
8607 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8608 ins_pipe(ialu_reg_reg);
8609 %}
8610 // end of ROL expand
8612 // Rotate Left by one
8613 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
8614 %{
8615 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8617 expand %{
8618 rolI_rReg_imm1(dst, cr);
8619 %}
8620 %}
8622 // Rotate Left by 8-bit immediate
8623 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
8624 %{
8625 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8626 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8628 expand %{
8629 rolI_rReg_imm8(dst, lshift, cr);
8630 %}
8631 %}
8633 // Rotate Left by variable
8634 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8635 %{
8636 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift))));
8638 expand %{
8639 rolI_rReg_CL(dst, shift, cr);
8640 %}
8641 %}
8643 // Rotate Left by variable
8644 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
8645 %{
8646 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift))));
8648 expand %{
8649 rolI_rReg_CL(dst, shift, cr);
8650 %}
8651 %}
8653 // ROR expand
8654 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr)
8655 %{
8656 effect(USE_DEF dst, KILL cr);
8658 format %{ "rorl $dst" %}
8659 opcode(0xD1, 0x1); /* D1 /1 */
8660 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8661 ins_pipe(ialu_reg);
8662 %}
8664 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr)
8665 %{
8666 effect(USE_DEF dst, USE shift, KILL cr);
8668 format %{ "rorl $dst, $shift" %}
8669 opcode(0xC1, 0x1); /* C1 /1 ib */
8670 ins_encode(reg_opc_imm(dst, shift));
8671 ins_pipe(ialu_reg);
8672 %}
8674 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
8675 %{
8676 effect(USE_DEF dst, USE shift, KILL cr);
8678 format %{ "rorl $dst, $shift" %}
8679 opcode(0xD3, 0x1); /* D3 /1 */
8680 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8681 ins_pipe(ialu_reg_reg);
8682 %}
8683 // end of ROR expand
8685 // Rotate Right by one
8686 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
8687 %{
8688 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8690 expand %{
8691 rorI_rReg_imm1(dst, cr);
8692 %}
8693 %}
8695 // Rotate Right by 8-bit immediate
8696 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
8697 %{
8698 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8699 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8701 expand %{
8702 rorI_rReg_imm8(dst, rshift, cr);
8703 %}
8704 %}
8706 // Rotate Right by variable
8707 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8708 %{
8709 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift))));
8711 expand %{
8712 rorI_rReg_CL(dst, shift, cr);
8713 %}
8714 %}
8716 // Rotate Right by variable
8717 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
8718 %{
8719 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift))));
8721 expand %{
8722 rorI_rReg_CL(dst, shift, cr);
8723 %}
8724 %}
8726 // for long rotate
8727 // ROL expand
8728 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{
8729 effect(USE_DEF dst, KILL cr);
8731 format %{ "rolq $dst" %}
8732 opcode(0xD1, 0x0); /* Opcode D1 /0 */
8733 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8734 ins_pipe(ialu_reg);
8735 %}
8737 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{
8738 effect(USE_DEF dst, USE shift, KILL cr);
8740 format %{ "rolq $dst, $shift" %}
8741 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
8742 ins_encode( reg_opc_imm_wide(dst, shift) );
8743 ins_pipe(ialu_reg);
8744 %}
8746 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
8747 %{
8748 effect(USE_DEF dst, USE shift, KILL cr);
8750 format %{ "rolq $dst, $shift" %}
8751 opcode(0xD3, 0x0); /* Opcode D3 /0 */
8752 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8753 ins_pipe(ialu_reg_reg);
8754 %}
8755 // end of ROL expand
8757 // Rotate Left by one
8758 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
8759 %{
8760 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
8762 expand %{
8763 rolL_rReg_imm1(dst, cr);
8764 %}
8765 %}
8767 // Rotate Left by 8-bit immediate
8768 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
8769 %{
8770 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
8771 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
8773 expand %{
8774 rolL_rReg_imm8(dst, lshift, cr);
8775 %}
8776 %}
8778 // Rotate Left by variable
8779 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8780 %{
8781 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift))));
8783 expand %{
8784 rolL_rReg_CL(dst, shift, cr);
8785 %}
8786 %}
8788 // Rotate Left by variable
8789 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
8790 %{
8791 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift))));
8793 expand %{
8794 rolL_rReg_CL(dst, shift, cr);
8795 %}
8796 %}
8798 // ROR expand
8799 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr)
8800 %{
8801 effect(USE_DEF dst, KILL cr);
8803 format %{ "rorq $dst" %}
8804 opcode(0xD1, 0x1); /* D1 /1 */
8805 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8806 ins_pipe(ialu_reg);
8807 %}
8809 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr)
8810 %{
8811 effect(USE_DEF dst, USE shift, KILL cr);
8813 format %{ "rorq $dst, $shift" %}
8814 opcode(0xC1, 0x1); /* C1 /1 ib */
8815 ins_encode(reg_opc_imm_wide(dst, shift));
8816 ins_pipe(ialu_reg);
8817 %}
8819 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
8820 %{
8821 effect(USE_DEF dst, USE shift, KILL cr);
8823 format %{ "rorq $dst, $shift" %}
8824 opcode(0xD3, 0x1); /* D3 /1 */
8825 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8826 ins_pipe(ialu_reg_reg);
8827 %}
8828 // end of ROR expand
8830 // Rotate Right by one
8831 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
8832 %{
8833 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
8835 expand %{
8836 rorL_rReg_imm1(dst, cr);
8837 %}
8838 %}
8840 // Rotate Right by 8-bit immediate
8841 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
8842 %{
8843 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
8844 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
8846 expand %{
8847 rorL_rReg_imm8(dst, rshift, cr);
8848 %}
8849 %}
8851 // Rotate Right by variable
8852 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8853 %{
8854 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift))));
8856 expand %{
8857 rorL_rReg_CL(dst, shift, cr);
8858 %}
8859 %}
8861 // Rotate Right by variable
8862 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
8863 %{
8864 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift))));
8866 expand %{
8867 rorL_rReg_CL(dst, shift, cr);
8868 %}
8869 %}
8871 // Logical Instructions
8873 // Integer Logical Instructions
8875 // And Instructions
8876 // And Register with Register
8877 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8878 %{
8879 match(Set dst (AndI dst src));
8880 effect(KILL cr);
8882 format %{ "andl $dst, $src\t# int" %}
8883 opcode(0x23);
8884 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8885 ins_pipe(ialu_reg_reg);
8886 %}
8888 // And Register with Immediate 255
8889 instruct andI_rReg_imm255(rRegI dst, immI_255 src)
8890 %{
8891 match(Set dst (AndI dst src));
8893 format %{ "movzbl $dst, $dst\t# int & 0xFF" %}
8894 opcode(0x0F, 0xB6);
8895 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
8896 ins_pipe(ialu_reg);
8897 %}
8899 // And Register with Immediate 255 and promote to long
8900 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask)
8901 %{
8902 match(Set dst (ConvI2L (AndI src mask)));
8904 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %}
8905 opcode(0x0F, 0xB6);
8906 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8907 ins_pipe(ialu_reg);
8908 %}
8910 // And Register with Immediate 65535
8911 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src)
8912 %{
8913 match(Set dst (AndI dst src));
8915 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %}
8916 opcode(0x0F, 0xB7);
8917 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
8918 ins_pipe(ialu_reg);
8919 %}
8921 // And Register with Immediate 65535 and promote to long
8922 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask)
8923 %{
8924 match(Set dst (ConvI2L (AndI src mask)));
8926 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %}
8927 opcode(0x0F, 0xB7);
8928 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8929 ins_pipe(ialu_reg);
8930 %}
8932 // And Register with Immediate
8933 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8934 %{
8935 match(Set dst (AndI dst src));
8936 effect(KILL cr);
8938 format %{ "andl $dst, $src\t# int" %}
8939 opcode(0x81, 0x04); /* Opcode 81 /4 */
8940 ins_encode(OpcSErm(dst, src), Con8or32(src));
8941 ins_pipe(ialu_reg);
8942 %}
8944 // And Register with Memory
8945 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
8946 %{
8947 match(Set dst (AndI dst (LoadI src)));
8948 effect(KILL cr);
8950 ins_cost(125);
8951 format %{ "andl $dst, $src\t# int" %}
8952 opcode(0x23);
8953 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
8954 ins_pipe(ialu_reg_mem);
8955 %}
8957 // And Memory with Register
8958 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
8959 %{
8960 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
8961 effect(KILL cr);
8963 ins_cost(150);
8964 format %{ "andl $dst, $src\t# int" %}
8965 opcode(0x21); /* Opcode 21 /r */
8966 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
8967 ins_pipe(ialu_mem_reg);
8968 %}
8970 // And Memory with Immediate
8971 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr)
8972 %{
8973 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
8974 effect(KILL cr);
8976 ins_cost(125);
8977 format %{ "andl $dst, $src\t# int" %}
8978 opcode(0x81, 0x4); /* Opcode 81 /4 id */
8979 ins_encode(REX_mem(dst), OpcSE(src),
8980 RM_opc_mem(secondary, dst), Con8or32(src));
8981 ins_pipe(ialu_mem_imm);
8982 %}
8984 // Or Instructions
8985 // Or Register with Register
8986 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
8987 %{
8988 match(Set dst (OrI dst src));
8989 effect(KILL cr);
8991 format %{ "orl $dst, $src\t# int" %}
8992 opcode(0x0B);
8993 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
8994 ins_pipe(ialu_reg_reg);
8995 %}
8997 // Or Register with Immediate
8998 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
8999 %{
9000 match(Set dst (OrI dst src));
9001 effect(KILL cr);
9003 format %{ "orl $dst, $src\t# int" %}
9004 opcode(0x81, 0x01); /* Opcode 81 /1 id */
9005 ins_encode(OpcSErm(dst, src), Con8or32(src));
9006 ins_pipe(ialu_reg);
9007 %}
9009 // Or Register with Memory
9010 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9011 %{
9012 match(Set dst (OrI dst (LoadI src)));
9013 effect(KILL cr);
9015 ins_cost(125);
9016 format %{ "orl $dst, $src\t# int" %}
9017 opcode(0x0B);
9018 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9019 ins_pipe(ialu_reg_mem);
9020 %}
9022 // Or Memory with Register
9023 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9024 %{
9025 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9026 effect(KILL cr);
9028 ins_cost(150);
9029 format %{ "orl $dst, $src\t# int" %}
9030 opcode(0x09); /* Opcode 09 /r */
9031 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9032 ins_pipe(ialu_mem_reg);
9033 %}
9035 // Or Memory with Immediate
9036 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr)
9037 %{
9038 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9039 effect(KILL cr);
9041 ins_cost(125);
9042 format %{ "orl $dst, $src\t# int" %}
9043 opcode(0x81, 0x1); /* Opcode 81 /1 id */
9044 ins_encode(REX_mem(dst), OpcSE(src),
9045 RM_opc_mem(secondary, dst), Con8or32(src));
9046 ins_pipe(ialu_mem_imm);
9047 %}
9049 // Xor Instructions
9050 // Xor Register with Register
9051 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9052 %{
9053 match(Set dst (XorI dst src));
9054 effect(KILL cr);
9056 format %{ "xorl $dst, $src\t# int" %}
9057 opcode(0x33);
9058 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9059 ins_pipe(ialu_reg_reg);
9060 %}
9062 // Xor Register with Immediate -1
9063 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
9064 match(Set dst (XorI dst imm));
9066 format %{ "not $dst" %}
9067 ins_encode %{
9068 __ notl($dst$$Register);
9069 %}
9070 ins_pipe(ialu_reg);
9071 %}
9073 // Xor Register with Immediate
9074 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9075 %{
9076 match(Set dst (XorI dst src));
9077 effect(KILL cr);
9079 format %{ "xorl $dst, $src\t# int" %}
9080 opcode(0x81, 0x06); /* Opcode 81 /6 id */
9081 ins_encode(OpcSErm(dst, src), Con8or32(src));
9082 ins_pipe(ialu_reg);
9083 %}
9085 // Xor Register with Memory
9086 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9087 %{
9088 match(Set dst (XorI dst (LoadI src)));
9089 effect(KILL cr);
9091 ins_cost(125);
9092 format %{ "xorl $dst, $src\t# int" %}
9093 opcode(0x33);
9094 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9095 ins_pipe(ialu_reg_mem);
9096 %}
9098 // Xor Memory with Register
9099 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9100 %{
9101 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9102 effect(KILL cr);
9104 ins_cost(150);
9105 format %{ "xorl $dst, $src\t# int" %}
9106 opcode(0x31); /* Opcode 31 /r */
9107 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9108 ins_pipe(ialu_mem_reg);
9109 %}
9111 // Xor Memory with Immediate
9112 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr)
9113 %{
9114 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9115 effect(KILL cr);
9117 ins_cost(125);
9118 format %{ "xorl $dst, $src\t# int" %}
9119 opcode(0x81, 0x6); /* Opcode 81 /6 id */
9120 ins_encode(REX_mem(dst), OpcSE(src),
9121 RM_opc_mem(secondary, dst), Con8or32(src));
9122 ins_pipe(ialu_mem_imm);
9123 %}
9126 // Long Logical Instructions
9128 // And Instructions
9129 // And Register with Register
9130 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9131 %{
9132 match(Set dst (AndL dst src));
9133 effect(KILL cr);
9135 format %{ "andq $dst, $src\t# long" %}
9136 opcode(0x23);
9137 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9138 ins_pipe(ialu_reg_reg);
9139 %}
9141 // And Register with Immediate 255
9142 instruct andL_rReg_imm255(rRegL dst, immL_255 src)
9143 %{
9144 match(Set dst (AndL dst src));
9146 format %{ "movzbq $dst, $dst\t# long & 0xFF" %}
9147 opcode(0x0F, 0xB6);
9148 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9149 ins_pipe(ialu_reg);
9150 %}
9152 // And Register with Immediate 65535
9153 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
9154 %{
9155 match(Set dst (AndL dst src));
9157 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %}
9158 opcode(0x0F, 0xB7);
9159 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9160 ins_pipe(ialu_reg);
9161 %}
9163 // And Register with Immediate
9164 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9165 %{
9166 match(Set dst (AndL dst src));
9167 effect(KILL cr);
9169 format %{ "andq $dst, $src\t# long" %}
9170 opcode(0x81, 0x04); /* Opcode 81 /4 */
9171 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9172 ins_pipe(ialu_reg);
9173 %}
9175 // And Register with Memory
9176 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9177 %{
9178 match(Set dst (AndL dst (LoadL src)));
9179 effect(KILL cr);
9181 ins_cost(125);
9182 format %{ "andq $dst, $src\t# long" %}
9183 opcode(0x23);
9184 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9185 ins_pipe(ialu_reg_mem);
9186 %}
9188 // And Memory with Register
9189 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9190 %{
9191 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9192 effect(KILL cr);
9194 ins_cost(150);
9195 format %{ "andq $dst, $src\t# long" %}
9196 opcode(0x21); /* Opcode 21 /r */
9197 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9198 ins_pipe(ialu_mem_reg);
9199 %}
9201 // And Memory with Immediate
9202 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9203 %{
9204 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9205 effect(KILL cr);
9207 ins_cost(125);
9208 format %{ "andq $dst, $src\t# long" %}
9209 opcode(0x81, 0x4); /* Opcode 81 /4 id */
9210 ins_encode(REX_mem_wide(dst), OpcSE(src),
9211 RM_opc_mem(secondary, dst), Con8or32(src));
9212 ins_pipe(ialu_mem_imm);
9213 %}
9215 // Or Instructions
9216 // Or Register with Register
9217 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9218 %{
9219 match(Set dst (OrL dst src));
9220 effect(KILL cr);
9222 format %{ "orq $dst, $src\t# long" %}
9223 opcode(0x0B);
9224 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9225 ins_pipe(ialu_reg_reg);
9226 %}
9228 // Use any_RegP to match R15 (TLS register) without spilling.
9229 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
9230 match(Set dst (OrL dst (CastP2X src)));
9231 effect(KILL cr);
9233 format %{ "orq $dst, $src\t# long" %}
9234 opcode(0x0B);
9235 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9236 ins_pipe(ialu_reg_reg);
9237 %}
9240 // Or Register with Immediate
9241 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9242 %{
9243 match(Set dst (OrL dst src));
9244 effect(KILL cr);
9246 format %{ "orq $dst, $src\t# long" %}
9247 opcode(0x81, 0x01); /* Opcode 81 /1 id */
9248 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9249 ins_pipe(ialu_reg);
9250 %}
9252 // Or Register with Memory
9253 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9254 %{
9255 match(Set dst (OrL dst (LoadL src)));
9256 effect(KILL cr);
9258 ins_cost(125);
9259 format %{ "orq $dst, $src\t# long" %}
9260 opcode(0x0B);
9261 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9262 ins_pipe(ialu_reg_mem);
9263 %}
9265 // Or Memory with Register
9266 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9267 %{
9268 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
9269 effect(KILL cr);
9271 ins_cost(150);
9272 format %{ "orq $dst, $src\t# long" %}
9273 opcode(0x09); /* Opcode 09 /r */
9274 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9275 ins_pipe(ialu_mem_reg);
9276 %}
9278 // Or Memory with Immediate
9279 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9280 %{
9281 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
9282 effect(KILL cr);
9284 ins_cost(125);
9285 format %{ "orq $dst, $src\t# long" %}
9286 opcode(0x81, 0x1); /* Opcode 81 /1 id */
9287 ins_encode(REX_mem_wide(dst), OpcSE(src),
9288 RM_opc_mem(secondary, dst), Con8or32(src));
9289 ins_pipe(ialu_mem_imm);
9290 %}
9292 // Xor Instructions
9293 // Xor Register with Register
9294 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9295 %{
9296 match(Set dst (XorL dst src));
9297 effect(KILL cr);
9299 format %{ "xorq $dst, $src\t# long" %}
9300 opcode(0x33);
9301 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9302 ins_pipe(ialu_reg_reg);
9303 %}
9305 // Xor Register with Immediate -1
9306 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
9307 match(Set dst (XorL dst imm));
9309 format %{ "notq $dst" %}
9310 ins_encode %{
9311 __ notq($dst$$Register);
9312 %}
9313 ins_pipe(ialu_reg);
9314 %}
9316 // Xor Register with Immediate
9317 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9318 %{
9319 match(Set dst (XorL dst src));
9320 effect(KILL cr);
9322 format %{ "xorq $dst, $src\t# long" %}
9323 opcode(0x81, 0x06); /* Opcode 81 /6 id */
9324 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9325 ins_pipe(ialu_reg);
9326 %}
9328 // Xor Register with Memory
9329 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9330 %{
9331 match(Set dst (XorL dst (LoadL src)));
9332 effect(KILL cr);
9334 ins_cost(125);
9335 format %{ "xorq $dst, $src\t# long" %}
9336 opcode(0x33);
9337 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9338 ins_pipe(ialu_reg_mem);
9339 %}
9341 // Xor Memory with Register
9342 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9343 %{
9344 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
9345 effect(KILL cr);
9347 ins_cost(150);
9348 format %{ "xorq $dst, $src\t# long" %}
9349 opcode(0x31); /* Opcode 31 /r */
9350 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9351 ins_pipe(ialu_mem_reg);
9352 %}
9354 // Xor Memory with Immediate
9355 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9356 %{
9357 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
9358 effect(KILL cr);
9360 ins_cost(125);
9361 format %{ "xorq $dst, $src\t# long" %}
9362 opcode(0x81, 0x6); /* Opcode 81 /6 id */
9363 ins_encode(REX_mem_wide(dst), OpcSE(src),
9364 RM_opc_mem(secondary, dst), Con8or32(src));
9365 ins_pipe(ialu_mem_imm);
9366 %}
9368 // Convert Int to Boolean
9369 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr)
9370 %{
9371 match(Set dst (Conv2B src));
9372 effect(KILL cr);
9374 format %{ "testl $src, $src\t# ci2b\n\t"
9375 "setnz $dst\n\t"
9376 "movzbl $dst, $dst" %}
9377 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl
9378 setNZ_reg(dst),
9379 REX_reg_breg(dst, dst), // movzbl
9380 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
9381 ins_pipe(pipe_slow); // XXX
9382 %}
9384 // Convert Pointer to Boolean
9385 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr)
9386 %{
9387 match(Set dst (Conv2B src));
9388 effect(KILL cr);
9390 format %{ "testq $src, $src\t# cp2b\n\t"
9391 "setnz $dst\n\t"
9392 "movzbl $dst, $dst" %}
9393 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq
9394 setNZ_reg(dst),
9395 REX_reg_breg(dst, dst), // movzbl
9396 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
9397 ins_pipe(pipe_slow); // XXX
9398 %}
9400 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr)
9401 %{
9402 match(Set dst (CmpLTMask p q));
9403 effect(KILL cr);
9405 ins_cost(400); // XXX
9406 format %{ "cmpl $p, $q\t# cmpLTMask\n\t"
9407 "setlt $dst\n\t"
9408 "movzbl $dst, $dst\n\t"
9409 "negl $dst" %}
9410 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl
9411 setLT_reg(dst),
9412 REX_reg_breg(dst, dst), // movzbl
9413 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst),
9414 neg_reg(dst));
9415 ins_pipe(pipe_slow);
9416 %}
9418 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr)
9419 %{
9420 match(Set dst (CmpLTMask dst zero));
9421 effect(KILL cr);
9423 ins_cost(100); // XXX
9424 format %{ "sarl $dst, #31\t# cmpLTMask0" %}
9425 opcode(0xC1, 0x7); /* C1 /7 ib */
9426 ins_encode(reg_opc_imm(dst, 0x1F));
9427 ins_pipe(ialu_reg);
9428 %}
9431 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr)
9432 %{
9433 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
9434 effect(TEMP tmp, KILL cr);
9436 ins_cost(400); // XXX
9437 format %{ "subl $p, $q\t# cadd_cmpLTMask1\n\t"
9438 "sbbl $tmp, $tmp\n\t"
9439 "andl $tmp, $y\n\t"
9440 "addl $p, $tmp" %}
9441 ins_encode %{
9442 Register Rp = $p$$Register;
9443 Register Rq = $q$$Register;
9444 Register Ry = $y$$Register;
9445 Register Rt = $tmp$$Register;
9446 __ subl(Rp, Rq);
9447 __ sbbl(Rt, Rt);
9448 __ andl(Rt, Ry);
9449 __ addl(Rp, Rt);
9450 %}
9451 ins_pipe(pipe_cmplt);
9452 %}
9454 //---------- FP Instructions------------------------------------------------
9456 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
9457 %{
9458 match(Set cr (CmpF src1 src2));
9460 ins_cost(145);
9461 format %{ "ucomiss $src1, $src2\n\t"
9462 "jnp,s exit\n\t"
9463 "pushfq\t# saw NaN, set CF\n\t"
9464 "andq [rsp], #0xffffff2b\n\t"
9465 "popfq\n"
9466 "exit:" %}
9467 ins_encode %{
9468 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9469 emit_cmpfp_fixup(_masm);
9470 %}
9471 ins_pipe(pipe_slow);
9472 %}
9474 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
9475 match(Set cr (CmpF src1 src2));
9477 ins_cost(100);
9478 format %{ "ucomiss $src1, $src2" %}
9479 ins_encode %{
9480 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9481 %}
9482 ins_pipe(pipe_slow);
9483 %}
9485 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
9486 %{
9487 match(Set cr (CmpF src1 (LoadF src2)));
9489 ins_cost(145);
9490 format %{ "ucomiss $src1, $src2\n\t"
9491 "jnp,s exit\n\t"
9492 "pushfq\t# saw NaN, set CF\n\t"
9493 "andq [rsp], #0xffffff2b\n\t"
9494 "popfq\n"
9495 "exit:" %}
9496 ins_encode %{
9497 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9498 emit_cmpfp_fixup(_masm);
9499 %}
9500 ins_pipe(pipe_slow);
9501 %}
9503 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
9504 match(Set cr (CmpF src1 (LoadF src2)));
9506 ins_cost(100);
9507 format %{ "ucomiss $src1, $src2" %}
9508 ins_encode %{
9509 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9510 %}
9511 ins_pipe(pipe_slow);
9512 %}
9514 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
9515 match(Set cr (CmpF src con));
9517 ins_cost(145);
9518 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
9519 "jnp,s exit\n\t"
9520 "pushfq\t# saw NaN, set CF\n\t"
9521 "andq [rsp], #0xffffff2b\n\t"
9522 "popfq\n"
9523 "exit:" %}
9524 ins_encode %{
9525 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9526 emit_cmpfp_fixup(_masm);
9527 %}
9528 ins_pipe(pipe_slow);
9529 %}
9531 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
9532 match(Set cr (CmpF src con));
9533 ins_cost(100);
9534 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
9535 ins_encode %{
9536 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9537 %}
9538 ins_pipe(pipe_slow);
9539 %}
9541 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
9542 %{
9543 match(Set cr (CmpD src1 src2));
9545 ins_cost(145);
9546 format %{ "ucomisd $src1, $src2\n\t"
9547 "jnp,s exit\n\t"
9548 "pushfq\t# saw NaN, set CF\n\t"
9549 "andq [rsp], #0xffffff2b\n\t"
9550 "popfq\n"
9551 "exit:" %}
9552 ins_encode %{
9553 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9554 emit_cmpfp_fixup(_masm);
9555 %}
9556 ins_pipe(pipe_slow);
9557 %}
9559 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
9560 match(Set cr (CmpD src1 src2));
9562 ins_cost(100);
9563 format %{ "ucomisd $src1, $src2 test" %}
9564 ins_encode %{
9565 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9566 %}
9567 ins_pipe(pipe_slow);
9568 %}
9570 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
9571 %{
9572 match(Set cr (CmpD src1 (LoadD src2)));
9574 ins_cost(145);
9575 format %{ "ucomisd $src1, $src2\n\t"
9576 "jnp,s exit\n\t"
9577 "pushfq\t# saw NaN, set CF\n\t"
9578 "andq [rsp], #0xffffff2b\n\t"
9579 "popfq\n"
9580 "exit:" %}
9581 ins_encode %{
9582 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9583 emit_cmpfp_fixup(_masm);
9584 %}
9585 ins_pipe(pipe_slow);
9586 %}
9588 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
9589 match(Set cr (CmpD src1 (LoadD src2)));
9591 ins_cost(100);
9592 format %{ "ucomisd $src1, $src2" %}
9593 ins_encode %{
9594 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9595 %}
9596 ins_pipe(pipe_slow);
9597 %}
9599 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
9600 match(Set cr (CmpD src con));
9602 ins_cost(145);
9603 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
9604 "jnp,s exit\n\t"
9605 "pushfq\t# saw NaN, set CF\n\t"
9606 "andq [rsp], #0xffffff2b\n\t"
9607 "popfq\n"
9608 "exit:" %}
9609 ins_encode %{
9610 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9611 emit_cmpfp_fixup(_masm);
9612 %}
9613 ins_pipe(pipe_slow);
9614 %}
9616 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
9617 match(Set cr (CmpD src con));
9618 ins_cost(100);
9619 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
9620 ins_encode %{
9621 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9622 %}
9623 ins_pipe(pipe_slow);
9624 %}
9626 // Compare into -1,0,1
9627 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
9628 %{
9629 match(Set dst (CmpF3 src1 src2));
9630 effect(KILL cr);
9632 ins_cost(275);
9633 format %{ "ucomiss $src1, $src2\n\t"
9634 "movl $dst, #-1\n\t"
9635 "jp,s done\n\t"
9636 "jb,s done\n\t"
9637 "setne $dst\n\t"
9638 "movzbl $dst, $dst\n"
9639 "done:" %}
9640 ins_encode %{
9641 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9642 emit_cmpfp3(_masm, $dst$$Register);
9643 %}
9644 ins_pipe(pipe_slow);
9645 %}
9647 // Compare into -1,0,1
9648 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
9649 %{
9650 match(Set dst (CmpF3 src1 (LoadF src2)));
9651 effect(KILL cr);
9653 ins_cost(275);
9654 format %{ "ucomiss $src1, $src2\n\t"
9655 "movl $dst, #-1\n\t"
9656 "jp,s done\n\t"
9657 "jb,s done\n\t"
9658 "setne $dst\n\t"
9659 "movzbl $dst, $dst\n"
9660 "done:" %}
9661 ins_encode %{
9662 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9663 emit_cmpfp3(_masm, $dst$$Register);
9664 %}
9665 ins_pipe(pipe_slow);
9666 %}
9668 // Compare into -1,0,1
9669 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
9670 match(Set dst (CmpF3 src con));
9671 effect(KILL cr);
9673 ins_cost(275);
9674 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
9675 "movl $dst, #-1\n\t"
9676 "jp,s done\n\t"
9677 "jb,s done\n\t"
9678 "setne $dst\n\t"
9679 "movzbl $dst, $dst\n"
9680 "done:" %}
9681 ins_encode %{
9682 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9683 emit_cmpfp3(_masm, $dst$$Register);
9684 %}
9685 ins_pipe(pipe_slow);
9686 %}
9688 // Compare into -1,0,1
9689 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
9690 %{
9691 match(Set dst (CmpD3 src1 src2));
9692 effect(KILL cr);
9694 ins_cost(275);
9695 format %{ "ucomisd $src1, $src2\n\t"
9696 "movl $dst, #-1\n\t"
9697 "jp,s done\n\t"
9698 "jb,s done\n\t"
9699 "setne $dst\n\t"
9700 "movzbl $dst, $dst\n"
9701 "done:" %}
9702 ins_encode %{
9703 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9704 emit_cmpfp3(_masm, $dst$$Register);
9705 %}
9706 ins_pipe(pipe_slow);
9707 %}
9709 // Compare into -1,0,1
9710 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
9711 %{
9712 match(Set dst (CmpD3 src1 (LoadD src2)));
9713 effect(KILL cr);
9715 ins_cost(275);
9716 format %{ "ucomisd $src1, $src2\n\t"
9717 "movl $dst, #-1\n\t"
9718 "jp,s done\n\t"
9719 "jb,s done\n\t"
9720 "setne $dst\n\t"
9721 "movzbl $dst, $dst\n"
9722 "done:" %}
9723 ins_encode %{
9724 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9725 emit_cmpfp3(_masm, $dst$$Register);
9726 %}
9727 ins_pipe(pipe_slow);
9728 %}
9730 // Compare into -1,0,1
9731 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
9732 match(Set dst (CmpD3 src con));
9733 effect(KILL cr);
9735 ins_cost(275);
9736 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
9737 "movl $dst, #-1\n\t"
9738 "jp,s done\n\t"
9739 "jb,s done\n\t"
9740 "setne $dst\n\t"
9741 "movzbl $dst, $dst\n"
9742 "done:" %}
9743 ins_encode %{
9744 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9745 emit_cmpfp3(_masm, $dst$$Register);
9746 %}
9747 ins_pipe(pipe_slow);
9748 %}
9750 // -----------Trig and Trancendental Instructions------------------------------
9751 instruct cosD_reg(regD dst) %{
9752 match(Set dst (CosD dst));
9754 format %{ "dcos $dst\n\t" %}
9755 opcode(0xD9, 0xFF);
9756 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
9757 ins_pipe( pipe_slow );
9758 %}
9760 instruct sinD_reg(regD dst) %{
9761 match(Set dst (SinD dst));
9763 format %{ "dsin $dst\n\t" %}
9764 opcode(0xD9, 0xFE);
9765 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
9766 ins_pipe( pipe_slow );
9767 %}
9769 instruct tanD_reg(regD dst) %{
9770 match(Set dst (TanD dst));
9772 format %{ "dtan $dst\n\t" %}
9773 ins_encode( Push_SrcXD(dst),
9774 Opcode(0xD9), Opcode(0xF2), //fptan
9775 Opcode(0xDD), Opcode(0xD8), //fstp st
9776 Push_ResultXD(dst) );
9777 ins_pipe( pipe_slow );
9778 %}
9780 instruct log10D_reg(regD dst) %{
9781 // The source and result Double operands in XMM registers
9782 match(Set dst (Log10D dst));
9783 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number
9784 // fyl2x ; compute log_10(2) * log_2(x)
9785 format %{ "fldlg2\t\t\t#Log10\n\t"
9786 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t"
9787 %}
9788 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2
9789 Push_SrcXD(dst),
9790 Opcode(0xD9), Opcode(0xF1), // fyl2x
9791 Push_ResultXD(dst));
9793 ins_pipe( pipe_slow );
9794 %}
9796 instruct logD_reg(regD dst) %{
9797 // The source and result Double operands in XMM registers
9798 match(Set dst (LogD dst));
9799 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number
9800 // fyl2x ; compute log_e(2) * log_2(x)
9801 format %{ "fldln2\t\t\t#Log_e\n\t"
9802 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t"
9803 %}
9804 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2
9805 Push_SrcXD(dst),
9806 Opcode(0xD9), Opcode(0xF1), // fyl2x
9807 Push_ResultXD(dst));
9808 ins_pipe( pipe_slow );
9809 %}
9811 instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{
9812 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power
9813 effect(KILL rax, KILL rdx, KILL rcx, KILL cr);
9814 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %}
9815 ins_encode %{
9816 __ subptr(rsp, 8);
9817 __ movdbl(Address(rsp, 0), $src1$$XMMRegister);
9818 __ fld_d(Address(rsp, 0));
9819 __ movdbl(Address(rsp, 0), $src0$$XMMRegister);
9820 __ fld_d(Address(rsp, 0));
9821 __ fast_pow();
9822 __ fstp_d(Address(rsp, 0));
9823 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
9824 __ addptr(rsp, 8);
9825 %}
9826 ins_pipe( pipe_slow );
9827 %}
9829 instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{
9830 match(Set dst (ExpD src));
9831 effect(KILL rax, KILL rcx, KILL rdx, KILL cr);
9832 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %}
9833 ins_encode %{
9834 __ subptr(rsp, 8);
9835 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
9836 __ fld_d(Address(rsp, 0));
9837 __ fast_exp();
9838 __ fstp_d(Address(rsp, 0));
9839 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
9840 __ addptr(rsp, 8);
9841 %}
9842 ins_pipe( pipe_slow );
9843 %}
9845 //----------Arithmetic Conversion Instructions---------------------------------
9847 instruct roundFloat_nop(regF dst)
9848 %{
9849 match(Set dst (RoundFloat dst));
9851 ins_cost(0);
9852 ins_encode();
9853 ins_pipe(empty);
9854 %}
9856 instruct roundDouble_nop(regD dst)
9857 %{
9858 match(Set dst (RoundDouble dst));
9860 ins_cost(0);
9861 ins_encode();
9862 ins_pipe(empty);
9863 %}
9865 instruct convF2D_reg_reg(regD dst, regF src)
9866 %{
9867 match(Set dst (ConvF2D src));
9869 format %{ "cvtss2sd $dst, $src" %}
9870 ins_encode %{
9871 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister);
9872 %}
9873 ins_pipe(pipe_slow); // XXX
9874 %}
9876 instruct convF2D_reg_mem(regD dst, memory src)
9877 %{
9878 match(Set dst (ConvF2D (LoadF src)));
9880 format %{ "cvtss2sd $dst, $src" %}
9881 ins_encode %{
9882 __ cvtss2sd ($dst$$XMMRegister, $src$$Address);
9883 %}
9884 ins_pipe(pipe_slow); // XXX
9885 %}
9887 instruct convD2F_reg_reg(regF dst, regD src)
9888 %{
9889 match(Set dst (ConvD2F src));
9891 format %{ "cvtsd2ss $dst, $src" %}
9892 ins_encode %{
9893 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister);
9894 %}
9895 ins_pipe(pipe_slow); // XXX
9896 %}
9898 instruct convD2F_reg_mem(regF dst, memory src)
9899 %{
9900 match(Set dst (ConvD2F (LoadD src)));
9902 format %{ "cvtsd2ss $dst, $src" %}
9903 ins_encode %{
9904 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address);
9905 %}
9906 ins_pipe(pipe_slow); // XXX
9907 %}
9909 // XXX do mem variants
9910 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
9911 %{
9912 match(Set dst (ConvF2I src));
9913 effect(KILL cr);
9915 format %{ "cvttss2sil $dst, $src\t# f2i\n\t"
9916 "cmpl $dst, #0x80000000\n\t"
9917 "jne,s done\n\t"
9918 "subq rsp, #8\n\t"
9919 "movss [rsp], $src\n\t"
9920 "call f2i_fixup\n\t"
9921 "popq $dst\n"
9922 "done: "%}
9923 ins_encode %{
9924 Label done;
9925 __ cvttss2sil($dst$$Register, $src$$XMMRegister);
9926 __ cmpl($dst$$Register, 0x80000000);
9927 __ jccb(Assembler::notEqual, done);
9928 __ subptr(rsp, 8);
9929 __ movflt(Address(rsp, 0), $src$$XMMRegister);
9930 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup())));
9931 __ pop($dst$$Register);
9932 __ bind(done);
9933 %}
9934 ins_pipe(pipe_slow);
9935 %}
9937 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
9938 %{
9939 match(Set dst (ConvF2L src));
9940 effect(KILL cr);
9942 format %{ "cvttss2siq $dst, $src\t# f2l\n\t"
9943 "cmpq $dst, [0x8000000000000000]\n\t"
9944 "jne,s done\n\t"
9945 "subq rsp, #8\n\t"
9946 "movss [rsp], $src\n\t"
9947 "call f2l_fixup\n\t"
9948 "popq $dst\n"
9949 "done: "%}
9950 ins_encode %{
9951 Label done;
9952 __ cvttss2siq($dst$$Register, $src$$XMMRegister);
9953 __ cmp64($dst$$Register,
9954 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
9955 __ jccb(Assembler::notEqual, done);
9956 __ subptr(rsp, 8);
9957 __ movflt(Address(rsp, 0), $src$$XMMRegister);
9958 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup())));
9959 __ pop($dst$$Register);
9960 __ bind(done);
9961 %}
9962 ins_pipe(pipe_slow);
9963 %}
9965 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
9966 %{
9967 match(Set dst (ConvD2I src));
9968 effect(KILL cr);
9970 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t"
9971 "cmpl $dst, #0x80000000\n\t"
9972 "jne,s done\n\t"
9973 "subq rsp, #8\n\t"
9974 "movsd [rsp], $src\n\t"
9975 "call d2i_fixup\n\t"
9976 "popq $dst\n"
9977 "done: "%}
9978 ins_encode %{
9979 Label done;
9980 __ cvttsd2sil($dst$$Register, $src$$XMMRegister);
9981 __ cmpl($dst$$Register, 0x80000000);
9982 __ jccb(Assembler::notEqual, done);
9983 __ subptr(rsp, 8);
9984 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
9985 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup())));
9986 __ pop($dst$$Register);
9987 __ bind(done);
9988 %}
9989 ins_pipe(pipe_slow);
9990 %}
9992 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
9993 %{
9994 match(Set dst (ConvD2L src));
9995 effect(KILL cr);
9997 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t"
9998 "cmpq $dst, [0x8000000000000000]\n\t"
9999 "jne,s done\n\t"
10000 "subq rsp, #8\n\t"
10001 "movsd [rsp], $src\n\t"
10002 "call d2l_fixup\n\t"
10003 "popq $dst\n"
10004 "done: "%}
10005 ins_encode %{
10006 Label done;
10007 __ cvttsd2siq($dst$$Register, $src$$XMMRegister);
10008 __ cmp64($dst$$Register,
10009 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
10010 __ jccb(Assembler::notEqual, done);
10011 __ subptr(rsp, 8);
10012 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
10013 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup())));
10014 __ pop($dst$$Register);
10015 __ bind(done);
10016 %}
10017 ins_pipe(pipe_slow);
10018 %}
10020 instruct convI2F_reg_reg(regF dst, rRegI src)
10021 %{
10022 predicate(!UseXmmI2F);
10023 match(Set dst (ConvI2F src));
10025 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10026 ins_encode %{
10027 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
10028 %}
10029 ins_pipe(pipe_slow); // XXX
10030 %}
10032 instruct convI2F_reg_mem(regF dst, memory src)
10033 %{
10034 match(Set dst (ConvI2F (LoadI src)));
10036 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10037 ins_encode %{
10038 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address);
10039 %}
10040 ins_pipe(pipe_slow); // XXX
10041 %}
10043 instruct convI2D_reg_reg(regD dst, rRegI src)
10044 %{
10045 predicate(!UseXmmI2D);
10046 match(Set dst (ConvI2D src));
10048 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10049 ins_encode %{
10050 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
10051 %}
10052 ins_pipe(pipe_slow); // XXX
10053 %}
10055 instruct convI2D_reg_mem(regD dst, memory src)
10056 %{
10057 match(Set dst (ConvI2D (LoadI src)));
10059 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10060 ins_encode %{
10061 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address);
10062 %}
10063 ins_pipe(pipe_slow); // XXX
10064 %}
10066 instruct convXI2F_reg(regF dst, rRegI src)
10067 %{
10068 predicate(UseXmmI2F);
10069 match(Set dst (ConvI2F src));
10071 format %{ "movdl $dst, $src\n\t"
10072 "cvtdq2psl $dst, $dst\t# i2f" %}
10073 ins_encode %{
10074 __ movdl($dst$$XMMRegister, $src$$Register);
10075 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
10076 %}
10077 ins_pipe(pipe_slow); // XXX
10078 %}
10080 instruct convXI2D_reg(regD dst, rRegI src)
10081 %{
10082 predicate(UseXmmI2D);
10083 match(Set dst (ConvI2D src));
10085 format %{ "movdl $dst, $src\n\t"
10086 "cvtdq2pdl $dst, $dst\t# i2d" %}
10087 ins_encode %{
10088 __ movdl($dst$$XMMRegister, $src$$Register);
10089 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
10090 %}
10091 ins_pipe(pipe_slow); // XXX
10092 %}
10094 instruct convL2F_reg_reg(regF dst, rRegL src)
10095 %{
10096 match(Set dst (ConvL2F src));
10098 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10099 ins_encode %{
10100 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register);
10101 %}
10102 ins_pipe(pipe_slow); // XXX
10103 %}
10105 instruct convL2F_reg_mem(regF dst, memory src)
10106 %{
10107 match(Set dst (ConvL2F (LoadL src)));
10109 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10110 ins_encode %{
10111 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address);
10112 %}
10113 ins_pipe(pipe_slow); // XXX
10114 %}
10116 instruct convL2D_reg_reg(regD dst, rRegL src)
10117 %{
10118 match(Set dst (ConvL2D src));
10120 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10121 ins_encode %{
10122 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register);
10123 %}
10124 ins_pipe(pipe_slow); // XXX
10125 %}
10127 instruct convL2D_reg_mem(regD dst, memory src)
10128 %{
10129 match(Set dst (ConvL2D (LoadL src)));
10131 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10132 ins_encode %{
10133 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address);
10134 %}
10135 ins_pipe(pipe_slow); // XXX
10136 %}
10138 instruct convI2L_reg_reg(rRegL dst, rRegI src)
10139 %{
10140 match(Set dst (ConvI2L src));
10142 ins_cost(125);
10143 format %{ "movslq $dst, $src\t# i2l" %}
10144 ins_encode %{
10145 __ movslq($dst$$Register, $src$$Register);
10146 %}
10147 ins_pipe(ialu_reg_reg);
10148 %}
10150 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src)
10151 // %{
10152 // match(Set dst (ConvI2L src));
10153 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 &&
10154 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0);
10155 // predicate(((const TypeNode*) n)->type()->is_long()->_hi ==
10156 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi &&
10157 // ((const TypeNode*) n)->type()->is_long()->_lo ==
10158 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo);
10160 // format %{ "movl $dst, $src\t# unsigned i2l" %}
10161 // ins_encode(enc_copy(dst, src));
10162 // // opcode(0x63); // needs REX.W
10163 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
10164 // ins_pipe(ialu_reg_reg);
10165 // %}
10167 // Zero-extend convert int to long
10168 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
10169 %{
10170 match(Set dst (AndL (ConvI2L src) mask));
10172 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10173 ins_encode %{
10174 if ($dst$$reg != $src$$reg) {
10175 __ movl($dst$$Register, $src$$Register);
10176 }
10177 %}
10178 ins_pipe(ialu_reg_reg);
10179 %}
10181 // Zero-extend convert int to long
10182 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
10183 %{
10184 match(Set dst (AndL (ConvI2L (LoadI src)) mask));
10186 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10187 ins_encode %{
10188 __ movl($dst$$Register, $src$$Address);
10189 %}
10190 ins_pipe(ialu_reg_mem);
10191 %}
10193 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
10194 %{
10195 match(Set dst (AndL src mask));
10197 format %{ "movl $dst, $src\t# zero-extend long" %}
10198 ins_encode %{
10199 __ movl($dst$$Register, $src$$Register);
10200 %}
10201 ins_pipe(ialu_reg_reg);
10202 %}
10204 instruct convL2I_reg_reg(rRegI dst, rRegL src)
10205 %{
10206 match(Set dst (ConvL2I src));
10208 format %{ "movl $dst, $src\t# l2i" %}
10209 ins_encode %{
10210 __ movl($dst$$Register, $src$$Register);
10211 %}
10212 ins_pipe(ialu_reg_reg);
10213 %}
10216 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
10217 match(Set dst (MoveF2I src));
10218 effect(DEF dst, USE src);
10220 ins_cost(125);
10221 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %}
10222 ins_encode %{
10223 __ movl($dst$$Register, Address(rsp, $src$$disp));
10224 %}
10225 ins_pipe(ialu_reg_mem);
10226 %}
10228 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
10229 match(Set dst (MoveI2F src));
10230 effect(DEF dst, USE src);
10232 ins_cost(125);
10233 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %}
10234 ins_encode %{
10235 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
10236 %}
10237 ins_pipe(pipe_slow);
10238 %}
10240 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
10241 match(Set dst (MoveD2L src));
10242 effect(DEF dst, USE src);
10244 ins_cost(125);
10245 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %}
10246 ins_encode %{
10247 __ movq($dst$$Register, Address(rsp, $src$$disp));
10248 %}
10249 ins_pipe(ialu_reg_mem);
10250 %}
10252 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
10253 predicate(!UseXmmLoadAndClearUpper);
10254 match(Set dst (MoveL2D src));
10255 effect(DEF dst, USE src);
10257 ins_cost(125);
10258 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %}
10259 ins_encode %{
10260 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10261 %}
10262 ins_pipe(pipe_slow);
10263 %}
10265 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
10266 predicate(UseXmmLoadAndClearUpper);
10267 match(Set dst (MoveL2D src));
10268 effect(DEF dst, USE src);
10270 ins_cost(125);
10271 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %}
10272 ins_encode %{
10273 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10274 %}
10275 ins_pipe(pipe_slow);
10276 %}
10279 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
10280 match(Set dst (MoveF2I src));
10281 effect(DEF dst, USE src);
10283 ins_cost(95); // XXX
10284 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %}
10285 ins_encode %{
10286 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
10287 %}
10288 ins_pipe(pipe_slow);
10289 %}
10291 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
10292 match(Set dst (MoveI2F src));
10293 effect(DEF dst, USE src);
10295 ins_cost(100);
10296 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %}
10297 ins_encode %{
10298 __ movl(Address(rsp, $dst$$disp), $src$$Register);
10299 %}
10300 ins_pipe( ialu_mem_reg );
10301 %}
10303 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
10304 match(Set dst (MoveD2L src));
10305 effect(DEF dst, USE src);
10307 ins_cost(95); // XXX
10308 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %}
10309 ins_encode %{
10310 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
10311 %}
10312 ins_pipe(pipe_slow);
10313 %}
10315 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
10316 match(Set dst (MoveL2D src));
10317 effect(DEF dst, USE src);
10319 ins_cost(100);
10320 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %}
10321 ins_encode %{
10322 __ movq(Address(rsp, $dst$$disp), $src$$Register);
10323 %}
10324 ins_pipe(ialu_mem_reg);
10325 %}
10327 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
10328 match(Set dst (MoveF2I src));
10329 effect(DEF dst, USE src);
10330 ins_cost(85);
10331 format %{ "movd $dst,$src\t# MoveF2I" %}
10332 ins_encode %{
10333 __ movdl($dst$$Register, $src$$XMMRegister);
10334 %}
10335 ins_pipe( pipe_slow );
10336 %}
10338 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
10339 match(Set dst (MoveD2L src));
10340 effect(DEF dst, USE src);
10341 ins_cost(85);
10342 format %{ "movd $dst,$src\t# MoveD2L" %}
10343 ins_encode %{
10344 __ movdq($dst$$Register, $src$$XMMRegister);
10345 %}
10346 ins_pipe( pipe_slow );
10347 %}
10349 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
10350 match(Set dst (MoveI2F src));
10351 effect(DEF dst, USE src);
10352 ins_cost(100);
10353 format %{ "movd $dst,$src\t# MoveI2F" %}
10354 ins_encode %{
10355 __ movdl($dst$$XMMRegister, $src$$Register);
10356 %}
10357 ins_pipe( pipe_slow );
10358 %}
10360 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
10361 match(Set dst (MoveL2D src));
10362 effect(DEF dst, USE src);
10363 ins_cost(100);
10364 format %{ "movd $dst,$src\t# MoveL2D" %}
10365 ins_encode %{
10366 __ movdq($dst$$XMMRegister, $src$$Register);
10367 %}
10368 ins_pipe( pipe_slow );
10369 %}
10372 // =======================================================================
10373 // fast clearing of an array
10374 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10375 rFlagsReg cr)
10376 %{
10377 predicate(!UseFastStosb);
10378 match(Set dummy (ClearArray cnt base));
10379 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10381 format %{ "xorq rax, rax\t# ClearArray:\n\t"
10382 "rep stosq\t# Store rax to *rdi++ while rcx--" %}
10383 ins_encode %{
10384 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
10385 %}
10386 ins_pipe(pipe_slow);
10387 %}
10389 instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10390 rFlagsReg cr)
10391 %{
10392 predicate(UseFastStosb);
10393 match(Set dummy (ClearArray cnt base));
10394 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10395 format %{ "xorq rax, rax\t# ClearArray:\n\t"
10396 "shlq rcx,3\t# Convert doublewords to bytes\n\t"
10397 "rep stosb\t# Store rax to *rdi++ while rcx--" %}
10398 ins_encode %{
10399 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
10400 %}
10401 ins_pipe( pipe_slow );
10402 %}
10404 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
10405 rax_RegI result, regD tmp1, rFlagsReg cr)
10406 %{
10407 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
10408 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
10410 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
10411 ins_encode %{
10412 __ string_compare($str1$$Register, $str2$$Register,
10413 $cnt1$$Register, $cnt2$$Register, $result$$Register,
10414 $tmp1$$XMMRegister);
10415 %}
10416 ins_pipe( pipe_slow );
10417 %}
10419 // fast search of substring with known size.
10420 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
10421 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
10422 %{
10423 predicate(UseSSE42Intrinsics);
10424 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
10425 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
10427 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
10428 ins_encode %{
10429 int icnt2 = (int)$int_cnt2$$constant;
10430 if (icnt2 >= 8) {
10431 // IndexOf for constant substrings with size >= 8 elements
10432 // which don't need to be loaded through stack.
10433 __ string_indexofC8($str1$$Register, $str2$$Register,
10434 $cnt1$$Register, $cnt2$$Register,
10435 icnt2, $result$$Register,
10436 $vec$$XMMRegister, $tmp$$Register);
10437 } else {
10438 // Small strings are loaded through stack if they cross page boundary.
10439 __ string_indexof($str1$$Register, $str2$$Register,
10440 $cnt1$$Register, $cnt2$$Register,
10441 icnt2, $result$$Register,
10442 $vec$$XMMRegister, $tmp$$Register);
10443 }
10444 %}
10445 ins_pipe( pipe_slow );
10446 %}
10448 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
10449 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
10450 %{
10451 predicate(UseSSE42Intrinsics);
10452 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
10453 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
10455 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
10456 ins_encode %{
10457 __ string_indexof($str1$$Register, $str2$$Register,
10458 $cnt1$$Register, $cnt2$$Register,
10459 (-1), $result$$Register,
10460 $vec$$XMMRegister, $tmp$$Register);
10461 %}
10462 ins_pipe( pipe_slow );
10463 %}
10465 // fast string equals
10466 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
10467 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
10468 %{
10469 match(Set result (StrEquals (Binary str1 str2) cnt));
10470 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
10472 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
10473 ins_encode %{
10474 __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
10475 $cnt$$Register, $result$$Register, $tmp3$$Register,
10476 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
10477 %}
10478 ins_pipe( pipe_slow );
10479 %}
10481 // fast array equals
10482 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
10483 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
10484 %{
10485 match(Set result (AryEq ary1 ary2));
10486 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
10487 //ins_cost(300);
10489 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
10490 ins_encode %{
10491 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
10492 $tmp3$$Register, $result$$Register, $tmp4$$Register,
10493 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
10494 %}
10495 ins_pipe( pipe_slow );
10496 %}
10498 //----------Control Flow Instructions------------------------------------------
10499 // Signed compare Instructions
10501 // XXX more variants!!
10502 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
10503 %{
10504 match(Set cr (CmpI op1 op2));
10505 effect(DEF cr, USE op1, USE op2);
10507 format %{ "cmpl $op1, $op2" %}
10508 opcode(0x3B); /* Opcode 3B /r */
10509 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
10510 ins_pipe(ialu_cr_reg_reg);
10511 %}
10513 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
10514 %{
10515 match(Set cr (CmpI op1 op2));
10517 format %{ "cmpl $op1, $op2" %}
10518 opcode(0x81, 0x07); /* Opcode 81 /7 */
10519 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
10520 ins_pipe(ialu_cr_reg_imm);
10521 %}
10523 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2)
10524 %{
10525 match(Set cr (CmpI op1 (LoadI op2)));
10527 ins_cost(500); // XXX
10528 format %{ "cmpl $op1, $op2" %}
10529 opcode(0x3B); /* Opcode 3B /r */
10530 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
10531 ins_pipe(ialu_cr_reg_mem);
10532 %}
10534 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero)
10535 %{
10536 match(Set cr (CmpI src zero));
10538 format %{ "testl $src, $src" %}
10539 opcode(0x85);
10540 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
10541 ins_pipe(ialu_cr_reg_imm);
10542 %}
10544 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero)
10545 %{
10546 match(Set cr (CmpI (AndI src con) zero));
10548 format %{ "testl $src, $con" %}
10549 opcode(0xF7, 0x00);
10550 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con));
10551 ins_pipe(ialu_cr_reg_imm);
10552 %}
10554 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero)
10555 %{
10556 match(Set cr (CmpI (AndI src (LoadI mem)) zero));
10558 format %{ "testl $src, $mem" %}
10559 opcode(0x85);
10560 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
10561 ins_pipe(ialu_cr_reg_mem);
10562 %}
10564 // Unsigned compare Instructions; really, same as signed except they
10565 // produce an rFlagsRegU instead of rFlagsReg.
10566 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2)
10567 %{
10568 match(Set cr (CmpU op1 op2));
10570 format %{ "cmpl $op1, $op2\t# unsigned" %}
10571 opcode(0x3B); /* Opcode 3B /r */
10572 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
10573 ins_pipe(ialu_cr_reg_reg);
10574 %}
10576 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2)
10577 %{
10578 match(Set cr (CmpU op1 op2));
10580 format %{ "cmpl $op1, $op2\t# unsigned" %}
10581 opcode(0x81,0x07); /* Opcode 81 /7 */
10582 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
10583 ins_pipe(ialu_cr_reg_imm);
10584 %}
10586 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2)
10587 %{
10588 match(Set cr (CmpU op1 (LoadI op2)));
10590 ins_cost(500); // XXX
10591 format %{ "cmpl $op1, $op2\t# unsigned" %}
10592 opcode(0x3B); /* Opcode 3B /r */
10593 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
10594 ins_pipe(ialu_cr_reg_mem);
10595 %}
10597 // // // Cisc-spilled version of cmpU_rReg
10598 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2)
10599 // //%{
10600 // // match(Set cr (CmpU (LoadI op1) op2));
10601 // //
10602 // // format %{ "CMPu $op1,$op2" %}
10603 // // ins_cost(500);
10604 // // opcode(0x39); /* Opcode 39 /r */
10605 // // ins_encode( OpcP, reg_mem( op1, op2) );
10606 // //%}
10608 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero)
10609 %{
10610 match(Set cr (CmpU src zero));
10612 format %{ "testl $src, $src\t# unsigned" %}
10613 opcode(0x85);
10614 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
10615 ins_pipe(ialu_cr_reg_imm);
10616 %}
10618 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2)
10619 %{
10620 match(Set cr (CmpP op1 op2));
10622 format %{ "cmpq $op1, $op2\t# ptr" %}
10623 opcode(0x3B); /* Opcode 3B /r */
10624 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
10625 ins_pipe(ialu_cr_reg_reg);
10626 %}
10628 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
10629 %{
10630 match(Set cr (CmpP op1 (LoadP op2)));
10632 ins_cost(500); // XXX
10633 format %{ "cmpq $op1, $op2\t# ptr" %}
10634 opcode(0x3B); /* Opcode 3B /r */
10635 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10636 ins_pipe(ialu_cr_reg_mem);
10637 %}
10639 // // // Cisc-spilled version of cmpP_rReg
10640 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2)
10641 // //%{
10642 // // match(Set cr (CmpP (LoadP op1) op2));
10643 // //
10644 // // format %{ "CMPu $op1,$op2" %}
10645 // // ins_cost(500);
10646 // // opcode(0x39); /* Opcode 39 /r */
10647 // // ins_encode( OpcP, reg_mem( op1, op2) );
10648 // //%}
10650 // XXX this is generalized by compP_rReg_mem???
10651 // Compare raw pointer (used in out-of-heap check).
10652 // Only works because non-oop pointers must be raw pointers
10653 // and raw pointers have no anti-dependencies.
10654 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
10655 %{
10656 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none);
10657 match(Set cr (CmpP op1 (LoadP op2)));
10659 format %{ "cmpq $op1, $op2\t# raw ptr" %}
10660 opcode(0x3B); /* Opcode 3B /r */
10661 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10662 ins_pipe(ialu_cr_reg_mem);
10663 %}
10665 // This will generate a signed flags result. This should be OK since
10666 // any compare to a zero should be eq/neq.
10667 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero)
10668 %{
10669 match(Set cr (CmpP src zero));
10671 format %{ "testq $src, $src\t# ptr" %}
10672 opcode(0x85);
10673 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
10674 ins_pipe(ialu_cr_reg_imm);
10675 %}
10677 // This will generate a signed flags result. This should be OK since
10678 // any compare to a zero should be eq/neq.
10679 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
10680 %{
10681 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
10682 match(Set cr (CmpP (LoadP op) zero));
10684 ins_cost(500); // XXX
10685 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %}
10686 opcode(0xF7); /* Opcode F7 /0 */
10687 ins_encode(REX_mem_wide(op),
10688 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
10689 ins_pipe(ialu_cr_reg_imm);
10690 %}
10692 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
10693 %{
10694 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
10695 match(Set cr (CmpP (LoadP mem) zero));
10697 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
10698 ins_encode %{
10699 __ cmpq(r12, $mem$$Address);
10700 %}
10701 ins_pipe(ialu_cr_reg_mem);
10702 %}
10704 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
10705 %{
10706 match(Set cr (CmpN op1 op2));
10708 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
10709 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %}
10710 ins_pipe(ialu_cr_reg_reg);
10711 %}
10713 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
10714 %{
10715 match(Set cr (CmpN src (LoadN mem)));
10717 format %{ "cmpl $src, $mem\t# compressed ptr" %}
10718 ins_encode %{
10719 __ cmpl($src$$Register, $mem$$Address);
10720 %}
10721 ins_pipe(ialu_cr_reg_mem);
10722 %}
10724 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{
10725 match(Set cr (CmpN op1 op2));
10727 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
10728 ins_encode %{
10729 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant);
10730 %}
10731 ins_pipe(ialu_cr_reg_imm);
10732 %}
10734 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src)
10735 %{
10736 match(Set cr (CmpN src (LoadN mem)));
10738 format %{ "cmpl $mem, $src\t# compressed ptr" %}
10739 ins_encode %{
10740 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
10741 %}
10742 ins_pipe(ialu_cr_reg_mem);
10743 %}
10745 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{
10746 match(Set cr (CmpN op1 op2));
10748 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %}
10749 ins_encode %{
10750 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant);
10751 %}
10752 ins_pipe(ialu_cr_reg_imm);
10753 %}
10755 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src)
10756 %{
10757 match(Set cr (CmpN src (LoadNKlass mem)));
10759 format %{ "cmpl $mem, $src\t# compressed klass ptr" %}
10760 ins_encode %{
10761 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant);
10762 %}
10763 ins_pipe(ialu_cr_reg_mem);
10764 %}
10766 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
10767 match(Set cr (CmpN src zero));
10769 format %{ "testl $src, $src\t# compressed ptr" %}
10770 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
10771 ins_pipe(ialu_cr_reg_imm);
10772 %}
10774 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
10775 %{
10776 predicate(Universe::narrow_oop_base() != NULL);
10777 match(Set cr (CmpN (LoadN mem) zero));
10779 ins_cost(500); // XXX
10780 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
10781 ins_encode %{
10782 __ cmpl($mem$$Address, (int)0xFFFFFFFF);
10783 %}
10784 ins_pipe(ialu_cr_reg_mem);
10785 %}
10787 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
10788 %{
10789 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL));
10790 match(Set cr (CmpN (LoadN mem) zero));
10792 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
10793 ins_encode %{
10794 __ cmpl(r12, $mem$$Address);
10795 %}
10796 ins_pipe(ialu_cr_reg_mem);
10797 %}
10799 // Yanked all unsigned pointer compare operations.
10800 // Pointer compares are done with CmpP which is already unsigned.
10802 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
10803 %{
10804 match(Set cr (CmpL op1 op2));
10806 format %{ "cmpq $op1, $op2" %}
10807 opcode(0x3B); /* Opcode 3B /r */
10808 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
10809 ins_pipe(ialu_cr_reg_reg);
10810 %}
10812 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
10813 %{
10814 match(Set cr (CmpL op1 op2));
10816 format %{ "cmpq $op1, $op2" %}
10817 opcode(0x81, 0x07); /* Opcode 81 /7 */
10818 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2));
10819 ins_pipe(ialu_cr_reg_imm);
10820 %}
10822 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2)
10823 %{
10824 match(Set cr (CmpL op1 (LoadL op2)));
10826 format %{ "cmpq $op1, $op2" %}
10827 opcode(0x3B); /* Opcode 3B /r */
10828 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10829 ins_pipe(ialu_cr_reg_mem);
10830 %}
10832 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero)
10833 %{
10834 match(Set cr (CmpL src zero));
10836 format %{ "testq $src, $src" %}
10837 opcode(0x85);
10838 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
10839 ins_pipe(ialu_cr_reg_imm);
10840 %}
10842 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero)
10843 %{
10844 match(Set cr (CmpL (AndL src con) zero));
10846 format %{ "testq $src, $con\t# long" %}
10847 opcode(0xF7, 0x00);
10848 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con));
10849 ins_pipe(ialu_cr_reg_imm);
10850 %}
10852 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero)
10853 %{
10854 match(Set cr (CmpL (AndL src (LoadL mem)) zero));
10856 format %{ "testq $src, $mem" %}
10857 opcode(0x85);
10858 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
10859 ins_pipe(ialu_cr_reg_mem);
10860 %}
10862 // Manifest a CmpL result in an integer register. Very painful.
10863 // This is the test to avoid.
10864 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
10865 %{
10866 match(Set dst (CmpL3 src1 src2));
10867 effect(KILL flags);
10869 ins_cost(275); // XXX
10870 format %{ "cmpq $src1, $src2\t# CmpL3\n\t"
10871 "movl $dst, -1\n\t"
10872 "jl,s done\n\t"
10873 "setne $dst\n\t"
10874 "movzbl $dst, $dst\n\t"
10875 "done:" %}
10876 ins_encode(cmpl3_flag(src1, src2, dst));
10877 ins_pipe(pipe_slow);
10878 %}
10880 //----------Max and Min--------------------------------------------------------
10881 // Min Instructions
10883 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr)
10884 %{
10885 effect(USE_DEF dst, USE src, USE cr);
10887 format %{ "cmovlgt $dst, $src\t# min" %}
10888 opcode(0x0F, 0x4F);
10889 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
10890 ins_pipe(pipe_cmov_reg);
10891 %}
10894 instruct minI_rReg(rRegI dst, rRegI src)
10895 %{
10896 match(Set dst (MinI dst src));
10898 ins_cost(200);
10899 expand %{
10900 rFlagsReg cr;
10901 compI_rReg(cr, dst, src);
10902 cmovI_reg_g(dst, src, cr);
10903 %}
10904 %}
10906 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr)
10907 %{
10908 effect(USE_DEF dst, USE src, USE cr);
10910 format %{ "cmovllt $dst, $src\t# max" %}
10911 opcode(0x0F, 0x4C);
10912 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
10913 ins_pipe(pipe_cmov_reg);
10914 %}
10917 instruct maxI_rReg(rRegI dst, rRegI src)
10918 %{
10919 match(Set dst (MaxI dst src));
10921 ins_cost(200);
10922 expand %{
10923 rFlagsReg cr;
10924 compI_rReg(cr, dst, src);
10925 cmovI_reg_l(dst, src, cr);
10926 %}
10927 %}
10929 // ============================================================================
10930 // Branch Instructions
10932 // Jump Direct - Label defines a relative address from JMP+1
10933 instruct jmpDir(label labl)
10934 %{
10935 match(Goto);
10936 effect(USE labl);
10938 ins_cost(300);
10939 format %{ "jmp $labl" %}
10940 size(5);
10941 ins_encode %{
10942 Label* L = $labl$$label;
10943 __ jmp(*L, false); // Always long jump
10944 %}
10945 ins_pipe(pipe_jmp);
10946 %}
10948 // Jump Direct Conditional - Label defines a relative address from Jcc+1
10949 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl)
10950 %{
10951 match(If cop cr);
10952 effect(USE labl);
10954 ins_cost(300);
10955 format %{ "j$cop $labl" %}
10956 size(6);
10957 ins_encode %{
10958 Label* L = $labl$$label;
10959 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
10960 %}
10961 ins_pipe(pipe_jcc);
10962 %}
10964 // Jump Direct Conditional - Label defines a relative address from Jcc+1
10965 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
10966 %{
10967 match(CountedLoopEnd cop cr);
10968 effect(USE labl);
10970 ins_cost(300);
10971 format %{ "j$cop $labl\t# loop end" %}
10972 size(6);
10973 ins_encode %{
10974 Label* L = $labl$$label;
10975 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
10976 %}
10977 ins_pipe(pipe_jcc);
10978 %}
10980 // Jump Direct Conditional - Label defines a relative address from Jcc+1
10981 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
10982 match(CountedLoopEnd cop cmp);
10983 effect(USE labl);
10985 ins_cost(300);
10986 format %{ "j$cop,u $labl\t# loop end" %}
10987 size(6);
10988 ins_encode %{
10989 Label* L = $labl$$label;
10990 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
10991 %}
10992 ins_pipe(pipe_jcc);
10993 %}
10995 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
10996 match(CountedLoopEnd cop cmp);
10997 effect(USE labl);
10999 ins_cost(200);
11000 format %{ "j$cop,u $labl\t# loop end" %}
11001 size(6);
11002 ins_encode %{
11003 Label* L = $labl$$label;
11004 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11005 %}
11006 ins_pipe(pipe_jcc);
11007 %}
11009 // Jump Direct Conditional - using unsigned comparison
11010 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11011 match(If cop cmp);
11012 effect(USE labl);
11014 ins_cost(300);
11015 format %{ "j$cop,u $labl" %}
11016 size(6);
11017 ins_encode %{
11018 Label* L = $labl$$label;
11019 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11020 %}
11021 ins_pipe(pipe_jcc);
11022 %}
11024 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11025 match(If cop cmp);
11026 effect(USE labl);
11028 ins_cost(200);
11029 format %{ "j$cop,u $labl" %}
11030 size(6);
11031 ins_encode %{
11032 Label* L = $labl$$label;
11033 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11034 %}
11035 ins_pipe(pipe_jcc);
11036 %}
11038 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
11039 match(If cop cmp);
11040 effect(USE labl);
11042 ins_cost(200);
11043 format %{ $$template
11044 if ($cop$$cmpcode == Assembler::notEqual) {
11045 $$emit$$"jp,u $labl\n\t"
11046 $$emit$$"j$cop,u $labl"
11047 } else {
11048 $$emit$$"jp,u done\n\t"
11049 $$emit$$"j$cop,u $labl\n\t"
11050 $$emit$$"done:"
11051 }
11052 %}
11053 ins_encode %{
11054 Label* l = $labl$$label;
11055 if ($cop$$cmpcode == Assembler::notEqual) {
11056 __ jcc(Assembler::parity, *l, false);
11057 __ jcc(Assembler::notEqual, *l, false);
11058 } else if ($cop$$cmpcode == Assembler::equal) {
11059 Label done;
11060 __ jccb(Assembler::parity, done);
11061 __ jcc(Assembler::equal, *l, false);
11062 __ bind(done);
11063 } else {
11064 ShouldNotReachHere();
11065 }
11066 %}
11067 ins_pipe(pipe_jcc);
11068 %}
11070 // ============================================================================
11071 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
11072 // superklass array for an instance of the superklass. Set a hidden
11073 // internal cache on a hit (cache is checked with exposed code in
11074 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The
11075 // encoding ALSO sets flags.
11077 instruct partialSubtypeCheck(rdi_RegP result,
11078 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
11079 rFlagsReg cr)
11080 %{
11081 match(Set result (PartialSubtypeCheck sub super));
11082 effect(KILL rcx, KILL cr);
11084 ins_cost(1100); // slightly larger than the next version
11085 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
11086 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t"
11087 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t"
11088 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t"
11089 "jne,s miss\t\t# Missed: rdi not-zero\n\t"
11090 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
11091 "xorq $result, $result\t\t Hit: rdi zero\n\t"
11092 "miss:\t" %}
11094 opcode(0x1); // Force a XOR of RDI
11095 ins_encode(enc_PartialSubtypeCheck());
11096 ins_pipe(pipe_slow);
11097 %}
11099 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr,
11100 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
11101 immP0 zero,
11102 rdi_RegP result)
11103 %{
11104 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
11105 effect(KILL rcx, KILL result);
11107 ins_cost(1000);
11108 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
11109 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t"
11110 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t"
11111 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t"
11112 "jne,s miss\t\t# Missed: flags nz\n\t"
11113 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
11114 "miss:\t" %}
11116 opcode(0x0); // No need to XOR RDI
11117 ins_encode(enc_PartialSubtypeCheck());
11118 ins_pipe(pipe_slow);
11119 %}
11121 // ============================================================================
11122 // Branch Instructions -- short offset versions
11123 //
11124 // These instructions are used to replace jumps of a long offset (the default
11125 // match) with jumps of a shorter offset. These instructions are all tagged
11126 // with the ins_short_branch attribute, which causes the ADLC to suppress the
11127 // match rules in general matching. Instead, the ADLC generates a conversion
11128 // method in the MachNode which can be used to do in-place replacement of the
11129 // long variant with the shorter variant. The compiler will determine if a
11130 // branch can be taken by the is_short_branch_offset() predicate in the machine
11131 // specific code section of the file.
11133 // Jump Direct - Label defines a relative address from JMP+1
11134 instruct jmpDir_short(label labl) %{
11135 match(Goto);
11136 effect(USE labl);
11138 ins_cost(300);
11139 format %{ "jmp,s $labl" %}
11140 size(2);
11141 ins_encode %{
11142 Label* L = $labl$$label;
11143 __ jmpb(*L);
11144 %}
11145 ins_pipe(pipe_jmp);
11146 ins_short_branch(1);
11147 %}
11149 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11150 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
11151 match(If cop cr);
11152 effect(USE labl);
11154 ins_cost(300);
11155 format %{ "j$cop,s $labl" %}
11156 size(2);
11157 ins_encode %{
11158 Label* L = $labl$$label;
11159 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11160 %}
11161 ins_pipe(pipe_jcc);
11162 ins_short_branch(1);
11163 %}
11165 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11166 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
11167 match(CountedLoopEnd cop cr);
11168 effect(USE labl);
11170 ins_cost(300);
11171 format %{ "j$cop,s $labl\t# loop end" %}
11172 size(2);
11173 ins_encode %{
11174 Label* L = $labl$$label;
11175 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11176 %}
11177 ins_pipe(pipe_jcc);
11178 ins_short_branch(1);
11179 %}
11181 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11182 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11183 match(CountedLoopEnd cop cmp);
11184 effect(USE labl);
11186 ins_cost(300);
11187 format %{ "j$cop,us $labl\t# loop end" %}
11188 size(2);
11189 ins_encode %{
11190 Label* L = $labl$$label;
11191 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11192 %}
11193 ins_pipe(pipe_jcc);
11194 ins_short_branch(1);
11195 %}
11197 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11198 match(CountedLoopEnd cop cmp);
11199 effect(USE labl);
11201 ins_cost(300);
11202 format %{ "j$cop,us $labl\t# loop end" %}
11203 size(2);
11204 ins_encode %{
11205 Label* L = $labl$$label;
11206 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11207 %}
11208 ins_pipe(pipe_jcc);
11209 ins_short_branch(1);
11210 %}
11212 // Jump Direct Conditional - using unsigned comparison
11213 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11214 match(If cop cmp);
11215 effect(USE labl);
11217 ins_cost(300);
11218 format %{ "j$cop,us $labl" %}
11219 size(2);
11220 ins_encode %{
11221 Label* L = $labl$$label;
11222 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11223 %}
11224 ins_pipe(pipe_jcc);
11225 ins_short_branch(1);
11226 %}
11228 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11229 match(If cop cmp);
11230 effect(USE labl);
11232 ins_cost(300);
11233 format %{ "j$cop,us $labl" %}
11234 size(2);
11235 ins_encode %{
11236 Label* L = $labl$$label;
11237 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11238 %}
11239 ins_pipe(pipe_jcc);
11240 ins_short_branch(1);
11241 %}
11243 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
11244 match(If cop cmp);
11245 effect(USE labl);
11247 ins_cost(300);
11248 format %{ $$template
11249 if ($cop$$cmpcode == Assembler::notEqual) {
11250 $$emit$$"jp,u,s $labl\n\t"
11251 $$emit$$"j$cop,u,s $labl"
11252 } else {
11253 $$emit$$"jp,u,s done\n\t"
11254 $$emit$$"j$cop,u,s $labl\n\t"
11255 $$emit$$"done:"
11256 }
11257 %}
11258 size(4);
11259 ins_encode %{
11260 Label* l = $labl$$label;
11261 if ($cop$$cmpcode == Assembler::notEqual) {
11262 __ jccb(Assembler::parity, *l);
11263 __ jccb(Assembler::notEqual, *l);
11264 } else if ($cop$$cmpcode == Assembler::equal) {
11265 Label done;
11266 __ jccb(Assembler::parity, done);
11267 __ jccb(Assembler::equal, *l);
11268 __ bind(done);
11269 } else {
11270 ShouldNotReachHere();
11271 }
11272 %}
11273 ins_pipe(pipe_jcc);
11274 ins_short_branch(1);
11275 %}
11277 // ============================================================================
11278 // inlined locking and unlocking
11280 instruct cmpFastLock(rFlagsReg cr,
11281 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr)
11282 %{
11283 match(Set cr (FastLock object box));
11284 effect(TEMP tmp, TEMP scr, USE_KILL box);
11286 ins_cost(300);
11287 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
11288 ins_encode(Fast_Lock(object, box, tmp, scr));
11289 ins_pipe(pipe_slow);
11290 %}
11292 instruct cmpFastUnlock(rFlagsReg cr,
11293 rRegP object, rax_RegP box, rRegP tmp)
11294 %{
11295 match(Set cr (FastUnlock object box));
11296 effect(TEMP tmp, USE_KILL box);
11298 ins_cost(300);
11299 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
11300 ins_encode(Fast_Unlock(object, box, tmp));
11301 ins_pipe(pipe_slow);
11302 %}
11305 // ============================================================================
11306 // Safepoint Instructions
11307 instruct safePoint_poll(rFlagsReg cr)
11308 %{
11309 predicate(!Assembler::is_polling_page_far());
11310 match(SafePoint);
11311 effect(KILL cr);
11313 format %{ "testl rax, [rip + #offset_to_poll_page]\t"
11314 "# Safepoint: poll for GC" %}
11315 ins_cost(125);
11316 ins_encode %{
11317 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type);
11318 __ testl(rax, addr);
11319 %}
11320 ins_pipe(ialu_reg_mem);
11321 %}
11323 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
11324 %{
11325 predicate(Assembler::is_polling_page_far());
11326 match(SafePoint poll);
11327 effect(KILL cr, USE poll);
11329 format %{ "testl rax, [$poll]\t"
11330 "# Safepoint: poll for GC" %}
11331 ins_cost(125);
11332 ins_encode %{
11333 __ relocate(relocInfo::poll_type);
11334 __ testl(rax, Address($poll$$Register, 0));
11335 %}
11336 ins_pipe(ialu_reg_mem);
11337 %}
11339 // ============================================================================
11340 // Procedure Call/Return Instructions
11341 // Call Java Static Instruction
11342 // Note: If this code changes, the corresponding ret_addr_offset() and
11343 // compute_padding() functions will have to be adjusted.
11344 instruct CallStaticJavaDirect(method meth) %{
11345 match(CallStaticJava);
11346 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke());
11347 effect(USE meth);
11349 ins_cost(300);
11350 format %{ "call,static " %}
11351 opcode(0xE8); /* E8 cd */
11352 ins_encode(Java_Static_Call(meth), call_epilog);
11353 ins_pipe(pipe_slow);
11354 ins_alignment(4);
11355 %}
11357 // Call Java Static Instruction (method handle version)
11358 // Note: If this code changes, the corresponding ret_addr_offset() and
11359 // compute_padding() functions will have to be adjusted.
11360 instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{
11361 match(CallStaticJava);
11362 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke());
11363 effect(USE meth);
11364 // RBP is saved by all callees (for interpreter stack correction).
11365 // We use it here for a similar purpose, in {preserve,restore}_SP.
11367 ins_cost(300);
11368 format %{ "call,static/MethodHandle " %}
11369 opcode(0xE8); /* E8 cd */
11370 ins_encode(preserve_SP,
11371 Java_Static_Call(meth),
11372 restore_SP,
11373 call_epilog);
11374 ins_pipe(pipe_slow);
11375 ins_alignment(4);
11376 %}
11378 // Call Java Dynamic Instruction
11379 // Note: If this code changes, the corresponding ret_addr_offset() and
11380 // compute_padding() functions will have to be adjusted.
11381 instruct CallDynamicJavaDirect(method meth)
11382 %{
11383 match(CallDynamicJava);
11384 effect(USE meth);
11386 ins_cost(300);
11387 format %{ "movq rax, #Universe::non_oop_word()\n\t"
11388 "call,dynamic " %}
11389 ins_encode(Java_Dynamic_Call(meth), call_epilog);
11390 ins_pipe(pipe_slow);
11391 ins_alignment(4);
11392 %}
11394 // Call Runtime Instruction
11395 instruct CallRuntimeDirect(method meth)
11396 %{
11397 match(CallRuntime);
11398 effect(USE meth);
11400 ins_cost(300);
11401 format %{ "call,runtime " %}
11402 opcode(0xE8); /* E8 cd */
11403 ins_encode(Java_To_Runtime(meth));
11404 ins_pipe(pipe_slow);
11405 %}
11407 // Call runtime without safepoint
11408 instruct CallLeafDirect(method meth)
11409 %{
11410 match(CallLeaf);
11411 effect(USE meth);
11413 ins_cost(300);
11414 format %{ "call_leaf,runtime " %}
11415 opcode(0xE8); /* E8 cd */
11416 ins_encode(Java_To_Runtime(meth));
11417 ins_pipe(pipe_slow);
11418 %}
11420 // Call runtime without safepoint
11421 instruct CallLeafNoFPDirect(method meth)
11422 %{
11423 match(CallLeafNoFP);
11424 effect(USE meth);
11426 ins_cost(300);
11427 format %{ "call_leaf_nofp,runtime " %}
11428 opcode(0xE8); /* E8 cd */
11429 ins_encode(Java_To_Runtime(meth));
11430 ins_pipe(pipe_slow);
11431 %}
11433 // Return Instruction
11434 // Remove the return address & jump to it.
11435 // Notice: We always emit a nop after a ret to make sure there is room
11436 // for safepoint patching
11437 instruct Ret()
11438 %{
11439 match(Return);
11441 format %{ "ret" %}
11442 opcode(0xC3);
11443 ins_encode(OpcP);
11444 ins_pipe(pipe_jmp);
11445 %}
11447 // Tail Call; Jump from runtime stub to Java code.
11448 // Also known as an 'interprocedural jump'.
11449 // Target of jump will eventually return to caller.
11450 // TailJump below removes the return address.
11451 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop)
11452 %{
11453 match(TailCall jump_target method_oop);
11455 ins_cost(300);
11456 format %{ "jmp $jump_target\t# rbx holds method oop" %}
11457 opcode(0xFF, 0x4); /* Opcode FF /4 */
11458 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target));
11459 ins_pipe(pipe_jmp);
11460 %}
11462 // Tail Jump; remove the return address; jump to target.
11463 // TailCall above leaves the return address around.
11464 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop)
11465 %{
11466 match(TailJump jump_target ex_oop);
11468 ins_cost(300);
11469 format %{ "popq rdx\t# pop return address\n\t"
11470 "jmp $jump_target" %}
11471 opcode(0xFF, 0x4); /* Opcode FF /4 */
11472 ins_encode(Opcode(0x5a), // popq rdx
11473 REX_reg(jump_target), OpcP, reg_opc(jump_target));
11474 ins_pipe(pipe_jmp);
11475 %}
11477 // Create exception oop: created by stack-crawling runtime code.
11478 // Created exception is now available to this handler, and is setup
11479 // just prior to jumping to this handler. No code emitted.
11480 instruct CreateException(rax_RegP ex_oop)
11481 %{
11482 match(Set ex_oop (CreateEx));
11484 size(0);
11485 // use the following format syntax
11486 format %{ "# exception oop is in rax; no code emitted" %}
11487 ins_encode();
11488 ins_pipe(empty);
11489 %}
11491 // Rethrow exception:
11492 // The exception oop will come in the first argument position.
11493 // Then JUMP (not call) to the rethrow stub code.
11494 instruct RethrowException()
11495 %{
11496 match(Rethrow);
11498 // use the following format syntax
11499 format %{ "jmp rethrow_stub" %}
11500 ins_encode(enc_rethrow);
11501 ins_pipe(pipe_jmp);
11502 %}
11505 // ============================================================================
11506 // This name is KNOWN by the ADLC and cannot be changed.
11507 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
11508 // for this guy.
11509 instruct tlsLoadP(r15_RegP dst) %{
11510 match(Set dst (ThreadLocal));
11511 effect(DEF dst);
11513 size(0);
11514 format %{ "# TLS is in R15" %}
11515 ins_encode( /*empty encoding*/ );
11516 ins_pipe(ialu_reg_reg);
11517 %}
11520 //----------PEEPHOLE RULES-----------------------------------------------------
11521 // These must follow all instruction definitions as they use the names
11522 // defined in the instructions definitions.
11523 //
11524 // peepmatch ( root_instr_name [preceding_instruction]* );
11525 //
11526 // peepconstraint %{
11527 // (instruction_number.operand_name relational_op instruction_number.operand_name
11528 // [, ...] );
11529 // // instruction numbers are zero-based using left to right order in peepmatch
11530 //
11531 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
11532 // // provide an instruction_number.operand_name for each operand that appears
11533 // // in the replacement instruction's match rule
11534 //
11535 // ---------VM FLAGS---------------------------------------------------------
11536 //
11537 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11538 //
11539 // Each peephole rule is given an identifying number starting with zero and
11540 // increasing by one in the order seen by the parser. An individual peephole
11541 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11542 // on the command-line.
11543 //
11544 // ---------CURRENT LIMITATIONS----------------------------------------------
11545 //
11546 // Only match adjacent instructions in same basic block
11547 // Only equality constraints
11548 // Only constraints between operands, not (0.dest_reg == RAX_enc)
11549 // Only one replacement instruction
11550 //
11551 // ---------EXAMPLE----------------------------------------------------------
11552 //
11553 // // pertinent parts of existing instructions in architecture description
11554 // instruct movI(rRegI dst, rRegI src)
11555 // %{
11556 // match(Set dst (CopyI src));
11557 // %}
11558 //
11559 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
11560 // %{
11561 // match(Set dst (AddI dst src));
11562 // effect(KILL cr);
11563 // %}
11564 //
11565 // // Change (inc mov) to lea
11566 // peephole %{
11567 // // increment preceeded by register-register move
11568 // peepmatch ( incI_rReg movI );
11569 // // require that the destination register of the increment
11570 // // match the destination register of the move
11571 // peepconstraint ( 0.dst == 1.dst );
11572 // // construct a replacement instruction that sets
11573 // // the destination to ( move's source register + one )
11574 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) );
11575 // %}
11576 //
11578 // Implementation no longer uses movX instructions since
11579 // machine-independent system no longer uses CopyX nodes.
11580 //
11581 // peephole
11582 // %{
11583 // peepmatch (incI_rReg movI);
11584 // peepconstraint (0.dst == 1.dst);
11585 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11586 // %}
11588 // peephole
11589 // %{
11590 // peepmatch (decI_rReg movI);
11591 // peepconstraint (0.dst == 1.dst);
11592 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11593 // %}
11595 // peephole
11596 // %{
11597 // peepmatch (addI_rReg_imm movI);
11598 // peepconstraint (0.dst == 1.dst);
11599 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11600 // %}
11602 // peephole
11603 // %{
11604 // peepmatch (incL_rReg movL);
11605 // peepconstraint (0.dst == 1.dst);
11606 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11607 // %}
11609 // peephole
11610 // %{
11611 // peepmatch (decL_rReg movL);
11612 // peepconstraint (0.dst == 1.dst);
11613 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11614 // %}
11616 // peephole
11617 // %{
11618 // peepmatch (addL_rReg_imm movL);
11619 // peepconstraint (0.dst == 1.dst);
11620 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11621 // %}
11623 // peephole
11624 // %{
11625 // peepmatch (addP_rReg_imm movP);
11626 // peepconstraint (0.dst == 1.dst);
11627 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src));
11628 // %}
11630 // // Change load of spilled value to only a spill
11631 // instruct storeI(memory mem, rRegI src)
11632 // %{
11633 // match(Set mem (StoreI mem src));
11634 // %}
11635 //
11636 // instruct loadI(rRegI dst, memory mem)
11637 // %{
11638 // match(Set dst (LoadI mem));
11639 // %}
11640 //
11642 peephole
11643 %{
11644 peepmatch (loadI storeI);
11645 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
11646 peepreplace (storeI(1.mem 1.mem 1.src));
11647 %}
11649 peephole
11650 %{
11651 peepmatch (loadL storeL);
11652 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
11653 peepreplace (storeL(1.mem 1.mem 1.src));
11654 %}
11656 //----------SMARTSPILL RULES---------------------------------------------------
11657 // These must follow all instruction definitions as they use the names
11658 // defined in the instructions definitions.