Tue, 26 Nov 2013 18:38:19 -0800
8028515: PPPC64 (part 113.2): opto: Introduce LoadFence/StoreFence.
Summary: Use new nodes for loadFence/storeFence intrinsics in C2.
Reviewed-by: kvn, dholmes
1 //
2 // Copyright (c) 2003, 2013, 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 }
402 static int clear_avx_size() {
403 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper
404 }
406 // !!!!! Special hack to get all types of calls to specify the byte offset
407 // from the start of the call to the point where the return address
408 // will point.
409 int MachCallStaticJavaNode::ret_addr_offset()
410 {
411 int offset = 5; // 5 bytes from start of call to where return address points
412 offset += clear_avx_size();
413 if (_method_handle_invoke)
414 offset += preserve_SP_size();
415 return offset;
416 }
418 int MachCallDynamicJavaNode::ret_addr_offset()
419 {
420 int offset = 15; // 15 bytes from start of call to where return address points
421 offset += clear_avx_size();
422 return offset;
423 }
425 int MachCallRuntimeNode::ret_addr_offset() {
426 int offset = 13; // movq r10,#addr; callq (r10)
427 offset += clear_avx_size();
428 return offset;
429 }
431 // Indicate if the safepoint node needs the polling page as an input,
432 // it does if the polling page is more than disp32 away.
433 bool SafePointNode::needs_polling_address_input()
434 {
435 return Assembler::is_polling_page_far();
436 }
438 //
439 // Compute padding required for nodes which need alignment
440 //
442 // The address of the call instruction needs to be 4-byte aligned to
443 // ensure that it does not span a cache line so that it can be patched.
444 int CallStaticJavaDirectNode::compute_padding(int current_offset) const
445 {
446 current_offset += clear_avx_size(); // skip vzeroupper
447 current_offset += 1; // skip call opcode byte
448 return round_to(current_offset, alignment_required()) - current_offset;
449 }
451 // The address of the call instruction needs to be 4-byte aligned to
452 // ensure that it does not span a cache line so that it can be patched.
453 int CallStaticJavaHandleNode::compute_padding(int current_offset) const
454 {
455 current_offset += preserve_SP_size(); // skip mov rbp, rsp
456 current_offset += clear_avx_size(); // skip vzeroupper
457 current_offset += 1; // skip call opcode byte
458 return round_to(current_offset, alignment_required()) - current_offset;
459 }
461 // The address of the call instruction needs to be 4-byte aligned to
462 // ensure that it does not span a cache line so that it can be patched.
463 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const
464 {
465 current_offset += clear_avx_size(); // skip vzeroupper
466 current_offset += 11; // skip movq instruction + call opcode byte
467 return round_to(current_offset, alignment_required()) - current_offset;
468 }
470 // EMIT_RM()
471 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) {
472 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3);
473 cbuf.insts()->emit_int8(c);
474 }
476 // EMIT_CC()
477 void emit_cc(CodeBuffer &cbuf, int f1, int f2) {
478 unsigned char c = (unsigned char) (f1 | f2);
479 cbuf.insts()->emit_int8(c);
480 }
482 // EMIT_OPCODE()
483 void emit_opcode(CodeBuffer &cbuf, int code) {
484 cbuf.insts()->emit_int8((unsigned char) code);
485 }
487 // EMIT_OPCODE() w/ relocation information
488 void emit_opcode(CodeBuffer &cbuf,
489 int code, relocInfo::relocType reloc, int offset, int format)
490 {
491 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format);
492 emit_opcode(cbuf, code);
493 }
495 // EMIT_D8()
496 void emit_d8(CodeBuffer &cbuf, int d8) {
497 cbuf.insts()->emit_int8((unsigned char) d8);
498 }
500 // EMIT_D16()
501 void emit_d16(CodeBuffer &cbuf, int d16) {
502 cbuf.insts()->emit_int16(d16);
503 }
505 // EMIT_D32()
506 void emit_d32(CodeBuffer &cbuf, int d32) {
507 cbuf.insts()->emit_int32(d32);
508 }
510 // EMIT_D64()
511 void emit_d64(CodeBuffer &cbuf, int64_t d64) {
512 cbuf.insts()->emit_int64(d64);
513 }
515 // emit 32 bit value and construct relocation entry from relocInfo::relocType
516 void emit_d32_reloc(CodeBuffer& cbuf,
517 int d32,
518 relocInfo::relocType reloc,
519 int format)
520 {
521 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc");
522 cbuf.relocate(cbuf.insts_mark(), reloc, format);
523 cbuf.insts()->emit_int32(d32);
524 }
526 // emit 32 bit value and construct relocation entry from RelocationHolder
527 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) {
528 #ifdef ASSERT
529 if (rspec.reloc()->type() == relocInfo::oop_type &&
530 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) {
531 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop");
532 assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code");
533 }
534 #endif
535 cbuf.relocate(cbuf.insts_mark(), rspec, format);
536 cbuf.insts()->emit_int32(d32);
537 }
539 void emit_d32_reloc(CodeBuffer& cbuf, address addr) {
540 address next_ip = cbuf.insts_end() + 4;
541 emit_d32_reloc(cbuf, (int) (addr - next_ip),
542 external_word_Relocation::spec(addr),
543 RELOC_DISP32);
544 }
547 // emit 64 bit value and construct relocation entry from relocInfo::relocType
548 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) {
549 cbuf.relocate(cbuf.insts_mark(), reloc, format);
550 cbuf.insts()->emit_int64(d64);
551 }
553 // emit 64 bit value and construct relocation entry from RelocationHolder
554 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) {
555 #ifdef ASSERT
556 if (rspec.reloc()->type() == relocInfo::oop_type &&
557 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) {
558 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop");
559 assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()),
560 "cannot embed scavengable oops in code");
561 }
562 #endif
563 cbuf.relocate(cbuf.insts_mark(), rspec, format);
564 cbuf.insts()->emit_int64(d64);
565 }
567 // Access stack slot for load or store
568 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp)
569 {
570 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src])
571 if (-0x80 <= disp && disp < 0x80) {
572 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte
573 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
574 emit_d8(cbuf, disp); // Displacement // R/M byte
575 } else {
576 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte
577 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte
578 emit_d32(cbuf, disp); // Displacement // R/M byte
579 }
580 }
582 // rRegI ereg, memory mem) %{ // emit_reg_mem
583 void encode_RegMem(CodeBuffer &cbuf,
584 int reg,
585 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc)
586 {
587 assert(disp_reloc == relocInfo::none, "cannot have disp");
588 int regenc = reg & 7;
589 int baseenc = base & 7;
590 int indexenc = index & 7;
592 // There is no index & no scale, use form without SIB byte
593 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) {
594 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
595 if (disp == 0 && base != RBP_enc && base != R13_enc) {
596 emit_rm(cbuf, 0x0, regenc, baseenc); // *
597 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
598 // If 8-bit displacement, mode 0x1
599 emit_rm(cbuf, 0x1, regenc, baseenc); // *
600 emit_d8(cbuf, disp);
601 } else {
602 // If 32-bit displacement
603 if (base == -1) { // Special flag for absolute address
604 emit_rm(cbuf, 0x0, regenc, 0x5); // *
605 if (disp_reloc != relocInfo::none) {
606 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
607 } else {
608 emit_d32(cbuf, disp);
609 }
610 } else {
611 // Normal base + offset
612 emit_rm(cbuf, 0x2, regenc, baseenc); // *
613 if (disp_reloc != relocInfo::none) {
614 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
615 } else {
616 emit_d32(cbuf, disp);
617 }
618 }
619 }
620 } else {
621 // Else, encode with the SIB byte
622 // If no displacement, mode is 0x0; unless base is [RBP] or [R13]
623 if (disp == 0 && base != RBP_enc && base != R13_enc) {
624 // If no displacement
625 emit_rm(cbuf, 0x0, regenc, 0x4); // *
626 emit_rm(cbuf, scale, indexenc, baseenc);
627 } else {
628 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) {
629 // If 8-bit displacement, mode 0x1
630 emit_rm(cbuf, 0x1, regenc, 0x4); // *
631 emit_rm(cbuf, scale, indexenc, baseenc);
632 emit_d8(cbuf, disp);
633 } else {
634 // If 32-bit displacement
635 if (base == 0x04 ) {
636 emit_rm(cbuf, 0x2, regenc, 0x4);
637 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid???
638 } else {
639 emit_rm(cbuf, 0x2, regenc, 0x4);
640 emit_rm(cbuf, scale, indexenc, baseenc); // *
641 }
642 if (disp_reloc != relocInfo::none) {
643 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32);
644 } else {
645 emit_d32(cbuf, disp);
646 }
647 }
648 }
649 }
650 }
652 // This could be in MacroAssembler but it's fairly C2 specific
653 void emit_cmpfp_fixup(MacroAssembler& _masm) {
654 Label exit;
655 __ jccb(Assembler::noParity, exit);
656 __ pushf();
657 //
658 // comiss/ucomiss instructions set ZF,PF,CF flags and
659 // zero OF,AF,SF for NaN values.
660 // Fixup flags by zeroing ZF,PF so that compare of NaN
661 // values returns 'less than' result (CF is set).
662 // Leave the rest of flags unchanged.
663 //
664 // 7 6 5 4 3 2 1 0
665 // |S|Z|r|A|r|P|r|C| (r - reserved bit)
666 // 0 0 1 0 1 0 1 1 (0x2B)
667 //
668 __ andq(Address(rsp, 0), 0xffffff2b);
669 __ popf();
670 __ bind(exit);
671 }
673 void emit_cmpfp3(MacroAssembler& _masm, Register dst) {
674 Label done;
675 __ movl(dst, -1);
676 __ jcc(Assembler::parity, done);
677 __ jcc(Assembler::below, done);
678 __ setb(Assembler::notEqual, dst);
679 __ movzbl(dst, dst);
680 __ bind(done);
681 }
684 //=============================================================================
685 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty;
687 int Compile::ConstantTable::calculate_table_base_offset() const {
688 return 0; // absolute addressing, no offset
689 }
691 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; }
692 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) {
693 ShouldNotReachHere();
694 }
696 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
697 // Empty encoding
698 }
700 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const {
701 return 0;
702 }
704 #ifndef PRODUCT
705 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
706 st->print("# MachConstantBaseNode (empty encoding)");
707 }
708 #endif
711 //=============================================================================
712 #ifndef PRODUCT
713 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
714 Compile* C = ra_->C;
716 int framesize = C->frame_slots() << LogBytesPerInt;
717 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
718 // Remove wordSize for return addr which is already pushed.
719 framesize -= wordSize;
721 if (C->need_stack_bang(framesize)) {
722 framesize -= wordSize;
723 st->print("# stack bang");
724 st->print("\n\t");
725 st->print("pushq rbp\t# Save rbp");
726 if (framesize) {
727 st->print("\n\t");
728 st->print("subq rsp, #%d\t# Create frame",framesize);
729 }
730 } else {
731 st->print("subq rsp, #%d\t# Create frame",framesize);
732 st->print("\n\t");
733 framesize -= wordSize;
734 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
735 }
737 if (VerifyStackAtCalls) {
738 st->print("\n\t");
739 framesize -= wordSize;
740 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize);
741 #ifdef ASSERT
742 st->print("\n\t");
743 st->print("# stack alignment check");
744 #endif
745 }
746 st->cr();
747 }
748 #endif
750 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
751 Compile* C = ra_->C;
752 MacroAssembler _masm(&cbuf);
754 int framesize = C->frame_slots() << LogBytesPerInt;
756 __ verified_entry(framesize, C->need_stack_bang(framesize), false);
758 C->set_frame_complete(cbuf.insts_size());
760 if (C->has_mach_constant_base_node()) {
761 // NOTE: We set the table base offset here because users might be
762 // emitted before MachConstantBaseNode.
763 Compile::ConstantTable& constant_table = C->constant_table();
764 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset());
765 }
766 }
768 uint MachPrologNode::size(PhaseRegAlloc* ra_) const
769 {
770 return MachNode::size(ra_); // too many variables; just compute it
771 // the hard way
772 }
774 int MachPrologNode::reloc() const
775 {
776 return 0; // a large enough number
777 }
779 //=============================================================================
780 #ifndef PRODUCT
781 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
782 {
783 Compile* C = ra_->C;
784 if (C->max_vector_size() > 16) {
785 st->print("vzeroupper");
786 st->cr(); st->print("\t");
787 }
789 int framesize = C->frame_slots() << LogBytesPerInt;
790 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
791 // Remove word for return adr already pushed
792 // and RBP
793 framesize -= 2*wordSize;
795 if (framesize) {
796 st->print_cr("addq rsp, %d\t# Destroy frame", framesize);
797 st->print("\t");
798 }
800 st->print_cr("popq rbp");
801 if (do_polling() && C->is_method_compilation()) {
802 st->print("\t");
803 if (Assembler::is_polling_page_far()) {
804 st->print_cr("movq rscratch1, #polling_page_address\n\t"
805 "testl rax, [rscratch1]\t"
806 "# Safepoint: poll for GC");
807 } else {
808 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t"
809 "# Safepoint: poll for GC");
810 }
811 }
812 }
813 #endif
815 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
816 {
817 Compile* C = ra_->C;
818 if (C->max_vector_size() > 16) {
819 // Clear upper bits of YMM registers when current compiled code uses
820 // wide vectors to avoid AVX <-> SSE transition penalty during call.
821 MacroAssembler _masm(&cbuf);
822 __ vzeroupper();
823 }
825 int framesize = C->frame_slots() << LogBytesPerInt;
826 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
827 // Remove word for return adr already pushed
828 // and RBP
829 framesize -= 2*wordSize;
831 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here
833 if (framesize) {
834 emit_opcode(cbuf, Assembler::REX_W);
835 if (framesize < 0x80) {
836 emit_opcode(cbuf, 0x83); // addq rsp, #framesize
837 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
838 emit_d8(cbuf, framesize);
839 } else {
840 emit_opcode(cbuf, 0x81); // addq rsp, #framesize
841 emit_rm(cbuf, 0x3, 0x00, RSP_enc);
842 emit_d32(cbuf, framesize);
843 }
844 }
846 // popq rbp
847 emit_opcode(cbuf, 0x58 | RBP_enc);
849 if (do_polling() && C->is_method_compilation()) {
850 MacroAssembler _masm(&cbuf);
851 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
852 if (Assembler::is_polling_page_far()) {
853 __ lea(rscratch1, polling_page);
854 __ relocate(relocInfo::poll_return_type);
855 __ testl(rax, Address(rscratch1, 0));
856 } else {
857 __ testl(rax, polling_page);
858 }
859 }
860 }
862 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
863 {
864 return MachNode::size(ra_); // too many variables; just compute it
865 // the hard way
866 }
868 int MachEpilogNode::reloc() const
869 {
870 return 2; // a large enough number
871 }
873 const Pipeline* MachEpilogNode::pipeline() const
874 {
875 return MachNode::pipeline_class();
876 }
878 int MachEpilogNode::safepoint_offset() const
879 {
880 return 0;
881 }
883 //=============================================================================
885 enum RC {
886 rc_bad,
887 rc_int,
888 rc_float,
889 rc_stack
890 };
892 static enum RC rc_class(OptoReg::Name reg)
893 {
894 if( !OptoReg::is_valid(reg) ) return rc_bad;
896 if (OptoReg::is_stack(reg)) return rc_stack;
898 VMReg r = OptoReg::as_VMReg(reg);
900 if (r->is_Register()) return rc_int;
902 assert(r->is_XMMRegister(), "must be");
903 return rc_float;
904 }
906 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad.
907 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
908 int src_hi, int dst_hi, uint ireg, outputStream* st);
910 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
911 int stack_offset, int reg, uint ireg, outputStream* st);
913 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
914 int dst_offset, uint ireg, outputStream* st) {
915 if (cbuf) {
916 MacroAssembler _masm(cbuf);
917 switch (ireg) {
918 case Op_VecS:
919 __ movq(Address(rsp, -8), rax);
920 __ movl(rax, Address(rsp, src_offset));
921 __ movl(Address(rsp, dst_offset), rax);
922 __ movq(rax, Address(rsp, -8));
923 break;
924 case Op_VecD:
925 __ pushq(Address(rsp, src_offset));
926 __ popq (Address(rsp, dst_offset));
927 break;
928 case Op_VecX:
929 __ pushq(Address(rsp, src_offset));
930 __ popq (Address(rsp, dst_offset));
931 __ pushq(Address(rsp, src_offset+8));
932 __ popq (Address(rsp, dst_offset+8));
933 break;
934 case Op_VecY:
935 __ vmovdqu(Address(rsp, -32), xmm0);
936 __ vmovdqu(xmm0, Address(rsp, src_offset));
937 __ vmovdqu(Address(rsp, dst_offset), xmm0);
938 __ vmovdqu(xmm0, Address(rsp, -32));
939 break;
940 default:
941 ShouldNotReachHere();
942 }
943 #ifndef PRODUCT
944 } else {
945 switch (ireg) {
946 case Op_VecS:
947 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
948 "movl rax, [rsp + #%d]\n\t"
949 "movl [rsp + #%d], rax\n\t"
950 "movq rax, [rsp - #8]",
951 src_offset, dst_offset);
952 break;
953 case Op_VecD:
954 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
955 "popq [rsp + #%d]",
956 src_offset, dst_offset);
957 break;
958 case Op_VecX:
959 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t"
960 "popq [rsp + #%d]\n\t"
961 "pushq [rsp + #%d]\n\t"
962 "popq [rsp + #%d]",
963 src_offset, dst_offset, src_offset+8, dst_offset+8);
964 break;
965 case Op_VecY:
966 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
967 "vmovdqu xmm0, [rsp + #%d]\n\t"
968 "vmovdqu [rsp + #%d], xmm0\n\t"
969 "vmovdqu xmm0, [rsp - #32]",
970 src_offset, dst_offset);
971 break;
972 default:
973 ShouldNotReachHere();
974 }
975 #endif
976 }
977 }
979 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
980 PhaseRegAlloc* ra_,
981 bool do_size,
982 outputStream* st) const {
983 assert(cbuf != NULL || st != NULL, "sanity");
984 // Get registers to move
985 OptoReg::Name src_second = ra_->get_reg_second(in(1));
986 OptoReg::Name src_first = ra_->get_reg_first(in(1));
987 OptoReg::Name dst_second = ra_->get_reg_second(this);
988 OptoReg::Name dst_first = ra_->get_reg_first(this);
990 enum RC src_second_rc = rc_class(src_second);
991 enum RC src_first_rc = rc_class(src_first);
992 enum RC dst_second_rc = rc_class(dst_second);
993 enum RC dst_first_rc = rc_class(dst_first);
995 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first),
996 "must move at least 1 register" );
998 if (src_first == dst_first && src_second == dst_second) {
999 // Self copy, no move
1000 return 0;
1001 }
1002 if (bottom_type()->isa_vect() != NULL) {
1003 uint ireg = ideal_reg();
1004 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
1005 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
1006 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
1007 // mem -> mem
1008 int src_offset = ra_->reg2offset(src_first);
1009 int dst_offset = ra_->reg2offset(dst_first);
1010 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st);
1011 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) {
1012 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st);
1013 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) {
1014 int stack_offset = ra_->reg2offset(dst_first);
1015 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st);
1016 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) {
1017 int stack_offset = ra_->reg2offset(src_first);
1018 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st);
1019 } else {
1020 ShouldNotReachHere();
1021 }
1022 return 0;
1023 }
1024 if (src_first_rc == rc_stack) {
1025 // mem ->
1026 if (dst_first_rc == rc_stack) {
1027 // mem -> mem
1028 assert(src_second != dst_first, "overlap");
1029 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1030 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1031 // 64-bit
1032 int src_offset = ra_->reg2offset(src_first);
1033 int dst_offset = ra_->reg2offset(dst_first);
1034 if (cbuf) {
1035 MacroAssembler _masm(cbuf);
1036 __ pushq(Address(rsp, src_offset));
1037 __ popq (Address(rsp, dst_offset));
1038 #ifndef PRODUCT
1039 } else {
1040 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
1041 "popq [rsp + #%d]",
1042 src_offset, dst_offset);
1043 #endif
1044 }
1045 } else {
1046 // 32-bit
1047 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1048 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1049 // No pushl/popl, so:
1050 int src_offset = ra_->reg2offset(src_first);
1051 int dst_offset = ra_->reg2offset(dst_first);
1052 if (cbuf) {
1053 MacroAssembler _masm(cbuf);
1054 __ movq(Address(rsp, -8), rax);
1055 __ movl(rax, Address(rsp, src_offset));
1056 __ movl(Address(rsp, dst_offset), rax);
1057 __ movq(rax, Address(rsp, -8));
1058 #ifndef PRODUCT
1059 } else {
1060 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
1061 "movl rax, [rsp + #%d]\n\t"
1062 "movl [rsp + #%d], rax\n\t"
1063 "movq rax, [rsp - #8]",
1064 src_offset, dst_offset);
1065 #endif
1066 }
1067 }
1068 return 0;
1069 } else if (dst_first_rc == rc_int) {
1070 // mem -> gpr
1071 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1072 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1073 // 64-bit
1074 int offset = ra_->reg2offset(src_first);
1075 if (cbuf) {
1076 MacroAssembler _masm(cbuf);
1077 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1078 #ifndef PRODUCT
1079 } else {
1080 st->print("movq %s, [rsp + #%d]\t# spill",
1081 Matcher::regName[dst_first],
1082 offset);
1083 #endif
1084 }
1085 } else {
1086 // 32-bit
1087 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1088 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1089 int offset = ra_->reg2offset(src_first);
1090 if (cbuf) {
1091 MacroAssembler _masm(cbuf);
1092 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1093 #ifndef PRODUCT
1094 } else {
1095 st->print("movl %s, [rsp + #%d]\t# spill",
1096 Matcher::regName[dst_first],
1097 offset);
1098 #endif
1099 }
1100 }
1101 return 0;
1102 } else if (dst_first_rc == rc_float) {
1103 // mem-> xmm
1104 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1105 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1106 // 64-bit
1107 int offset = ra_->reg2offset(src_first);
1108 if (cbuf) {
1109 MacroAssembler _masm(cbuf);
1110 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1111 #ifndef PRODUCT
1112 } else {
1113 st->print("%s %s, [rsp + #%d]\t# spill",
1114 UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
1115 Matcher::regName[dst_first],
1116 offset);
1117 #endif
1118 }
1119 } else {
1120 // 32-bit
1121 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1122 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1123 int offset = ra_->reg2offset(src_first);
1124 if (cbuf) {
1125 MacroAssembler _masm(cbuf);
1126 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
1127 #ifndef PRODUCT
1128 } else {
1129 st->print("movss %s, [rsp + #%d]\t# spill",
1130 Matcher::regName[dst_first],
1131 offset);
1132 #endif
1133 }
1134 }
1135 return 0;
1136 }
1137 } else if (src_first_rc == rc_int) {
1138 // gpr ->
1139 if (dst_first_rc == rc_stack) {
1140 // gpr -> mem
1141 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1142 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1143 // 64-bit
1144 int offset = ra_->reg2offset(dst_first);
1145 if (cbuf) {
1146 MacroAssembler _masm(cbuf);
1147 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
1148 #ifndef PRODUCT
1149 } else {
1150 st->print("movq [rsp + #%d], %s\t# spill",
1151 offset,
1152 Matcher::regName[src_first]);
1153 #endif
1154 }
1155 } else {
1156 // 32-bit
1157 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1158 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1159 int offset = ra_->reg2offset(dst_first);
1160 if (cbuf) {
1161 MacroAssembler _masm(cbuf);
1162 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
1163 #ifndef PRODUCT
1164 } else {
1165 st->print("movl [rsp + #%d], %s\t# spill",
1166 offset,
1167 Matcher::regName[src_first]);
1168 #endif
1169 }
1170 }
1171 return 0;
1172 } else if (dst_first_rc == rc_int) {
1173 // gpr -> gpr
1174 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1175 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1176 // 64-bit
1177 if (cbuf) {
1178 MacroAssembler _masm(cbuf);
1179 __ movq(as_Register(Matcher::_regEncode[dst_first]),
1180 as_Register(Matcher::_regEncode[src_first]));
1181 #ifndef PRODUCT
1182 } else {
1183 st->print("movq %s, %s\t# spill",
1184 Matcher::regName[dst_first],
1185 Matcher::regName[src_first]);
1186 #endif
1187 }
1188 return 0;
1189 } else {
1190 // 32-bit
1191 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1192 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1193 if (cbuf) {
1194 MacroAssembler _masm(cbuf);
1195 __ movl(as_Register(Matcher::_regEncode[dst_first]),
1196 as_Register(Matcher::_regEncode[src_first]));
1197 #ifndef PRODUCT
1198 } else {
1199 st->print("movl %s, %s\t# spill",
1200 Matcher::regName[dst_first],
1201 Matcher::regName[src_first]);
1202 #endif
1203 }
1204 return 0;
1205 }
1206 } else if (dst_first_rc == rc_float) {
1207 // gpr -> xmm
1208 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1209 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1210 // 64-bit
1211 if (cbuf) {
1212 MacroAssembler _masm(cbuf);
1213 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1214 #ifndef PRODUCT
1215 } else {
1216 st->print("movdq %s, %s\t# spill",
1217 Matcher::regName[dst_first],
1218 Matcher::regName[src_first]);
1219 #endif
1220 }
1221 } else {
1222 // 32-bit
1223 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1224 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1225 if (cbuf) {
1226 MacroAssembler _masm(cbuf);
1227 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
1228 #ifndef PRODUCT
1229 } else {
1230 st->print("movdl %s, %s\t# spill",
1231 Matcher::regName[dst_first],
1232 Matcher::regName[src_first]);
1233 #endif
1234 }
1235 }
1236 return 0;
1237 }
1238 } else if (src_first_rc == rc_float) {
1239 // xmm ->
1240 if (dst_first_rc == rc_stack) {
1241 // xmm -> mem
1242 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1243 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1244 // 64-bit
1245 int offset = ra_->reg2offset(dst_first);
1246 if (cbuf) {
1247 MacroAssembler _masm(cbuf);
1248 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1249 #ifndef PRODUCT
1250 } else {
1251 st->print("movsd [rsp + #%d], %s\t# spill",
1252 offset,
1253 Matcher::regName[src_first]);
1254 #endif
1255 }
1256 } else {
1257 // 32-bit
1258 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1259 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1260 int offset = ra_->reg2offset(dst_first);
1261 if (cbuf) {
1262 MacroAssembler _masm(cbuf);
1263 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
1264 #ifndef PRODUCT
1265 } else {
1266 st->print("movss [rsp + #%d], %s\t# spill",
1267 offset,
1268 Matcher::regName[src_first]);
1269 #endif
1270 }
1271 }
1272 return 0;
1273 } else if (dst_first_rc == rc_int) {
1274 // xmm -> gpr
1275 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1276 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1277 // 64-bit
1278 if (cbuf) {
1279 MacroAssembler _masm(cbuf);
1280 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1281 #ifndef PRODUCT
1282 } else {
1283 st->print("movdq %s, %s\t# spill",
1284 Matcher::regName[dst_first],
1285 Matcher::regName[src_first]);
1286 #endif
1287 }
1288 } else {
1289 // 32-bit
1290 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1291 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1292 if (cbuf) {
1293 MacroAssembler _masm(cbuf);
1294 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1295 #ifndef PRODUCT
1296 } else {
1297 st->print("movdl %s, %s\t# spill",
1298 Matcher::regName[dst_first],
1299 Matcher::regName[src_first]);
1300 #endif
1301 }
1302 }
1303 return 0;
1304 } else if (dst_first_rc == rc_float) {
1305 // xmm -> xmm
1306 if ((src_first & 1) == 0 && src_first + 1 == src_second &&
1307 (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
1308 // 64-bit
1309 if (cbuf) {
1310 MacroAssembler _masm(cbuf);
1311 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1312 #ifndef PRODUCT
1313 } else {
1314 st->print("%s %s, %s\t# spill",
1315 UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
1316 Matcher::regName[dst_first],
1317 Matcher::regName[src_first]);
1318 #endif
1319 }
1320 } else {
1321 // 32-bit
1322 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
1323 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
1324 if (cbuf) {
1325 MacroAssembler _masm(cbuf);
1326 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
1327 #ifndef PRODUCT
1328 } else {
1329 st->print("%s %s, %s\t# spill",
1330 UseXmmRegToRegMoveAll ? "movaps" : "movss ",
1331 Matcher::regName[dst_first],
1332 Matcher::regName[src_first]);
1333 #endif
1334 }
1335 }
1336 return 0;
1337 }
1338 }
1340 assert(0," foo ");
1341 Unimplemented();
1342 return 0;
1343 }
1345 #ifndef PRODUCT
1346 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const {
1347 implementation(NULL, ra_, false, st);
1348 }
1349 #endif
1351 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
1352 implementation(&cbuf, ra_, false, NULL);
1353 }
1355 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
1356 return MachNode::size(ra_);
1357 }
1359 //=============================================================================
1360 #ifndef PRODUCT
1361 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1362 {
1363 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1364 int reg = ra_->get_reg_first(this);
1365 st->print("leaq %s, [rsp + #%d]\t# box lock",
1366 Matcher::regName[reg], offset);
1367 }
1368 #endif
1370 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1371 {
1372 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1373 int reg = ra_->get_encode(this);
1374 if (offset >= 0x80) {
1375 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1376 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1377 emit_rm(cbuf, 0x2, reg & 7, 0x04);
1378 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1379 emit_d32(cbuf, offset);
1380 } else {
1381 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR);
1382 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset]
1383 emit_rm(cbuf, 0x1, reg & 7, 0x04);
1384 emit_rm(cbuf, 0x0, 0x04, RSP_enc);
1385 emit_d8(cbuf, offset);
1386 }
1387 }
1389 uint BoxLockNode::size(PhaseRegAlloc *ra_) const
1390 {
1391 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem());
1392 return (offset < 0x80) ? 5 : 8; // REX
1393 }
1395 //=============================================================================
1396 #ifndef PRODUCT
1397 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const
1398 {
1399 if (UseCompressedClassPointers) {
1400 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass");
1401 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1");
1402 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check");
1403 } else {
1404 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t"
1405 "# Inline cache check");
1406 }
1407 st->print_cr("\tjne SharedRuntime::_ic_miss_stub");
1408 st->print_cr("\tnop\t# nops to align entry point");
1409 }
1410 #endif
1412 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1413 {
1414 MacroAssembler masm(&cbuf);
1415 uint insts_size = cbuf.insts_size();
1416 if (UseCompressedClassPointers) {
1417 masm.load_klass(rscratch1, j_rarg0);
1418 masm.cmpptr(rax, rscratch1);
1419 } else {
1420 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes()));
1421 }
1423 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
1425 /* WARNING these NOPs are critical so that verified entry point is properly
1426 4 bytes aligned for patching by NativeJump::patch_verified_entry() */
1427 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3);
1428 if (OptoBreakpoint) {
1429 // Leave space for int3
1430 nops_cnt -= 1;
1431 }
1432 nops_cnt &= 0x3; // Do not add nops if code is aligned.
1433 if (nops_cnt > 0)
1434 masm.nop(nops_cnt);
1435 }
1437 uint MachUEPNode::size(PhaseRegAlloc* ra_) const
1438 {
1439 return MachNode::size(ra_); // too many variables; just compute it
1440 // the hard way
1441 }
1444 //=============================================================================
1445 uint size_exception_handler()
1446 {
1447 // NativeCall instruction size is the same as NativeJump.
1448 // Note that this value is also credited (in output.cpp) to
1449 // the size of the code section.
1450 return NativeJump::instruction_size;
1451 }
1453 // Emit exception handler code.
1454 int emit_exception_handler(CodeBuffer& cbuf)
1455 {
1457 // Note that the code buffer's insts_mark is always relative to insts.
1458 // That's why we must use the macroassembler to generate a handler.
1459 MacroAssembler _masm(&cbuf);
1460 address base =
1461 __ start_a_stub(size_exception_handler());
1462 if (base == NULL) return 0; // CodeBuffer::expand failed
1463 int offset = __ offset();
1464 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
1465 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
1466 __ end_a_stub();
1467 return offset;
1468 }
1470 uint size_deopt_handler()
1471 {
1472 // three 5 byte instructions
1473 return 15;
1474 }
1476 // Emit deopt handler code.
1477 int emit_deopt_handler(CodeBuffer& cbuf)
1478 {
1480 // Note that the code buffer's insts_mark is always relative to insts.
1481 // That's why we must use the macroassembler to generate a handler.
1482 MacroAssembler _masm(&cbuf);
1483 address base =
1484 __ start_a_stub(size_deopt_handler());
1485 if (base == NULL) return 0; // CodeBuffer::expand failed
1486 int offset = __ offset();
1487 address the_pc = (address) __ pc();
1488 Label next;
1489 // push a "the_pc" on the stack without destroying any registers
1490 // as they all may be live.
1492 // push address of "next"
1493 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32
1494 __ bind(next);
1495 // adjust it so it matches "the_pc"
1496 __ subptr(Address(rsp, 0), __ offset() - offset);
1497 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack()));
1498 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
1499 __ end_a_stub();
1500 return offset;
1501 }
1503 int Matcher::regnum_to_fpu_offset(int regnum)
1504 {
1505 return regnum - 32; // The FP registers are in the second chunk
1506 }
1508 // This is UltraSparc specific, true just means we have fast l2f conversion
1509 const bool Matcher::convL2FSupported(void) {
1510 return true;
1511 }
1513 // Is this branch offset short enough that a short branch can be used?
1514 //
1515 // NOTE: If the platform does not provide any short branch variants, then
1516 // this method should return false for offset 0.
1517 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1518 // The passed offset is relative to address of the branch.
1519 // On 86 a branch displacement is calculated relative to address
1520 // of a next instruction.
1521 offset -= br_size;
1523 // the short version of jmpConUCF2 contains multiple branches,
1524 // making the reach slightly less
1525 if (rule == jmpConUCF2_rule)
1526 return (-126 <= offset && offset <= 125);
1527 return (-128 <= offset && offset <= 127);
1528 }
1530 const bool Matcher::isSimpleConstant64(jlong value) {
1531 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1532 //return value == (int) value; // Cf. storeImmL and immL32.
1534 // Probably always true, even if a temp register is required.
1535 return true;
1536 }
1538 // The ecx parameter to rep stosq for the ClearArray node is in words.
1539 const bool Matcher::init_array_count_is_in_bytes = false;
1541 // Threshold size for cleararray.
1542 const int Matcher::init_array_short_size = 8 * BytesPerLong;
1544 // No additional cost for CMOVL.
1545 const int Matcher::long_cmove_cost() { return 0; }
1547 // No CMOVF/CMOVD with SSE2
1548 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; }
1550 // Does the CPU require late expand (see block.cpp for description of late expand)?
1551 const bool Matcher::require_postalloc_expand = false;
1553 // Should the Matcher clone shifts on addressing modes, expecting them
1554 // to be subsumed into complex addressing expressions or compute them
1555 // into registers? True for Intel but false for most RISCs
1556 const bool Matcher::clone_shift_expressions = true;
1558 // Do we need to mask the count passed to shift instructions or does
1559 // the cpu only look at the lower 5/6 bits anyway?
1560 const bool Matcher::need_masked_shift_count = false;
1562 bool Matcher::narrow_oop_use_complex_address() {
1563 assert(UseCompressedOops, "only for compressed oops code");
1564 return (LogMinObjAlignmentInBytes <= 3);
1565 }
1567 bool Matcher::narrow_klass_use_complex_address() {
1568 assert(UseCompressedClassPointers, "only for compressed klass code");
1569 return (LogKlassAlignmentInBytes <= 3);
1570 }
1572 // Is it better to copy float constants, or load them directly from
1573 // memory? Intel can load a float constant from a direct address,
1574 // requiring no extra registers. Most RISCs will have to materialize
1575 // an address into a register first, so they would do better to copy
1576 // the constant from stack.
1577 const bool Matcher::rematerialize_float_constants = true; // XXX
1579 // If CPU can load and store mis-aligned doubles directly then no
1580 // fixup is needed. Else we split the double into 2 integer pieces
1581 // and move it piece-by-piece. Only happens when passing doubles into
1582 // C code as the Java calling convention forces doubles to be aligned.
1583 const bool Matcher::misaligned_doubles_ok = true;
1585 // No-op on amd64
1586 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {}
1588 // Advertise here if the CPU requires explicit rounding operations to
1589 // implement the UseStrictFP mode.
1590 const bool Matcher::strict_fp_requires_explicit_rounding = true;
1592 // Are floats conerted to double when stored to stack during deoptimization?
1593 // On x64 it is stored without convertion so we can use normal access.
1594 bool Matcher::float_in_double() { return false; }
1596 // Do ints take an entire long register or just half?
1597 const bool Matcher::int_in_long = true;
1599 // Return whether or not this register is ever used as an argument.
1600 // This function is used on startup to build the trampoline stubs in
1601 // generateOptoStub. Registers not mentioned will be killed by the VM
1602 // call in the trampoline, and arguments in those registers not be
1603 // available to the callee.
1604 bool Matcher::can_be_java_arg(int reg)
1605 {
1606 return
1607 reg == RDI_num || reg == RDI_H_num ||
1608 reg == RSI_num || reg == RSI_H_num ||
1609 reg == RDX_num || reg == RDX_H_num ||
1610 reg == RCX_num || reg == RCX_H_num ||
1611 reg == R8_num || reg == R8_H_num ||
1612 reg == R9_num || reg == R9_H_num ||
1613 reg == R12_num || reg == R12_H_num ||
1614 reg == XMM0_num || reg == XMM0b_num ||
1615 reg == XMM1_num || reg == XMM1b_num ||
1616 reg == XMM2_num || reg == XMM2b_num ||
1617 reg == XMM3_num || reg == XMM3b_num ||
1618 reg == XMM4_num || reg == XMM4b_num ||
1619 reg == XMM5_num || reg == XMM5b_num ||
1620 reg == XMM6_num || reg == XMM6b_num ||
1621 reg == XMM7_num || reg == XMM7b_num;
1622 }
1624 bool Matcher::is_spillable_arg(int reg)
1625 {
1626 return can_be_java_arg(reg);
1627 }
1629 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1630 // In 64 bit mode a code which use multiply when
1631 // devisor is constant is faster than hardware
1632 // DIV instruction (it uses MulHiL).
1633 return false;
1634 }
1636 // Register for DIVI projection of divmodI
1637 RegMask Matcher::divI_proj_mask() {
1638 return INT_RAX_REG_mask();
1639 }
1641 // Register for MODI projection of divmodI
1642 RegMask Matcher::modI_proj_mask() {
1643 return INT_RDX_REG_mask();
1644 }
1646 // Register for DIVL projection of divmodL
1647 RegMask Matcher::divL_proj_mask() {
1648 return LONG_RAX_REG_mask();
1649 }
1651 // Register for MODL projection of divmodL
1652 RegMask Matcher::modL_proj_mask() {
1653 return LONG_RDX_REG_mask();
1654 }
1656 const RegMask Matcher::method_handle_invoke_SP_save_mask() {
1657 return PTR_RBP_REG_mask();
1658 }
1660 const RegMask Matcher::mathExactI_result_proj_mask() {
1661 return INT_RAX_REG_mask();
1662 }
1664 const RegMask Matcher::mathExactL_result_proj_mask() {
1665 return LONG_RAX_REG_mask();
1666 }
1668 const RegMask Matcher::mathExactI_flags_proj_mask() {
1669 return INT_FLAGS_mask();
1670 }
1672 %}
1674 //----------ENCODING BLOCK-----------------------------------------------------
1675 // This block specifies the encoding classes used by the compiler to
1676 // output byte streams. Encoding classes are parameterized macros
1677 // used by Machine Instruction Nodes in order to generate the bit
1678 // encoding of the instruction. Operands specify their base encoding
1679 // interface with the interface keyword. There are currently
1680 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
1681 // COND_INTER. REG_INTER causes an operand to generate a function
1682 // which returns its register number when queried. CONST_INTER causes
1683 // an operand to generate a function which returns the value of the
1684 // constant when queried. MEMORY_INTER causes an operand to generate
1685 // four functions which return the Base Register, the Index Register,
1686 // the Scale Value, and the Offset Value of the operand when queried.
1687 // COND_INTER causes an operand to generate six functions which return
1688 // the encoding code (ie - encoding bits for the instruction)
1689 // associated with each basic boolean condition for a conditional
1690 // instruction.
1691 //
1692 // Instructions specify two basic values for encoding. Again, a
1693 // function is available to check if the constant displacement is an
1694 // oop. They use the ins_encode keyword to specify their encoding
1695 // classes (which must be a sequence of enc_class names, and their
1696 // parameters, specified in the encoding block), and they use the
1697 // opcode keyword to specify, in order, their primary, secondary, and
1698 // tertiary opcode. Only the opcode sections which a particular
1699 // instruction needs for encoding need to be specified.
1700 encode %{
1701 // Build emit functions for each basic byte or larger field in the
1702 // intel encoding scheme (opcode, rm, sib, immediate), and call them
1703 // from C++ code in the enc_class source block. Emit functions will
1704 // live in the main source block for now. In future, we can
1705 // generalize this by adding a syntax that specifies the sizes of
1706 // fields in an order, so that the adlc can build the emit functions
1707 // automagically
1709 // Emit primary opcode
1710 enc_class OpcP
1711 %{
1712 emit_opcode(cbuf, $primary);
1713 %}
1715 // Emit secondary opcode
1716 enc_class OpcS
1717 %{
1718 emit_opcode(cbuf, $secondary);
1719 %}
1721 // Emit tertiary opcode
1722 enc_class OpcT
1723 %{
1724 emit_opcode(cbuf, $tertiary);
1725 %}
1727 // Emit opcode directly
1728 enc_class Opcode(immI d8)
1729 %{
1730 emit_opcode(cbuf, $d8$$constant);
1731 %}
1733 // Emit size prefix
1734 enc_class SizePrefix
1735 %{
1736 emit_opcode(cbuf, 0x66);
1737 %}
1739 enc_class reg(rRegI reg)
1740 %{
1741 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7);
1742 %}
1744 enc_class reg_reg(rRegI dst, rRegI src)
1745 %{
1746 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1747 %}
1749 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src)
1750 %{
1751 emit_opcode(cbuf, $opcode$$constant);
1752 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7);
1753 %}
1755 enc_class cdql_enc(no_rax_rdx_RegI div)
1756 %{
1757 // Full implementation of Java idiv and irem; checks for
1758 // special case as described in JVM spec., p.243 & p.271.
1759 //
1760 // normal case special case
1761 //
1762 // input : rax: dividend min_int
1763 // reg: divisor -1
1764 //
1765 // output: rax: quotient (= rax idiv reg) min_int
1766 // rdx: remainder (= rax irem reg) 0
1767 //
1768 // Code sequnce:
1769 //
1770 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax
1771 // 5: 75 07/08 jne e <normal>
1772 // 7: 33 d2 xor %edx,%edx
1773 // [div >= 8 -> offset + 1]
1774 // [REX_B]
1775 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div
1776 // c: 74 03/04 je 11 <done>
1777 // 000000000000000e <normal>:
1778 // e: 99 cltd
1779 // [div >= 8 -> offset + 1]
1780 // [REX_B]
1781 // f: f7 f9 idiv $div
1782 // 0000000000000011 <done>:
1784 // cmp $0x80000000,%eax
1785 emit_opcode(cbuf, 0x3d);
1786 emit_d8(cbuf, 0x00);
1787 emit_d8(cbuf, 0x00);
1788 emit_d8(cbuf, 0x00);
1789 emit_d8(cbuf, 0x80);
1791 // jne e <normal>
1792 emit_opcode(cbuf, 0x75);
1793 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08);
1795 // xor %edx,%edx
1796 emit_opcode(cbuf, 0x33);
1797 emit_d8(cbuf, 0xD2);
1799 // cmp $0xffffffffffffffff,%ecx
1800 if ($div$$reg >= 8) {
1801 emit_opcode(cbuf, Assembler::REX_B);
1802 }
1803 emit_opcode(cbuf, 0x83);
1804 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
1805 emit_d8(cbuf, 0xFF);
1807 // je 11 <done>
1808 emit_opcode(cbuf, 0x74);
1809 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04);
1811 // <normal>
1812 // cltd
1813 emit_opcode(cbuf, 0x99);
1815 // idivl (note: must be emitted by the user of this rule)
1816 // <done>
1817 %}
1819 enc_class cdqq_enc(no_rax_rdx_RegL div)
1820 %{
1821 // Full implementation of Java ldiv and lrem; checks for
1822 // special case as described in JVM spec., p.243 & p.271.
1823 //
1824 // normal case special case
1825 //
1826 // input : rax: dividend min_long
1827 // reg: divisor -1
1828 //
1829 // output: rax: quotient (= rax idiv reg) min_long
1830 // rdx: remainder (= rax irem reg) 0
1831 //
1832 // Code sequnce:
1833 //
1834 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx
1835 // 7: 00 00 80
1836 // a: 48 39 d0 cmp %rdx,%rax
1837 // d: 75 08 jne 17 <normal>
1838 // f: 33 d2 xor %edx,%edx
1839 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div
1840 // 15: 74 05 je 1c <done>
1841 // 0000000000000017 <normal>:
1842 // 17: 48 99 cqto
1843 // 19: 48 f7 f9 idiv $div
1844 // 000000000000001c <done>:
1846 // mov $0x8000000000000000,%rdx
1847 emit_opcode(cbuf, Assembler::REX_W);
1848 emit_opcode(cbuf, 0xBA);
1849 emit_d8(cbuf, 0x00);
1850 emit_d8(cbuf, 0x00);
1851 emit_d8(cbuf, 0x00);
1852 emit_d8(cbuf, 0x00);
1853 emit_d8(cbuf, 0x00);
1854 emit_d8(cbuf, 0x00);
1855 emit_d8(cbuf, 0x00);
1856 emit_d8(cbuf, 0x80);
1858 // cmp %rdx,%rax
1859 emit_opcode(cbuf, Assembler::REX_W);
1860 emit_opcode(cbuf, 0x39);
1861 emit_d8(cbuf, 0xD0);
1863 // jne 17 <normal>
1864 emit_opcode(cbuf, 0x75);
1865 emit_d8(cbuf, 0x08);
1867 // xor %edx,%edx
1868 emit_opcode(cbuf, 0x33);
1869 emit_d8(cbuf, 0xD2);
1871 // cmp $0xffffffffffffffff,$div
1872 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB);
1873 emit_opcode(cbuf, 0x83);
1874 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7);
1875 emit_d8(cbuf, 0xFF);
1877 // je 1e <done>
1878 emit_opcode(cbuf, 0x74);
1879 emit_d8(cbuf, 0x05);
1881 // <normal>
1882 // cqto
1883 emit_opcode(cbuf, Assembler::REX_W);
1884 emit_opcode(cbuf, 0x99);
1886 // idivq (note: must be emitted by the user of this rule)
1887 // <done>
1888 %}
1890 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
1891 enc_class OpcSE(immI imm)
1892 %{
1893 // Emit primary opcode and set sign-extend bit
1894 // Check for 8-bit immediate, and set sign extend bit in opcode
1895 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1896 emit_opcode(cbuf, $primary | 0x02);
1897 } else {
1898 // 32-bit immediate
1899 emit_opcode(cbuf, $primary);
1900 }
1901 %}
1903 enc_class OpcSErm(rRegI dst, immI imm)
1904 %{
1905 // OpcSEr/m
1906 int dstenc = $dst$$reg;
1907 if (dstenc >= 8) {
1908 emit_opcode(cbuf, Assembler::REX_B);
1909 dstenc -= 8;
1910 }
1911 // Emit primary opcode and set sign-extend bit
1912 // Check for 8-bit immediate, and set sign extend bit in opcode
1913 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1914 emit_opcode(cbuf, $primary | 0x02);
1915 } else {
1916 // 32-bit immediate
1917 emit_opcode(cbuf, $primary);
1918 }
1919 // Emit r/m byte with secondary opcode, after primary opcode.
1920 emit_rm(cbuf, 0x3, $secondary, dstenc);
1921 %}
1923 enc_class OpcSErm_wide(rRegL dst, immI imm)
1924 %{
1925 // OpcSEr/m
1926 int dstenc = $dst$$reg;
1927 if (dstenc < 8) {
1928 emit_opcode(cbuf, Assembler::REX_W);
1929 } else {
1930 emit_opcode(cbuf, Assembler::REX_WB);
1931 dstenc -= 8;
1932 }
1933 // Emit primary opcode and set sign-extend bit
1934 // Check for 8-bit immediate, and set sign extend bit in opcode
1935 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1936 emit_opcode(cbuf, $primary | 0x02);
1937 } else {
1938 // 32-bit immediate
1939 emit_opcode(cbuf, $primary);
1940 }
1941 // Emit r/m byte with secondary opcode, after primary opcode.
1942 emit_rm(cbuf, 0x3, $secondary, dstenc);
1943 %}
1945 enc_class Con8or32(immI imm)
1946 %{
1947 // Check for 8-bit immediate, and set sign extend bit in opcode
1948 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) {
1949 $$$emit8$imm$$constant;
1950 } else {
1951 // 32-bit immediate
1952 $$$emit32$imm$$constant;
1953 }
1954 %}
1956 enc_class opc2_reg(rRegI dst)
1957 %{
1958 // BSWAP
1959 emit_cc(cbuf, $secondary, $dst$$reg);
1960 %}
1962 enc_class opc3_reg(rRegI dst)
1963 %{
1964 // BSWAP
1965 emit_cc(cbuf, $tertiary, $dst$$reg);
1966 %}
1968 enc_class reg_opc(rRegI div)
1969 %{
1970 // INC, DEC, IDIV, IMOD, JMP indirect, ...
1971 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7);
1972 %}
1974 enc_class enc_cmov(cmpOp cop)
1975 %{
1976 // CMOV
1977 $$$emit8$primary;
1978 emit_cc(cbuf, $secondary, $cop$$cmpcode);
1979 %}
1981 enc_class enc_PartialSubtypeCheck()
1982 %{
1983 Register Rrdi = as_Register(RDI_enc); // result register
1984 Register Rrax = as_Register(RAX_enc); // super class
1985 Register Rrcx = as_Register(RCX_enc); // killed
1986 Register Rrsi = as_Register(RSI_enc); // sub class
1987 Label miss;
1988 const bool set_cond_codes = true;
1990 MacroAssembler _masm(&cbuf);
1991 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi,
1992 NULL, &miss,
1993 /*set_cond_codes:*/ true);
1994 if ($primary) {
1995 __ xorptr(Rrdi, Rrdi);
1996 }
1997 __ bind(miss);
1998 %}
2000 enc_class clear_avx %{
2001 debug_only(int off0 = cbuf.insts_size());
2002 if (ra_->C->max_vector_size() > 16) {
2003 // Clear upper bits of YMM registers when current compiled code uses
2004 // wide vectors to avoid AVX <-> SSE transition penalty during call.
2005 MacroAssembler _masm(&cbuf);
2006 __ vzeroupper();
2007 }
2008 debug_only(int off1 = cbuf.insts_size());
2009 assert(off1 - off0 == clear_avx_size(), "correct size prediction");
2010 %}
2012 enc_class Java_To_Runtime(method meth) %{
2013 // No relocation needed
2014 MacroAssembler _masm(&cbuf);
2015 __ mov64(r10, (int64_t) $meth$$method);
2016 __ call(r10);
2017 %}
2019 enc_class Java_To_Interpreter(method meth)
2020 %{
2021 // CALL Java_To_Interpreter
2022 // This is the instruction starting address for relocation info.
2023 cbuf.set_insts_mark();
2024 $$$emit8$primary;
2025 // CALL directly to the runtime
2026 emit_d32_reloc(cbuf,
2027 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2028 runtime_call_Relocation::spec(),
2029 RELOC_DISP32);
2030 %}
2032 enc_class Java_Static_Call(method meth)
2033 %{
2034 // JAVA STATIC CALL
2035 // CALL to fixup routine. Fixup routine uses ScopeDesc info to
2036 // determine who we intended to call.
2037 cbuf.set_insts_mark();
2038 $$$emit8$primary;
2040 if (!_method) {
2041 emit_d32_reloc(cbuf,
2042 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2043 runtime_call_Relocation::spec(),
2044 RELOC_DISP32);
2045 } else if (_optimized_virtual) {
2046 emit_d32_reloc(cbuf,
2047 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2048 opt_virtual_call_Relocation::spec(),
2049 RELOC_DISP32);
2050 } else {
2051 emit_d32_reloc(cbuf,
2052 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4),
2053 static_call_Relocation::spec(),
2054 RELOC_DISP32);
2055 }
2056 if (_method) {
2057 // Emit stub for static call.
2058 CompiledStaticCall::emit_to_interp_stub(cbuf);
2059 }
2060 %}
2062 enc_class Java_Dynamic_Call(method meth) %{
2063 MacroAssembler _masm(&cbuf);
2064 __ ic_call((address)$meth$$method);
2065 %}
2067 enc_class Java_Compiled_Call(method meth)
2068 %{
2069 // JAVA COMPILED CALL
2070 int disp = in_bytes(Method:: from_compiled_offset());
2072 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!!
2073 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small");
2075 // callq *disp(%rax)
2076 cbuf.set_insts_mark();
2077 $$$emit8$primary;
2078 if (disp < 0x80) {
2079 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte
2080 emit_d8(cbuf, disp); // Displacement
2081 } else {
2082 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte
2083 emit_d32(cbuf, disp); // Displacement
2084 }
2085 %}
2087 enc_class reg_opc_imm(rRegI dst, immI8 shift)
2088 %{
2089 // SAL, SAR, SHR
2090 int dstenc = $dst$$reg;
2091 if (dstenc >= 8) {
2092 emit_opcode(cbuf, Assembler::REX_B);
2093 dstenc -= 8;
2094 }
2095 $$$emit8$primary;
2096 emit_rm(cbuf, 0x3, $secondary, dstenc);
2097 $$$emit8$shift$$constant;
2098 %}
2100 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift)
2101 %{
2102 // SAL, SAR, SHR
2103 int dstenc = $dst$$reg;
2104 if (dstenc < 8) {
2105 emit_opcode(cbuf, Assembler::REX_W);
2106 } else {
2107 emit_opcode(cbuf, Assembler::REX_WB);
2108 dstenc -= 8;
2109 }
2110 $$$emit8$primary;
2111 emit_rm(cbuf, 0x3, $secondary, dstenc);
2112 $$$emit8$shift$$constant;
2113 %}
2115 enc_class load_immI(rRegI dst, immI src)
2116 %{
2117 int dstenc = $dst$$reg;
2118 if (dstenc >= 8) {
2119 emit_opcode(cbuf, Assembler::REX_B);
2120 dstenc -= 8;
2121 }
2122 emit_opcode(cbuf, 0xB8 | dstenc);
2123 $$$emit32$src$$constant;
2124 %}
2126 enc_class load_immL(rRegL dst, immL src)
2127 %{
2128 int dstenc = $dst$$reg;
2129 if (dstenc < 8) {
2130 emit_opcode(cbuf, Assembler::REX_W);
2131 } else {
2132 emit_opcode(cbuf, Assembler::REX_WB);
2133 dstenc -= 8;
2134 }
2135 emit_opcode(cbuf, 0xB8 | dstenc);
2136 emit_d64(cbuf, $src$$constant);
2137 %}
2139 enc_class load_immUL32(rRegL dst, immUL32 src)
2140 %{
2141 // same as load_immI, but this time we care about zeroes in the high word
2142 int dstenc = $dst$$reg;
2143 if (dstenc >= 8) {
2144 emit_opcode(cbuf, Assembler::REX_B);
2145 dstenc -= 8;
2146 }
2147 emit_opcode(cbuf, 0xB8 | dstenc);
2148 $$$emit32$src$$constant;
2149 %}
2151 enc_class load_immL32(rRegL dst, immL32 src)
2152 %{
2153 int dstenc = $dst$$reg;
2154 if (dstenc < 8) {
2155 emit_opcode(cbuf, Assembler::REX_W);
2156 } else {
2157 emit_opcode(cbuf, Assembler::REX_WB);
2158 dstenc -= 8;
2159 }
2160 emit_opcode(cbuf, 0xC7);
2161 emit_rm(cbuf, 0x03, 0x00, dstenc);
2162 $$$emit32$src$$constant;
2163 %}
2165 enc_class load_immP31(rRegP dst, immP32 src)
2166 %{
2167 // same as load_immI, but this time we care about zeroes in the high word
2168 int dstenc = $dst$$reg;
2169 if (dstenc >= 8) {
2170 emit_opcode(cbuf, Assembler::REX_B);
2171 dstenc -= 8;
2172 }
2173 emit_opcode(cbuf, 0xB8 | dstenc);
2174 $$$emit32$src$$constant;
2175 %}
2177 enc_class load_immP(rRegP dst, immP src)
2178 %{
2179 int dstenc = $dst$$reg;
2180 if (dstenc < 8) {
2181 emit_opcode(cbuf, Assembler::REX_W);
2182 } else {
2183 emit_opcode(cbuf, Assembler::REX_WB);
2184 dstenc -= 8;
2185 }
2186 emit_opcode(cbuf, 0xB8 | dstenc);
2187 // This next line should be generated from ADLC
2188 if ($src->constant_reloc() != relocInfo::none) {
2189 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64);
2190 } else {
2191 emit_d64(cbuf, $src$$constant);
2192 }
2193 %}
2195 enc_class Con32(immI src)
2196 %{
2197 // Output immediate
2198 $$$emit32$src$$constant;
2199 %}
2201 enc_class Con32F_as_bits(immF src)
2202 %{
2203 // Output Float immediate bits
2204 jfloat jf = $src$$constant;
2205 jint jf_as_bits = jint_cast(jf);
2206 emit_d32(cbuf, jf_as_bits);
2207 %}
2209 enc_class Con16(immI src)
2210 %{
2211 // Output immediate
2212 $$$emit16$src$$constant;
2213 %}
2215 // How is this different from Con32??? XXX
2216 enc_class Con_d32(immI src)
2217 %{
2218 emit_d32(cbuf,$src$$constant);
2219 %}
2221 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI)
2222 // Output immediate memory reference
2223 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2224 emit_d32(cbuf, 0x00);
2225 %}
2227 enc_class lock_prefix()
2228 %{
2229 if (os::is_MP()) {
2230 emit_opcode(cbuf, 0xF0); // lock
2231 }
2232 %}
2234 enc_class REX_mem(memory mem)
2235 %{
2236 if ($mem$$base >= 8) {
2237 if ($mem$$index < 8) {
2238 emit_opcode(cbuf, Assembler::REX_B);
2239 } else {
2240 emit_opcode(cbuf, Assembler::REX_XB);
2241 }
2242 } else {
2243 if ($mem$$index >= 8) {
2244 emit_opcode(cbuf, Assembler::REX_X);
2245 }
2246 }
2247 %}
2249 enc_class REX_mem_wide(memory mem)
2250 %{
2251 if ($mem$$base >= 8) {
2252 if ($mem$$index < 8) {
2253 emit_opcode(cbuf, Assembler::REX_WB);
2254 } else {
2255 emit_opcode(cbuf, Assembler::REX_WXB);
2256 }
2257 } else {
2258 if ($mem$$index < 8) {
2259 emit_opcode(cbuf, Assembler::REX_W);
2260 } else {
2261 emit_opcode(cbuf, Assembler::REX_WX);
2262 }
2263 }
2264 %}
2266 // for byte regs
2267 enc_class REX_breg(rRegI reg)
2268 %{
2269 if ($reg$$reg >= 4) {
2270 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2271 }
2272 %}
2274 // for byte regs
2275 enc_class REX_reg_breg(rRegI dst, rRegI src)
2276 %{
2277 if ($dst$$reg < 8) {
2278 if ($src$$reg >= 4) {
2279 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B);
2280 }
2281 } else {
2282 if ($src$$reg < 8) {
2283 emit_opcode(cbuf, Assembler::REX_R);
2284 } else {
2285 emit_opcode(cbuf, Assembler::REX_RB);
2286 }
2287 }
2288 %}
2290 // for byte regs
2291 enc_class REX_breg_mem(rRegI reg, memory mem)
2292 %{
2293 if ($reg$$reg < 8) {
2294 if ($mem$$base < 8) {
2295 if ($mem$$index >= 8) {
2296 emit_opcode(cbuf, Assembler::REX_X);
2297 } else if ($reg$$reg >= 4) {
2298 emit_opcode(cbuf, Assembler::REX);
2299 }
2300 } else {
2301 if ($mem$$index < 8) {
2302 emit_opcode(cbuf, Assembler::REX_B);
2303 } else {
2304 emit_opcode(cbuf, Assembler::REX_XB);
2305 }
2306 }
2307 } else {
2308 if ($mem$$base < 8) {
2309 if ($mem$$index < 8) {
2310 emit_opcode(cbuf, Assembler::REX_R);
2311 } else {
2312 emit_opcode(cbuf, Assembler::REX_RX);
2313 }
2314 } else {
2315 if ($mem$$index < 8) {
2316 emit_opcode(cbuf, Assembler::REX_RB);
2317 } else {
2318 emit_opcode(cbuf, Assembler::REX_RXB);
2319 }
2320 }
2321 }
2322 %}
2324 enc_class REX_reg(rRegI reg)
2325 %{
2326 if ($reg$$reg >= 8) {
2327 emit_opcode(cbuf, Assembler::REX_B);
2328 }
2329 %}
2331 enc_class REX_reg_wide(rRegI reg)
2332 %{
2333 if ($reg$$reg < 8) {
2334 emit_opcode(cbuf, Assembler::REX_W);
2335 } else {
2336 emit_opcode(cbuf, Assembler::REX_WB);
2337 }
2338 %}
2340 enc_class REX_reg_reg(rRegI dst, rRegI src)
2341 %{
2342 if ($dst$$reg < 8) {
2343 if ($src$$reg >= 8) {
2344 emit_opcode(cbuf, Assembler::REX_B);
2345 }
2346 } else {
2347 if ($src$$reg < 8) {
2348 emit_opcode(cbuf, Assembler::REX_R);
2349 } else {
2350 emit_opcode(cbuf, Assembler::REX_RB);
2351 }
2352 }
2353 %}
2355 enc_class REX_reg_reg_wide(rRegI dst, rRegI src)
2356 %{
2357 if ($dst$$reg < 8) {
2358 if ($src$$reg < 8) {
2359 emit_opcode(cbuf, Assembler::REX_W);
2360 } else {
2361 emit_opcode(cbuf, Assembler::REX_WB);
2362 }
2363 } else {
2364 if ($src$$reg < 8) {
2365 emit_opcode(cbuf, Assembler::REX_WR);
2366 } else {
2367 emit_opcode(cbuf, Assembler::REX_WRB);
2368 }
2369 }
2370 %}
2372 enc_class REX_reg_mem(rRegI reg, memory mem)
2373 %{
2374 if ($reg$$reg < 8) {
2375 if ($mem$$base < 8) {
2376 if ($mem$$index >= 8) {
2377 emit_opcode(cbuf, Assembler::REX_X);
2378 }
2379 } else {
2380 if ($mem$$index < 8) {
2381 emit_opcode(cbuf, Assembler::REX_B);
2382 } else {
2383 emit_opcode(cbuf, Assembler::REX_XB);
2384 }
2385 }
2386 } else {
2387 if ($mem$$base < 8) {
2388 if ($mem$$index < 8) {
2389 emit_opcode(cbuf, Assembler::REX_R);
2390 } else {
2391 emit_opcode(cbuf, Assembler::REX_RX);
2392 }
2393 } else {
2394 if ($mem$$index < 8) {
2395 emit_opcode(cbuf, Assembler::REX_RB);
2396 } else {
2397 emit_opcode(cbuf, Assembler::REX_RXB);
2398 }
2399 }
2400 }
2401 %}
2403 enc_class REX_reg_mem_wide(rRegL reg, memory mem)
2404 %{
2405 if ($reg$$reg < 8) {
2406 if ($mem$$base < 8) {
2407 if ($mem$$index < 8) {
2408 emit_opcode(cbuf, Assembler::REX_W);
2409 } else {
2410 emit_opcode(cbuf, Assembler::REX_WX);
2411 }
2412 } else {
2413 if ($mem$$index < 8) {
2414 emit_opcode(cbuf, Assembler::REX_WB);
2415 } else {
2416 emit_opcode(cbuf, Assembler::REX_WXB);
2417 }
2418 }
2419 } else {
2420 if ($mem$$base < 8) {
2421 if ($mem$$index < 8) {
2422 emit_opcode(cbuf, Assembler::REX_WR);
2423 } else {
2424 emit_opcode(cbuf, Assembler::REX_WRX);
2425 }
2426 } else {
2427 if ($mem$$index < 8) {
2428 emit_opcode(cbuf, Assembler::REX_WRB);
2429 } else {
2430 emit_opcode(cbuf, Assembler::REX_WRXB);
2431 }
2432 }
2433 }
2434 %}
2436 enc_class reg_mem(rRegI ereg, memory mem)
2437 %{
2438 // High registers handle in encode_RegMem
2439 int reg = $ereg$$reg;
2440 int base = $mem$$base;
2441 int index = $mem$$index;
2442 int scale = $mem$$scale;
2443 int disp = $mem$$disp;
2444 relocInfo::relocType disp_reloc = $mem->disp_reloc();
2446 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc);
2447 %}
2449 enc_class RM_opc_mem(immI rm_opcode, memory mem)
2450 %{
2451 int rm_byte_opcode = $rm_opcode$$constant;
2453 // High registers handle in encode_RegMem
2454 int base = $mem$$base;
2455 int index = $mem$$index;
2456 int scale = $mem$$scale;
2457 int displace = $mem$$disp;
2459 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when
2460 // working with static
2461 // globals
2462 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace,
2463 disp_reloc);
2464 %}
2466 enc_class reg_lea(rRegI dst, rRegI src0, immI src1)
2467 %{
2468 int reg_encoding = $dst$$reg;
2469 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
2470 int index = 0x04; // 0x04 indicates no index
2471 int scale = 0x00; // 0x00 indicates no scale
2472 int displace = $src1$$constant; // 0x00 indicates no displacement
2473 relocInfo::relocType disp_reloc = relocInfo::none;
2474 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace,
2475 disp_reloc);
2476 %}
2478 enc_class neg_reg(rRegI dst)
2479 %{
2480 int dstenc = $dst$$reg;
2481 if (dstenc >= 8) {
2482 emit_opcode(cbuf, Assembler::REX_B);
2483 dstenc -= 8;
2484 }
2485 // NEG $dst
2486 emit_opcode(cbuf, 0xF7);
2487 emit_rm(cbuf, 0x3, 0x03, dstenc);
2488 %}
2490 enc_class neg_reg_wide(rRegI dst)
2491 %{
2492 int dstenc = $dst$$reg;
2493 if (dstenc < 8) {
2494 emit_opcode(cbuf, Assembler::REX_W);
2495 } else {
2496 emit_opcode(cbuf, Assembler::REX_WB);
2497 dstenc -= 8;
2498 }
2499 // NEG $dst
2500 emit_opcode(cbuf, 0xF7);
2501 emit_rm(cbuf, 0x3, 0x03, dstenc);
2502 %}
2504 enc_class setLT_reg(rRegI dst)
2505 %{
2506 int dstenc = $dst$$reg;
2507 if (dstenc >= 8) {
2508 emit_opcode(cbuf, Assembler::REX_B);
2509 dstenc -= 8;
2510 } else if (dstenc >= 4) {
2511 emit_opcode(cbuf, Assembler::REX);
2512 }
2513 // SETLT $dst
2514 emit_opcode(cbuf, 0x0F);
2515 emit_opcode(cbuf, 0x9C);
2516 emit_rm(cbuf, 0x3, 0x0, dstenc);
2517 %}
2519 enc_class setNZ_reg(rRegI dst)
2520 %{
2521 int dstenc = $dst$$reg;
2522 if (dstenc >= 8) {
2523 emit_opcode(cbuf, Assembler::REX_B);
2524 dstenc -= 8;
2525 } else if (dstenc >= 4) {
2526 emit_opcode(cbuf, Assembler::REX);
2527 }
2528 // SETNZ $dst
2529 emit_opcode(cbuf, 0x0F);
2530 emit_opcode(cbuf, 0x95);
2531 emit_rm(cbuf, 0x3, 0x0, dstenc);
2532 %}
2535 // Compare the lonogs and set -1, 0, or 1 into dst
2536 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst)
2537 %{
2538 int src1enc = $src1$$reg;
2539 int src2enc = $src2$$reg;
2540 int dstenc = $dst$$reg;
2542 // cmpq $src1, $src2
2543 if (src1enc < 8) {
2544 if (src2enc < 8) {
2545 emit_opcode(cbuf, Assembler::REX_W);
2546 } else {
2547 emit_opcode(cbuf, Assembler::REX_WB);
2548 }
2549 } else {
2550 if (src2enc < 8) {
2551 emit_opcode(cbuf, Assembler::REX_WR);
2552 } else {
2553 emit_opcode(cbuf, Assembler::REX_WRB);
2554 }
2555 }
2556 emit_opcode(cbuf, 0x3B);
2557 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7);
2559 // movl $dst, -1
2560 if (dstenc >= 8) {
2561 emit_opcode(cbuf, Assembler::REX_B);
2562 }
2563 emit_opcode(cbuf, 0xB8 | (dstenc & 7));
2564 emit_d32(cbuf, -1);
2566 // jl,s done
2567 emit_opcode(cbuf, 0x7C);
2568 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08);
2570 // setne $dst
2571 if (dstenc >= 4) {
2572 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B);
2573 }
2574 emit_opcode(cbuf, 0x0F);
2575 emit_opcode(cbuf, 0x95);
2576 emit_opcode(cbuf, 0xC0 | (dstenc & 7));
2578 // movzbl $dst, $dst
2579 if (dstenc >= 4) {
2580 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB);
2581 }
2582 emit_opcode(cbuf, 0x0F);
2583 emit_opcode(cbuf, 0xB6);
2584 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7);
2585 %}
2587 enc_class Push_ResultXD(regD dst) %{
2588 MacroAssembler _masm(&cbuf);
2589 __ fstp_d(Address(rsp, 0));
2590 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
2591 __ addptr(rsp, 8);
2592 %}
2594 enc_class Push_SrcXD(regD src) %{
2595 MacroAssembler _masm(&cbuf);
2596 __ subptr(rsp, 8);
2597 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
2598 __ fld_d(Address(rsp, 0));
2599 %}
2602 // obj: object to lock
2603 // box: box address (header location) -- killed
2604 // tmp: rax -- killed
2605 // scr: rbx -- killed
2606 //
2607 // What follows is a direct transliteration of fast_lock() and fast_unlock()
2608 // from i486.ad. See that file for comments.
2609 // TODO: where possible switch from movq (r, 0) to movl(r,0) and
2610 // use the shorter encoding. (Movl clears the high-order 32-bits).
2613 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr)
2614 %{
2615 Register objReg = as_Register((int)$obj$$reg);
2616 Register boxReg = as_Register((int)$box$$reg);
2617 Register tmpReg = as_Register($tmp$$reg);
2618 Register scrReg = as_Register($scr$$reg);
2619 MacroAssembler masm(&cbuf);
2621 // Verify uniqueness of register assignments -- necessary but not sufficient
2622 assert (objReg != boxReg && objReg != tmpReg &&
2623 objReg != scrReg && tmpReg != scrReg, "invariant") ;
2625 if (_counters != NULL) {
2626 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr()));
2627 }
2628 if (EmitSync & 1) {
2629 // Without cast to int32_t a movptr will destroy r10 which is typically obj
2630 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
2631 masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
2632 } else
2633 if (EmitSync & 2) {
2634 Label DONE_LABEL;
2635 if (UseBiasedLocking) {
2636 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument.
2637 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters);
2638 }
2639 // QQQ was movl...
2640 masm.movptr(tmpReg, 0x1);
2641 masm.orptr(tmpReg, Address(objReg, 0));
2642 masm.movptr(Address(boxReg, 0), tmpReg);
2643 if (os::is_MP()) {
2644 masm.lock();
2645 }
2646 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
2647 masm.jcc(Assembler::equal, DONE_LABEL);
2649 // Recursive locking
2650 masm.subptr(tmpReg, rsp);
2651 masm.andptr(tmpReg, 7 - os::vm_page_size());
2652 masm.movptr(Address(boxReg, 0), tmpReg);
2654 masm.bind(DONE_LABEL);
2655 masm.nop(); // avoid branch to branch
2656 } else {
2657 Label DONE_LABEL, IsInflated, Egress;
2659 masm.movptr(tmpReg, Address(objReg, 0)) ;
2660 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased
2661 masm.jcc (Assembler::notZero, IsInflated) ;
2663 // it's stack-locked, biased or neutral
2664 // TODO: optimize markword triage order to reduce the number of
2665 // conditional branches in the most common cases.
2666 // Beware -- there's a subtle invariant that fetch of the markword
2667 // at [FETCH], below, will never observe a biased encoding (*101b).
2668 // If this invariant is not held we'll suffer exclusion (safety) failure.
2670 if (UseBiasedLocking && !UseOptoBiasInlining) {
2671 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
2672 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH]
2673 }
2675 // was q will it destroy high?
2676 masm.orl (tmpReg, 1) ;
2677 masm.movptr(Address(boxReg, 0), tmpReg) ;
2678 if (os::is_MP()) { masm.lock(); }
2679 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
2680 if (_counters != NULL) {
2681 masm.cond_inc32(Assembler::equal,
2682 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
2683 }
2684 masm.jcc (Assembler::equal, DONE_LABEL);
2686 // Recursive locking
2687 masm.subptr(tmpReg, rsp);
2688 masm.andptr(tmpReg, 7 - os::vm_page_size());
2689 masm.movptr(Address(boxReg, 0), tmpReg);
2690 if (_counters != NULL) {
2691 masm.cond_inc32(Assembler::equal,
2692 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
2693 }
2694 masm.jmp (DONE_LABEL) ;
2696 masm.bind (IsInflated) ;
2697 // It's inflated
2699 // TODO: someday avoid the ST-before-CAS penalty by
2700 // relocating (deferring) the following ST.
2701 // We should also think about trying a CAS without having
2702 // fetched _owner. If the CAS is successful we may
2703 // avoid an RTO->RTS upgrade on the $line.
2704 // Without cast to int32_t a movptr will destroy r10 which is typically obj
2705 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
2707 masm.mov (boxReg, tmpReg) ;
2708 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
2709 masm.testptr(tmpReg, tmpReg) ;
2710 masm.jcc (Assembler::notZero, DONE_LABEL) ;
2712 // It's inflated and appears unlocked
2713 if (os::is_MP()) { masm.lock(); }
2714 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
2715 // Intentional fall-through into DONE_LABEL ...
2717 masm.bind (DONE_LABEL) ;
2718 masm.nop () ; // avoid jmp to jmp
2719 }
2720 %}
2722 // obj: object to unlock
2723 // box: box address (displaced header location), killed
2724 // RBX: killed tmp; cannot be obj nor box
2725 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp)
2726 %{
2728 Register objReg = as_Register($obj$$reg);
2729 Register boxReg = as_Register($box$$reg);
2730 Register tmpReg = as_Register($tmp$$reg);
2731 MacroAssembler masm(&cbuf);
2733 if (EmitSync & 4) {
2734 masm.cmpptr(rsp, 0) ;
2735 } else
2736 if (EmitSync & 8) {
2737 Label DONE_LABEL;
2738 if (UseBiasedLocking) {
2739 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
2740 }
2742 // Check whether the displaced header is 0
2743 //(=> recursive unlock)
2744 masm.movptr(tmpReg, Address(boxReg, 0));
2745 masm.testptr(tmpReg, tmpReg);
2746 masm.jcc(Assembler::zero, DONE_LABEL);
2748 // If not recursive lock, reset the header to displaced header
2749 if (os::is_MP()) {
2750 masm.lock();
2751 }
2752 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
2753 masm.bind(DONE_LABEL);
2754 masm.nop(); // avoid branch to branch
2755 } else {
2756 Label DONE_LABEL, Stacked, CheckSucc ;
2758 if (UseBiasedLocking && !UseOptoBiasInlining) {
2759 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
2760 }
2762 masm.movptr(tmpReg, Address(objReg, 0)) ;
2763 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
2764 masm.jcc (Assembler::zero, DONE_LABEL) ;
2765 masm.testl (tmpReg, 0x02) ;
2766 masm.jcc (Assembler::zero, Stacked) ;
2768 // It's inflated
2769 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
2770 masm.xorptr(boxReg, r15_thread) ;
2771 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
2772 masm.jcc (Assembler::notZero, DONE_LABEL) ;
2773 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
2774 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
2775 masm.jcc (Assembler::notZero, CheckSucc) ;
2776 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
2777 masm.jmp (DONE_LABEL) ;
2779 if ((EmitSync & 65536) == 0) {
2780 Label LSuccess, LGoSlowPath ;
2781 masm.bind (CheckSucc) ;
2782 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
2783 masm.jcc (Assembler::zero, LGoSlowPath) ;
2785 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the
2786 // the explicit ST;MEMBAR combination, but masm doesn't currently support
2787 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc
2788 // are all faster when the write buffer is populated.
2789 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
2790 if (os::is_MP()) {
2791 masm.lock () ; masm.addl (Address(rsp, 0), 0) ;
2792 }
2793 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
2794 masm.jcc (Assembler::notZero, LSuccess) ;
2796 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX
2797 if (os::is_MP()) { masm.lock(); }
2798 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2));
2799 masm.jcc (Assembler::notEqual, LSuccess) ;
2800 // Intentional fall-through into slow-path
2802 masm.bind (LGoSlowPath) ;
2803 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure
2804 masm.jmp (DONE_LABEL) ;
2806 masm.bind (LSuccess) ;
2807 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success
2808 masm.jmp (DONE_LABEL) ;
2809 }
2811 masm.bind (Stacked) ;
2812 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch
2813 if (os::is_MP()) { masm.lock(); }
2814 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
2816 if (EmitSync & 65536) {
2817 masm.bind (CheckSucc) ;
2818 }
2819 masm.bind(DONE_LABEL);
2820 if (EmitSync & 32768) {
2821 masm.nop(); // avoid branch to branch
2822 }
2823 }
2824 %}
2827 enc_class enc_rethrow()
2828 %{
2829 cbuf.set_insts_mark();
2830 emit_opcode(cbuf, 0xE9); // jmp entry
2831 emit_d32_reloc(cbuf,
2832 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4),
2833 runtime_call_Relocation::spec(),
2834 RELOC_DISP32);
2835 %}
2837 %}
2841 //----------FRAME--------------------------------------------------------------
2842 // Definition of frame structure and management information.
2843 //
2844 // S T A C K L A Y O U T Allocators stack-slot number
2845 // | (to get allocators register number
2846 // G Owned by | | v add OptoReg::stack0())
2847 // r CALLER | |
2848 // o | +--------+ pad to even-align allocators stack-slot
2849 // w V | pad0 | numbers; owned by CALLER
2850 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned
2851 // h ^ | in | 5
2852 // | | args | 4 Holes in incoming args owned by SELF
2853 // | | | | 3
2854 // | | +--------+
2855 // V | | old out| Empty on Intel, window on Sparc
2856 // | old |preserve| Must be even aligned.
2857 // | SP-+--------+----> Matcher::_old_SP, even aligned
2858 // | | in | 3 area for Intel ret address
2859 // Owned by |preserve| Empty on Sparc.
2860 // SELF +--------+
2861 // | | pad2 | 2 pad to align old SP
2862 // | +--------+ 1
2863 // | | locks | 0
2864 // | +--------+----> OptoReg::stack0(), even aligned
2865 // | | pad1 | 11 pad to align new SP
2866 // | +--------+
2867 // | | | 10
2868 // | | spills | 9 spills
2869 // V | | 8 (pad0 slot for callee)
2870 // -----------+--------+----> Matcher::_out_arg_limit, unaligned
2871 // ^ | out | 7
2872 // | | args | 6 Holes in outgoing args owned by CALLEE
2873 // Owned by +--------+
2874 // CALLEE | new out| 6 Empty on Intel, window on Sparc
2875 // | new |preserve| Must be even-aligned.
2876 // | SP-+--------+----> Matcher::_new_SP, even aligned
2877 // | | |
2878 //
2879 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is
2880 // known from SELF's arguments and the Java calling convention.
2881 // Region 6-7 is determined per call site.
2882 // Note 2: If the calling convention leaves holes in the incoming argument
2883 // area, those holes are owned by SELF. Holes in the outgoing area
2884 // are owned by the CALLEE. Holes should not be nessecary in the
2885 // incoming area, as the Java calling convention is completely under
2886 // the control of the AD file. Doubles can be sorted and packed to
2887 // avoid holes. Holes in the outgoing arguments may be nessecary for
2888 // varargs C calling conventions.
2889 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is
2890 // even aligned with pad0 as needed.
2891 // Region 6 is even aligned. Region 6-7 is NOT even aligned;
2892 // region 6-11 is even aligned; it may be padded out more so that
2893 // the region from SP to FP meets the minimum stack alignment.
2894 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack
2895 // alignment. Region 11, pad1, may be dynamically extended so that
2896 // SP meets the minimum alignment.
2898 frame
2899 %{
2900 // What direction does stack grow in (assumed to be same for C & Java)
2901 stack_direction(TOWARDS_LOW);
2903 // These three registers define part of the calling convention
2904 // between compiled code and the interpreter.
2905 inline_cache_reg(RAX); // Inline Cache Register
2906 interpreter_method_oop_reg(RBX); // Method Oop Register when
2907 // calling interpreter
2909 // Optional: name the operand used by cisc-spilling to access
2910 // [stack_pointer + offset]
2911 cisc_spilling_operand_name(indOffset32);
2913 // Number of stack slots consumed by locking an object
2914 sync_stack_slots(2);
2916 // Compiled code's Frame Pointer
2917 frame_pointer(RSP);
2919 // Interpreter stores its frame pointer in a register which is
2920 // stored to the stack by I2CAdaptors.
2921 // I2CAdaptors convert from interpreted java to compiled java.
2922 interpreter_frame_pointer(RBP);
2924 // Stack alignment requirement
2925 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes)
2927 // Number of stack slots between incoming argument block and the start of
2928 // a new frame. The PROLOG must add this many slots to the stack. The
2929 // EPILOG must remove this many slots. amd64 needs two slots for
2930 // return address.
2931 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls);
2933 // Number of outgoing stack slots killed above the out_preserve_stack_slots
2934 // for calls to C. Supports the var-args backing area for register parms.
2935 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt);
2937 // The after-PROLOG location of the return address. Location of
2938 // return address specifies a type (REG or STACK) and a number
2939 // representing the register number (i.e. - use a register name) or
2940 // stack slot.
2941 // Ret Addr is on stack in slot 0 if no locks or verification or alignment.
2942 // Otherwise, it is above the locks and verification slot and alignment word
2943 return_addr(STACK - 2 +
2944 round_to((Compile::current()->in_preserve_stack_slots() +
2945 Compile::current()->fixed_slots()),
2946 stack_alignment_in_slots()));
2948 // Body of function which returns an integer array locating
2949 // arguments either in registers or in stack slots. Passed an array
2950 // of ideal registers called "sig" and a "length" count. Stack-slot
2951 // offsets are based on outgoing arguments, i.e. a CALLER setting up
2952 // arguments for a CALLEE. Incoming stack arguments are
2953 // automatically biased by the preserve_stack_slots field above.
2955 calling_convention
2956 %{
2957 // No difference between ingoing/outgoing just pass false
2958 SharedRuntime::java_calling_convention(sig_bt, regs, length, false);
2959 %}
2961 c_calling_convention
2962 %{
2963 // This is obviously always outgoing
2964 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length);
2965 %}
2967 // Location of compiled Java return values. Same as C for now.
2968 return_value
2969 %{
2970 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL,
2971 "only return normal values");
2973 static const int lo[Op_RegL + 1] = {
2974 0,
2975 0,
2976 RAX_num, // Op_RegN
2977 RAX_num, // Op_RegI
2978 RAX_num, // Op_RegP
2979 XMM0_num, // Op_RegF
2980 XMM0_num, // Op_RegD
2981 RAX_num // Op_RegL
2982 };
2983 static const int hi[Op_RegL + 1] = {
2984 0,
2985 0,
2986 OptoReg::Bad, // Op_RegN
2987 OptoReg::Bad, // Op_RegI
2988 RAX_H_num, // Op_RegP
2989 OptoReg::Bad, // Op_RegF
2990 XMM0b_num, // Op_RegD
2991 RAX_H_num // Op_RegL
2992 };
2993 // Excluded flags and vector registers.
2994 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type");
2995 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
2996 %}
2997 %}
2999 //----------ATTRIBUTES---------------------------------------------------------
3000 //----------Operand Attributes-------------------------------------------------
3001 op_attrib op_cost(0); // Required cost attribute
3003 //----------Instruction Attributes---------------------------------------------
3004 ins_attrib ins_cost(100); // Required cost attribute
3005 ins_attrib ins_size(8); // Required size attribute (in bits)
3006 ins_attrib ins_short_branch(0); // Required flag: is this instruction
3007 // a non-matching short branch variant
3008 // of some long branch?
3009 ins_attrib ins_alignment(1); // Required alignment attribute (must
3010 // be a power of 2) specifies the
3011 // alignment that some part of the
3012 // instruction (not necessarily the
3013 // start) requires. If > 1, a
3014 // compute_padding() function must be
3015 // provided for the instruction
3017 //----------OPERANDS-----------------------------------------------------------
3018 // Operand definitions must precede instruction definitions for correct parsing
3019 // in the ADLC because operands constitute user defined types which are used in
3020 // instruction definitions.
3022 //----------Simple Operands----------------------------------------------------
3023 // Immediate Operands
3024 // Integer Immediate
3025 operand immI()
3026 %{
3027 match(ConI);
3029 op_cost(10);
3030 format %{ %}
3031 interface(CONST_INTER);
3032 %}
3034 // Constant for test vs zero
3035 operand immI0()
3036 %{
3037 predicate(n->get_int() == 0);
3038 match(ConI);
3040 op_cost(0);
3041 format %{ %}
3042 interface(CONST_INTER);
3043 %}
3045 // Constant for increment
3046 operand immI1()
3047 %{
3048 predicate(n->get_int() == 1);
3049 match(ConI);
3051 op_cost(0);
3052 format %{ %}
3053 interface(CONST_INTER);
3054 %}
3056 // Constant for decrement
3057 operand immI_M1()
3058 %{
3059 predicate(n->get_int() == -1);
3060 match(ConI);
3062 op_cost(0);
3063 format %{ %}
3064 interface(CONST_INTER);
3065 %}
3067 // Valid scale values for addressing modes
3068 operand immI2()
3069 %{
3070 predicate(0 <= n->get_int() && (n->get_int() <= 3));
3071 match(ConI);
3073 format %{ %}
3074 interface(CONST_INTER);
3075 %}
3077 operand immI8()
3078 %{
3079 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80));
3080 match(ConI);
3082 op_cost(5);
3083 format %{ %}
3084 interface(CONST_INTER);
3085 %}
3087 operand immI16()
3088 %{
3089 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767));
3090 match(ConI);
3092 op_cost(10);
3093 format %{ %}
3094 interface(CONST_INTER);
3095 %}
3097 // Constant for long shifts
3098 operand immI_32()
3099 %{
3100 predicate( n->get_int() == 32 );
3101 match(ConI);
3103 op_cost(0);
3104 format %{ %}
3105 interface(CONST_INTER);
3106 %}
3108 // Constant for long shifts
3109 operand immI_64()
3110 %{
3111 predicate( n->get_int() == 64 );
3112 match(ConI);
3114 op_cost(0);
3115 format %{ %}
3116 interface(CONST_INTER);
3117 %}
3119 // Pointer Immediate
3120 operand immP()
3121 %{
3122 match(ConP);
3124 op_cost(10);
3125 format %{ %}
3126 interface(CONST_INTER);
3127 %}
3129 // NULL Pointer Immediate
3130 operand immP0()
3131 %{
3132 predicate(n->get_ptr() == 0);
3133 match(ConP);
3135 op_cost(5);
3136 format %{ %}
3137 interface(CONST_INTER);
3138 %}
3140 // Pointer Immediate
3141 operand immN() %{
3142 match(ConN);
3144 op_cost(10);
3145 format %{ %}
3146 interface(CONST_INTER);
3147 %}
3149 operand immNKlass() %{
3150 match(ConNKlass);
3152 op_cost(10);
3153 format %{ %}
3154 interface(CONST_INTER);
3155 %}
3157 // NULL Pointer Immediate
3158 operand immN0() %{
3159 predicate(n->get_narrowcon() == 0);
3160 match(ConN);
3162 op_cost(5);
3163 format %{ %}
3164 interface(CONST_INTER);
3165 %}
3167 operand immP31()
3168 %{
3169 predicate(n->as_Type()->type()->reloc() == relocInfo::none
3170 && (n->get_ptr() >> 31) == 0);
3171 match(ConP);
3173 op_cost(5);
3174 format %{ %}
3175 interface(CONST_INTER);
3176 %}
3179 // Long Immediate
3180 operand immL()
3181 %{
3182 match(ConL);
3184 op_cost(20);
3185 format %{ %}
3186 interface(CONST_INTER);
3187 %}
3189 // Long Immediate 8-bit
3190 operand immL8()
3191 %{
3192 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L);
3193 match(ConL);
3195 op_cost(5);
3196 format %{ %}
3197 interface(CONST_INTER);
3198 %}
3200 // Long Immediate 32-bit unsigned
3201 operand immUL32()
3202 %{
3203 predicate(n->get_long() == (unsigned int) (n->get_long()));
3204 match(ConL);
3206 op_cost(10);
3207 format %{ %}
3208 interface(CONST_INTER);
3209 %}
3211 // Long Immediate 32-bit signed
3212 operand immL32()
3213 %{
3214 predicate(n->get_long() == (int) (n->get_long()));
3215 match(ConL);
3217 op_cost(15);
3218 format %{ %}
3219 interface(CONST_INTER);
3220 %}
3222 // Long Immediate zero
3223 operand immL0()
3224 %{
3225 predicate(n->get_long() == 0L);
3226 match(ConL);
3228 op_cost(10);
3229 format %{ %}
3230 interface(CONST_INTER);
3231 %}
3233 // Constant for increment
3234 operand immL1()
3235 %{
3236 predicate(n->get_long() == 1);
3237 match(ConL);
3239 format %{ %}
3240 interface(CONST_INTER);
3241 %}
3243 // Constant for decrement
3244 operand immL_M1()
3245 %{
3246 predicate(n->get_long() == -1);
3247 match(ConL);
3249 format %{ %}
3250 interface(CONST_INTER);
3251 %}
3253 // Long Immediate: the value 10
3254 operand immL10()
3255 %{
3256 predicate(n->get_long() == 10);
3257 match(ConL);
3259 format %{ %}
3260 interface(CONST_INTER);
3261 %}
3263 // Long immediate from 0 to 127.
3264 // Used for a shorter form of long mul by 10.
3265 operand immL_127()
3266 %{
3267 predicate(0 <= n->get_long() && n->get_long() < 0x80);
3268 match(ConL);
3270 op_cost(10);
3271 format %{ %}
3272 interface(CONST_INTER);
3273 %}
3275 // Long Immediate: low 32-bit mask
3276 operand immL_32bits()
3277 %{
3278 predicate(n->get_long() == 0xFFFFFFFFL);
3279 match(ConL);
3280 op_cost(20);
3282 format %{ %}
3283 interface(CONST_INTER);
3284 %}
3286 // Float Immediate zero
3287 operand immF0()
3288 %{
3289 predicate(jint_cast(n->getf()) == 0);
3290 match(ConF);
3292 op_cost(5);
3293 format %{ %}
3294 interface(CONST_INTER);
3295 %}
3297 // Float Immediate
3298 operand immF()
3299 %{
3300 match(ConF);
3302 op_cost(15);
3303 format %{ %}
3304 interface(CONST_INTER);
3305 %}
3307 // Double Immediate zero
3308 operand immD0()
3309 %{
3310 predicate(jlong_cast(n->getd()) == 0);
3311 match(ConD);
3313 op_cost(5);
3314 format %{ %}
3315 interface(CONST_INTER);
3316 %}
3318 // Double Immediate
3319 operand immD()
3320 %{
3321 match(ConD);
3323 op_cost(15);
3324 format %{ %}
3325 interface(CONST_INTER);
3326 %}
3328 // Immediates for special shifts (sign extend)
3330 // Constants for increment
3331 operand immI_16()
3332 %{
3333 predicate(n->get_int() == 16);
3334 match(ConI);
3336 format %{ %}
3337 interface(CONST_INTER);
3338 %}
3340 operand immI_24()
3341 %{
3342 predicate(n->get_int() == 24);
3343 match(ConI);
3345 format %{ %}
3346 interface(CONST_INTER);
3347 %}
3349 // Constant for byte-wide masking
3350 operand immI_255()
3351 %{
3352 predicate(n->get_int() == 255);
3353 match(ConI);
3355 format %{ %}
3356 interface(CONST_INTER);
3357 %}
3359 // Constant for short-wide masking
3360 operand immI_65535()
3361 %{
3362 predicate(n->get_int() == 65535);
3363 match(ConI);
3365 format %{ %}
3366 interface(CONST_INTER);
3367 %}
3369 // Constant for byte-wide masking
3370 operand immL_255()
3371 %{
3372 predicate(n->get_long() == 255);
3373 match(ConL);
3375 format %{ %}
3376 interface(CONST_INTER);
3377 %}
3379 // Constant for short-wide masking
3380 operand immL_65535()
3381 %{
3382 predicate(n->get_long() == 65535);
3383 match(ConL);
3385 format %{ %}
3386 interface(CONST_INTER);
3387 %}
3389 // Register Operands
3390 // Integer Register
3391 operand rRegI()
3392 %{
3393 constraint(ALLOC_IN_RC(int_reg));
3394 match(RegI);
3396 match(rax_RegI);
3397 match(rbx_RegI);
3398 match(rcx_RegI);
3399 match(rdx_RegI);
3400 match(rdi_RegI);
3402 format %{ %}
3403 interface(REG_INTER);
3404 %}
3406 // Special Registers
3407 operand rax_RegI()
3408 %{
3409 constraint(ALLOC_IN_RC(int_rax_reg));
3410 match(RegI);
3411 match(rRegI);
3413 format %{ "RAX" %}
3414 interface(REG_INTER);
3415 %}
3417 // Special Registers
3418 operand rbx_RegI()
3419 %{
3420 constraint(ALLOC_IN_RC(int_rbx_reg));
3421 match(RegI);
3422 match(rRegI);
3424 format %{ "RBX" %}
3425 interface(REG_INTER);
3426 %}
3428 operand rcx_RegI()
3429 %{
3430 constraint(ALLOC_IN_RC(int_rcx_reg));
3431 match(RegI);
3432 match(rRegI);
3434 format %{ "RCX" %}
3435 interface(REG_INTER);
3436 %}
3438 operand rdx_RegI()
3439 %{
3440 constraint(ALLOC_IN_RC(int_rdx_reg));
3441 match(RegI);
3442 match(rRegI);
3444 format %{ "RDX" %}
3445 interface(REG_INTER);
3446 %}
3448 operand rdi_RegI()
3449 %{
3450 constraint(ALLOC_IN_RC(int_rdi_reg));
3451 match(RegI);
3452 match(rRegI);
3454 format %{ "RDI" %}
3455 interface(REG_INTER);
3456 %}
3458 operand no_rcx_RegI()
3459 %{
3460 constraint(ALLOC_IN_RC(int_no_rcx_reg));
3461 match(RegI);
3462 match(rax_RegI);
3463 match(rbx_RegI);
3464 match(rdx_RegI);
3465 match(rdi_RegI);
3467 format %{ %}
3468 interface(REG_INTER);
3469 %}
3471 operand no_rax_rdx_RegI()
3472 %{
3473 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg));
3474 match(RegI);
3475 match(rbx_RegI);
3476 match(rcx_RegI);
3477 match(rdi_RegI);
3479 format %{ %}
3480 interface(REG_INTER);
3481 %}
3483 // Pointer Register
3484 operand any_RegP()
3485 %{
3486 constraint(ALLOC_IN_RC(any_reg));
3487 match(RegP);
3488 match(rax_RegP);
3489 match(rbx_RegP);
3490 match(rdi_RegP);
3491 match(rsi_RegP);
3492 match(rbp_RegP);
3493 match(r15_RegP);
3494 match(rRegP);
3496 format %{ %}
3497 interface(REG_INTER);
3498 %}
3500 operand rRegP()
3501 %{
3502 constraint(ALLOC_IN_RC(ptr_reg));
3503 match(RegP);
3504 match(rax_RegP);
3505 match(rbx_RegP);
3506 match(rdi_RegP);
3507 match(rsi_RegP);
3508 match(rbp_RegP);
3509 match(r15_RegP); // See Q&A below about r15_RegP.
3511 format %{ %}
3512 interface(REG_INTER);
3513 %}
3515 operand rRegN() %{
3516 constraint(ALLOC_IN_RC(int_reg));
3517 match(RegN);
3519 format %{ %}
3520 interface(REG_INTER);
3521 %}
3523 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP?
3524 // Answer: Operand match rules govern the DFA as it processes instruction inputs.
3525 // It's fine for an instruction input which expects rRegP to match a r15_RegP.
3526 // The output of an instruction is controlled by the allocator, which respects
3527 // register class masks, not match rules. Unless an instruction mentions
3528 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered
3529 // by the allocator as an input.
3531 operand no_rax_RegP()
3532 %{
3533 constraint(ALLOC_IN_RC(ptr_no_rax_reg));
3534 match(RegP);
3535 match(rbx_RegP);
3536 match(rsi_RegP);
3537 match(rdi_RegP);
3539 format %{ %}
3540 interface(REG_INTER);
3541 %}
3543 operand no_rbp_RegP()
3544 %{
3545 constraint(ALLOC_IN_RC(ptr_no_rbp_reg));
3546 match(RegP);
3547 match(rbx_RegP);
3548 match(rsi_RegP);
3549 match(rdi_RegP);
3551 format %{ %}
3552 interface(REG_INTER);
3553 %}
3555 operand no_rax_rbx_RegP()
3556 %{
3557 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg));
3558 match(RegP);
3559 match(rsi_RegP);
3560 match(rdi_RegP);
3562 format %{ %}
3563 interface(REG_INTER);
3564 %}
3566 // Special Registers
3567 // Return a pointer value
3568 operand rax_RegP()
3569 %{
3570 constraint(ALLOC_IN_RC(ptr_rax_reg));
3571 match(RegP);
3572 match(rRegP);
3574 format %{ %}
3575 interface(REG_INTER);
3576 %}
3578 // Special Registers
3579 // Return a compressed pointer value
3580 operand rax_RegN()
3581 %{
3582 constraint(ALLOC_IN_RC(int_rax_reg));
3583 match(RegN);
3584 match(rRegN);
3586 format %{ %}
3587 interface(REG_INTER);
3588 %}
3590 // Used in AtomicAdd
3591 operand rbx_RegP()
3592 %{
3593 constraint(ALLOC_IN_RC(ptr_rbx_reg));
3594 match(RegP);
3595 match(rRegP);
3597 format %{ %}
3598 interface(REG_INTER);
3599 %}
3601 operand rsi_RegP()
3602 %{
3603 constraint(ALLOC_IN_RC(ptr_rsi_reg));
3604 match(RegP);
3605 match(rRegP);
3607 format %{ %}
3608 interface(REG_INTER);
3609 %}
3611 // Used in rep stosq
3612 operand rdi_RegP()
3613 %{
3614 constraint(ALLOC_IN_RC(ptr_rdi_reg));
3615 match(RegP);
3616 match(rRegP);
3618 format %{ %}
3619 interface(REG_INTER);
3620 %}
3622 operand rbp_RegP()
3623 %{
3624 constraint(ALLOC_IN_RC(ptr_rbp_reg));
3625 match(RegP);
3626 match(rRegP);
3628 format %{ %}
3629 interface(REG_INTER);
3630 %}
3632 operand r15_RegP()
3633 %{
3634 constraint(ALLOC_IN_RC(ptr_r15_reg));
3635 match(RegP);
3636 match(rRegP);
3638 format %{ %}
3639 interface(REG_INTER);
3640 %}
3642 operand rRegL()
3643 %{
3644 constraint(ALLOC_IN_RC(long_reg));
3645 match(RegL);
3646 match(rax_RegL);
3647 match(rdx_RegL);
3649 format %{ %}
3650 interface(REG_INTER);
3651 %}
3653 // Special Registers
3654 operand no_rax_rdx_RegL()
3655 %{
3656 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3657 match(RegL);
3658 match(rRegL);
3660 format %{ %}
3661 interface(REG_INTER);
3662 %}
3664 operand no_rax_RegL()
3665 %{
3666 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg));
3667 match(RegL);
3668 match(rRegL);
3669 match(rdx_RegL);
3671 format %{ %}
3672 interface(REG_INTER);
3673 %}
3675 operand no_rcx_RegL()
3676 %{
3677 constraint(ALLOC_IN_RC(long_no_rcx_reg));
3678 match(RegL);
3679 match(rRegL);
3681 format %{ %}
3682 interface(REG_INTER);
3683 %}
3685 operand rax_RegL()
3686 %{
3687 constraint(ALLOC_IN_RC(long_rax_reg));
3688 match(RegL);
3689 match(rRegL);
3691 format %{ "RAX" %}
3692 interface(REG_INTER);
3693 %}
3695 operand rcx_RegL()
3696 %{
3697 constraint(ALLOC_IN_RC(long_rcx_reg));
3698 match(RegL);
3699 match(rRegL);
3701 format %{ %}
3702 interface(REG_INTER);
3703 %}
3705 operand rdx_RegL()
3706 %{
3707 constraint(ALLOC_IN_RC(long_rdx_reg));
3708 match(RegL);
3709 match(rRegL);
3711 format %{ %}
3712 interface(REG_INTER);
3713 %}
3715 // Flags register, used as output of compare instructions
3716 operand rFlagsReg()
3717 %{
3718 constraint(ALLOC_IN_RC(int_flags));
3719 match(RegFlags);
3721 format %{ "RFLAGS" %}
3722 interface(REG_INTER);
3723 %}
3725 // Flags register, used as output of FLOATING POINT compare instructions
3726 operand rFlagsRegU()
3727 %{
3728 constraint(ALLOC_IN_RC(int_flags));
3729 match(RegFlags);
3731 format %{ "RFLAGS_U" %}
3732 interface(REG_INTER);
3733 %}
3735 operand rFlagsRegUCF() %{
3736 constraint(ALLOC_IN_RC(int_flags));
3737 match(RegFlags);
3738 predicate(false);
3740 format %{ "RFLAGS_U_CF" %}
3741 interface(REG_INTER);
3742 %}
3744 // Float register operands
3745 operand regF()
3746 %{
3747 constraint(ALLOC_IN_RC(float_reg));
3748 match(RegF);
3750 format %{ %}
3751 interface(REG_INTER);
3752 %}
3754 // Double register operands
3755 operand regD()
3756 %{
3757 constraint(ALLOC_IN_RC(double_reg));
3758 match(RegD);
3760 format %{ %}
3761 interface(REG_INTER);
3762 %}
3764 //----------Memory Operands----------------------------------------------------
3765 // Direct Memory Operand
3766 // operand direct(immP addr)
3767 // %{
3768 // match(addr);
3770 // format %{ "[$addr]" %}
3771 // interface(MEMORY_INTER) %{
3772 // base(0xFFFFFFFF);
3773 // index(0x4);
3774 // scale(0x0);
3775 // disp($addr);
3776 // %}
3777 // %}
3779 // Indirect Memory Operand
3780 operand indirect(any_RegP reg)
3781 %{
3782 constraint(ALLOC_IN_RC(ptr_reg));
3783 match(reg);
3785 format %{ "[$reg]" %}
3786 interface(MEMORY_INTER) %{
3787 base($reg);
3788 index(0x4);
3789 scale(0x0);
3790 disp(0x0);
3791 %}
3792 %}
3794 // Indirect Memory Plus Short Offset Operand
3795 operand indOffset8(any_RegP reg, immL8 off)
3796 %{
3797 constraint(ALLOC_IN_RC(ptr_reg));
3798 match(AddP reg off);
3800 format %{ "[$reg + $off (8-bit)]" %}
3801 interface(MEMORY_INTER) %{
3802 base($reg);
3803 index(0x4);
3804 scale(0x0);
3805 disp($off);
3806 %}
3807 %}
3809 // Indirect Memory Plus Long Offset Operand
3810 operand indOffset32(any_RegP reg, immL32 off)
3811 %{
3812 constraint(ALLOC_IN_RC(ptr_reg));
3813 match(AddP reg off);
3815 format %{ "[$reg + $off (32-bit)]" %}
3816 interface(MEMORY_INTER) %{
3817 base($reg);
3818 index(0x4);
3819 scale(0x0);
3820 disp($off);
3821 %}
3822 %}
3824 // Indirect Memory Plus Index Register Plus Offset Operand
3825 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off)
3826 %{
3827 constraint(ALLOC_IN_RC(ptr_reg));
3828 match(AddP (AddP reg lreg) off);
3830 op_cost(10);
3831 format %{"[$reg + $off + $lreg]" %}
3832 interface(MEMORY_INTER) %{
3833 base($reg);
3834 index($lreg);
3835 scale(0x0);
3836 disp($off);
3837 %}
3838 %}
3840 // Indirect Memory Plus Index Register Plus Offset Operand
3841 operand indIndex(any_RegP reg, rRegL lreg)
3842 %{
3843 constraint(ALLOC_IN_RC(ptr_reg));
3844 match(AddP reg lreg);
3846 op_cost(10);
3847 format %{"[$reg + $lreg]" %}
3848 interface(MEMORY_INTER) %{
3849 base($reg);
3850 index($lreg);
3851 scale(0x0);
3852 disp(0x0);
3853 %}
3854 %}
3856 // Indirect Memory Times Scale Plus Index Register
3857 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale)
3858 %{
3859 constraint(ALLOC_IN_RC(ptr_reg));
3860 match(AddP reg (LShiftL lreg scale));
3862 op_cost(10);
3863 format %{"[$reg + $lreg << $scale]" %}
3864 interface(MEMORY_INTER) %{
3865 base($reg);
3866 index($lreg);
3867 scale($scale);
3868 disp(0x0);
3869 %}
3870 %}
3872 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
3873 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
3874 %{
3875 constraint(ALLOC_IN_RC(ptr_reg));
3876 match(AddP (AddP reg (LShiftL lreg scale)) off);
3878 op_cost(10);
3879 format %{"[$reg + $off + $lreg << $scale]" %}
3880 interface(MEMORY_INTER) %{
3881 base($reg);
3882 index($lreg);
3883 scale($scale);
3884 disp($off);
3885 %}
3886 %}
3888 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
3889 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale)
3890 %{
3891 constraint(ALLOC_IN_RC(ptr_reg));
3892 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
3893 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off);
3895 op_cost(10);
3896 format %{"[$reg + $off + $idx << $scale]" %}
3897 interface(MEMORY_INTER) %{
3898 base($reg);
3899 index($idx);
3900 scale($scale);
3901 disp($off);
3902 %}
3903 %}
3905 // Indirect Narrow Oop Plus Offset Operand
3906 // Note: x86 architecture doesn't support "scale * index + offset" without a base
3907 // we can't free r12 even with Universe::narrow_oop_base() == NULL.
3908 operand indCompressedOopOffset(rRegN reg, immL32 off) %{
3909 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8));
3910 constraint(ALLOC_IN_RC(ptr_reg));
3911 match(AddP (DecodeN reg) off);
3913 op_cost(10);
3914 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %}
3915 interface(MEMORY_INTER) %{
3916 base(0xc); // R12
3917 index($reg);
3918 scale(0x3);
3919 disp($off);
3920 %}
3921 %}
3923 // Indirect Memory Operand
3924 operand indirectNarrow(rRegN reg)
3925 %{
3926 predicate(Universe::narrow_oop_shift() == 0);
3927 constraint(ALLOC_IN_RC(ptr_reg));
3928 match(DecodeN reg);
3930 format %{ "[$reg]" %}
3931 interface(MEMORY_INTER) %{
3932 base($reg);
3933 index(0x4);
3934 scale(0x0);
3935 disp(0x0);
3936 %}
3937 %}
3939 // Indirect Memory Plus Short Offset Operand
3940 operand indOffset8Narrow(rRegN reg, immL8 off)
3941 %{
3942 predicate(Universe::narrow_oop_shift() == 0);
3943 constraint(ALLOC_IN_RC(ptr_reg));
3944 match(AddP (DecodeN reg) off);
3946 format %{ "[$reg + $off (8-bit)]" %}
3947 interface(MEMORY_INTER) %{
3948 base($reg);
3949 index(0x4);
3950 scale(0x0);
3951 disp($off);
3952 %}
3953 %}
3955 // Indirect Memory Plus Long Offset Operand
3956 operand indOffset32Narrow(rRegN reg, immL32 off)
3957 %{
3958 predicate(Universe::narrow_oop_shift() == 0);
3959 constraint(ALLOC_IN_RC(ptr_reg));
3960 match(AddP (DecodeN reg) off);
3962 format %{ "[$reg + $off (32-bit)]" %}
3963 interface(MEMORY_INTER) %{
3964 base($reg);
3965 index(0x4);
3966 scale(0x0);
3967 disp($off);
3968 %}
3969 %}
3971 // Indirect Memory Plus Index Register Plus Offset Operand
3972 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off)
3973 %{
3974 predicate(Universe::narrow_oop_shift() == 0);
3975 constraint(ALLOC_IN_RC(ptr_reg));
3976 match(AddP (AddP (DecodeN reg) lreg) off);
3978 op_cost(10);
3979 format %{"[$reg + $off + $lreg]" %}
3980 interface(MEMORY_INTER) %{
3981 base($reg);
3982 index($lreg);
3983 scale(0x0);
3984 disp($off);
3985 %}
3986 %}
3988 // Indirect Memory Plus Index Register Plus Offset Operand
3989 operand indIndexNarrow(rRegN reg, rRegL lreg)
3990 %{
3991 predicate(Universe::narrow_oop_shift() == 0);
3992 constraint(ALLOC_IN_RC(ptr_reg));
3993 match(AddP (DecodeN reg) lreg);
3995 op_cost(10);
3996 format %{"[$reg + $lreg]" %}
3997 interface(MEMORY_INTER) %{
3998 base($reg);
3999 index($lreg);
4000 scale(0x0);
4001 disp(0x0);
4002 %}
4003 %}
4005 // Indirect Memory Times Scale Plus Index Register
4006 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale)
4007 %{
4008 predicate(Universe::narrow_oop_shift() == 0);
4009 constraint(ALLOC_IN_RC(ptr_reg));
4010 match(AddP (DecodeN reg) (LShiftL lreg scale));
4012 op_cost(10);
4013 format %{"[$reg + $lreg << $scale]" %}
4014 interface(MEMORY_INTER) %{
4015 base($reg);
4016 index($lreg);
4017 scale($scale);
4018 disp(0x0);
4019 %}
4020 %}
4022 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
4023 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale)
4024 %{
4025 predicate(Universe::narrow_oop_shift() == 0);
4026 constraint(ALLOC_IN_RC(ptr_reg));
4027 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off);
4029 op_cost(10);
4030 format %{"[$reg + $off + $lreg << $scale]" %}
4031 interface(MEMORY_INTER) %{
4032 base($reg);
4033 index($lreg);
4034 scale($scale);
4035 disp($off);
4036 %}
4037 %}
4039 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand
4040 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale)
4041 %{
4042 constraint(ALLOC_IN_RC(ptr_reg));
4043 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0);
4044 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off);
4046 op_cost(10);
4047 format %{"[$reg + $off + $idx << $scale]" %}
4048 interface(MEMORY_INTER) %{
4049 base($reg);
4050 index($idx);
4051 scale($scale);
4052 disp($off);
4053 %}
4054 %}
4056 //----------Special Memory Operands--------------------------------------------
4057 // Stack Slot Operand - This operand is used for loading and storing temporary
4058 // values on the stack where a match requires a value to
4059 // flow through memory.
4060 operand stackSlotP(sRegP reg)
4061 %{
4062 constraint(ALLOC_IN_RC(stack_slots));
4063 // No match rule because this operand is only generated in matching
4065 format %{ "[$reg]" %}
4066 interface(MEMORY_INTER) %{
4067 base(0x4); // RSP
4068 index(0x4); // No Index
4069 scale(0x0); // No Scale
4070 disp($reg); // Stack Offset
4071 %}
4072 %}
4074 operand stackSlotI(sRegI reg)
4075 %{
4076 constraint(ALLOC_IN_RC(stack_slots));
4077 // No match rule because this operand is only generated in matching
4079 format %{ "[$reg]" %}
4080 interface(MEMORY_INTER) %{
4081 base(0x4); // RSP
4082 index(0x4); // No Index
4083 scale(0x0); // No Scale
4084 disp($reg); // Stack Offset
4085 %}
4086 %}
4088 operand stackSlotF(sRegF reg)
4089 %{
4090 constraint(ALLOC_IN_RC(stack_slots));
4091 // No match rule because this operand is only generated in matching
4093 format %{ "[$reg]" %}
4094 interface(MEMORY_INTER) %{
4095 base(0x4); // RSP
4096 index(0x4); // No Index
4097 scale(0x0); // No Scale
4098 disp($reg); // Stack Offset
4099 %}
4100 %}
4102 operand stackSlotD(sRegD reg)
4103 %{
4104 constraint(ALLOC_IN_RC(stack_slots));
4105 // No match rule because this operand is only generated in matching
4107 format %{ "[$reg]" %}
4108 interface(MEMORY_INTER) %{
4109 base(0x4); // RSP
4110 index(0x4); // No Index
4111 scale(0x0); // No Scale
4112 disp($reg); // Stack Offset
4113 %}
4114 %}
4115 operand stackSlotL(sRegL reg)
4116 %{
4117 constraint(ALLOC_IN_RC(stack_slots));
4118 // No match rule because this operand is only generated in matching
4120 format %{ "[$reg]" %}
4121 interface(MEMORY_INTER) %{
4122 base(0x4); // RSP
4123 index(0x4); // No Index
4124 scale(0x0); // No Scale
4125 disp($reg); // Stack Offset
4126 %}
4127 %}
4129 //----------Conditional Branch Operands----------------------------------------
4130 // Comparison Op - This is the operation of the comparison, and is limited to
4131 // the following set of codes:
4132 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
4133 //
4134 // Other attributes of the comparison, such as unsignedness, are specified
4135 // by the comparison instruction that sets a condition code flags register.
4136 // That result is represented by a flags operand whose subtype is appropriate
4137 // to the unsignedness (etc.) of the comparison.
4138 //
4139 // Later, the instruction which matches both the Comparison Op (a Bool) and
4140 // the flags (produced by the Cmp) specifies the coding of the comparison op
4141 // by matching a specific subtype of Bool operand below, such as cmpOpU.
4143 // Comparision Code
4144 operand cmpOp()
4145 %{
4146 match(Bool);
4148 format %{ "" %}
4149 interface(COND_INTER) %{
4150 equal(0x4, "e");
4151 not_equal(0x5, "ne");
4152 less(0xC, "l");
4153 greater_equal(0xD, "ge");
4154 less_equal(0xE, "le");
4155 greater(0xF, "g");
4156 overflow(0x0, "o");
4157 no_overflow(0x1, "no");
4158 %}
4159 %}
4161 // Comparison Code, unsigned compare. Used by FP also, with
4162 // C2 (unordered) turned into GT or LT already. The other bits
4163 // C0 and C3 are turned into Carry & Zero flags.
4164 operand cmpOpU()
4165 %{
4166 match(Bool);
4168 format %{ "" %}
4169 interface(COND_INTER) %{
4170 equal(0x4, "e");
4171 not_equal(0x5, "ne");
4172 less(0x2, "b");
4173 greater_equal(0x3, "nb");
4174 less_equal(0x6, "be");
4175 greater(0x7, "nbe");
4176 overflow(0x0, "o");
4177 no_overflow(0x1, "no");
4178 %}
4179 %}
4182 // Floating comparisons that don't require any fixup for the unordered case
4183 operand cmpOpUCF() %{
4184 match(Bool);
4185 predicate(n->as_Bool()->_test._test == BoolTest::lt ||
4186 n->as_Bool()->_test._test == BoolTest::ge ||
4187 n->as_Bool()->_test._test == BoolTest::le ||
4188 n->as_Bool()->_test._test == BoolTest::gt);
4189 format %{ "" %}
4190 interface(COND_INTER) %{
4191 equal(0x4, "e");
4192 not_equal(0x5, "ne");
4193 less(0x2, "b");
4194 greater_equal(0x3, "nb");
4195 less_equal(0x6, "be");
4196 greater(0x7, "nbe");
4197 overflow(0x0, "o");
4198 no_overflow(0x1, "no");
4199 %}
4200 %}
4203 // Floating comparisons that can be fixed up with extra conditional jumps
4204 operand cmpOpUCF2() %{
4205 match(Bool);
4206 predicate(n->as_Bool()->_test._test == BoolTest::ne ||
4207 n->as_Bool()->_test._test == BoolTest::eq);
4208 format %{ "" %}
4209 interface(COND_INTER) %{
4210 equal(0x4, "e");
4211 not_equal(0x5, "ne");
4212 less(0x2, "b");
4213 greater_equal(0x3, "nb");
4214 less_equal(0x6, "be");
4215 greater(0x7, "nbe");
4216 overflow(0x0, "o");
4217 no_overflow(0x1, "no");
4218 %}
4219 %}
4222 //----------OPERAND CLASSES----------------------------------------------------
4223 // Operand Classes are groups of operands that are used as to simplify
4224 // instruction definitions by not requiring the AD writer to specify separate
4225 // instructions for every form of operand when the instruction accepts
4226 // multiple operand types with the same basic encoding and format. The classic
4227 // case of this is memory operands.
4229 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
4230 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
4231 indCompressedOopOffset,
4232 indirectNarrow, indOffset8Narrow, indOffset32Narrow,
4233 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow,
4234 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow);
4236 //----------PIPELINE-----------------------------------------------------------
4237 // Rules which define the behavior of the target architectures pipeline.
4238 pipeline %{
4240 //----------ATTRIBUTES---------------------------------------------------------
4241 attributes %{
4242 variable_size_instructions; // Fixed size instructions
4243 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle
4244 instruction_unit_size = 1; // An instruction is 1 bytes long
4245 instruction_fetch_unit_size = 16; // The processor fetches one line
4246 instruction_fetch_units = 1; // of 16 bytes
4248 // List of nop instructions
4249 nops( MachNop );
4250 %}
4252 //----------RESOURCES----------------------------------------------------------
4253 // Resources are the functional units available to the machine
4255 // Generic P2/P3 pipeline
4256 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of
4257 // 3 instructions decoded per cycle.
4258 // 2 load/store ops per cycle, 1 branch, 1 FPU,
4259 // 3 ALU op, only ALU0 handles mul instructions.
4260 resources( D0, D1, D2, DECODE = D0 | D1 | D2,
4261 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2,
4262 BR, FPU,
4263 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2);
4265 //----------PIPELINE DESCRIPTION-----------------------------------------------
4266 // Pipeline Description specifies the stages in the machine's pipeline
4268 // Generic P2/P3 pipeline
4269 pipe_desc(S0, S1, S2, S3, S4, S5);
4271 //----------PIPELINE CLASSES---------------------------------------------------
4272 // Pipeline Classes describe the stages in which input and output are
4273 // referenced by the hardware pipeline.
4275 // Naming convention: ialu or fpu
4276 // Then: _reg
4277 // Then: _reg if there is a 2nd register
4278 // Then: _long if it's a pair of instructions implementing a long
4279 // Then: _fat if it requires the big decoder
4280 // Or: _mem if it requires the big decoder and a memory unit.
4282 // Integer ALU reg operation
4283 pipe_class ialu_reg(rRegI dst)
4284 %{
4285 single_instruction;
4286 dst : S4(write);
4287 dst : S3(read);
4288 DECODE : S0; // any decoder
4289 ALU : S3; // any alu
4290 %}
4292 // Long ALU reg operation
4293 pipe_class ialu_reg_long(rRegL dst)
4294 %{
4295 instruction_count(2);
4296 dst : S4(write);
4297 dst : S3(read);
4298 DECODE : S0(2); // any 2 decoders
4299 ALU : S3(2); // both alus
4300 %}
4302 // Integer ALU reg operation using big decoder
4303 pipe_class ialu_reg_fat(rRegI dst)
4304 %{
4305 single_instruction;
4306 dst : S4(write);
4307 dst : S3(read);
4308 D0 : S0; // big decoder only
4309 ALU : S3; // any alu
4310 %}
4312 // Long ALU reg operation using big decoder
4313 pipe_class ialu_reg_long_fat(rRegL dst)
4314 %{
4315 instruction_count(2);
4316 dst : S4(write);
4317 dst : S3(read);
4318 D0 : S0(2); // big decoder only; twice
4319 ALU : S3(2); // any 2 alus
4320 %}
4322 // Integer ALU reg-reg operation
4323 pipe_class ialu_reg_reg(rRegI dst, rRegI src)
4324 %{
4325 single_instruction;
4326 dst : S4(write);
4327 src : S3(read);
4328 DECODE : S0; // any decoder
4329 ALU : S3; // any alu
4330 %}
4332 // Long ALU reg-reg operation
4333 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src)
4334 %{
4335 instruction_count(2);
4336 dst : S4(write);
4337 src : S3(read);
4338 DECODE : S0(2); // any 2 decoders
4339 ALU : S3(2); // both alus
4340 %}
4342 // Integer ALU reg-reg operation
4343 pipe_class ialu_reg_reg_fat(rRegI dst, memory src)
4344 %{
4345 single_instruction;
4346 dst : S4(write);
4347 src : S3(read);
4348 D0 : S0; // big decoder only
4349 ALU : S3; // any alu
4350 %}
4352 // Long ALU reg-reg operation
4353 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src)
4354 %{
4355 instruction_count(2);
4356 dst : S4(write);
4357 src : S3(read);
4358 D0 : S0(2); // big decoder only; twice
4359 ALU : S3(2); // both alus
4360 %}
4362 // Integer ALU reg-mem operation
4363 pipe_class ialu_reg_mem(rRegI dst, memory mem)
4364 %{
4365 single_instruction;
4366 dst : S5(write);
4367 mem : S3(read);
4368 D0 : S0; // big decoder only
4369 ALU : S4; // any alu
4370 MEM : S3; // any mem
4371 %}
4373 // Integer mem operation (prefetch)
4374 pipe_class ialu_mem(memory mem)
4375 %{
4376 single_instruction;
4377 mem : S3(read);
4378 D0 : S0; // big decoder only
4379 MEM : S3; // any mem
4380 %}
4382 // Integer Store to Memory
4383 pipe_class ialu_mem_reg(memory mem, rRegI src)
4384 %{
4385 single_instruction;
4386 mem : S3(read);
4387 src : S5(read);
4388 D0 : S0; // big decoder only
4389 ALU : S4; // any alu
4390 MEM : S3;
4391 %}
4393 // // Long Store to Memory
4394 // pipe_class ialu_mem_long_reg(memory mem, rRegL src)
4395 // %{
4396 // instruction_count(2);
4397 // mem : S3(read);
4398 // src : S5(read);
4399 // D0 : S0(2); // big decoder only; twice
4400 // ALU : S4(2); // any 2 alus
4401 // MEM : S3(2); // Both mems
4402 // %}
4404 // Integer Store to Memory
4405 pipe_class ialu_mem_imm(memory mem)
4406 %{
4407 single_instruction;
4408 mem : S3(read);
4409 D0 : S0; // big decoder only
4410 ALU : S4; // any alu
4411 MEM : S3;
4412 %}
4414 // Integer ALU0 reg-reg operation
4415 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src)
4416 %{
4417 single_instruction;
4418 dst : S4(write);
4419 src : S3(read);
4420 D0 : S0; // Big decoder only
4421 ALU0 : S3; // only alu0
4422 %}
4424 // Integer ALU0 reg-mem operation
4425 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem)
4426 %{
4427 single_instruction;
4428 dst : S5(write);
4429 mem : S3(read);
4430 D0 : S0; // big decoder only
4431 ALU0 : S4; // ALU0 only
4432 MEM : S3; // any mem
4433 %}
4435 // Integer ALU reg-reg operation
4436 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2)
4437 %{
4438 single_instruction;
4439 cr : S4(write);
4440 src1 : S3(read);
4441 src2 : S3(read);
4442 DECODE : S0; // any decoder
4443 ALU : S3; // any alu
4444 %}
4446 // Integer ALU reg-imm operation
4447 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1)
4448 %{
4449 single_instruction;
4450 cr : S4(write);
4451 src1 : S3(read);
4452 DECODE : S0; // any decoder
4453 ALU : S3; // any alu
4454 %}
4456 // Integer ALU reg-mem operation
4457 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2)
4458 %{
4459 single_instruction;
4460 cr : S4(write);
4461 src1 : S3(read);
4462 src2 : S3(read);
4463 D0 : S0; // big decoder only
4464 ALU : S4; // any alu
4465 MEM : S3;
4466 %}
4468 // Conditional move reg-reg
4469 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y)
4470 %{
4471 instruction_count(4);
4472 y : S4(read);
4473 q : S3(read);
4474 p : S3(read);
4475 DECODE : S0(4); // any decoder
4476 %}
4478 // Conditional move reg-reg
4479 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr)
4480 %{
4481 single_instruction;
4482 dst : S4(write);
4483 src : S3(read);
4484 cr : S3(read);
4485 DECODE : S0; // any decoder
4486 %}
4488 // Conditional move reg-mem
4489 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src)
4490 %{
4491 single_instruction;
4492 dst : S4(write);
4493 src : S3(read);
4494 cr : S3(read);
4495 DECODE : S0; // any decoder
4496 MEM : S3;
4497 %}
4499 // Conditional move reg-reg long
4500 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src)
4501 %{
4502 single_instruction;
4503 dst : S4(write);
4504 src : S3(read);
4505 cr : S3(read);
4506 DECODE : S0(2); // any 2 decoders
4507 %}
4509 // XXX
4510 // // Conditional move double reg-reg
4511 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src)
4512 // %{
4513 // single_instruction;
4514 // dst : S4(write);
4515 // src : S3(read);
4516 // cr : S3(read);
4517 // DECODE : S0; // any decoder
4518 // %}
4520 // Float reg-reg operation
4521 pipe_class fpu_reg(regD dst)
4522 %{
4523 instruction_count(2);
4524 dst : S3(read);
4525 DECODE : S0(2); // any 2 decoders
4526 FPU : S3;
4527 %}
4529 // Float reg-reg operation
4530 pipe_class fpu_reg_reg(regD dst, regD src)
4531 %{
4532 instruction_count(2);
4533 dst : S4(write);
4534 src : S3(read);
4535 DECODE : S0(2); // any 2 decoders
4536 FPU : S3;
4537 %}
4539 // Float reg-reg operation
4540 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2)
4541 %{
4542 instruction_count(3);
4543 dst : S4(write);
4544 src1 : S3(read);
4545 src2 : S3(read);
4546 DECODE : S0(3); // any 3 decoders
4547 FPU : S3(2);
4548 %}
4550 // Float reg-reg operation
4551 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3)
4552 %{
4553 instruction_count(4);
4554 dst : S4(write);
4555 src1 : S3(read);
4556 src2 : S3(read);
4557 src3 : S3(read);
4558 DECODE : S0(4); // any 3 decoders
4559 FPU : S3(2);
4560 %}
4562 // Float reg-reg operation
4563 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3)
4564 %{
4565 instruction_count(4);
4566 dst : S4(write);
4567 src1 : S3(read);
4568 src2 : S3(read);
4569 src3 : S3(read);
4570 DECODE : S1(3); // any 3 decoders
4571 D0 : S0; // Big decoder only
4572 FPU : S3(2);
4573 MEM : S3;
4574 %}
4576 // Float reg-mem operation
4577 pipe_class fpu_reg_mem(regD dst, memory mem)
4578 %{
4579 instruction_count(2);
4580 dst : S5(write);
4581 mem : S3(read);
4582 D0 : S0; // big decoder only
4583 DECODE : S1; // any decoder for FPU POP
4584 FPU : S4;
4585 MEM : S3; // any mem
4586 %}
4588 // Float reg-mem operation
4589 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem)
4590 %{
4591 instruction_count(3);
4592 dst : S5(write);
4593 src1 : S3(read);
4594 mem : S3(read);
4595 D0 : S0; // big decoder only
4596 DECODE : S1(2); // any decoder for FPU POP
4597 FPU : S4;
4598 MEM : S3; // any mem
4599 %}
4601 // Float mem-reg operation
4602 pipe_class fpu_mem_reg(memory mem, regD src)
4603 %{
4604 instruction_count(2);
4605 src : S5(read);
4606 mem : S3(read);
4607 DECODE : S0; // any decoder for FPU PUSH
4608 D0 : S1; // big decoder only
4609 FPU : S4;
4610 MEM : S3; // any mem
4611 %}
4613 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2)
4614 %{
4615 instruction_count(3);
4616 src1 : S3(read);
4617 src2 : S3(read);
4618 mem : S3(read);
4619 DECODE : S0(2); // any decoder for FPU PUSH
4620 D0 : S1; // big decoder only
4621 FPU : S4;
4622 MEM : S3; // any mem
4623 %}
4625 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2)
4626 %{
4627 instruction_count(3);
4628 src1 : S3(read);
4629 src2 : S3(read);
4630 mem : S4(read);
4631 DECODE : S0; // any decoder for FPU PUSH
4632 D0 : S0(2); // big decoder only
4633 FPU : S4;
4634 MEM : S3(2); // any mem
4635 %}
4637 pipe_class fpu_mem_mem(memory dst, memory src1)
4638 %{
4639 instruction_count(2);
4640 src1 : S3(read);
4641 dst : S4(read);
4642 D0 : S0(2); // big decoder only
4643 MEM : S3(2); // any mem
4644 %}
4646 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2)
4647 %{
4648 instruction_count(3);
4649 src1 : S3(read);
4650 src2 : S3(read);
4651 dst : S4(read);
4652 D0 : S0(3); // big decoder only
4653 FPU : S4;
4654 MEM : S3(3); // any mem
4655 %}
4657 pipe_class fpu_mem_reg_con(memory mem, regD src1)
4658 %{
4659 instruction_count(3);
4660 src1 : S4(read);
4661 mem : S4(read);
4662 DECODE : S0; // any decoder for FPU PUSH
4663 D0 : S0(2); // big decoder only
4664 FPU : S4;
4665 MEM : S3(2); // any mem
4666 %}
4668 // Float load constant
4669 pipe_class fpu_reg_con(regD dst)
4670 %{
4671 instruction_count(2);
4672 dst : S5(write);
4673 D0 : S0; // big decoder only for the load
4674 DECODE : S1; // any decoder for FPU POP
4675 FPU : S4;
4676 MEM : S3; // any mem
4677 %}
4679 // Float load constant
4680 pipe_class fpu_reg_reg_con(regD dst, regD src)
4681 %{
4682 instruction_count(3);
4683 dst : S5(write);
4684 src : S3(read);
4685 D0 : S0; // big decoder only for the load
4686 DECODE : S1(2); // any decoder for FPU POP
4687 FPU : S4;
4688 MEM : S3; // any mem
4689 %}
4691 // UnConditional branch
4692 pipe_class pipe_jmp(label labl)
4693 %{
4694 single_instruction;
4695 BR : S3;
4696 %}
4698 // Conditional branch
4699 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl)
4700 %{
4701 single_instruction;
4702 cr : S1(read);
4703 BR : S3;
4704 %}
4706 // Allocation idiom
4707 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr)
4708 %{
4709 instruction_count(1); force_serialization;
4710 fixed_latency(6);
4711 heap_ptr : S3(read);
4712 DECODE : S0(3);
4713 D0 : S2;
4714 MEM : S3;
4715 ALU : S3(2);
4716 dst : S5(write);
4717 BR : S5;
4718 %}
4720 // Generic big/slow expanded idiom
4721 pipe_class pipe_slow()
4722 %{
4723 instruction_count(10); multiple_bundles; force_serialization;
4724 fixed_latency(100);
4725 D0 : S0(2);
4726 MEM : S3(2);
4727 %}
4729 // The real do-nothing guy
4730 pipe_class empty()
4731 %{
4732 instruction_count(0);
4733 %}
4735 // Define the class for the Nop node
4736 define
4737 %{
4738 MachNop = empty;
4739 %}
4741 %}
4743 //----------INSTRUCTIONS-------------------------------------------------------
4744 //
4745 // match -- States which machine-independent subtree may be replaced
4746 // by this instruction.
4747 // ins_cost -- The estimated cost of this instruction is used by instruction
4748 // selection to identify a minimum cost tree of machine
4749 // instructions that matches a tree of machine-independent
4750 // instructions.
4751 // format -- A string providing the disassembly for this instruction.
4752 // The value of an instruction's operand may be inserted
4753 // by referring to it with a '$' prefix.
4754 // opcode -- Three instruction opcodes may be provided. These are referred
4755 // to within an encode class as $primary, $secondary, and $tertiary
4756 // rrspectively. The primary opcode is commonly used to
4757 // indicate the type of machine instruction, while secondary
4758 // and tertiary are often used for prefix options or addressing
4759 // modes.
4760 // ins_encode -- A list of encode classes with parameters. The encode class
4761 // name must have been defined in an 'enc_class' specification
4762 // in the encode section of the architecture description.
4765 //----------Load/Store/Move Instructions---------------------------------------
4766 //----------Load Instructions--------------------------------------------------
4768 // Load Byte (8 bit signed)
4769 instruct loadB(rRegI dst, memory mem)
4770 %{
4771 match(Set dst (LoadB mem));
4773 ins_cost(125);
4774 format %{ "movsbl $dst, $mem\t# byte" %}
4776 ins_encode %{
4777 __ movsbl($dst$$Register, $mem$$Address);
4778 %}
4780 ins_pipe(ialu_reg_mem);
4781 %}
4783 // Load Byte (8 bit signed) into Long Register
4784 instruct loadB2L(rRegL dst, memory mem)
4785 %{
4786 match(Set dst (ConvI2L (LoadB mem)));
4788 ins_cost(125);
4789 format %{ "movsbq $dst, $mem\t# byte -> long" %}
4791 ins_encode %{
4792 __ movsbq($dst$$Register, $mem$$Address);
4793 %}
4795 ins_pipe(ialu_reg_mem);
4796 %}
4798 // Load Unsigned Byte (8 bit UNsigned)
4799 instruct loadUB(rRegI dst, memory mem)
4800 %{
4801 match(Set dst (LoadUB mem));
4803 ins_cost(125);
4804 format %{ "movzbl $dst, $mem\t# ubyte" %}
4806 ins_encode %{
4807 __ movzbl($dst$$Register, $mem$$Address);
4808 %}
4810 ins_pipe(ialu_reg_mem);
4811 %}
4813 // Load Unsigned Byte (8 bit UNsigned) into Long Register
4814 instruct loadUB2L(rRegL dst, memory mem)
4815 %{
4816 match(Set dst (ConvI2L (LoadUB mem)));
4818 ins_cost(125);
4819 format %{ "movzbq $dst, $mem\t# ubyte -> long" %}
4821 ins_encode %{
4822 __ movzbq($dst$$Register, $mem$$Address);
4823 %}
4825 ins_pipe(ialu_reg_mem);
4826 %}
4828 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register
4829 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{
4830 match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
4831 effect(KILL cr);
4833 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t"
4834 "andl $dst, $mask" %}
4835 ins_encode %{
4836 Register Rdst = $dst$$Register;
4837 __ movzbq(Rdst, $mem$$Address);
4838 __ andl(Rdst, $mask$$constant);
4839 %}
4840 ins_pipe(ialu_reg_mem);
4841 %}
4843 // Load Short (16 bit signed)
4844 instruct loadS(rRegI dst, memory mem)
4845 %{
4846 match(Set dst (LoadS mem));
4848 ins_cost(125);
4849 format %{ "movswl $dst, $mem\t# short" %}
4851 ins_encode %{
4852 __ movswl($dst$$Register, $mem$$Address);
4853 %}
4855 ins_pipe(ialu_reg_mem);
4856 %}
4858 // Load Short (16 bit signed) to Byte (8 bit signed)
4859 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4860 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
4862 ins_cost(125);
4863 format %{ "movsbl $dst, $mem\t# short -> byte" %}
4864 ins_encode %{
4865 __ movsbl($dst$$Register, $mem$$Address);
4866 %}
4867 ins_pipe(ialu_reg_mem);
4868 %}
4870 // Load Short (16 bit signed) into Long Register
4871 instruct loadS2L(rRegL dst, memory mem)
4872 %{
4873 match(Set dst (ConvI2L (LoadS mem)));
4875 ins_cost(125);
4876 format %{ "movswq $dst, $mem\t# short -> long" %}
4878 ins_encode %{
4879 __ movswq($dst$$Register, $mem$$Address);
4880 %}
4882 ins_pipe(ialu_reg_mem);
4883 %}
4885 // Load Unsigned Short/Char (16 bit UNsigned)
4886 instruct loadUS(rRegI dst, memory mem)
4887 %{
4888 match(Set dst (LoadUS mem));
4890 ins_cost(125);
4891 format %{ "movzwl $dst, $mem\t# ushort/char" %}
4893 ins_encode %{
4894 __ movzwl($dst$$Register, $mem$$Address);
4895 %}
4897 ins_pipe(ialu_reg_mem);
4898 %}
4900 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
4901 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4902 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
4904 ins_cost(125);
4905 format %{ "movsbl $dst, $mem\t# ushort -> byte" %}
4906 ins_encode %{
4907 __ movsbl($dst$$Register, $mem$$Address);
4908 %}
4909 ins_pipe(ialu_reg_mem);
4910 %}
4912 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
4913 instruct loadUS2L(rRegL dst, memory mem)
4914 %{
4915 match(Set dst (ConvI2L (LoadUS mem)));
4917 ins_cost(125);
4918 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %}
4920 ins_encode %{
4921 __ movzwq($dst$$Register, $mem$$Address);
4922 %}
4924 ins_pipe(ialu_reg_mem);
4925 %}
4927 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register
4928 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
4929 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4931 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %}
4932 ins_encode %{
4933 __ movzbq($dst$$Register, $mem$$Address);
4934 %}
4935 ins_pipe(ialu_reg_mem);
4936 %}
4938 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register
4939 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{
4940 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
4941 effect(KILL cr);
4943 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t"
4944 "andl $dst, $mask" %}
4945 ins_encode %{
4946 Register Rdst = $dst$$Register;
4947 __ movzwq(Rdst, $mem$$Address);
4948 __ andl(Rdst, $mask$$constant);
4949 %}
4950 ins_pipe(ialu_reg_mem);
4951 %}
4953 // Load Integer
4954 instruct loadI(rRegI dst, memory mem)
4955 %{
4956 match(Set dst (LoadI mem));
4958 ins_cost(125);
4959 format %{ "movl $dst, $mem\t# int" %}
4961 ins_encode %{
4962 __ movl($dst$$Register, $mem$$Address);
4963 %}
4965 ins_pipe(ialu_reg_mem);
4966 %}
4968 // Load Integer (32 bit signed) to Byte (8 bit signed)
4969 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
4970 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
4972 ins_cost(125);
4973 format %{ "movsbl $dst, $mem\t# int -> byte" %}
4974 ins_encode %{
4975 __ movsbl($dst$$Register, $mem$$Address);
4976 %}
4977 ins_pipe(ialu_reg_mem);
4978 %}
4980 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
4981 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
4982 match(Set dst (AndI (LoadI mem) mask));
4984 ins_cost(125);
4985 format %{ "movzbl $dst, $mem\t# int -> ubyte" %}
4986 ins_encode %{
4987 __ movzbl($dst$$Register, $mem$$Address);
4988 %}
4989 ins_pipe(ialu_reg_mem);
4990 %}
4992 // Load Integer (32 bit signed) to Short (16 bit signed)
4993 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
4994 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
4996 ins_cost(125);
4997 format %{ "movswl $dst, $mem\t# int -> short" %}
4998 ins_encode %{
4999 __ movswl($dst$$Register, $mem$$Address);
5000 %}
5001 ins_pipe(ialu_reg_mem);
5002 %}
5004 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
5005 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
5006 match(Set dst (AndI (LoadI mem) mask));
5008 ins_cost(125);
5009 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %}
5010 ins_encode %{
5011 __ movzwl($dst$$Register, $mem$$Address);
5012 %}
5013 ins_pipe(ialu_reg_mem);
5014 %}
5016 // Load Integer into Long Register
5017 instruct loadI2L(rRegL dst, memory mem)
5018 %{
5019 match(Set dst (ConvI2L (LoadI mem)));
5021 ins_cost(125);
5022 format %{ "movslq $dst, $mem\t# int -> long" %}
5024 ins_encode %{
5025 __ movslq($dst$$Register, $mem$$Address);
5026 %}
5028 ins_pipe(ialu_reg_mem);
5029 %}
5031 // Load Integer with mask 0xFF into Long Register
5032 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{
5033 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5035 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %}
5036 ins_encode %{
5037 __ movzbq($dst$$Register, $mem$$Address);
5038 %}
5039 ins_pipe(ialu_reg_mem);
5040 %}
5042 // Load Integer with mask 0xFFFF into Long Register
5043 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{
5044 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5046 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %}
5047 ins_encode %{
5048 __ movzwq($dst$$Register, $mem$$Address);
5049 %}
5050 ins_pipe(ialu_reg_mem);
5051 %}
5053 // Load Integer with a 32-bit mask into Long Register
5054 instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{
5055 match(Set dst (ConvI2L (AndI (LoadI mem) mask)));
5056 effect(KILL cr);
5058 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t"
5059 "andl $dst, $mask" %}
5060 ins_encode %{
5061 Register Rdst = $dst$$Register;
5062 __ movl(Rdst, $mem$$Address);
5063 __ andl(Rdst, $mask$$constant);
5064 %}
5065 ins_pipe(ialu_reg_mem);
5066 %}
5068 // Load Unsigned Integer into Long Register
5069 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask)
5070 %{
5071 match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
5073 ins_cost(125);
5074 format %{ "movl $dst, $mem\t# uint -> long" %}
5076 ins_encode %{
5077 __ movl($dst$$Register, $mem$$Address);
5078 %}
5080 ins_pipe(ialu_reg_mem);
5081 %}
5083 // Load Long
5084 instruct loadL(rRegL dst, memory mem)
5085 %{
5086 match(Set dst (LoadL mem));
5088 ins_cost(125);
5089 format %{ "movq $dst, $mem\t# long" %}
5091 ins_encode %{
5092 __ movq($dst$$Register, $mem$$Address);
5093 %}
5095 ins_pipe(ialu_reg_mem); // XXX
5096 %}
5098 // Load Range
5099 instruct loadRange(rRegI dst, memory mem)
5100 %{
5101 match(Set dst (LoadRange mem));
5103 ins_cost(125); // XXX
5104 format %{ "movl $dst, $mem\t# range" %}
5105 opcode(0x8B);
5106 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem));
5107 ins_pipe(ialu_reg_mem);
5108 %}
5110 // Load Pointer
5111 instruct loadP(rRegP dst, memory mem)
5112 %{
5113 match(Set dst (LoadP mem));
5115 ins_cost(125); // XXX
5116 format %{ "movq $dst, $mem\t# ptr" %}
5117 opcode(0x8B);
5118 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5119 ins_pipe(ialu_reg_mem); // XXX
5120 %}
5122 // Load Compressed Pointer
5123 instruct loadN(rRegN dst, memory mem)
5124 %{
5125 match(Set dst (LoadN mem));
5127 ins_cost(125); // XXX
5128 format %{ "movl $dst, $mem\t# compressed ptr" %}
5129 ins_encode %{
5130 __ movl($dst$$Register, $mem$$Address);
5131 %}
5132 ins_pipe(ialu_reg_mem); // XXX
5133 %}
5136 // Load Klass Pointer
5137 instruct loadKlass(rRegP dst, memory mem)
5138 %{
5139 match(Set dst (LoadKlass mem));
5141 ins_cost(125); // XXX
5142 format %{ "movq $dst, $mem\t# class" %}
5143 opcode(0x8B);
5144 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5145 ins_pipe(ialu_reg_mem); // XXX
5146 %}
5148 // Load narrow Klass Pointer
5149 instruct loadNKlass(rRegN dst, memory mem)
5150 %{
5151 match(Set dst (LoadNKlass mem));
5153 ins_cost(125); // XXX
5154 format %{ "movl $dst, $mem\t# compressed klass ptr" %}
5155 ins_encode %{
5156 __ movl($dst$$Register, $mem$$Address);
5157 %}
5158 ins_pipe(ialu_reg_mem); // XXX
5159 %}
5161 // Load Float
5162 instruct loadF(regF dst, memory mem)
5163 %{
5164 match(Set dst (LoadF mem));
5166 ins_cost(145); // XXX
5167 format %{ "movss $dst, $mem\t# float" %}
5168 ins_encode %{
5169 __ movflt($dst$$XMMRegister, $mem$$Address);
5170 %}
5171 ins_pipe(pipe_slow); // XXX
5172 %}
5174 // Load Double
5175 instruct loadD_partial(regD dst, memory mem)
5176 %{
5177 predicate(!UseXmmLoadAndClearUpper);
5178 match(Set dst (LoadD mem));
5180 ins_cost(145); // XXX
5181 format %{ "movlpd $dst, $mem\t# double" %}
5182 ins_encode %{
5183 __ movdbl($dst$$XMMRegister, $mem$$Address);
5184 %}
5185 ins_pipe(pipe_slow); // XXX
5186 %}
5188 instruct loadD(regD dst, memory mem)
5189 %{
5190 predicate(UseXmmLoadAndClearUpper);
5191 match(Set dst (LoadD mem));
5193 ins_cost(145); // XXX
5194 format %{ "movsd $dst, $mem\t# double" %}
5195 ins_encode %{
5196 __ movdbl($dst$$XMMRegister, $mem$$Address);
5197 %}
5198 ins_pipe(pipe_slow); // XXX
5199 %}
5201 // Load Effective Address
5202 instruct leaP8(rRegP dst, indOffset8 mem)
5203 %{
5204 match(Set dst mem);
5206 ins_cost(110); // XXX
5207 format %{ "leaq $dst, $mem\t# ptr 8" %}
5208 opcode(0x8D);
5209 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5210 ins_pipe(ialu_reg_reg_fat);
5211 %}
5213 instruct leaP32(rRegP dst, indOffset32 mem)
5214 %{
5215 match(Set dst mem);
5217 ins_cost(110);
5218 format %{ "leaq $dst, $mem\t# ptr 32" %}
5219 opcode(0x8D);
5220 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5221 ins_pipe(ialu_reg_reg_fat);
5222 %}
5224 // instruct leaPIdx(rRegP dst, indIndex mem)
5225 // %{
5226 // match(Set dst mem);
5228 // ins_cost(110);
5229 // format %{ "leaq $dst, $mem\t# ptr idx" %}
5230 // opcode(0x8D);
5231 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5232 // ins_pipe(ialu_reg_reg_fat);
5233 // %}
5235 instruct leaPIdxOff(rRegP dst, indIndexOffset mem)
5236 %{
5237 match(Set dst mem);
5239 ins_cost(110);
5240 format %{ "leaq $dst, $mem\t# ptr idxoff" %}
5241 opcode(0x8D);
5242 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5243 ins_pipe(ialu_reg_reg_fat);
5244 %}
5246 instruct leaPIdxScale(rRegP dst, indIndexScale mem)
5247 %{
5248 match(Set dst mem);
5250 ins_cost(110);
5251 format %{ "leaq $dst, $mem\t# ptr idxscale" %}
5252 opcode(0x8D);
5253 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5254 ins_pipe(ialu_reg_reg_fat);
5255 %}
5257 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem)
5258 %{
5259 match(Set dst mem);
5261 ins_cost(110);
5262 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %}
5263 opcode(0x8D);
5264 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5265 ins_pipe(ialu_reg_reg_fat);
5266 %}
5268 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem)
5269 %{
5270 match(Set dst mem);
5272 ins_cost(110);
5273 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %}
5274 opcode(0x8D);
5275 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5276 ins_pipe(ialu_reg_reg_fat);
5277 %}
5279 // Load Effective Address which uses Narrow (32-bits) oop
5280 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem)
5281 %{
5282 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0));
5283 match(Set dst mem);
5285 ins_cost(110);
5286 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %}
5287 opcode(0x8D);
5288 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5289 ins_pipe(ialu_reg_reg_fat);
5290 %}
5292 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem)
5293 %{
5294 predicate(Universe::narrow_oop_shift() == 0);
5295 match(Set dst mem);
5297 ins_cost(110); // XXX
5298 format %{ "leaq $dst, $mem\t# ptr off8narrow" %}
5299 opcode(0x8D);
5300 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5301 ins_pipe(ialu_reg_reg_fat);
5302 %}
5304 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem)
5305 %{
5306 predicate(Universe::narrow_oop_shift() == 0);
5307 match(Set dst mem);
5309 ins_cost(110);
5310 format %{ "leaq $dst, $mem\t# ptr off32narrow" %}
5311 opcode(0x8D);
5312 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5313 ins_pipe(ialu_reg_reg_fat);
5314 %}
5316 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem)
5317 %{
5318 predicate(Universe::narrow_oop_shift() == 0);
5319 match(Set dst mem);
5321 ins_cost(110);
5322 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %}
5323 opcode(0x8D);
5324 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5325 ins_pipe(ialu_reg_reg_fat);
5326 %}
5328 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem)
5329 %{
5330 predicate(Universe::narrow_oop_shift() == 0);
5331 match(Set dst mem);
5333 ins_cost(110);
5334 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %}
5335 opcode(0x8D);
5336 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5337 ins_pipe(ialu_reg_reg_fat);
5338 %}
5340 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem)
5341 %{
5342 predicate(Universe::narrow_oop_shift() == 0);
5343 match(Set dst mem);
5345 ins_cost(110);
5346 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %}
5347 opcode(0x8D);
5348 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5349 ins_pipe(ialu_reg_reg_fat);
5350 %}
5352 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem)
5353 %{
5354 predicate(Universe::narrow_oop_shift() == 0);
5355 match(Set dst mem);
5357 ins_cost(110);
5358 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %}
5359 opcode(0x8D);
5360 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
5361 ins_pipe(ialu_reg_reg_fat);
5362 %}
5364 instruct loadConI(rRegI dst, immI src)
5365 %{
5366 match(Set dst src);
5368 format %{ "movl $dst, $src\t# int" %}
5369 ins_encode(load_immI(dst, src));
5370 ins_pipe(ialu_reg_fat); // XXX
5371 %}
5373 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr)
5374 %{
5375 match(Set dst src);
5376 effect(KILL cr);
5378 ins_cost(50);
5379 format %{ "xorl $dst, $dst\t# int" %}
5380 opcode(0x33); /* + rd */
5381 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5382 ins_pipe(ialu_reg);
5383 %}
5385 instruct loadConL(rRegL dst, immL src)
5386 %{
5387 match(Set dst src);
5389 ins_cost(150);
5390 format %{ "movq $dst, $src\t# long" %}
5391 ins_encode(load_immL(dst, src));
5392 ins_pipe(ialu_reg);
5393 %}
5395 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr)
5396 %{
5397 match(Set dst src);
5398 effect(KILL cr);
5400 ins_cost(50);
5401 format %{ "xorl $dst, $dst\t# long" %}
5402 opcode(0x33); /* + rd */
5403 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5404 ins_pipe(ialu_reg); // XXX
5405 %}
5407 instruct loadConUL32(rRegL dst, immUL32 src)
5408 %{
5409 match(Set dst src);
5411 ins_cost(60);
5412 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %}
5413 ins_encode(load_immUL32(dst, src));
5414 ins_pipe(ialu_reg);
5415 %}
5417 instruct loadConL32(rRegL dst, immL32 src)
5418 %{
5419 match(Set dst src);
5421 ins_cost(70);
5422 format %{ "movq $dst, $src\t# long (32-bit)" %}
5423 ins_encode(load_immL32(dst, src));
5424 ins_pipe(ialu_reg);
5425 %}
5427 instruct loadConP(rRegP dst, immP con) %{
5428 match(Set dst con);
5430 format %{ "movq $dst, $con\t# ptr" %}
5431 ins_encode(load_immP(dst, con));
5432 ins_pipe(ialu_reg_fat); // XXX
5433 %}
5435 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr)
5436 %{
5437 match(Set dst src);
5438 effect(KILL cr);
5440 ins_cost(50);
5441 format %{ "xorl $dst, $dst\t# ptr" %}
5442 opcode(0x33); /* + rd */
5443 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
5444 ins_pipe(ialu_reg);
5445 %}
5447 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
5448 %{
5449 match(Set dst src);
5450 effect(KILL cr);
5452 ins_cost(60);
5453 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %}
5454 ins_encode(load_immP31(dst, src));
5455 ins_pipe(ialu_reg);
5456 %}
5458 instruct loadConF(regF dst, immF con) %{
5459 match(Set dst con);
5460 ins_cost(125);
5461 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %}
5462 ins_encode %{
5463 __ movflt($dst$$XMMRegister, $constantaddress($con));
5464 %}
5465 ins_pipe(pipe_slow);
5466 %}
5468 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{
5469 match(Set dst src);
5470 effect(KILL cr);
5471 format %{ "xorq $dst, $src\t# compressed NULL ptr" %}
5472 ins_encode %{
5473 __ xorq($dst$$Register, $dst$$Register);
5474 %}
5475 ins_pipe(ialu_reg);
5476 %}
5478 instruct loadConN(rRegN dst, immN src) %{
5479 match(Set dst src);
5481 ins_cost(125);
5482 format %{ "movl $dst, $src\t# compressed ptr" %}
5483 ins_encode %{
5484 address con = (address)$src$$constant;
5485 if (con == NULL) {
5486 ShouldNotReachHere();
5487 } else {
5488 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant);
5489 }
5490 %}
5491 ins_pipe(ialu_reg_fat); // XXX
5492 %}
5494 instruct loadConNKlass(rRegN dst, immNKlass src) %{
5495 match(Set dst src);
5497 ins_cost(125);
5498 format %{ "movl $dst, $src\t# compressed klass ptr" %}
5499 ins_encode %{
5500 address con = (address)$src$$constant;
5501 if (con == NULL) {
5502 ShouldNotReachHere();
5503 } else {
5504 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant);
5505 }
5506 %}
5507 ins_pipe(ialu_reg_fat); // XXX
5508 %}
5510 instruct loadConF0(regF dst, immF0 src)
5511 %{
5512 match(Set dst src);
5513 ins_cost(100);
5515 format %{ "xorps $dst, $dst\t# float 0.0" %}
5516 ins_encode %{
5517 __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
5518 %}
5519 ins_pipe(pipe_slow);
5520 %}
5522 // Use the same format since predicate() can not be used here.
5523 instruct loadConD(regD dst, immD con) %{
5524 match(Set dst con);
5525 ins_cost(125);
5526 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %}
5527 ins_encode %{
5528 __ movdbl($dst$$XMMRegister, $constantaddress($con));
5529 %}
5530 ins_pipe(pipe_slow);
5531 %}
5533 instruct loadConD0(regD dst, immD0 src)
5534 %{
5535 match(Set dst src);
5536 ins_cost(100);
5538 format %{ "xorpd $dst, $dst\t# double 0.0" %}
5539 ins_encode %{
5540 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
5541 %}
5542 ins_pipe(pipe_slow);
5543 %}
5545 instruct loadSSI(rRegI dst, stackSlotI src)
5546 %{
5547 match(Set dst src);
5549 ins_cost(125);
5550 format %{ "movl $dst, $src\t# int stk" %}
5551 opcode(0x8B);
5552 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
5553 ins_pipe(ialu_reg_mem);
5554 %}
5556 instruct loadSSL(rRegL dst, stackSlotL src)
5557 %{
5558 match(Set dst src);
5560 ins_cost(125);
5561 format %{ "movq $dst, $src\t# long stk" %}
5562 opcode(0x8B);
5563 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5564 ins_pipe(ialu_reg_mem);
5565 %}
5567 instruct loadSSP(rRegP dst, stackSlotP src)
5568 %{
5569 match(Set dst src);
5571 ins_cost(125);
5572 format %{ "movq $dst, $src\t# ptr stk" %}
5573 opcode(0x8B);
5574 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
5575 ins_pipe(ialu_reg_mem);
5576 %}
5578 instruct loadSSF(regF dst, stackSlotF src)
5579 %{
5580 match(Set dst src);
5582 ins_cost(125);
5583 format %{ "movss $dst, $src\t# float stk" %}
5584 ins_encode %{
5585 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
5586 %}
5587 ins_pipe(pipe_slow); // XXX
5588 %}
5590 // Use the same format since predicate() can not be used here.
5591 instruct loadSSD(regD dst, stackSlotD src)
5592 %{
5593 match(Set dst src);
5595 ins_cost(125);
5596 format %{ "movsd $dst, $src\t# double stk" %}
5597 ins_encode %{
5598 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
5599 %}
5600 ins_pipe(pipe_slow); // XXX
5601 %}
5603 // Prefetch instructions.
5604 // Must be safe to execute with invalid address (cannot fault).
5606 instruct prefetchr( memory mem ) %{
5607 predicate(ReadPrefetchInstr==3);
5608 match(PrefetchRead mem);
5609 ins_cost(125);
5611 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %}
5612 ins_encode %{
5613 __ prefetchr($mem$$Address);
5614 %}
5615 ins_pipe(ialu_mem);
5616 %}
5618 instruct prefetchrNTA( memory mem ) %{
5619 predicate(ReadPrefetchInstr==0);
5620 match(PrefetchRead mem);
5621 ins_cost(125);
5623 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %}
5624 ins_encode %{
5625 __ prefetchnta($mem$$Address);
5626 %}
5627 ins_pipe(ialu_mem);
5628 %}
5630 instruct prefetchrT0( memory mem ) %{
5631 predicate(ReadPrefetchInstr==1);
5632 match(PrefetchRead mem);
5633 ins_cost(125);
5635 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %}
5636 ins_encode %{
5637 __ prefetcht0($mem$$Address);
5638 %}
5639 ins_pipe(ialu_mem);
5640 %}
5642 instruct prefetchrT2( memory mem ) %{
5643 predicate(ReadPrefetchInstr==2);
5644 match(PrefetchRead mem);
5645 ins_cost(125);
5647 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %}
5648 ins_encode %{
5649 __ prefetcht2($mem$$Address);
5650 %}
5651 ins_pipe(ialu_mem);
5652 %}
5654 instruct prefetchwNTA( memory mem ) %{
5655 match(PrefetchWrite mem);
5656 ins_cost(125);
5658 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %}
5659 ins_encode %{
5660 __ prefetchnta($mem$$Address);
5661 %}
5662 ins_pipe(ialu_mem);
5663 %}
5665 // Prefetch instructions for allocation.
5667 instruct prefetchAlloc( memory mem ) %{
5668 predicate(AllocatePrefetchInstr==3);
5669 match(PrefetchAllocation mem);
5670 ins_cost(125);
5672 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %}
5673 ins_encode %{
5674 __ prefetchw($mem$$Address);
5675 %}
5676 ins_pipe(ialu_mem);
5677 %}
5679 instruct prefetchAllocNTA( memory mem ) %{
5680 predicate(AllocatePrefetchInstr==0);
5681 match(PrefetchAllocation mem);
5682 ins_cost(125);
5684 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %}
5685 ins_encode %{
5686 __ prefetchnta($mem$$Address);
5687 %}
5688 ins_pipe(ialu_mem);
5689 %}
5691 instruct prefetchAllocT0( memory mem ) %{
5692 predicate(AllocatePrefetchInstr==1);
5693 match(PrefetchAllocation mem);
5694 ins_cost(125);
5696 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %}
5697 ins_encode %{
5698 __ prefetcht0($mem$$Address);
5699 %}
5700 ins_pipe(ialu_mem);
5701 %}
5703 instruct prefetchAllocT2( memory mem ) %{
5704 predicate(AllocatePrefetchInstr==2);
5705 match(PrefetchAllocation mem);
5706 ins_cost(125);
5708 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %}
5709 ins_encode %{
5710 __ prefetcht2($mem$$Address);
5711 %}
5712 ins_pipe(ialu_mem);
5713 %}
5715 //----------Store Instructions-------------------------------------------------
5717 // Store Byte
5718 instruct storeB(memory mem, rRegI src)
5719 %{
5720 match(Set mem (StoreB mem src));
5722 ins_cost(125); // XXX
5723 format %{ "movb $mem, $src\t# byte" %}
5724 opcode(0x88);
5725 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem));
5726 ins_pipe(ialu_mem_reg);
5727 %}
5729 // Store Char/Short
5730 instruct storeC(memory mem, rRegI src)
5731 %{
5732 match(Set mem (StoreC mem src));
5734 ins_cost(125); // XXX
5735 format %{ "movw $mem, $src\t# char/short" %}
5736 opcode(0x89);
5737 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
5738 ins_pipe(ialu_mem_reg);
5739 %}
5741 // Store Integer
5742 instruct storeI(memory mem, rRegI src)
5743 %{
5744 match(Set mem (StoreI mem src));
5746 ins_cost(125); // XXX
5747 format %{ "movl $mem, $src\t# int" %}
5748 opcode(0x89);
5749 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
5750 ins_pipe(ialu_mem_reg);
5751 %}
5753 // Store Long
5754 instruct storeL(memory mem, rRegL src)
5755 %{
5756 match(Set mem (StoreL mem src));
5758 ins_cost(125); // XXX
5759 format %{ "movq $mem, $src\t# long" %}
5760 opcode(0x89);
5761 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5762 ins_pipe(ialu_mem_reg); // XXX
5763 %}
5765 // Store Pointer
5766 instruct storeP(memory mem, any_RegP src)
5767 %{
5768 match(Set mem (StoreP mem src));
5770 ins_cost(125); // XXX
5771 format %{ "movq $mem, $src\t# ptr" %}
5772 opcode(0x89);
5773 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
5774 ins_pipe(ialu_mem_reg);
5775 %}
5777 instruct storeImmP0(memory mem, immP0 zero)
5778 %{
5779 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5780 match(Set mem (StoreP mem zero));
5782 ins_cost(125); // XXX
5783 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %}
5784 ins_encode %{
5785 __ movq($mem$$Address, r12);
5786 %}
5787 ins_pipe(ialu_mem_reg);
5788 %}
5790 // Store NULL Pointer, mark word, or other simple pointer constant.
5791 instruct storeImmP(memory mem, immP31 src)
5792 %{
5793 match(Set mem (StoreP mem src));
5795 ins_cost(150); // XXX
5796 format %{ "movq $mem, $src\t# ptr" %}
5797 opcode(0xC7); /* C7 /0 */
5798 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5799 ins_pipe(ialu_mem_imm);
5800 %}
5802 // Store Compressed Pointer
5803 instruct storeN(memory mem, rRegN src)
5804 %{
5805 match(Set mem (StoreN mem src));
5807 ins_cost(125); // XXX
5808 format %{ "movl $mem, $src\t# compressed ptr" %}
5809 ins_encode %{
5810 __ movl($mem$$Address, $src$$Register);
5811 %}
5812 ins_pipe(ialu_mem_reg);
5813 %}
5815 instruct storeNKlass(memory mem, rRegN src)
5816 %{
5817 match(Set mem (StoreNKlass mem src));
5819 ins_cost(125); // XXX
5820 format %{ "movl $mem, $src\t# compressed klass ptr" %}
5821 ins_encode %{
5822 __ movl($mem$$Address, $src$$Register);
5823 %}
5824 ins_pipe(ialu_mem_reg);
5825 %}
5827 instruct storeImmN0(memory mem, immN0 zero)
5828 %{
5829 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL);
5830 match(Set mem (StoreN mem zero));
5832 ins_cost(125); // XXX
5833 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %}
5834 ins_encode %{
5835 __ movl($mem$$Address, r12);
5836 %}
5837 ins_pipe(ialu_mem_reg);
5838 %}
5840 instruct storeImmN(memory mem, immN src)
5841 %{
5842 match(Set mem (StoreN mem src));
5844 ins_cost(150); // XXX
5845 format %{ "movl $mem, $src\t# compressed ptr" %}
5846 ins_encode %{
5847 address con = (address)$src$$constant;
5848 if (con == NULL) {
5849 __ movl($mem$$Address, (int32_t)0);
5850 } else {
5851 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant);
5852 }
5853 %}
5854 ins_pipe(ialu_mem_imm);
5855 %}
5857 instruct storeImmNKlass(memory mem, immNKlass src)
5858 %{
5859 match(Set mem (StoreNKlass mem src));
5861 ins_cost(150); // XXX
5862 format %{ "movl $mem, $src\t# compressed klass ptr" %}
5863 ins_encode %{
5864 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant);
5865 %}
5866 ins_pipe(ialu_mem_imm);
5867 %}
5869 // Store Integer Immediate
5870 instruct storeImmI0(memory mem, immI0 zero)
5871 %{
5872 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5873 match(Set mem (StoreI mem zero));
5875 ins_cost(125); // XXX
5876 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %}
5877 ins_encode %{
5878 __ movl($mem$$Address, r12);
5879 %}
5880 ins_pipe(ialu_mem_reg);
5881 %}
5883 instruct storeImmI(memory mem, immI src)
5884 %{
5885 match(Set mem (StoreI mem src));
5887 ins_cost(150);
5888 format %{ "movl $mem, $src\t# int" %}
5889 opcode(0xC7); /* C7 /0 */
5890 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5891 ins_pipe(ialu_mem_imm);
5892 %}
5894 // Store Long Immediate
5895 instruct storeImmL0(memory mem, immL0 zero)
5896 %{
5897 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5898 match(Set mem (StoreL mem zero));
5900 ins_cost(125); // XXX
5901 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %}
5902 ins_encode %{
5903 __ movq($mem$$Address, r12);
5904 %}
5905 ins_pipe(ialu_mem_reg);
5906 %}
5908 instruct storeImmL(memory mem, immL32 src)
5909 %{
5910 match(Set mem (StoreL mem src));
5912 ins_cost(150);
5913 format %{ "movq $mem, $src\t# long" %}
5914 opcode(0xC7); /* C7 /0 */
5915 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src));
5916 ins_pipe(ialu_mem_imm);
5917 %}
5919 // Store Short/Char Immediate
5920 instruct storeImmC0(memory mem, immI0 zero)
5921 %{
5922 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5923 match(Set mem (StoreC mem zero));
5925 ins_cost(125); // XXX
5926 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %}
5927 ins_encode %{
5928 __ movw($mem$$Address, r12);
5929 %}
5930 ins_pipe(ialu_mem_reg);
5931 %}
5933 instruct storeImmI16(memory mem, immI16 src)
5934 %{
5935 predicate(UseStoreImmI16);
5936 match(Set mem (StoreC mem src));
5938 ins_cost(150);
5939 format %{ "movw $mem, $src\t# short/char" %}
5940 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */
5941 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src));
5942 ins_pipe(ialu_mem_imm);
5943 %}
5945 // Store Byte Immediate
5946 instruct storeImmB0(memory mem, immI0 zero)
5947 %{
5948 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5949 match(Set mem (StoreB mem zero));
5951 ins_cost(125); // XXX
5952 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %}
5953 ins_encode %{
5954 __ movb($mem$$Address, r12);
5955 %}
5956 ins_pipe(ialu_mem_reg);
5957 %}
5959 instruct storeImmB(memory mem, immI8 src)
5960 %{
5961 match(Set mem (StoreB mem src));
5963 ins_cost(150); // XXX
5964 format %{ "movb $mem, $src\t# byte" %}
5965 opcode(0xC6); /* C6 /0 */
5966 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
5967 ins_pipe(ialu_mem_imm);
5968 %}
5970 // Store CMS card-mark Immediate
5971 instruct storeImmCM0_reg(memory mem, immI0 zero)
5972 %{
5973 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
5974 match(Set mem (StoreCM mem zero));
5976 ins_cost(125); // XXX
5977 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %}
5978 ins_encode %{
5979 __ movb($mem$$Address, r12);
5980 %}
5981 ins_pipe(ialu_mem_reg);
5982 %}
5984 instruct storeImmCM0(memory mem, immI0 src)
5985 %{
5986 match(Set mem (StoreCM mem src));
5988 ins_cost(150); // XXX
5989 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %}
5990 opcode(0xC6); /* C6 /0 */
5991 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src));
5992 ins_pipe(ialu_mem_imm);
5993 %}
5995 // Store Float
5996 instruct storeF(memory mem, regF src)
5997 %{
5998 match(Set mem (StoreF mem src));
6000 ins_cost(95); // XXX
6001 format %{ "movss $mem, $src\t# float" %}
6002 ins_encode %{
6003 __ movflt($mem$$Address, $src$$XMMRegister);
6004 %}
6005 ins_pipe(pipe_slow); // XXX
6006 %}
6008 // Store immediate Float value (it is faster than store from XMM register)
6009 instruct storeF0(memory mem, immF0 zero)
6010 %{
6011 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6012 match(Set mem (StoreF mem zero));
6014 ins_cost(25); // XXX
6015 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %}
6016 ins_encode %{
6017 __ movl($mem$$Address, r12);
6018 %}
6019 ins_pipe(ialu_mem_reg);
6020 %}
6022 instruct storeF_imm(memory mem, immF src)
6023 %{
6024 match(Set mem (StoreF mem src));
6026 ins_cost(50);
6027 format %{ "movl $mem, $src\t# float" %}
6028 opcode(0xC7); /* C7 /0 */
6029 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6030 ins_pipe(ialu_mem_imm);
6031 %}
6033 // Store Double
6034 instruct storeD(memory mem, regD src)
6035 %{
6036 match(Set mem (StoreD mem src));
6038 ins_cost(95); // XXX
6039 format %{ "movsd $mem, $src\t# double" %}
6040 ins_encode %{
6041 __ movdbl($mem$$Address, $src$$XMMRegister);
6042 %}
6043 ins_pipe(pipe_slow); // XXX
6044 %}
6046 // Store immediate double 0.0 (it is faster than store from XMM register)
6047 instruct storeD0_imm(memory mem, immD0 src)
6048 %{
6049 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
6050 match(Set mem (StoreD mem src));
6052 ins_cost(50);
6053 format %{ "movq $mem, $src\t# double 0." %}
6054 opcode(0xC7); /* C7 /0 */
6055 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src));
6056 ins_pipe(ialu_mem_imm);
6057 %}
6059 instruct storeD0(memory mem, immD0 zero)
6060 %{
6061 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
6062 match(Set mem (StoreD mem zero));
6064 ins_cost(25); // XXX
6065 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %}
6066 ins_encode %{
6067 __ movq($mem$$Address, r12);
6068 %}
6069 ins_pipe(ialu_mem_reg);
6070 %}
6072 instruct storeSSI(stackSlotI dst, rRegI src)
6073 %{
6074 match(Set dst src);
6076 ins_cost(100);
6077 format %{ "movl $dst, $src\t# int stk" %}
6078 opcode(0x89);
6079 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
6080 ins_pipe( ialu_mem_reg );
6081 %}
6083 instruct storeSSL(stackSlotL dst, rRegL src)
6084 %{
6085 match(Set dst src);
6087 ins_cost(100);
6088 format %{ "movq $dst, $src\t# long stk" %}
6089 opcode(0x89);
6090 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6091 ins_pipe(ialu_mem_reg);
6092 %}
6094 instruct storeSSP(stackSlotP dst, rRegP src)
6095 %{
6096 match(Set dst src);
6098 ins_cost(100);
6099 format %{ "movq $dst, $src\t# ptr stk" %}
6100 opcode(0x89);
6101 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
6102 ins_pipe(ialu_mem_reg);
6103 %}
6105 instruct storeSSF(stackSlotF dst, regF src)
6106 %{
6107 match(Set dst src);
6109 ins_cost(95); // XXX
6110 format %{ "movss $dst, $src\t# float stk" %}
6111 ins_encode %{
6112 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
6113 %}
6114 ins_pipe(pipe_slow); // XXX
6115 %}
6117 instruct storeSSD(stackSlotD dst, regD src)
6118 %{
6119 match(Set dst src);
6121 ins_cost(95); // XXX
6122 format %{ "movsd $dst, $src\t# double stk" %}
6123 ins_encode %{
6124 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
6125 %}
6126 ins_pipe(pipe_slow); // XXX
6127 %}
6129 //----------BSWAP Instructions-------------------------------------------------
6130 instruct bytes_reverse_int(rRegI dst) %{
6131 match(Set dst (ReverseBytesI dst));
6133 format %{ "bswapl $dst" %}
6134 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */
6135 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) );
6136 ins_pipe( ialu_reg );
6137 %}
6139 instruct bytes_reverse_long(rRegL dst) %{
6140 match(Set dst (ReverseBytesL dst));
6142 format %{ "bswapq $dst" %}
6143 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */
6144 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) );
6145 ins_pipe( ialu_reg);
6146 %}
6148 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{
6149 match(Set dst (ReverseBytesUS dst));
6150 effect(KILL cr);
6152 format %{ "bswapl $dst\n\t"
6153 "shrl $dst,16\n\t" %}
6154 ins_encode %{
6155 __ bswapl($dst$$Register);
6156 __ shrl($dst$$Register, 16);
6157 %}
6158 ins_pipe( ialu_reg );
6159 %}
6161 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{
6162 match(Set dst (ReverseBytesS dst));
6163 effect(KILL cr);
6165 format %{ "bswapl $dst\n\t"
6166 "sar $dst,16\n\t" %}
6167 ins_encode %{
6168 __ bswapl($dst$$Register);
6169 __ sarl($dst$$Register, 16);
6170 %}
6171 ins_pipe( ialu_reg );
6172 %}
6174 //---------- Zeros Count Instructions ------------------------------------------
6176 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6177 predicate(UseCountLeadingZerosInstruction);
6178 match(Set dst (CountLeadingZerosI src));
6179 effect(KILL cr);
6181 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %}
6182 ins_encode %{
6183 __ lzcntl($dst$$Register, $src$$Register);
6184 %}
6185 ins_pipe(ialu_reg);
6186 %}
6188 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{
6189 predicate(!UseCountLeadingZerosInstruction);
6190 match(Set dst (CountLeadingZerosI src));
6191 effect(KILL cr);
6193 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t"
6194 "jnz skip\n\t"
6195 "movl $dst, -1\n"
6196 "skip:\n\t"
6197 "negl $dst\n\t"
6198 "addl $dst, 31" %}
6199 ins_encode %{
6200 Register Rdst = $dst$$Register;
6201 Register Rsrc = $src$$Register;
6202 Label skip;
6203 __ bsrl(Rdst, Rsrc);
6204 __ jccb(Assembler::notZero, skip);
6205 __ movl(Rdst, -1);
6206 __ bind(skip);
6207 __ negl(Rdst);
6208 __ addl(Rdst, BitsPerInt - 1);
6209 %}
6210 ins_pipe(ialu_reg);
6211 %}
6213 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6214 predicate(UseCountLeadingZerosInstruction);
6215 match(Set dst (CountLeadingZerosL src));
6216 effect(KILL cr);
6218 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %}
6219 ins_encode %{
6220 __ lzcntq($dst$$Register, $src$$Register);
6221 %}
6222 ins_pipe(ialu_reg);
6223 %}
6225 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{
6226 predicate(!UseCountLeadingZerosInstruction);
6227 match(Set dst (CountLeadingZerosL src));
6228 effect(KILL cr);
6230 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t"
6231 "jnz skip\n\t"
6232 "movl $dst, -1\n"
6233 "skip:\n\t"
6234 "negl $dst\n\t"
6235 "addl $dst, 63" %}
6236 ins_encode %{
6237 Register Rdst = $dst$$Register;
6238 Register Rsrc = $src$$Register;
6239 Label skip;
6240 __ bsrq(Rdst, Rsrc);
6241 __ jccb(Assembler::notZero, skip);
6242 __ movl(Rdst, -1);
6243 __ bind(skip);
6244 __ negl(Rdst);
6245 __ addl(Rdst, BitsPerLong - 1);
6246 %}
6247 ins_pipe(ialu_reg);
6248 %}
6250 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{
6251 match(Set dst (CountTrailingZerosI src));
6252 effect(KILL cr);
6254 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t"
6255 "jnz done\n\t"
6256 "movl $dst, 32\n"
6257 "done:" %}
6258 ins_encode %{
6259 Register Rdst = $dst$$Register;
6260 Label done;
6261 __ bsfl(Rdst, $src$$Register);
6262 __ jccb(Assembler::notZero, done);
6263 __ movl(Rdst, BitsPerInt);
6264 __ bind(done);
6265 %}
6266 ins_pipe(ialu_reg);
6267 %}
6269 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{
6270 match(Set dst (CountTrailingZerosL src));
6271 effect(KILL cr);
6273 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t"
6274 "jnz done\n\t"
6275 "movl $dst, 64\n"
6276 "done:" %}
6277 ins_encode %{
6278 Register Rdst = $dst$$Register;
6279 Label done;
6280 __ bsfq(Rdst, $src$$Register);
6281 __ jccb(Assembler::notZero, done);
6282 __ movl(Rdst, BitsPerLong);
6283 __ bind(done);
6284 %}
6285 ins_pipe(ialu_reg);
6286 %}
6289 //---------- Population Count Instructions -------------------------------------
6291 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{
6292 predicate(UsePopCountInstruction);
6293 match(Set dst (PopCountI src));
6294 effect(KILL cr);
6296 format %{ "popcnt $dst, $src" %}
6297 ins_encode %{
6298 __ popcntl($dst$$Register, $src$$Register);
6299 %}
6300 ins_pipe(ialu_reg);
6301 %}
6303 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{
6304 predicate(UsePopCountInstruction);
6305 match(Set dst (PopCountI (LoadI mem)));
6306 effect(KILL cr);
6308 format %{ "popcnt $dst, $mem" %}
6309 ins_encode %{
6310 __ popcntl($dst$$Register, $mem$$Address);
6311 %}
6312 ins_pipe(ialu_reg);
6313 %}
6315 // Note: Long.bitCount(long) returns an int.
6316 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{
6317 predicate(UsePopCountInstruction);
6318 match(Set dst (PopCountL src));
6319 effect(KILL cr);
6321 format %{ "popcnt $dst, $src" %}
6322 ins_encode %{
6323 __ popcntq($dst$$Register, $src$$Register);
6324 %}
6325 ins_pipe(ialu_reg);
6326 %}
6328 // Note: Long.bitCount(long) returns an int.
6329 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{
6330 predicate(UsePopCountInstruction);
6331 match(Set dst (PopCountL (LoadL mem)));
6332 effect(KILL cr);
6334 format %{ "popcnt $dst, $mem" %}
6335 ins_encode %{
6336 __ popcntq($dst$$Register, $mem$$Address);
6337 %}
6338 ins_pipe(ialu_reg);
6339 %}
6342 //----------MemBar Instructions-----------------------------------------------
6343 // Memory barrier flavors
6345 instruct membar_acquire()
6346 %{
6347 match(MemBarAcquire);
6348 match(LoadFence);
6349 ins_cost(0);
6351 size(0);
6352 format %{ "MEMBAR-acquire ! (empty encoding)" %}
6353 ins_encode();
6354 ins_pipe(empty);
6355 %}
6357 instruct membar_acquire_lock()
6358 %{
6359 match(MemBarAcquireLock);
6360 ins_cost(0);
6362 size(0);
6363 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %}
6364 ins_encode();
6365 ins_pipe(empty);
6366 %}
6368 instruct membar_release()
6369 %{
6370 match(MemBarRelease);
6371 match(StoreFence);
6372 ins_cost(0);
6374 size(0);
6375 format %{ "MEMBAR-release ! (empty encoding)" %}
6376 ins_encode();
6377 ins_pipe(empty);
6378 %}
6380 instruct membar_release_lock()
6381 %{
6382 match(MemBarReleaseLock);
6383 ins_cost(0);
6385 size(0);
6386 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
6387 ins_encode();
6388 ins_pipe(empty);
6389 %}
6391 instruct membar_volatile(rFlagsReg cr) %{
6392 match(MemBarVolatile);
6393 effect(KILL cr);
6394 ins_cost(400);
6396 format %{
6397 $$template
6398 if (os::is_MP()) {
6399 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
6400 } else {
6401 $$emit$$"MEMBAR-volatile ! (empty encoding)"
6402 }
6403 %}
6404 ins_encode %{
6405 __ membar(Assembler::StoreLoad);
6406 %}
6407 ins_pipe(pipe_slow);
6408 %}
6410 instruct unnecessary_membar_volatile()
6411 %{
6412 match(MemBarVolatile);
6413 predicate(Matcher::post_store_load_barrier(n));
6414 ins_cost(0);
6416 size(0);
6417 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
6418 ins_encode();
6419 ins_pipe(empty);
6420 %}
6422 instruct membar_storestore() %{
6423 match(MemBarStoreStore);
6424 ins_cost(0);
6426 size(0);
6427 format %{ "MEMBAR-storestore (empty encoding)" %}
6428 ins_encode( );
6429 ins_pipe(empty);
6430 %}
6432 //----------Move Instructions--------------------------------------------------
6434 instruct castX2P(rRegP dst, rRegL src)
6435 %{
6436 match(Set dst (CastX2P src));
6438 format %{ "movq $dst, $src\t# long->ptr" %}
6439 ins_encode %{
6440 if ($dst$$reg != $src$$reg) {
6441 __ movptr($dst$$Register, $src$$Register);
6442 }
6443 %}
6444 ins_pipe(ialu_reg_reg); // XXX
6445 %}
6447 instruct castP2X(rRegL dst, rRegP src)
6448 %{
6449 match(Set dst (CastP2X src));
6451 format %{ "movq $dst, $src\t# ptr -> long" %}
6452 ins_encode %{
6453 if ($dst$$reg != $src$$reg) {
6454 __ movptr($dst$$Register, $src$$Register);
6455 }
6456 %}
6457 ins_pipe(ialu_reg_reg); // XXX
6458 %}
6460 // Convert oop into int for vectors alignment masking
6461 instruct convP2I(rRegI dst, rRegP src)
6462 %{
6463 match(Set dst (ConvL2I (CastP2X src)));
6465 format %{ "movl $dst, $src\t# ptr -> int" %}
6466 ins_encode %{
6467 __ movl($dst$$Register, $src$$Register);
6468 %}
6469 ins_pipe(ialu_reg_reg); // XXX
6470 %}
6472 // Convert compressed oop into int for vectors alignment masking
6473 // in case of 32bit oops (heap < 4Gb).
6474 instruct convN2I(rRegI dst, rRegN src)
6475 %{
6476 predicate(Universe::narrow_oop_shift() == 0);
6477 match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6479 format %{ "movl $dst, $src\t# compressed ptr -> int" %}
6480 ins_encode %{
6481 __ movl($dst$$Register, $src$$Register);
6482 %}
6483 ins_pipe(ialu_reg_reg); // XXX
6484 %}
6486 // Convert oop pointer into compressed form
6487 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
6488 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
6489 match(Set dst (EncodeP src));
6490 effect(KILL cr);
6491 format %{ "encode_heap_oop $dst,$src" %}
6492 ins_encode %{
6493 Register s = $src$$Register;
6494 Register d = $dst$$Register;
6495 if (s != d) {
6496 __ movq(d, s);
6497 }
6498 __ encode_heap_oop(d);
6499 %}
6500 ins_pipe(ialu_reg_long);
6501 %}
6503 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6504 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
6505 match(Set dst (EncodeP src));
6506 effect(KILL cr);
6507 format %{ "encode_heap_oop_not_null $dst,$src" %}
6508 ins_encode %{
6509 __ encode_heap_oop_not_null($dst$$Register, $src$$Register);
6510 %}
6511 ins_pipe(ialu_reg_long);
6512 %}
6514 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
6515 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull &&
6516 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant);
6517 match(Set dst (DecodeN src));
6518 effect(KILL cr);
6519 format %{ "decode_heap_oop $dst,$src" %}
6520 ins_encode %{
6521 Register s = $src$$Register;
6522 Register d = $dst$$Register;
6523 if (s != d) {
6524 __ movq(d, s);
6525 }
6526 __ decode_heap_oop(d);
6527 %}
6528 ins_pipe(ialu_reg_long);
6529 %}
6531 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6532 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull ||
6533 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant);
6534 match(Set dst (DecodeN src));
6535 effect(KILL cr);
6536 format %{ "decode_heap_oop_not_null $dst,$src" %}
6537 ins_encode %{
6538 Register s = $src$$Register;
6539 Register d = $dst$$Register;
6540 if (s != d) {
6541 __ decode_heap_oop_not_null(d, s);
6542 } else {
6543 __ decode_heap_oop_not_null(d);
6544 }
6545 %}
6546 ins_pipe(ialu_reg_long);
6547 %}
6549 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6550 match(Set dst (EncodePKlass src));
6551 effect(KILL cr);
6552 format %{ "encode_klass_not_null $dst,$src" %}
6553 ins_encode %{
6554 __ encode_klass_not_null($dst$$Register, $src$$Register);
6555 %}
6556 ins_pipe(ialu_reg_long);
6557 %}
6559 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{
6560 match(Set dst (DecodeNKlass src));
6561 effect(KILL cr);
6562 format %{ "decode_klass_not_null $dst,$src" %}
6563 ins_encode %{
6564 Register s = $src$$Register;
6565 Register d = $dst$$Register;
6566 if (s != d) {
6567 __ decode_klass_not_null(d, s);
6568 } else {
6569 __ decode_klass_not_null(d);
6570 }
6571 %}
6572 ins_pipe(ialu_reg_long);
6573 %}
6576 //----------Conditional Move---------------------------------------------------
6577 // Jump
6578 // dummy instruction for generating temp registers
6579 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{
6580 match(Jump (LShiftL switch_val shift));
6581 ins_cost(350);
6582 predicate(false);
6583 effect(TEMP dest);
6585 format %{ "leaq $dest, [$constantaddress]\n\t"
6586 "jmp [$dest + $switch_val << $shift]\n\t" %}
6587 ins_encode %{
6588 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6589 // to do that and the compiler is using that register as one it can allocate.
6590 // So we build it all by hand.
6591 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant);
6592 // ArrayAddress dispatch(table, index);
6593 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant);
6594 __ lea($dest$$Register, $constantaddress);
6595 __ jmp(dispatch);
6596 %}
6597 ins_pipe(pipe_jmp);
6598 %}
6600 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{
6601 match(Jump (AddL (LShiftL switch_val shift) offset));
6602 ins_cost(350);
6603 effect(TEMP dest);
6605 format %{ "leaq $dest, [$constantaddress]\n\t"
6606 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %}
6607 ins_encode %{
6608 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6609 // to do that and the compiler is using that register as one it can allocate.
6610 // So we build it all by hand.
6611 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6612 // ArrayAddress dispatch(table, index);
6613 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant);
6614 __ lea($dest$$Register, $constantaddress);
6615 __ jmp(dispatch);
6616 %}
6617 ins_pipe(pipe_jmp);
6618 %}
6620 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{
6621 match(Jump switch_val);
6622 ins_cost(350);
6623 effect(TEMP dest);
6625 format %{ "leaq $dest, [$constantaddress]\n\t"
6626 "jmp [$dest + $switch_val]\n\t" %}
6627 ins_encode %{
6628 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10
6629 // to do that and the compiler is using that register as one it can allocate.
6630 // So we build it all by hand.
6631 // Address index(noreg, switch_reg, Address::times_1);
6632 // ArrayAddress dispatch(table, index);
6633 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1);
6634 __ lea($dest$$Register, $constantaddress);
6635 __ jmp(dispatch);
6636 %}
6637 ins_pipe(pipe_jmp);
6638 %}
6640 // Conditional move
6641 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop)
6642 %{
6643 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6645 ins_cost(200); // XXX
6646 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
6647 opcode(0x0F, 0x40);
6648 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6649 ins_pipe(pipe_cmov_reg);
6650 %}
6652 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{
6653 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6655 ins_cost(200); // XXX
6656 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
6657 opcode(0x0F, 0x40);
6658 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6659 ins_pipe(pipe_cmov_reg);
6660 %}
6662 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{
6663 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
6664 ins_cost(200);
6665 expand %{
6666 cmovI_regU(cop, cr, dst, src);
6667 %}
6668 %}
6670 // Conditional move
6671 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{
6672 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6674 ins_cost(250); // XXX
6675 format %{ "cmovl$cop $dst, $src\t# signed, int" %}
6676 opcode(0x0F, 0x40);
6677 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
6678 ins_pipe(pipe_cmov_mem);
6679 %}
6681 // Conditional move
6682 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
6683 %{
6684 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6686 ins_cost(250); // XXX
6687 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %}
6688 opcode(0x0F, 0x40);
6689 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src));
6690 ins_pipe(pipe_cmov_mem);
6691 %}
6693 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{
6694 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
6695 ins_cost(250);
6696 expand %{
6697 cmovI_memU(cop, cr, dst, src);
6698 %}
6699 %}
6701 // Conditional move
6702 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
6703 %{
6704 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6706 ins_cost(200); // XXX
6707 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
6708 opcode(0x0F, 0x40);
6709 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6710 ins_pipe(pipe_cmov_reg);
6711 %}
6713 // Conditional move
6714 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src)
6715 %{
6716 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6718 ins_cost(200); // XXX
6719 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
6720 opcode(0x0F, 0x40);
6721 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
6722 ins_pipe(pipe_cmov_reg);
6723 %}
6725 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{
6726 match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
6727 ins_cost(200);
6728 expand %{
6729 cmovN_regU(cop, cr, dst, src);
6730 %}
6731 %}
6733 // Conditional move
6734 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
6735 %{
6736 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6738 ins_cost(200); // XXX
6739 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %}
6740 opcode(0x0F, 0x40);
6741 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6742 ins_pipe(pipe_cmov_reg); // XXX
6743 %}
6745 // Conditional move
6746 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src)
6747 %{
6748 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6750 ins_cost(200); // XXX
6751 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %}
6752 opcode(0x0F, 0x40);
6753 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6754 ins_pipe(pipe_cmov_reg); // XXX
6755 %}
6757 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{
6758 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
6759 ins_cost(200);
6760 expand %{
6761 cmovP_regU(cop, cr, dst, src);
6762 %}
6763 %}
6765 // DISABLED: Requires the ADLC to emit a bottom_type call that
6766 // correctly meets the two pointer arguments; one is an incoming
6767 // register but the other is a memory operand. ALSO appears to
6768 // be buggy with implicit null checks.
6769 //
6770 //// Conditional move
6771 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src)
6772 //%{
6773 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
6774 // ins_cost(250);
6775 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
6776 // opcode(0x0F,0x40);
6777 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
6778 // ins_pipe( pipe_cmov_mem );
6779 //%}
6780 //
6781 //// Conditional move
6782 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src)
6783 //%{
6784 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src))));
6785 // ins_cost(250);
6786 // format %{ "CMOV$cop $dst,$src\t# ptr" %}
6787 // opcode(0x0F,0x40);
6788 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) );
6789 // ins_pipe( pipe_cmov_mem );
6790 //%}
6792 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src)
6793 %{
6794 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
6796 ins_cost(200); // XXX
6797 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
6798 opcode(0x0F, 0x40);
6799 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6800 ins_pipe(pipe_cmov_reg); // XXX
6801 %}
6803 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src)
6804 %{
6805 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
6807 ins_cost(200); // XXX
6808 format %{ "cmovq$cop $dst, $src\t# signed, long" %}
6809 opcode(0x0F, 0x40);
6810 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
6811 ins_pipe(pipe_cmov_mem); // XXX
6812 %}
6814 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src)
6815 %{
6816 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
6818 ins_cost(200); // XXX
6819 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
6820 opcode(0x0F, 0x40);
6821 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src));
6822 ins_pipe(pipe_cmov_reg); // XXX
6823 %}
6825 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{
6826 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
6827 ins_cost(200);
6828 expand %{
6829 cmovL_regU(cop, cr, dst, src);
6830 %}
6831 %}
6833 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src)
6834 %{
6835 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
6837 ins_cost(200); // XXX
6838 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %}
6839 opcode(0x0F, 0x40);
6840 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src));
6841 ins_pipe(pipe_cmov_mem); // XXX
6842 %}
6844 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{
6845 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src))));
6846 ins_cost(200);
6847 expand %{
6848 cmovL_memU(cop, cr, dst, src);
6849 %}
6850 %}
6852 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src)
6853 %{
6854 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
6856 ins_cost(200); // XXX
6857 format %{ "jn$cop skip\t# signed cmove float\n\t"
6858 "movss $dst, $src\n"
6859 "skip:" %}
6860 ins_encode %{
6861 Label Lskip;
6862 // Invert sense of branch from sense of CMOV
6863 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
6864 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
6865 __ bind(Lskip);
6866 %}
6867 ins_pipe(pipe_slow);
6868 %}
6870 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src)
6871 // %{
6872 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src))));
6874 // ins_cost(200); // XXX
6875 // format %{ "jn$cop skip\t# signed cmove float\n\t"
6876 // "movss $dst, $src\n"
6877 // "skip:" %}
6878 // ins_encode(enc_cmovf_mem_branch(cop, dst, src));
6879 // ins_pipe(pipe_slow);
6880 // %}
6882 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src)
6883 %{
6884 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
6886 ins_cost(200); // XXX
6887 format %{ "jn$cop skip\t# unsigned cmove float\n\t"
6888 "movss $dst, $src\n"
6889 "skip:" %}
6890 ins_encode %{
6891 Label Lskip;
6892 // Invert sense of branch from sense of CMOV
6893 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
6894 __ movflt($dst$$XMMRegister, $src$$XMMRegister);
6895 __ bind(Lskip);
6896 %}
6897 ins_pipe(pipe_slow);
6898 %}
6900 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{
6901 match(Set dst (CMoveF (Binary cop cr) (Binary dst src)));
6902 ins_cost(200);
6903 expand %{
6904 cmovF_regU(cop, cr, dst, src);
6905 %}
6906 %}
6908 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src)
6909 %{
6910 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
6912 ins_cost(200); // XXX
6913 format %{ "jn$cop skip\t# signed cmove double\n\t"
6914 "movsd $dst, $src\n"
6915 "skip:" %}
6916 ins_encode %{
6917 Label Lskip;
6918 // Invert sense of branch from sense of CMOV
6919 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
6920 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
6921 __ bind(Lskip);
6922 %}
6923 ins_pipe(pipe_slow);
6924 %}
6926 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src)
6927 %{
6928 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
6930 ins_cost(200); // XXX
6931 format %{ "jn$cop skip\t# unsigned cmove double\n\t"
6932 "movsd $dst, $src\n"
6933 "skip:" %}
6934 ins_encode %{
6935 Label Lskip;
6936 // Invert sense of branch from sense of CMOV
6937 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
6938 __ movdbl($dst$$XMMRegister, $src$$XMMRegister);
6939 __ bind(Lskip);
6940 %}
6941 ins_pipe(pipe_slow);
6942 %}
6944 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{
6945 match(Set dst (CMoveD (Binary cop cr) (Binary dst src)));
6946 ins_cost(200);
6947 expand %{
6948 cmovD_regU(cop, cr, dst, src);
6949 %}
6950 %}
6952 //----------Arithmetic Instructions--------------------------------------------
6953 //----------Addition Instructions----------------------------------------------
6955 instruct addExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
6956 %{
6957 match(AddExactI dst src);
6958 effect(DEF cr);
6960 format %{ "addl $dst, $src\t# addExact int" %}
6961 ins_encode %{
6962 __ addl($dst$$Register, $src$$Register);
6963 %}
6964 ins_pipe(ialu_reg_reg);
6965 %}
6967 instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr)
6968 %{
6969 match(AddExactI dst src);
6970 effect(DEF cr);
6972 format %{ "addl $dst, $src\t# addExact int" %}
6973 ins_encode %{
6974 __ addl($dst$$Register, $src$$constant);
6975 %}
6976 ins_pipe(ialu_reg_reg);
6977 %}
6979 instruct addExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
6980 %{
6981 match(AddExactI dst (LoadI src));
6982 effect(DEF cr);
6984 ins_cost(125); // XXX
6985 format %{ "addl $dst, $src\t# addExact int" %}
6986 ins_encode %{
6987 __ addl($dst$$Register, $src$$Address);
6988 %}
6990 ins_pipe(ialu_reg_mem);
6991 %}
6993 instruct addExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
6994 %{
6995 match(AddExactL dst src);
6996 effect(DEF cr);
6998 format %{ "addq $dst, $src\t# addExact long" %}
6999 ins_encode %{
7000 __ addq($dst$$Register, $src$$Register);
7001 %}
7002 ins_pipe(ialu_reg_reg);
7003 %}
7005 instruct addExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr)
7006 %{
7007 match(AddExactL dst src);
7008 effect(DEF cr);
7010 format %{ "addq $dst, $src\t# addExact long" %}
7011 ins_encode %{
7012 __ addq($dst$$Register, $src$$constant);
7013 %}
7014 ins_pipe(ialu_reg_reg);
7015 %}
7017 instruct addExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr)
7018 %{
7019 match(AddExactL dst (LoadL src));
7020 effect(DEF cr);
7022 ins_cost(125); // XXX
7023 format %{ "addq $dst, $src\t# addExact long" %}
7024 ins_encode %{
7025 __ addq($dst$$Register, $src$$Address);
7026 %}
7028 ins_pipe(ialu_reg_mem);
7029 %}
7031 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7032 %{
7033 match(Set dst (AddI dst src));
7034 effect(KILL cr);
7036 format %{ "addl $dst, $src\t# int" %}
7037 opcode(0x03);
7038 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
7039 ins_pipe(ialu_reg_reg);
7040 %}
7042 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7043 %{
7044 match(Set dst (AddI dst src));
7045 effect(KILL cr);
7047 format %{ "addl $dst, $src\t# int" %}
7048 opcode(0x81, 0x00); /* /0 id */
7049 ins_encode(OpcSErm(dst, src), Con8or32(src));
7050 ins_pipe( ialu_reg );
7051 %}
7053 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
7054 %{
7055 match(Set dst (AddI dst (LoadI src)));
7056 effect(KILL cr);
7058 ins_cost(125); // XXX
7059 format %{ "addl $dst, $src\t# int" %}
7060 opcode(0x03);
7061 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
7062 ins_pipe(ialu_reg_mem);
7063 %}
7065 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
7066 %{
7067 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7068 effect(KILL cr);
7070 ins_cost(150); // XXX
7071 format %{ "addl $dst, $src\t# int" %}
7072 opcode(0x01); /* Opcode 01 /r */
7073 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
7074 ins_pipe(ialu_mem_reg);
7075 %}
7077 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr)
7078 %{
7079 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7080 effect(KILL cr);
7082 ins_cost(125); // XXX
7083 format %{ "addl $dst, $src\t# int" %}
7084 opcode(0x81); /* Opcode 81 /0 id */
7085 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
7086 ins_pipe(ialu_mem_imm);
7087 %}
7089 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
7090 %{
7091 predicate(UseIncDec);
7092 match(Set dst (AddI dst src));
7093 effect(KILL cr);
7095 format %{ "incl $dst\t# int" %}
7096 opcode(0xFF, 0x00); // FF /0
7097 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7098 ins_pipe(ialu_reg);
7099 %}
7101 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr)
7102 %{
7103 predicate(UseIncDec);
7104 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7105 effect(KILL cr);
7107 ins_cost(125); // XXX
7108 format %{ "incl $dst\t# int" %}
7109 opcode(0xFF); /* Opcode FF /0 */
7110 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst));
7111 ins_pipe(ialu_mem_imm);
7112 %}
7114 // XXX why does that use AddI
7115 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr)
7116 %{
7117 predicate(UseIncDec);
7118 match(Set dst (AddI dst src));
7119 effect(KILL cr);
7121 format %{ "decl $dst\t# int" %}
7122 opcode(0xFF, 0x01); // FF /1
7123 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7124 ins_pipe(ialu_reg);
7125 %}
7127 // XXX why does that use AddI
7128 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr)
7129 %{
7130 predicate(UseIncDec);
7131 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7132 effect(KILL cr);
7134 ins_cost(125); // XXX
7135 format %{ "decl $dst\t# int" %}
7136 opcode(0xFF); /* Opcode FF /1 */
7137 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst));
7138 ins_pipe(ialu_mem_imm);
7139 %}
7141 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1)
7142 %{
7143 match(Set dst (AddI src0 src1));
7145 ins_cost(110);
7146 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %}
7147 opcode(0x8D); /* 0x8D /r */
7148 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
7149 ins_pipe(ialu_reg_reg);
7150 %}
7152 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7153 %{
7154 match(Set dst (AddL dst src));
7155 effect(KILL cr);
7157 format %{ "addq $dst, $src\t# long" %}
7158 opcode(0x03);
7159 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7160 ins_pipe(ialu_reg_reg);
7161 %}
7163 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
7164 %{
7165 match(Set dst (AddL dst src));
7166 effect(KILL cr);
7168 format %{ "addq $dst, $src\t# long" %}
7169 opcode(0x81, 0x00); /* /0 id */
7170 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7171 ins_pipe( ialu_reg );
7172 %}
7174 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
7175 %{
7176 match(Set dst (AddL dst (LoadL src)));
7177 effect(KILL cr);
7179 ins_cost(125); // XXX
7180 format %{ "addq $dst, $src\t# long" %}
7181 opcode(0x03);
7182 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
7183 ins_pipe(ialu_reg_mem);
7184 %}
7186 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
7187 %{
7188 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7189 effect(KILL cr);
7191 ins_cost(150); // XXX
7192 format %{ "addq $dst, $src\t# long" %}
7193 opcode(0x01); /* Opcode 01 /r */
7194 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7195 ins_pipe(ialu_mem_reg);
7196 %}
7198 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
7199 %{
7200 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7201 effect(KILL cr);
7203 ins_cost(125); // XXX
7204 format %{ "addq $dst, $src\t# long" %}
7205 opcode(0x81); /* Opcode 81 /0 id */
7206 ins_encode(REX_mem_wide(dst),
7207 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src));
7208 ins_pipe(ialu_mem_imm);
7209 %}
7211 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr)
7212 %{
7213 predicate(UseIncDec);
7214 match(Set dst (AddL dst src));
7215 effect(KILL cr);
7217 format %{ "incq $dst\t# long" %}
7218 opcode(0xFF, 0x00); // FF /0
7219 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7220 ins_pipe(ialu_reg);
7221 %}
7223 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr)
7224 %{
7225 predicate(UseIncDec);
7226 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7227 effect(KILL cr);
7229 ins_cost(125); // XXX
7230 format %{ "incq $dst\t# long" %}
7231 opcode(0xFF); /* Opcode FF /0 */
7232 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst));
7233 ins_pipe(ialu_mem_imm);
7234 %}
7236 // XXX why does that use AddL
7237 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr)
7238 %{
7239 predicate(UseIncDec);
7240 match(Set dst (AddL dst src));
7241 effect(KILL cr);
7243 format %{ "decq $dst\t# long" %}
7244 opcode(0xFF, 0x01); // FF /1
7245 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7246 ins_pipe(ialu_reg);
7247 %}
7249 // XXX why does that use AddL
7250 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr)
7251 %{
7252 predicate(UseIncDec);
7253 match(Set dst (StoreL dst (AddL (LoadL dst) src)));
7254 effect(KILL cr);
7256 ins_cost(125); // XXX
7257 format %{ "decq $dst\t# long" %}
7258 opcode(0xFF); /* Opcode FF /1 */
7259 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst));
7260 ins_pipe(ialu_mem_imm);
7261 %}
7263 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1)
7264 %{
7265 match(Set dst (AddL src0 src1));
7267 ins_cost(110);
7268 format %{ "leaq $dst, [$src0 + $src1]\t# long" %}
7269 opcode(0x8D); /* 0x8D /r */
7270 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX
7271 ins_pipe(ialu_reg_reg);
7272 %}
7274 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr)
7275 %{
7276 match(Set dst (AddP dst src));
7277 effect(KILL cr);
7279 format %{ "addq $dst, $src\t# ptr" %}
7280 opcode(0x03);
7281 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7282 ins_pipe(ialu_reg_reg);
7283 %}
7285 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr)
7286 %{
7287 match(Set dst (AddP dst src));
7288 effect(KILL cr);
7290 format %{ "addq $dst, $src\t# ptr" %}
7291 opcode(0x81, 0x00); /* /0 id */
7292 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7293 ins_pipe( ialu_reg );
7294 %}
7296 // XXX addP mem ops ????
7298 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1)
7299 %{
7300 match(Set dst (AddP src0 src1));
7302 ins_cost(110);
7303 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %}
7304 opcode(0x8D); /* 0x8D /r */
7305 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX
7306 ins_pipe(ialu_reg_reg);
7307 %}
7309 instruct checkCastPP(rRegP dst)
7310 %{
7311 match(Set dst (CheckCastPP dst));
7313 size(0);
7314 format %{ "# checkcastPP of $dst" %}
7315 ins_encode(/* empty encoding */);
7316 ins_pipe(empty);
7317 %}
7319 instruct castPP(rRegP dst)
7320 %{
7321 match(Set dst (CastPP dst));
7323 size(0);
7324 format %{ "# castPP of $dst" %}
7325 ins_encode(/* empty encoding */);
7326 ins_pipe(empty);
7327 %}
7329 instruct castII(rRegI dst)
7330 %{
7331 match(Set dst (CastII dst));
7333 size(0);
7334 format %{ "# castII of $dst" %}
7335 ins_encode(/* empty encoding */);
7336 ins_cost(0);
7337 ins_pipe(empty);
7338 %}
7340 // LoadP-locked same as a regular LoadP when used with compare-swap
7341 instruct loadPLocked(rRegP dst, memory mem)
7342 %{
7343 match(Set dst (LoadPLocked mem));
7345 ins_cost(125); // XXX
7346 format %{ "movq $dst, $mem\t# ptr locked" %}
7347 opcode(0x8B);
7348 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
7349 ins_pipe(ialu_reg_mem); // XXX
7350 %}
7352 // Conditional-store of the updated heap-top.
7353 // Used during allocation of the shared heap.
7354 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
7356 instruct storePConditional(memory heap_top_ptr,
7357 rax_RegP oldval, rRegP newval,
7358 rFlagsReg cr)
7359 %{
7360 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
7362 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
7363 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
7364 opcode(0x0F, 0xB1);
7365 ins_encode(lock_prefix,
7366 REX_reg_mem_wide(newval, heap_top_ptr),
7367 OpcP, OpcS,
7368 reg_mem(newval, heap_top_ptr));
7369 ins_pipe(pipe_cmpxchg);
7370 %}
7372 // Conditional-store of an int value.
7373 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
7374 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr)
7375 %{
7376 match(Set cr (StoreIConditional mem (Binary oldval newval)));
7377 effect(KILL oldval);
7379 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7380 opcode(0x0F, 0xB1);
7381 ins_encode(lock_prefix,
7382 REX_reg_mem(newval, mem),
7383 OpcP, OpcS,
7384 reg_mem(newval, mem));
7385 ins_pipe(pipe_cmpxchg);
7386 %}
7388 // Conditional-store of a long value.
7389 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG.
7390 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr)
7391 %{
7392 match(Set cr (StoreLConditional mem (Binary oldval newval)));
7393 effect(KILL oldval);
7395 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7396 opcode(0x0F, 0xB1);
7397 ins_encode(lock_prefix,
7398 REX_reg_mem_wide(newval, mem),
7399 OpcP, OpcS,
7400 reg_mem(newval, mem));
7401 ins_pipe(pipe_cmpxchg);
7402 %}
7405 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7406 instruct compareAndSwapP(rRegI res,
7407 memory mem_ptr,
7408 rax_RegP oldval, rRegP newval,
7409 rFlagsReg cr)
7410 %{
7411 predicate(VM_Version::supports_cx8());
7412 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7413 effect(KILL cr, KILL oldval);
7415 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7416 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7417 "sete $res\n\t"
7418 "movzbl $res, $res" %}
7419 opcode(0x0F, 0xB1);
7420 ins_encode(lock_prefix,
7421 REX_reg_mem_wide(newval, mem_ptr),
7422 OpcP, OpcS,
7423 reg_mem(newval, mem_ptr),
7424 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7425 REX_reg_breg(res, res), // movzbl
7426 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7427 ins_pipe( pipe_cmpxchg );
7428 %}
7430 instruct compareAndSwapL(rRegI res,
7431 memory mem_ptr,
7432 rax_RegL oldval, rRegL newval,
7433 rFlagsReg cr)
7434 %{
7435 predicate(VM_Version::supports_cx8());
7436 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7437 effect(KILL cr, KILL oldval);
7439 format %{ "cmpxchgq $mem_ptr,$newval\t# "
7440 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7441 "sete $res\n\t"
7442 "movzbl $res, $res" %}
7443 opcode(0x0F, 0xB1);
7444 ins_encode(lock_prefix,
7445 REX_reg_mem_wide(newval, mem_ptr),
7446 OpcP, OpcS,
7447 reg_mem(newval, mem_ptr),
7448 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7449 REX_reg_breg(res, res), // movzbl
7450 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7451 ins_pipe( pipe_cmpxchg );
7452 %}
7454 instruct compareAndSwapI(rRegI res,
7455 memory mem_ptr,
7456 rax_RegI oldval, rRegI newval,
7457 rFlagsReg cr)
7458 %{
7459 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
7460 effect(KILL cr, KILL oldval);
7462 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7463 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7464 "sete $res\n\t"
7465 "movzbl $res, $res" %}
7466 opcode(0x0F, 0xB1);
7467 ins_encode(lock_prefix,
7468 REX_reg_mem(newval, mem_ptr),
7469 OpcP, OpcS,
7470 reg_mem(newval, mem_ptr),
7471 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7472 REX_reg_breg(res, res), // movzbl
7473 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7474 ins_pipe( pipe_cmpxchg );
7475 %}
7478 instruct compareAndSwapN(rRegI res,
7479 memory mem_ptr,
7480 rax_RegN oldval, rRegN newval,
7481 rFlagsReg cr) %{
7482 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7483 effect(KILL cr, KILL oldval);
7485 format %{ "cmpxchgl $mem_ptr,$newval\t# "
7486 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7487 "sete $res\n\t"
7488 "movzbl $res, $res" %}
7489 opcode(0x0F, 0xB1);
7490 ins_encode(lock_prefix,
7491 REX_reg_mem(newval, mem_ptr),
7492 OpcP, OpcS,
7493 reg_mem(newval, mem_ptr),
7494 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7495 REX_reg_breg(res, res), // movzbl
7496 Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7497 ins_pipe( pipe_cmpxchg );
7498 %}
7500 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
7501 predicate(n->as_LoadStore()->result_not_used());
7502 match(Set dummy (GetAndAddI mem add));
7503 effect(KILL cr);
7504 format %{ "ADDL [$mem],$add" %}
7505 ins_encode %{
7506 if (os::is_MP()) { __ lock(); }
7507 __ addl($mem$$Address, $add$$constant);
7508 %}
7509 ins_pipe( pipe_cmpxchg );
7510 %}
7512 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{
7513 match(Set newval (GetAndAddI mem newval));
7514 effect(KILL cr);
7515 format %{ "XADDL [$mem],$newval" %}
7516 ins_encode %{
7517 if (os::is_MP()) { __ lock(); }
7518 __ xaddl($mem$$Address, $newval$$Register);
7519 %}
7520 ins_pipe( pipe_cmpxchg );
7521 %}
7523 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{
7524 predicate(n->as_LoadStore()->result_not_used());
7525 match(Set dummy (GetAndAddL mem add));
7526 effect(KILL cr);
7527 format %{ "ADDQ [$mem],$add" %}
7528 ins_encode %{
7529 if (os::is_MP()) { __ lock(); }
7530 __ addq($mem$$Address, $add$$constant);
7531 %}
7532 ins_pipe( pipe_cmpxchg );
7533 %}
7535 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{
7536 match(Set newval (GetAndAddL mem newval));
7537 effect(KILL cr);
7538 format %{ "XADDQ [$mem],$newval" %}
7539 ins_encode %{
7540 if (os::is_MP()) { __ lock(); }
7541 __ xaddq($mem$$Address, $newval$$Register);
7542 %}
7543 ins_pipe( pipe_cmpxchg );
7544 %}
7546 instruct xchgI( memory mem, rRegI newval) %{
7547 match(Set newval (GetAndSetI mem newval));
7548 format %{ "XCHGL $newval,[$mem]" %}
7549 ins_encode %{
7550 __ xchgl($newval$$Register, $mem$$Address);
7551 %}
7552 ins_pipe( pipe_cmpxchg );
7553 %}
7555 instruct xchgL( memory mem, rRegL newval) %{
7556 match(Set newval (GetAndSetL mem newval));
7557 format %{ "XCHGL $newval,[$mem]" %}
7558 ins_encode %{
7559 __ xchgq($newval$$Register, $mem$$Address);
7560 %}
7561 ins_pipe( pipe_cmpxchg );
7562 %}
7564 instruct xchgP( memory mem, rRegP newval) %{
7565 match(Set newval (GetAndSetP mem newval));
7566 format %{ "XCHGQ $newval,[$mem]" %}
7567 ins_encode %{
7568 __ xchgq($newval$$Register, $mem$$Address);
7569 %}
7570 ins_pipe( pipe_cmpxchg );
7571 %}
7573 instruct xchgN( memory mem, rRegN newval) %{
7574 match(Set newval (GetAndSetN mem newval));
7575 format %{ "XCHGL $newval,$mem]" %}
7576 ins_encode %{
7577 __ xchgl($newval$$Register, $mem$$Address);
7578 %}
7579 ins_pipe( pipe_cmpxchg );
7580 %}
7582 //----------Subtraction Instructions-------------------------------------------
7584 // Integer Subtraction Instructions
7585 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7586 %{
7587 match(Set dst (SubI dst src));
7588 effect(KILL cr);
7590 format %{ "subl $dst, $src\t# int" %}
7591 opcode(0x2B);
7592 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
7593 ins_pipe(ialu_reg_reg);
7594 %}
7596 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
7597 %{
7598 match(Set dst (SubI dst src));
7599 effect(KILL cr);
7601 format %{ "subl $dst, $src\t# int" %}
7602 opcode(0x81, 0x05); /* Opcode 81 /5 */
7603 ins_encode(OpcSErm(dst, src), Con8or32(src));
7604 ins_pipe(ialu_reg);
7605 %}
7607 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
7608 %{
7609 match(Set dst (SubI dst (LoadI src)));
7610 effect(KILL cr);
7612 ins_cost(125);
7613 format %{ "subl $dst, $src\t# int" %}
7614 opcode(0x2B);
7615 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
7616 ins_pipe(ialu_reg_mem);
7617 %}
7619 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
7620 %{
7621 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
7622 effect(KILL cr);
7624 ins_cost(150);
7625 format %{ "subl $dst, $src\t# int" %}
7626 opcode(0x29); /* Opcode 29 /r */
7627 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
7628 ins_pipe(ialu_mem_reg);
7629 %}
7631 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr)
7632 %{
7633 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
7634 effect(KILL cr);
7636 ins_cost(125); // XXX
7637 format %{ "subl $dst, $src\t# int" %}
7638 opcode(0x81); /* Opcode 81 /5 id */
7639 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
7640 ins_pipe(ialu_mem_imm);
7641 %}
7643 instruct subExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
7644 %{
7645 match(SubExactI dst src);
7646 effect(DEF cr);
7648 format %{ "subl $dst, $src\t# subExact int" %}
7649 ins_encode %{
7650 __ subl($dst$$Register, $src$$Register);
7651 %}
7652 ins_pipe(ialu_reg_reg);
7653 %}
7655 instruct subExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr)
7656 %{
7657 match(SubExactI dst src);
7658 effect(DEF cr);
7660 format %{ "subl $dst, $src\t# subExact int" %}
7661 ins_encode %{
7662 __ subl($dst$$Register, $src$$constant);
7663 %}
7664 ins_pipe(ialu_reg_reg);
7665 %}
7667 instruct subExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
7668 %{
7669 match(SubExactI dst (LoadI src));
7670 effect(DEF cr);
7672 ins_cost(125);
7673 format %{ "subl $dst, $src\t# subExact int" %}
7674 ins_encode %{
7675 __ subl($dst$$Register, $src$$Address);
7676 %}
7677 ins_pipe(ialu_reg_mem);
7678 %}
7680 instruct subExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
7681 %{
7682 match(SubExactL dst src);
7683 effect(DEF cr);
7685 format %{ "subq $dst, $src\t# subExact long" %}
7686 ins_encode %{
7687 __ subq($dst$$Register, $src$$Register);
7688 %}
7689 ins_pipe(ialu_reg_reg);
7690 %}
7692 instruct subExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr)
7693 %{
7694 match(SubExactL dst (LoadL src));
7695 effect(DEF cr);
7697 format %{ "subq $dst, $src\t# subExact long" %}
7698 ins_encode %{
7699 __ subq($dst$$Register, $src$$constant);
7700 %}
7701 ins_pipe(ialu_reg_reg);
7702 %}
7704 instruct subExactL_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
7705 %{
7706 match(SubExactI dst src);
7707 effect(DEF cr);
7709 ins_cost(125);
7710 format %{ "subq $dst, $src\t# subExact long" %}
7711 ins_encode %{
7712 __ subq($dst$$Register, $src$$Address);
7713 %}
7714 ins_pipe(ialu_reg_mem);
7715 %}
7717 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7718 %{
7719 match(Set dst (SubL dst src));
7720 effect(KILL cr);
7722 format %{ "subq $dst, $src\t# long" %}
7723 opcode(0x2B);
7724 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7725 ins_pipe(ialu_reg_reg);
7726 %}
7728 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr)
7729 %{
7730 match(Set dst (SubL dst src));
7731 effect(KILL cr);
7733 format %{ "subq $dst, $src\t# long" %}
7734 opcode(0x81, 0x05); /* Opcode 81 /5 */
7735 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
7736 ins_pipe(ialu_reg);
7737 %}
7739 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
7740 %{
7741 match(Set dst (SubL dst (LoadL src)));
7742 effect(KILL cr);
7744 ins_cost(125);
7745 format %{ "subq $dst, $src\t# long" %}
7746 opcode(0x2B);
7747 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
7748 ins_pipe(ialu_reg_mem);
7749 %}
7751 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
7752 %{
7753 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
7754 effect(KILL cr);
7756 ins_cost(150);
7757 format %{ "subq $dst, $src\t# long" %}
7758 opcode(0x29); /* Opcode 29 /r */
7759 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
7760 ins_pipe(ialu_mem_reg);
7761 %}
7763 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
7764 %{
7765 match(Set dst (StoreL dst (SubL (LoadL dst) src)));
7766 effect(KILL cr);
7768 ins_cost(125); // XXX
7769 format %{ "subq $dst, $src\t# long" %}
7770 opcode(0x81); /* Opcode 81 /5 id */
7771 ins_encode(REX_mem_wide(dst),
7772 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src));
7773 ins_pipe(ialu_mem_imm);
7774 %}
7776 // Subtract from a pointer
7777 // XXX hmpf???
7778 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr)
7779 %{
7780 match(Set dst (AddP dst (SubI zero src)));
7781 effect(KILL cr);
7783 format %{ "subq $dst, $src\t# ptr - int" %}
7784 opcode(0x2B);
7785 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
7786 ins_pipe(ialu_reg_reg);
7787 %}
7789 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr)
7790 %{
7791 match(Set dst (SubI zero dst));
7792 effect(KILL cr);
7794 format %{ "negl $dst\t# int" %}
7795 opcode(0xF7, 0x03); // Opcode F7 /3
7796 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
7797 ins_pipe(ialu_reg);
7798 %}
7800 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr)
7801 %{
7802 match(Set dst (StoreI dst (SubI zero (LoadI dst))));
7803 effect(KILL cr);
7805 format %{ "negl $dst\t# int" %}
7806 opcode(0xF7, 0x03); // Opcode F7 /3
7807 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
7808 ins_pipe(ialu_reg);
7809 %}
7811 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr)
7812 %{
7813 match(Set dst (SubL zero dst));
7814 effect(KILL cr);
7816 format %{ "negq $dst\t# long" %}
7817 opcode(0xF7, 0x03); // Opcode F7 /3
7818 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
7819 ins_pipe(ialu_reg);
7820 %}
7822 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr)
7823 %{
7824 match(Set dst (StoreL dst (SubL zero (LoadL dst))));
7825 effect(KILL cr);
7827 format %{ "negq $dst\t# long" %}
7828 opcode(0xF7, 0x03); // Opcode F7 /3
7829 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
7830 ins_pipe(ialu_reg);
7831 %}
7833 instruct negExactI_rReg(rax_RegI dst, rFlagsReg cr)
7834 %{
7835 match(NegExactI dst);
7836 effect(KILL cr);
7838 format %{ "negl $dst\t# negExact int" %}
7839 ins_encode %{
7840 __ negl($dst$$Register);
7841 %}
7842 ins_pipe(ialu_reg);
7843 %}
7845 instruct negExactL_rReg(rax_RegL dst, rFlagsReg cr)
7846 %{
7847 match(NegExactL dst);
7848 effect(KILL cr);
7850 format %{ "negq $dst\t# negExact long" %}
7851 ins_encode %{
7852 __ negq($dst$$Register);
7853 %}
7854 ins_pipe(ialu_reg);
7855 %}
7858 //----------Multiplication/Division Instructions-------------------------------
7859 // Integer Multiplication Instructions
7860 // Multiply Register
7862 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
7863 %{
7864 match(Set dst (MulI dst src));
7865 effect(KILL cr);
7867 ins_cost(300);
7868 format %{ "imull $dst, $src\t# int" %}
7869 opcode(0x0F, 0xAF);
7870 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
7871 ins_pipe(ialu_reg_reg_alu0);
7872 %}
7874 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr)
7875 %{
7876 match(Set dst (MulI src imm));
7877 effect(KILL cr);
7879 ins_cost(300);
7880 format %{ "imull $dst, $src, $imm\t# int" %}
7881 opcode(0x69); /* 69 /r id */
7882 ins_encode(REX_reg_reg(dst, src),
7883 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
7884 ins_pipe(ialu_reg_reg_alu0);
7885 %}
7887 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr)
7888 %{
7889 match(Set dst (MulI dst (LoadI src)));
7890 effect(KILL cr);
7892 ins_cost(350);
7893 format %{ "imull $dst, $src\t# int" %}
7894 opcode(0x0F, 0xAF);
7895 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src));
7896 ins_pipe(ialu_reg_mem_alu0);
7897 %}
7899 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr)
7900 %{
7901 match(Set dst (MulI (LoadI src) imm));
7902 effect(KILL cr);
7904 ins_cost(300);
7905 format %{ "imull $dst, $src, $imm\t# int" %}
7906 opcode(0x69); /* 69 /r id */
7907 ins_encode(REX_reg_mem(dst, src),
7908 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
7909 ins_pipe(ialu_reg_mem_alu0);
7910 %}
7912 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
7913 %{
7914 match(Set dst (MulL dst src));
7915 effect(KILL cr);
7917 ins_cost(300);
7918 format %{ "imulq $dst, $src\t# long" %}
7919 opcode(0x0F, 0xAF);
7920 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src));
7921 ins_pipe(ialu_reg_reg_alu0);
7922 %}
7924 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr)
7925 %{
7926 match(Set dst (MulL src imm));
7927 effect(KILL cr);
7929 ins_cost(300);
7930 format %{ "imulq $dst, $src, $imm\t# long" %}
7931 opcode(0x69); /* 69 /r id */
7932 ins_encode(REX_reg_reg_wide(dst, src),
7933 OpcSE(imm), reg_reg(dst, src), Con8or32(imm));
7934 ins_pipe(ialu_reg_reg_alu0);
7935 %}
7937 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr)
7938 %{
7939 match(Set dst (MulL dst (LoadL src)));
7940 effect(KILL cr);
7942 ins_cost(350);
7943 format %{ "imulq $dst, $src\t# long" %}
7944 opcode(0x0F, 0xAF);
7945 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src));
7946 ins_pipe(ialu_reg_mem_alu0);
7947 %}
7949 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr)
7950 %{
7951 match(Set dst (MulL (LoadL src) imm));
7952 effect(KILL cr);
7954 ins_cost(300);
7955 format %{ "imulq $dst, $src, $imm\t# long" %}
7956 opcode(0x69); /* 69 /r id */
7957 ins_encode(REX_reg_mem_wide(dst, src),
7958 OpcSE(imm), reg_mem(dst, src), Con8or32(imm));
7959 ins_pipe(ialu_reg_mem_alu0);
7960 %}
7962 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
7963 %{
7964 match(Set dst (MulHiL src rax));
7965 effect(USE_KILL rax, KILL cr);
7967 ins_cost(300);
7968 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %}
7969 opcode(0xF7, 0x5); /* Opcode F7 /5 */
7970 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
7971 ins_pipe(ialu_reg_reg_alu0);
7972 %}
7975 instruct mulExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr)
7976 %{
7977 match(MulExactI dst src);
7978 effect(DEF cr);
7980 ins_cost(300);
7981 format %{ "imull $dst, $src\t# mulExact int" %}
7982 ins_encode %{
7983 __ imull($dst$$Register, $src$$Register);
7984 %}
7985 ins_pipe(ialu_reg_reg_alu0);
7986 %}
7989 instruct mulExactI_rReg_imm(rax_RegI dst, rRegI src, immI imm, rFlagsReg cr)
7990 %{
7991 match(MulExactI src imm);
7992 effect(DEF cr);
7994 ins_cost(300);
7995 format %{ "imull $dst, $src, $imm\t# mulExact int" %}
7996 ins_encode %{
7997 __ imull($dst$$Register, $src$$Register, $imm$$constant);
7998 %}
7999 ins_pipe(ialu_reg_reg_alu0);
8000 %}
8002 instruct mulExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr)
8003 %{
8004 match(MulExactI dst (LoadI src));
8005 effect(DEF cr);
8007 ins_cost(350);
8008 format %{ "imull $dst, $src\t# mulExact int" %}
8009 ins_encode %{
8010 __ imull($dst$$Register, $src$$Address);
8011 %}
8012 ins_pipe(ialu_reg_mem_alu0);
8013 %}
8015 instruct mulExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr)
8016 %{
8017 match(MulExactL dst src);
8018 effect(DEF cr);
8020 ins_cost(300);
8021 format %{ "imulq $dst, $src\t# mulExact long" %}
8022 ins_encode %{
8023 __ imulq($dst$$Register, $src$$Register);
8024 %}
8025 ins_pipe(ialu_reg_reg_alu0);
8026 %}
8028 instruct mulExactL_rReg_imm(rax_RegL dst, rRegL src, immL32 imm, rFlagsReg cr)
8029 %{
8030 match(MulExactL src imm);
8031 effect(DEF cr);
8033 ins_cost(300);
8034 format %{ "imulq $dst, $src, $imm\t# mulExact long" %}
8035 ins_encode %{
8036 __ imulq($dst$$Register, $src$$Register, $imm$$constant);
8037 %}
8038 ins_pipe(ialu_reg_reg_alu0);
8039 %}
8041 instruct mulExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr)
8042 %{
8043 match(MulExactL dst (LoadL src));
8044 effect(DEF cr);
8046 ins_cost(350);
8047 format %{ "imulq $dst, $src\t# mulExact long" %}
8048 ins_encode %{
8049 __ imulq($dst$$Register, $src$$Address);
8050 %}
8051 ins_pipe(ialu_reg_mem_alu0);
8052 %}
8054 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8055 rFlagsReg cr)
8056 %{
8057 match(Set rax (DivI rax div));
8058 effect(KILL rdx, KILL cr);
8060 ins_cost(30*100+10*100); // XXX
8061 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
8062 "jne,s normal\n\t"
8063 "xorl rdx, rdx\n\t"
8064 "cmpl $div, -1\n\t"
8065 "je,s done\n"
8066 "normal: cdql\n\t"
8067 "idivl $div\n"
8068 "done:" %}
8069 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8070 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8071 ins_pipe(ialu_reg_reg_alu0);
8072 %}
8074 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8075 rFlagsReg cr)
8076 %{
8077 match(Set rax (DivL rax div));
8078 effect(KILL rdx, KILL cr);
8080 ins_cost(30*100+10*100); // XXX
8081 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8082 "cmpq rax, rdx\n\t"
8083 "jne,s normal\n\t"
8084 "xorl rdx, rdx\n\t"
8085 "cmpq $div, -1\n\t"
8086 "je,s done\n"
8087 "normal: cdqq\n\t"
8088 "idivq $div\n"
8089 "done:" %}
8090 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8091 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8092 ins_pipe(ialu_reg_reg_alu0);
8093 %}
8095 // Integer DIVMOD with Register, both quotient and mod results
8096 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div,
8097 rFlagsReg cr)
8098 %{
8099 match(DivModI rax div);
8100 effect(KILL cr);
8102 ins_cost(30*100+10*100); // XXX
8103 format %{ "cmpl rax, 0x80000000\t# idiv\n\t"
8104 "jne,s normal\n\t"
8105 "xorl rdx, rdx\n\t"
8106 "cmpl $div, -1\n\t"
8107 "je,s done\n"
8108 "normal: cdql\n\t"
8109 "idivl $div\n"
8110 "done:" %}
8111 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8112 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8113 ins_pipe(pipe_slow);
8114 %}
8116 // Long DIVMOD with Register, both quotient and mod results
8117 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div,
8118 rFlagsReg cr)
8119 %{
8120 match(DivModL rax div);
8121 effect(KILL cr);
8123 ins_cost(30*100+10*100); // XXX
8124 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t"
8125 "cmpq rax, rdx\n\t"
8126 "jne,s normal\n\t"
8127 "xorl rdx, rdx\n\t"
8128 "cmpq $div, -1\n\t"
8129 "je,s done\n"
8130 "normal: cdqq\n\t"
8131 "idivq $div\n"
8132 "done:" %}
8133 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8134 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8135 ins_pipe(pipe_slow);
8136 %}
8138 //----------- DivL-By-Constant-Expansions--------------------------------------
8139 // DivI cases are handled by the compiler
8141 // Magic constant, reciprocal of 10
8142 instruct loadConL_0x6666666666666667(rRegL dst)
8143 %{
8144 effect(DEF dst);
8146 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %}
8147 ins_encode(load_immL(dst, 0x6666666666666667));
8148 ins_pipe(ialu_reg);
8149 %}
8151 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr)
8152 %{
8153 effect(DEF dst, USE src, USE_KILL rax, KILL cr);
8155 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %}
8156 opcode(0xF7, 0x5); /* Opcode F7 /5 */
8157 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src));
8158 ins_pipe(ialu_reg_reg_alu0);
8159 %}
8161 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr)
8162 %{
8163 effect(USE_DEF dst, KILL cr);
8165 format %{ "sarq $dst, #63\t# Used in div-by-10" %}
8166 opcode(0xC1, 0x7); /* C1 /7 ib */
8167 ins_encode(reg_opc_imm_wide(dst, 0x3F));
8168 ins_pipe(ialu_reg);
8169 %}
8171 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr)
8172 %{
8173 effect(USE_DEF dst, KILL cr);
8175 format %{ "sarq $dst, #2\t# Used in div-by-10" %}
8176 opcode(0xC1, 0x7); /* C1 /7 ib */
8177 ins_encode(reg_opc_imm_wide(dst, 0x2));
8178 ins_pipe(ialu_reg);
8179 %}
8181 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div)
8182 %{
8183 match(Set dst (DivL src div));
8185 ins_cost((5+8)*100);
8186 expand %{
8187 rax_RegL rax; // Killed temp
8188 rFlagsReg cr; // Killed
8189 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667
8190 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src
8191 sarL_rReg_63(src, cr); // sarq src, 63
8192 sarL_rReg_2(dst, cr); // sarq rdx, 2
8193 subL_rReg(dst, src, cr); // subl rdx, src
8194 %}
8195 %}
8197 //-----------------------------------------------------------------------------
8199 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div,
8200 rFlagsReg cr)
8201 %{
8202 match(Set rdx (ModI rax div));
8203 effect(KILL rax, KILL cr);
8205 ins_cost(300); // XXX
8206 format %{ "cmpl rax, 0x80000000\t# irem\n\t"
8207 "jne,s normal\n\t"
8208 "xorl rdx, rdx\n\t"
8209 "cmpl $div, -1\n\t"
8210 "je,s done\n"
8211 "normal: cdql\n\t"
8212 "idivl $div\n"
8213 "done:" %}
8214 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8215 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div));
8216 ins_pipe(ialu_reg_reg_alu0);
8217 %}
8219 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div,
8220 rFlagsReg cr)
8221 %{
8222 match(Set rdx (ModL rax div));
8223 effect(KILL rax, KILL cr);
8225 ins_cost(300); // XXX
8226 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t"
8227 "cmpq rax, rdx\n\t"
8228 "jne,s normal\n\t"
8229 "xorl rdx, rdx\n\t"
8230 "cmpq $div, -1\n\t"
8231 "je,s done\n"
8232 "normal: cdqq\n\t"
8233 "idivq $div\n"
8234 "done:" %}
8235 opcode(0xF7, 0x7); /* Opcode F7 /7 */
8236 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div));
8237 ins_pipe(ialu_reg_reg_alu0);
8238 %}
8240 // Integer Shift Instructions
8241 // Shift Left by one
8242 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8243 %{
8244 match(Set dst (LShiftI dst shift));
8245 effect(KILL cr);
8247 format %{ "sall $dst, $shift" %}
8248 opcode(0xD1, 0x4); /* D1 /4 */
8249 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8250 ins_pipe(ialu_reg);
8251 %}
8253 // Shift Left by one
8254 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8255 %{
8256 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8257 effect(KILL cr);
8259 format %{ "sall $dst, $shift\t" %}
8260 opcode(0xD1, 0x4); /* D1 /4 */
8261 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8262 ins_pipe(ialu_mem_imm);
8263 %}
8265 // Shift Left by 8-bit immediate
8266 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8267 %{
8268 match(Set dst (LShiftI dst shift));
8269 effect(KILL cr);
8271 format %{ "sall $dst, $shift" %}
8272 opcode(0xC1, 0x4); /* C1 /4 ib */
8273 ins_encode(reg_opc_imm(dst, shift));
8274 ins_pipe(ialu_reg);
8275 %}
8277 // Shift Left by 8-bit immediate
8278 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8279 %{
8280 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8281 effect(KILL cr);
8283 format %{ "sall $dst, $shift" %}
8284 opcode(0xC1, 0x4); /* C1 /4 ib */
8285 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8286 ins_pipe(ialu_mem_imm);
8287 %}
8289 // Shift Left by variable
8290 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8291 %{
8292 match(Set dst (LShiftI dst shift));
8293 effect(KILL cr);
8295 format %{ "sall $dst, $shift" %}
8296 opcode(0xD3, 0x4); /* D3 /4 */
8297 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8298 ins_pipe(ialu_reg_reg);
8299 %}
8301 // Shift Left by variable
8302 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8303 %{
8304 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift)));
8305 effect(KILL cr);
8307 format %{ "sall $dst, $shift" %}
8308 opcode(0xD3, 0x4); /* D3 /4 */
8309 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8310 ins_pipe(ialu_mem_reg);
8311 %}
8313 // Arithmetic shift right by one
8314 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8315 %{
8316 match(Set dst (RShiftI dst shift));
8317 effect(KILL cr);
8319 format %{ "sarl $dst, $shift" %}
8320 opcode(0xD1, 0x7); /* D1 /7 */
8321 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8322 ins_pipe(ialu_reg);
8323 %}
8325 // Arithmetic shift right by one
8326 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8327 %{
8328 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8329 effect(KILL cr);
8331 format %{ "sarl $dst, $shift" %}
8332 opcode(0xD1, 0x7); /* D1 /7 */
8333 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8334 ins_pipe(ialu_mem_imm);
8335 %}
8337 // Arithmetic Shift Right by 8-bit immediate
8338 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8339 %{
8340 match(Set dst (RShiftI dst shift));
8341 effect(KILL cr);
8343 format %{ "sarl $dst, $shift" %}
8344 opcode(0xC1, 0x7); /* C1 /7 ib */
8345 ins_encode(reg_opc_imm(dst, shift));
8346 ins_pipe(ialu_mem_imm);
8347 %}
8349 // Arithmetic Shift Right by 8-bit immediate
8350 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8351 %{
8352 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8353 effect(KILL cr);
8355 format %{ "sarl $dst, $shift" %}
8356 opcode(0xC1, 0x7); /* C1 /7 ib */
8357 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8358 ins_pipe(ialu_mem_imm);
8359 %}
8361 // Arithmetic Shift Right by variable
8362 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8363 %{
8364 match(Set dst (RShiftI dst shift));
8365 effect(KILL cr);
8367 format %{ "sarl $dst, $shift" %}
8368 opcode(0xD3, 0x7); /* D3 /7 */
8369 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8370 ins_pipe(ialu_reg_reg);
8371 %}
8373 // Arithmetic Shift Right by variable
8374 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8375 %{
8376 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8377 effect(KILL cr);
8379 format %{ "sarl $dst, $shift" %}
8380 opcode(0xD3, 0x7); /* D3 /7 */
8381 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8382 ins_pipe(ialu_mem_reg);
8383 %}
8385 // Logical shift right by one
8386 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr)
8387 %{
8388 match(Set dst (URShiftI dst shift));
8389 effect(KILL cr);
8391 format %{ "shrl $dst, $shift" %}
8392 opcode(0xD1, 0x5); /* D1 /5 */
8393 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8394 ins_pipe(ialu_reg);
8395 %}
8397 // Logical shift right by one
8398 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8399 %{
8400 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8401 effect(KILL cr);
8403 format %{ "shrl $dst, $shift" %}
8404 opcode(0xD1, 0x5); /* D1 /5 */
8405 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8406 ins_pipe(ialu_mem_imm);
8407 %}
8409 // Logical Shift Right by 8-bit immediate
8410 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr)
8411 %{
8412 match(Set dst (URShiftI dst shift));
8413 effect(KILL cr);
8415 format %{ "shrl $dst, $shift" %}
8416 opcode(0xC1, 0x5); /* C1 /5 ib */
8417 ins_encode(reg_opc_imm(dst, shift));
8418 ins_pipe(ialu_reg);
8419 %}
8421 // Logical Shift Right by 8-bit immediate
8422 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8423 %{
8424 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8425 effect(KILL cr);
8427 format %{ "shrl $dst, $shift" %}
8428 opcode(0xC1, 0x5); /* C1 /5 ib */
8429 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift));
8430 ins_pipe(ialu_mem_imm);
8431 %}
8433 // Logical Shift Right by variable
8434 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr)
8435 %{
8436 match(Set dst (URShiftI dst shift));
8437 effect(KILL cr);
8439 format %{ "shrl $dst, $shift" %}
8440 opcode(0xD3, 0x5); /* D3 /5 */
8441 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8442 ins_pipe(ialu_reg_reg);
8443 %}
8445 // Logical Shift Right by variable
8446 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8447 %{
8448 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift)));
8449 effect(KILL cr);
8451 format %{ "shrl $dst, $shift" %}
8452 opcode(0xD3, 0x5); /* D3 /5 */
8453 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst));
8454 ins_pipe(ialu_mem_reg);
8455 %}
8457 // Long Shift Instructions
8458 // Shift Left by one
8459 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8460 %{
8461 match(Set dst (LShiftL dst shift));
8462 effect(KILL cr);
8464 format %{ "salq $dst, $shift" %}
8465 opcode(0xD1, 0x4); /* D1 /4 */
8466 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8467 ins_pipe(ialu_reg);
8468 %}
8470 // Shift Left by one
8471 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8472 %{
8473 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8474 effect(KILL cr);
8476 format %{ "salq $dst, $shift" %}
8477 opcode(0xD1, 0x4); /* D1 /4 */
8478 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8479 ins_pipe(ialu_mem_imm);
8480 %}
8482 // Shift Left by 8-bit immediate
8483 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8484 %{
8485 match(Set dst (LShiftL dst shift));
8486 effect(KILL cr);
8488 format %{ "salq $dst, $shift" %}
8489 opcode(0xC1, 0x4); /* C1 /4 ib */
8490 ins_encode(reg_opc_imm_wide(dst, shift));
8491 ins_pipe(ialu_reg);
8492 %}
8494 // Shift Left by 8-bit immediate
8495 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8496 %{
8497 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8498 effect(KILL cr);
8500 format %{ "salq $dst, $shift" %}
8501 opcode(0xC1, 0x4); /* C1 /4 ib */
8502 ins_encode(REX_mem_wide(dst), OpcP,
8503 RM_opc_mem(secondary, dst), Con8or32(shift));
8504 ins_pipe(ialu_mem_imm);
8505 %}
8507 // Shift Left by variable
8508 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8509 %{
8510 match(Set dst (LShiftL dst shift));
8511 effect(KILL cr);
8513 format %{ "salq $dst, $shift" %}
8514 opcode(0xD3, 0x4); /* D3 /4 */
8515 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8516 ins_pipe(ialu_reg_reg);
8517 %}
8519 // Shift Left by variable
8520 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8521 %{
8522 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift)));
8523 effect(KILL cr);
8525 format %{ "salq $dst, $shift" %}
8526 opcode(0xD3, 0x4); /* D3 /4 */
8527 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8528 ins_pipe(ialu_mem_reg);
8529 %}
8531 // Arithmetic shift right by one
8532 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8533 %{
8534 match(Set dst (RShiftL dst shift));
8535 effect(KILL cr);
8537 format %{ "sarq $dst, $shift" %}
8538 opcode(0xD1, 0x7); /* D1 /7 */
8539 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8540 ins_pipe(ialu_reg);
8541 %}
8543 // Arithmetic shift right by one
8544 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8545 %{
8546 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8547 effect(KILL cr);
8549 format %{ "sarq $dst, $shift" %}
8550 opcode(0xD1, 0x7); /* D1 /7 */
8551 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8552 ins_pipe(ialu_mem_imm);
8553 %}
8555 // Arithmetic Shift Right by 8-bit immediate
8556 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8557 %{
8558 match(Set dst (RShiftL dst shift));
8559 effect(KILL cr);
8561 format %{ "sarq $dst, $shift" %}
8562 opcode(0xC1, 0x7); /* C1 /7 ib */
8563 ins_encode(reg_opc_imm_wide(dst, shift));
8564 ins_pipe(ialu_mem_imm);
8565 %}
8567 // Arithmetic Shift Right by 8-bit immediate
8568 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8569 %{
8570 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8571 effect(KILL cr);
8573 format %{ "sarq $dst, $shift" %}
8574 opcode(0xC1, 0x7); /* C1 /7 ib */
8575 ins_encode(REX_mem_wide(dst), OpcP,
8576 RM_opc_mem(secondary, dst), Con8or32(shift));
8577 ins_pipe(ialu_mem_imm);
8578 %}
8580 // Arithmetic Shift Right by variable
8581 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8582 %{
8583 match(Set dst (RShiftL dst shift));
8584 effect(KILL cr);
8586 format %{ "sarq $dst, $shift" %}
8587 opcode(0xD3, 0x7); /* D3 /7 */
8588 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8589 ins_pipe(ialu_reg_reg);
8590 %}
8592 // Arithmetic Shift Right by variable
8593 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8594 %{
8595 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift)));
8596 effect(KILL cr);
8598 format %{ "sarq $dst, $shift" %}
8599 opcode(0xD3, 0x7); /* D3 /7 */
8600 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8601 ins_pipe(ialu_mem_reg);
8602 %}
8604 // Logical shift right by one
8605 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr)
8606 %{
8607 match(Set dst (URShiftL dst shift));
8608 effect(KILL cr);
8610 format %{ "shrq $dst, $shift" %}
8611 opcode(0xD1, 0x5); /* D1 /5 */
8612 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst ));
8613 ins_pipe(ialu_reg);
8614 %}
8616 // Logical shift right by one
8617 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr)
8618 %{
8619 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8620 effect(KILL cr);
8622 format %{ "shrq $dst, $shift" %}
8623 opcode(0xD1, 0x5); /* D1 /5 */
8624 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8625 ins_pipe(ialu_mem_imm);
8626 %}
8628 // Logical Shift Right by 8-bit immediate
8629 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr)
8630 %{
8631 match(Set dst (URShiftL dst shift));
8632 effect(KILL cr);
8634 format %{ "shrq $dst, $shift" %}
8635 opcode(0xC1, 0x5); /* C1 /5 ib */
8636 ins_encode(reg_opc_imm_wide(dst, shift));
8637 ins_pipe(ialu_reg);
8638 %}
8641 // Logical Shift Right by 8-bit immediate
8642 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr)
8643 %{
8644 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8645 effect(KILL cr);
8647 format %{ "shrq $dst, $shift" %}
8648 opcode(0xC1, 0x5); /* C1 /5 ib */
8649 ins_encode(REX_mem_wide(dst), OpcP,
8650 RM_opc_mem(secondary, dst), Con8or32(shift));
8651 ins_pipe(ialu_mem_imm);
8652 %}
8654 // Logical Shift Right by variable
8655 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr)
8656 %{
8657 match(Set dst (URShiftL dst shift));
8658 effect(KILL cr);
8660 format %{ "shrq $dst, $shift" %}
8661 opcode(0xD3, 0x5); /* D3 /5 */
8662 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8663 ins_pipe(ialu_reg_reg);
8664 %}
8666 // Logical Shift Right by variable
8667 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr)
8668 %{
8669 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift)));
8670 effect(KILL cr);
8672 format %{ "shrq $dst, $shift" %}
8673 opcode(0xD3, 0x5); /* D3 /5 */
8674 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst));
8675 ins_pipe(ialu_mem_reg);
8676 %}
8678 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
8679 // This idiom is used by the compiler for the i2b bytecode.
8680 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour)
8681 %{
8682 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
8684 format %{ "movsbl $dst, $src\t# i2b" %}
8685 opcode(0x0F, 0xBE);
8686 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8687 ins_pipe(ialu_reg_reg);
8688 %}
8690 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
8691 // This idiom is used by the compiler the i2s bytecode.
8692 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen)
8693 %{
8694 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
8696 format %{ "movswl $dst, $src\t# i2s" %}
8697 opcode(0x0F, 0xBF);
8698 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
8699 ins_pipe(ialu_reg_reg);
8700 %}
8702 // ROL/ROR instructions
8704 // ROL expand
8705 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{
8706 effect(KILL cr, USE_DEF dst);
8708 format %{ "roll $dst" %}
8709 opcode(0xD1, 0x0); /* Opcode D1 /0 */
8710 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8711 ins_pipe(ialu_reg);
8712 %}
8714 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{
8715 effect(USE_DEF dst, USE shift, KILL cr);
8717 format %{ "roll $dst, $shift" %}
8718 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
8719 ins_encode( reg_opc_imm(dst, shift) );
8720 ins_pipe(ialu_reg);
8721 %}
8723 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
8724 %{
8725 effect(USE_DEF dst, USE shift, KILL cr);
8727 format %{ "roll $dst, $shift" %}
8728 opcode(0xD3, 0x0); /* Opcode D3 /0 */
8729 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8730 ins_pipe(ialu_reg_reg);
8731 %}
8732 // end of ROL expand
8734 // Rotate Left by one
8735 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
8736 %{
8737 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8739 expand %{
8740 rolI_rReg_imm1(dst, cr);
8741 %}
8742 %}
8744 // Rotate Left by 8-bit immediate
8745 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
8746 %{
8747 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8748 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8750 expand %{
8751 rolI_rReg_imm8(dst, lshift, cr);
8752 %}
8753 %}
8755 // Rotate Left by variable
8756 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8757 %{
8758 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift))));
8760 expand %{
8761 rolI_rReg_CL(dst, shift, cr);
8762 %}
8763 %}
8765 // Rotate Left by variable
8766 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
8767 %{
8768 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift))));
8770 expand %{
8771 rolI_rReg_CL(dst, shift, cr);
8772 %}
8773 %}
8775 // ROR expand
8776 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr)
8777 %{
8778 effect(USE_DEF dst, KILL cr);
8780 format %{ "rorl $dst" %}
8781 opcode(0xD1, 0x1); /* D1 /1 */
8782 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8783 ins_pipe(ialu_reg);
8784 %}
8786 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr)
8787 %{
8788 effect(USE_DEF dst, USE shift, KILL cr);
8790 format %{ "rorl $dst, $shift" %}
8791 opcode(0xC1, 0x1); /* C1 /1 ib */
8792 ins_encode(reg_opc_imm(dst, shift));
8793 ins_pipe(ialu_reg);
8794 %}
8796 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr)
8797 %{
8798 effect(USE_DEF dst, USE shift, KILL cr);
8800 format %{ "rorl $dst, $shift" %}
8801 opcode(0xD3, 0x1); /* D3 /1 */
8802 ins_encode(REX_reg(dst), OpcP, reg_opc(dst));
8803 ins_pipe(ialu_reg_reg);
8804 %}
8805 // end of ROR expand
8807 // Rotate Right by one
8808 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
8809 %{
8810 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8812 expand %{
8813 rorI_rReg_imm1(dst, cr);
8814 %}
8815 %}
8817 // Rotate Right by 8-bit immediate
8818 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
8819 %{
8820 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8821 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8823 expand %{
8824 rorI_rReg_imm8(dst, rshift, cr);
8825 %}
8826 %}
8828 // Rotate Right by variable
8829 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8830 %{
8831 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift))));
8833 expand %{
8834 rorI_rReg_CL(dst, shift, cr);
8835 %}
8836 %}
8838 // Rotate Right by variable
8839 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr)
8840 %{
8841 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift))));
8843 expand %{
8844 rorI_rReg_CL(dst, shift, cr);
8845 %}
8846 %}
8848 // for long rotate
8849 // ROL expand
8850 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{
8851 effect(USE_DEF dst, KILL cr);
8853 format %{ "rolq $dst" %}
8854 opcode(0xD1, 0x0); /* Opcode D1 /0 */
8855 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8856 ins_pipe(ialu_reg);
8857 %}
8859 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{
8860 effect(USE_DEF dst, USE shift, KILL cr);
8862 format %{ "rolq $dst, $shift" %}
8863 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */
8864 ins_encode( reg_opc_imm_wide(dst, shift) );
8865 ins_pipe(ialu_reg);
8866 %}
8868 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
8869 %{
8870 effect(USE_DEF dst, USE shift, KILL cr);
8872 format %{ "rolq $dst, $shift" %}
8873 opcode(0xD3, 0x0); /* Opcode D3 /0 */
8874 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8875 ins_pipe(ialu_reg_reg);
8876 %}
8877 // end of ROL expand
8879 // Rotate Left by one
8880 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr)
8881 %{
8882 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
8884 expand %{
8885 rolL_rReg_imm1(dst, cr);
8886 %}
8887 %}
8889 // Rotate Left by 8-bit immediate
8890 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr)
8891 %{
8892 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
8893 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift)));
8895 expand %{
8896 rolL_rReg_imm8(dst, lshift, cr);
8897 %}
8898 %}
8900 // Rotate Left by variable
8901 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8902 %{
8903 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift))));
8905 expand %{
8906 rolL_rReg_CL(dst, shift, cr);
8907 %}
8908 %}
8910 // Rotate Left by variable
8911 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
8912 %{
8913 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift))));
8915 expand %{
8916 rolL_rReg_CL(dst, shift, cr);
8917 %}
8918 %}
8920 // ROR expand
8921 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr)
8922 %{
8923 effect(USE_DEF dst, KILL cr);
8925 format %{ "rorq $dst" %}
8926 opcode(0xD1, 0x1); /* D1 /1 */
8927 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8928 ins_pipe(ialu_reg);
8929 %}
8931 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr)
8932 %{
8933 effect(USE_DEF dst, USE shift, KILL cr);
8935 format %{ "rorq $dst, $shift" %}
8936 opcode(0xC1, 0x1); /* C1 /1 ib */
8937 ins_encode(reg_opc_imm_wide(dst, shift));
8938 ins_pipe(ialu_reg);
8939 %}
8941 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr)
8942 %{
8943 effect(USE_DEF dst, USE shift, KILL cr);
8945 format %{ "rorq $dst, $shift" %}
8946 opcode(0xD3, 0x1); /* D3 /1 */
8947 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst));
8948 ins_pipe(ialu_reg_reg);
8949 %}
8950 // end of ROR expand
8952 // Rotate Right by one
8953 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr)
8954 %{
8955 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
8957 expand %{
8958 rorL_rReg_imm1(dst, cr);
8959 %}
8960 %}
8962 // Rotate Right by 8-bit immediate
8963 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr)
8964 %{
8965 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f));
8966 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift)));
8968 expand %{
8969 rorL_rReg_imm8(dst, rshift, cr);
8970 %}
8971 %}
8973 // Rotate Right by variable
8974 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr)
8975 %{
8976 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift))));
8978 expand %{
8979 rorL_rReg_CL(dst, shift, cr);
8980 %}
8981 %}
8983 // Rotate Right by variable
8984 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr)
8985 %{
8986 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift))));
8988 expand %{
8989 rorL_rReg_CL(dst, shift, cr);
8990 %}
8991 %}
8993 // Logical Instructions
8995 // Integer Logical Instructions
8997 // And Instructions
8998 // And Register with Register
8999 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9000 %{
9001 match(Set dst (AndI dst src));
9002 effect(KILL cr);
9004 format %{ "andl $dst, $src\t# int" %}
9005 opcode(0x23);
9006 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9007 ins_pipe(ialu_reg_reg);
9008 %}
9010 // And Register with Immediate 255
9011 instruct andI_rReg_imm255(rRegI dst, immI_255 src)
9012 %{
9013 match(Set dst (AndI dst src));
9015 format %{ "movzbl $dst, $dst\t# int & 0xFF" %}
9016 opcode(0x0F, 0xB6);
9017 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9018 ins_pipe(ialu_reg);
9019 %}
9021 // And Register with Immediate 255 and promote to long
9022 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask)
9023 %{
9024 match(Set dst (ConvI2L (AndI src mask)));
9026 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %}
9027 opcode(0x0F, 0xB6);
9028 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9029 ins_pipe(ialu_reg);
9030 %}
9032 // And Register with Immediate 65535
9033 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src)
9034 %{
9035 match(Set dst (AndI dst src));
9037 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %}
9038 opcode(0x0F, 0xB7);
9039 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9040 ins_pipe(ialu_reg);
9041 %}
9043 // And Register with Immediate 65535 and promote to long
9044 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask)
9045 %{
9046 match(Set dst (ConvI2L (AndI src mask)));
9048 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %}
9049 opcode(0x0F, 0xB7);
9050 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
9051 ins_pipe(ialu_reg);
9052 %}
9054 // And Register with Immediate
9055 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9056 %{
9057 match(Set dst (AndI dst src));
9058 effect(KILL cr);
9060 format %{ "andl $dst, $src\t# int" %}
9061 opcode(0x81, 0x04); /* Opcode 81 /4 */
9062 ins_encode(OpcSErm(dst, src), Con8or32(src));
9063 ins_pipe(ialu_reg);
9064 %}
9066 // And Register with Memory
9067 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9068 %{
9069 match(Set dst (AndI dst (LoadI src)));
9070 effect(KILL cr);
9072 ins_cost(125);
9073 format %{ "andl $dst, $src\t# int" %}
9074 opcode(0x23);
9075 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9076 ins_pipe(ialu_reg_mem);
9077 %}
9079 // And Memory with Register
9080 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9081 %{
9082 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9083 effect(KILL cr);
9085 ins_cost(150);
9086 format %{ "andl $dst, $src\t# int" %}
9087 opcode(0x21); /* Opcode 21 /r */
9088 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9089 ins_pipe(ialu_mem_reg);
9090 %}
9092 // And Memory with Immediate
9093 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr)
9094 %{
9095 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
9096 effect(KILL cr);
9098 ins_cost(125);
9099 format %{ "andl $dst, $src\t# int" %}
9100 opcode(0x81, 0x4); /* Opcode 81 /4 id */
9101 ins_encode(REX_mem(dst), OpcSE(src),
9102 RM_opc_mem(secondary, dst), Con8or32(src));
9103 ins_pipe(ialu_mem_imm);
9104 %}
9106 // Or Instructions
9107 // Or Register with Register
9108 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9109 %{
9110 match(Set dst (OrI dst src));
9111 effect(KILL cr);
9113 format %{ "orl $dst, $src\t# int" %}
9114 opcode(0x0B);
9115 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9116 ins_pipe(ialu_reg_reg);
9117 %}
9119 // Or Register with Immediate
9120 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9121 %{
9122 match(Set dst (OrI dst src));
9123 effect(KILL cr);
9125 format %{ "orl $dst, $src\t# int" %}
9126 opcode(0x81, 0x01); /* Opcode 81 /1 id */
9127 ins_encode(OpcSErm(dst, src), Con8or32(src));
9128 ins_pipe(ialu_reg);
9129 %}
9131 // Or Register with Memory
9132 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9133 %{
9134 match(Set dst (OrI dst (LoadI src)));
9135 effect(KILL cr);
9137 ins_cost(125);
9138 format %{ "orl $dst, $src\t# int" %}
9139 opcode(0x0B);
9140 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9141 ins_pipe(ialu_reg_mem);
9142 %}
9144 // Or Memory with Register
9145 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9146 %{
9147 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9148 effect(KILL cr);
9150 ins_cost(150);
9151 format %{ "orl $dst, $src\t# int" %}
9152 opcode(0x09); /* Opcode 09 /r */
9153 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9154 ins_pipe(ialu_mem_reg);
9155 %}
9157 // Or Memory with Immediate
9158 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr)
9159 %{
9160 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
9161 effect(KILL cr);
9163 ins_cost(125);
9164 format %{ "orl $dst, $src\t# int" %}
9165 opcode(0x81, 0x1); /* Opcode 81 /1 id */
9166 ins_encode(REX_mem(dst), OpcSE(src),
9167 RM_opc_mem(secondary, dst), Con8or32(src));
9168 ins_pipe(ialu_mem_imm);
9169 %}
9171 // Xor Instructions
9172 // Xor Register with Register
9173 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr)
9174 %{
9175 match(Set dst (XorI dst src));
9176 effect(KILL cr);
9178 format %{ "xorl $dst, $src\t# int" %}
9179 opcode(0x33);
9180 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src));
9181 ins_pipe(ialu_reg_reg);
9182 %}
9184 // Xor Register with Immediate -1
9185 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
9186 match(Set dst (XorI dst imm));
9188 format %{ "not $dst" %}
9189 ins_encode %{
9190 __ notl($dst$$Register);
9191 %}
9192 ins_pipe(ialu_reg);
9193 %}
9195 // Xor Register with Immediate
9196 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr)
9197 %{
9198 match(Set dst (XorI dst src));
9199 effect(KILL cr);
9201 format %{ "xorl $dst, $src\t# int" %}
9202 opcode(0x81, 0x06); /* Opcode 81 /6 id */
9203 ins_encode(OpcSErm(dst, src), Con8or32(src));
9204 ins_pipe(ialu_reg);
9205 %}
9207 // Xor Register with Memory
9208 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr)
9209 %{
9210 match(Set dst (XorI dst (LoadI src)));
9211 effect(KILL cr);
9213 ins_cost(125);
9214 format %{ "xorl $dst, $src\t# int" %}
9215 opcode(0x33);
9216 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src));
9217 ins_pipe(ialu_reg_mem);
9218 %}
9220 // Xor Memory with Register
9221 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr)
9222 %{
9223 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9224 effect(KILL cr);
9226 ins_cost(150);
9227 format %{ "xorl $dst, $src\t# int" %}
9228 opcode(0x31); /* Opcode 31 /r */
9229 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst));
9230 ins_pipe(ialu_mem_reg);
9231 %}
9233 // Xor Memory with Immediate
9234 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr)
9235 %{
9236 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
9237 effect(KILL cr);
9239 ins_cost(125);
9240 format %{ "xorl $dst, $src\t# int" %}
9241 opcode(0x81, 0x6); /* Opcode 81 /6 id */
9242 ins_encode(REX_mem(dst), OpcSE(src),
9243 RM_opc_mem(secondary, dst), Con8or32(src));
9244 ins_pipe(ialu_mem_imm);
9245 %}
9248 // Long Logical Instructions
9250 // And Instructions
9251 // And Register with Register
9252 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9253 %{
9254 match(Set dst (AndL dst src));
9255 effect(KILL cr);
9257 format %{ "andq $dst, $src\t# long" %}
9258 opcode(0x23);
9259 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9260 ins_pipe(ialu_reg_reg);
9261 %}
9263 // And Register with Immediate 255
9264 instruct andL_rReg_imm255(rRegL dst, immL_255 src)
9265 %{
9266 match(Set dst (AndL dst src));
9268 format %{ "movzbq $dst, $dst\t# long & 0xFF" %}
9269 opcode(0x0F, 0xB6);
9270 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9271 ins_pipe(ialu_reg);
9272 %}
9274 // And Register with Immediate 65535
9275 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src)
9276 %{
9277 match(Set dst (AndL dst src));
9279 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %}
9280 opcode(0x0F, 0xB7);
9281 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst));
9282 ins_pipe(ialu_reg);
9283 %}
9285 // And Register with Immediate
9286 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9287 %{
9288 match(Set dst (AndL dst src));
9289 effect(KILL cr);
9291 format %{ "andq $dst, $src\t# long" %}
9292 opcode(0x81, 0x04); /* Opcode 81 /4 */
9293 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9294 ins_pipe(ialu_reg);
9295 %}
9297 // And Register with Memory
9298 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9299 %{
9300 match(Set dst (AndL dst (LoadL src)));
9301 effect(KILL cr);
9303 ins_cost(125);
9304 format %{ "andq $dst, $src\t# long" %}
9305 opcode(0x23);
9306 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9307 ins_pipe(ialu_reg_mem);
9308 %}
9310 // And Memory with Register
9311 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9312 %{
9313 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9314 effect(KILL cr);
9316 ins_cost(150);
9317 format %{ "andq $dst, $src\t# long" %}
9318 opcode(0x21); /* Opcode 21 /r */
9319 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9320 ins_pipe(ialu_mem_reg);
9321 %}
9323 // And Memory with Immediate
9324 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9325 %{
9326 match(Set dst (StoreL dst (AndL (LoadL dst) src)));
9327 effect(KILL cr);
9329 ins_cost(125);
9330 format %{ "andq $dst, $src\t# long" %}
9331 opcode(0x81, 0x4); /* Opcode 81 /4 id */
9332 ins_encode(REX_mem_wide(dst), OpcSE(src),
9333 RM_opc_mem(secondary, dst), Con8or32(src));
9334 ins_pipe(ialu_mem_imm);
9335 %}
9337 // Or Instructions
9338 // Or Register with Register
9339 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9340 %{
9341 match(Set dst (OrL dst src));
9342 effect(KILL cr);
9344 format %{ "orq $dst, $src\t# long" %}
9345 opcode(0x0B);
9346 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9347 ins_pipe(ialu_reg_reg);
9348 %}
9350 // Use any_RegP to match R15 (TLS register) without spilling.
9351 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{
9352 match(Set dst (OrL dst (CastP2X src)));
9353 effect(KILL cr);
9355 format %{ "orq $dst, $src\t# long" %}
9356 opcode(0x0B);
9357 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9358 ins_pipe(ialu_reg_reg);
9359 %}
9362 // Or Register with Immediate
9363 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9364 %{
9365 match(Set dst (OrL dst src));
9366 effect(KILL cr);
9368 format %{ "orq $dst, $src\t# long" %}
9369 opcode(0x81, 0x01); /* Opcode 81 /1 id */
9370 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9371 ins_pipe(ialu_reg);
9372 %}
9374 // Or Register with Memory
9375 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9376 %{
9377 match(Set dst (OrL dst (LoadL src)));
9378 effect(KILL cr);
9380 ins_cost(125);
9381 format %{ "orq $dst, $src\t# long" %}
9382 opcode(0x0B);
9383 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9384 ins_pipe(ialu_reg_mem);
9385 %}
9387 // Or Memory with Register
9388 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9389 %{
9390 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
9391 effect(KILL cr);
9393 ins_cost(150);
9394 format %{ "orq $dst, $src\t# long" %}
9395 opcode(0x09); /* Opcode 09 /r */
9396 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9397 ins_pipe(ialu_mem_reg);
9398 %}
9400 // Or Memory with Immediate
9401 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9402 %{
9403 match(Set dst (StoreL dst (OrL (LoadL dst) src)));
9404 effect(KILL cr);
9406 ins_cost(125);
9407 format %{ "orq $dst, $src\t# long" %}
9408 opcode(0x81, 0x1); /* Opcode 81 /1 id */
9409 ins_encode(REX_mem_wide(dst), OpcSE(src),
9410 RM_opc_mem(secondary, dst), Con8or32(src));
9411 ins_pipe(ialu_mem_imm);
9412 %}
9414 // Xor Instructions
9415 // Xor Register with Register
9416 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr)
9417 %{
9418 match(Set dst (XorL dst src));
9419 effect(KILL cr);
9421 format %{ "xorq $dst, $src\t# long" %}
9422 opcode(0x33);
9423 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src));
9424 ins_pipe(ialu_reg_reg);
9425 %}
9427 // Xor Register with Immediate -1
9428 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
9429 match(Set dst (XorL dst imm));
9431 format %{ "notq $dst" %}
9432 ins_encode %{
9433 __ notq($dst$$Register);
9434 %}
9435 ins_pipe(ialu_reg);
9436 %}
9438 // Xor Register with Immediate
9439 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr)
9440 %{
9441 match(Set dst (XorL dst src));
9442 effect(KILL cr);
9444 format %{ "xorq $dst, $src\t# long" %}
9445 opcode(0x81, 0x06); /* Opcode 81 /6 id */
9446 ins_encode(OpcSErm_wide(dst, src), Con8or32(src));
9447 ins_pipe(ialu_reg);
9448 %}
9450 // Xor Register with Memory
9451 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr)
9452 %{
9453 match(Set dst (XorL dst (LoadL src)));
9454 effect(KILL cr);
9456 ins_cost(125);
9457 format %{ "xorq $dst, $src\t# long" %}
9458 opcode(0x33);
9459 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src));
9460 ins_pipe(ialu_reg_mem);
9461 %}
9463 // Xor Memory with Register
9464 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr)
9465 %{
9466 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
9467 effect(KILL cr);
9469 ins_cost(150);
9470 format %{ "xorq $dst, $src\t# long" %}
9471 opcode(0x31); /* Opcode 31 /r */
9472 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst));
9473 ins_pipe(ialu_mem_reg);
9474 %}
9476 // Xor Memory with Immediate
9477 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
9478 %{
9479 match(Set dst (StoreL dst (XorL (LoadL dst) src)));
9480 effect(KILL cr);
9482 ins_cost(125);
9483 format %{ "xorq $dst, $src\t# long" %}
9484 opcode(0x81, 0x6); /* Opcode 81 /6 id */
9485 ins_encode(REX_mem_wide(dst), OpcSE(src),
9486 RM_opc_mem(secondary, dst), Con8or32(src));
9487 ins_pipe(ialu_mem_imm);
9488 %}
9490 // Convert Int to Boolean
9491 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr)
9492 %{
9493 match(Set dst (Conv2B src));
9494 effect(KILL cr);
9496 format %{ "testl $src, $src\t# ci2b\n\t"
9497 "setnz $dst\n\t"
9498 "movzbl $dst, $dst" %}
9499 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl
9500 setNZ_reg(dst),
9501 REX_reg_breg(dst, dst), // movzbl
9502 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
9503 ins_pipe(pipe_slow); // XXX
9504 %}
9506 // Convert Pointer to Boolean
9507 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr)
9508 %{
9509 match(Set dst (Conv2B src));
9510 effect(KILL cr);
9512 format %{ "testq $src, $src\t# cp2b\n\t"
9513 "setnz $dst\n\t"
9514 "movzbl $dst, $dst" %}
9515 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq
9516 setNZ_reg(dst),
9517 REX_reg_breg(dst, dst), // movzbl
9518 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst));
9519 ins_pipe(pipe_slow); // XXX
9520 %}
9522 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr)
9523 %{
9524 match(Set dst (CmpLTMask p q));
9525 effect(KILL cr);
9527 ins_cost(400);
9528 format %{ "cmpl $p, $q\t# cmpLTMask\n\t"
9529 "setlt $dst\n\t"
9530 "movzbl $dst, $dst\n\t"
9531 "negl $dst" %}
9532 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl
9533 setLT_reg(dst),
9534 REX_reg_breg(dst, dst), // movzbl
9535 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst),
9536 neg_reg(dst));
9537 ins_pipe(pipe_slow);
9538 %}
9540 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr)
9541 %{
9542 match(Set dst (CmpLTMask dst zero));
9543 effect(KILL cr);
9545 ins_cost(100);
9546 format %{ "sarl $dst, #31\t# cmpLTMask0" %}
9547 ins_encode %{
9548 __ sarl($dst$$Register, 31);
9549 %}
9550 ins_pipe(ialu_reg);
9551 %}
9553 /* Better to save a register than avoid a branch */
9554 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr)
9555 %{
9556 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
9557 effect(KILL cr);
9558 ins_cost(300);
9559 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t"
9560 "jge done\n\t"
9561 "addl $p,$y\n"
9562 "done: " %}
9563 ins_encode %{
9564 Register Rp = $p$$Register;
9565 Register Rq = $q$$Register;
9566 Register Ry = $y$$Register;
9567 Label done;
9568 __ subl(Rp, Rq);
9569 __ jccb(Assembler::greaterEqual, done);
9570 __ addl(Rp, Ry);
9571 __ bind(done);
9572 %}
9573 ins_pipe(pipe_cmplt);
9574 %}
9576 /* Better to save a register than avoid a branch */
9577 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr)
9578 %{
9579 match(Set y (AndI (CmpLTMask p q) y));
9580 effect(KILL cr);
9582 ins_cost(300);
9584 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t"
9585 "jlt done\n\t"
9586 "xorl $y, $y\n"
9587 "done: " %}
9588 ins_encode %{
9589 Register Rp = $p$$Register;
9590 Register Rq = $q$$Register;
9591 Register Ry = $y$$Register;
9592 Label done;
9593 __ cmpl(Rp, Rq);
9594 __ jccb(Assembler::less, done);
9595 __ xorl(Ry, Ry);
9596 __ bind(done);
9597 %}
9598 ins_pipe(pipe_cmplt);
9599 %}
9602 //---------- FP Instructions------------------------------------------------
9604 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
9605 %{
9606 match(Set cr (CmpF src1 src2));
9608 ins_cost(145);
9609 format %{ "ucomiss $src1, $src2\n\t"
9610 "jnp,s exit\n\t"
9611 "pushfq\t# saw NaN, set CF\n\t"
9612 "andq [rsp], #0xffffff2b\n\t"
9613 "popfq\n"
9614 "exit:" %}
9615 ins_encode %{
9616 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9617 emit_cmpfp_fixup(_masm);
9618 %}
9619 ins_pipe(pipe_slow);
9620 %}
9622 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{
9623 match(Set cr (CmpF src1 src2));
9625 ins_cost(100);
9626 format %{ "ucomiss $src1, $src2" %}
9627 ins_encode %{
9628 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9629 %}
9630 ins_pipe(pipe_slow);
9631 %}
9633 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2)
9634 %{
9635 match(Set cr (CmpF src1 (LoadF src2)));
9637 ins_cost(145);
9638 format %{ "ucomiss $src1, $src2\n\t"
9639 "jnp,s exit\n\t"
9640 "pushfq\t# saw NaN, set CF\n\t"
9641 "andq [rsp], #0xffffff2b\n\t"
9642 "popfq\n"
9643 "exit:" %}
9644 ins_encode %{
9645 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9646 emit_cmpfp_fixup(_masm);
9647 %}
9648 ins_pipe(pipe_slow);
9649 %}
9651 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{
9652 match(Set cr (CmpF src1 (LoadF src2)));
9654 ins_cost(100);
9655 format %{ "ucomiss $src1, $src2" %}
9656 ins_encode %{
9657 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9658 %}
9659 ins_pipe(pipe_slow);
9660 %}
9662 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{
9663 match(Set cr (CmpF src con));
9665 ins_cost(145);
9666 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
9667 "jnp,s exit\n\t"
9668 "pushfq\t# saw NaN, set CF\n\t"
9669 "andq [rsp], #0xffffff2b\n\t"
9670 "popfq\n"
9671 "exit:" %}
9672 ins_encode %{
9673 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9674 emit_cmpfp_fixup(_masm);
9675 %}
9676 ins_pipe(pipe_slow);
9677 %}
9679 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{
9680 match(Set cr (CmpF src con));
9681 ins_cost(100);
9682 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %}
9683 ins_encode %{
9684 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9685 %}
9686 ins_pipe(pipe_slow);
9687 %}
9689 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2)
9690 %{
9691 match(Set cr (CmpD src1 src2));
9693 ins_cost(145);
9694 format %{ "ucomisd $src1, $src2\n\t"
9695 "jnp,s exit\n\t"
9696 "pushfq\t# saw NaN, set CF\n\t"
9697 "andq [rsp], #0xffffff2b\n\t"
9698 "popfq\n"
9699 "exit:" %}
9700 ins_encode %{
9701 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9702 emit_cmpfp_fixup(_masm);
9703 %}
9704 ins_pipe(pipe_slow);
9705 %}
9707 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{
9708 match(Set cr (CmpD src1 src2));
9710 ins_cost(100);
9711 format %{ "ucomisd $src1, $src2 test" %}
9712 ins_encode %{
9713 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9714 %}
9715 ins_pipe(pipe_slow);
9716 %}
9718 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2)
9719 %{
9720 match(Set cr (CmpD src1 (LoadD src2)));
9722 ins_cost(145);
9723 format %{ "ucomisd $src1, $src2\n\t"
9724 "jnp,s exit\n\t"
9725 "pushfq\t# saw NaN, set CF\n\t"
9726 "andq [rsp], #0xffffff2b\n\t"
9727 "popfq\n"
9728 "exit:" %}
9729 ins_encode %{
9730 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9731 emit_cmpfp_fixup(_masm);
9732 %}
9733 ins_pipe(pipe_slow);
9734 %}
9736 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{
9737 match(Set cr (CmpD src1 (LoadD src2)));
9739 ins_cost(100);
9740 format %{ "ucomisd $src1, $src2" %}
9741 ins_encode %{
9742 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9743 %}
9744 ins_pipe(pipe_slow);
9745 %}
9747 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{
9748 match(Set cr (CmpD src con));
9750 ins_cost(145);
9751 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
9752 "jnp,s exit\n\t"
9753 "pushfq\t# saw NaN, set CF\n\t"
9754 "andq [rsp], #0xffffff2b\n\t"
9755 "popfq\n"
9756 "exit:" %}
9757 ins_encode %{
9758 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9759 emit_cmpfp_fixup(_masm);
9760 %}
9761 ins_pipe(pipe_slow);
9762 %}
9764 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{
9765 match(Set cr (CmpD src con));
9766 ins_cost(100);
9767 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %}
9768 ins_encode %{
9769 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9770 %}
9771 ins_pipe(pipe_slow);
9772 %}
9774 // Compare into -1,0,1
9775 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr)
9776 %{
9777 match(Set dst (CmpF3 src1 src2));
9778 effect(KILL cr);
9780 ins_cost(275);
9781 format %{ "ucomiss $src1, $src2\n\t"
9782 "movl $dst, #-1\n\t"
9783 "jp,s done\n\t"
9784 "jb,s done\n\t"
9785 "setne $dst\n\t"
9786 "movzbl $dst, $dst\n"
9787 "done:" %}
9788 ins_encode %{
9789 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister);
9790 emit_cmpfp3(_masm, $dst$$Register);
9791 %}
9792 ins_pipe(pipe_slow);
9793 %}
9795 // Compare into -1,0,1
9796 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr)
9797 %{
9798 match(Set dst (CmpF3 src1 (LoadF src2)));
9799 effect(KILL cr);
9801 ins_cost(275);
9802 format %{ "ucomiss $src1, $src2\n\t"
9803 "movl $dst, #-1\n\t"
9804 "jp,s done\n\t"
9805 "jb,s done\n\t"
9806 "setne $dst\n\t"
9807 "movzbl $dst, $dst\n"
9808 "done:" %}
9809 ins_encode %{
9810 __ ucomiss($src1$$XMMRegister, $src2$$Address);
9811 emit_cmpfp3(_masm, $dst$$Register);
9812 %}
9813 ins_pipe(pipe_slow);
9814 %}
9816 // Compare into -1,0,1
9817 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{
9818 match(Set dst (CmpF3 src con));
9819 effect(KILL cr);
9821 ins_cost(275);
9822 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t"
9823 "movl $dst, #-1\n\t"
9824 "jp,s done\n\t"
9825 "jb,s done\n\t"
9826 "setne $dst\n\t"
9827 "movzbl $dst, $dst\n"
9828 "done:" %}
9829 ins_encode %{
9830 __ ucomiss($src$$XMMRegister, $constantaddress($con));
9831 emit_cmpfp3(_masm, $dst$$Register);
9832 %}
9833 ins_pipe(pipe_slow);
9834 %}
9836 // Compare into -1,0,1
9837 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr)
9838 %{
9839 match(Set dst (CmpD3 src1 src2));
9840 effect(KILL cr);
9842 ins_cost(275);
9843 format %{ "ucomisd $src1, $src2\n\t"
9844 "movl $dst, #-1\n\t"
9845 "jp,s done\n\t"
9846 "jb,s done\n\t"
9847 "setne $dst\n\t"
9848 "movzbl $dst, $dst\n"
9849 "done:" %}
9850 ins_encode %{
9851 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister);
9852 emit_cmpfp3(_masm, $dst$$Register);
9853 %}
9854 ins_pipe(pipe_slow);
9855 %}
9857 // Compare into -1,0,1
9858 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr)
9859 %{
9860 match(Set dst (CmpD3 src1 (LoadD src2)));
9861 effect(KILL cr);
9863 ins_cost(275);
9864 format %{ "ucomisd $src1, $src2\n\t"
9865 "movl $dst, #-1\n\t"
9866 "jp,s done\n\t"
9867 "jb,s done\n\t"
9868 "setne $dst\n\t"
9869 "movzbl $dst, $dst\n"
9870 "done:" %}
9871 ins_encode %{
9872 __ ucomisd($src1$$XMMRegister, $src2$$Address);
9873 emit_cmpfp3(_masm, $dst$$Register);
9874 %}
9875 ins_pipe(pipe_slow);
9876 %}
9878 // Compare into -1,0,1
9879 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{
9880 match(Set dst (CmpD3 src con));
9881 effect(KILL cr);
9883 ins_cost(275);
9884 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t"
9885 "movl $dst, #-1\n\t"
9886 "jp,s done\n\t"
9887 "jb,s done\n\t"
9888 "setne $dst\n\t"
9889 "movzbl $dst, $dst\n"
9890 "done:" %}
9891 ins_encode %{
9892 __ ucomisd($src$$XMMRegister, $constantaddress($con));
9893 emit_cmpfp3(_masm, $dst$$Register);
9894 %}
9895 ins_pipe(pipe_slow);
9896 %}
9898 // -----------Trig and Trancendental Instructions------------------------------
9899 instruct cosD_reg(regD dst) %{
9900 match(Set dst (CosD dst));
9902 format %{ "dcos $dst\n\t" %}
9903 opcode(0xD9, 0xFF);
9904 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
9905 ins_pipe( pipe_slow );
9906 %}
9908 instruct sinD_reg(regD dst) %{
9909 match(Set dst (SinD dst));
9911 format %{ "dsin $dst\n\t" %}
9912 opcode(0xD9, 0xFE);
9913 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) );
9914 ins_pipe( pipe_slow );
9915 %}
9917 instruct tanD_reg(regD dst) %{
9918 match(Set dst (TanD dst));
9920 format %{ "dtan $dst\n\t" %}
9921 ins_encode( Push_SrcXD(dst),
9922 Opcode(0xD9), Opcode(0xF2), //fptan
9923 Opcode(0xDD), Opcode(0xD8), //fstp st
9924 Push_ResultXD(dst) );
9925 ins_pipe( pipe_slow );
9926 %}
9928 instruct log10D_reg(regD dst) %{
9929 // The source and result Double operands in XMM registers
9930 match(Set dst (Log10D dst));
9931 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number
9932 // fyl2x ; compute log_10(2) * log_2(x)
9933 format %{ "fldlg2\t\t\t#Log10\n\t"
9934 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t"
9935 %}
9936 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2
9937 Push_SrcXD(dst),
9938 Opcode(0xD9), Opcode(0xF1), // fyl2x
9939 Push_ResultXD(dst));
9941 ins_pipe( pipe_slow );
9942 %}
9944 instruct logD_reg(regD dst) %{
9945 // The source and result Double operands in XMM registers
9946 match(Set dst (LogD dst));
9947 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number
9948 // fyl2x ; compute log_e(2) * log_2(x)
9949 format %{ "fldln2\t\t\t#Log_e\n\t"
9950 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t"
9951 %}
9952 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2
9953 Push_SrcXD(dst),
9954 Opcode(0xD9), Opcode(0xF1), // fyl2x
9955 Push_ResultXD(dst));
9956 ins_pipe( pipe_slow );
9957 %}
9959 instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{
9960 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power
9961 effect(KILL rax, KILL rdx, KILL rcx, KILL cr);
9962 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %}
9963 ins_encode %{
9964 __ subptr(rsp, 8);
9965 __ movdbl(Address(rsp, 0), $src1$$XMMRegister);
9966 __ fld_d(Address(rsp, 0));
9967 __ movdbl(Address(rsp, 0), $src0$$XMMRegister);
9968 __ fld_d(Address(rsp, 0));
9969 __ fast_pow();
9970 __ fstp_d(Address(rsp, 0));
9971 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
9972 __ addptr(rsp, 8);
9973 %}
9974 ins_pipe( pipe_slow );
9975 %}
9977 instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{
9978 match(Set dst (ExpD src));
9979 effect(KILL rax, KILL rcx, KILL rdx, KILL cr);
9980 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %}
9981 ins_encode %{
9982 __ subptr(rsp, 8);
9983 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
9984 __ fld_d(Address(rsp, 0));
9985 __ fast_exp();
9986 __ fstp_d(Address(rsp, 0));
9987 __ movdbl($dst$$XMMRegister, Address(rsp, 0));
9988 __ addptr(rsp, 8);
9989 %}
9990 ins_pipe( pipe_slow );
9991 %}
9993 //----------Arithmetic Conversion Instructions---------------------------------
9995 instruct roundFloat_nop(regF dst)
9996 %{
9997 match(Set dst (RoundFloat dst));
9999 ins_cost(0);
10000 ins_encode();
10001 ins_pipe(empty);
10002 %}
10004 instruct roundDouble_nop(regD dst)
10005 %{
10006 match(Set dst (RoundDouble dst));
10008 ins_cost(0);
10009 ins_encode();
10010 ins_pipe(empty);
10011 %}
10013 instruct convF2D_reg_reg(regD dst, regF src)
10014 %{
10015 match(Set dst (ConvF2D src));
10017 format %{ "cvtss2sd $dst, $src" %}
10018 ins_encode %{
10019 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister);
10020 %}
10021 ins_pipe(pipe_slow); // XXX
10022 %}
10024 instruct convF2D_reg_mem(regD dst, memory src)
10025 %{
10026 match(Set dst (ConvF2D (LoadF src)));
10028 format %{ "cvtss2sd $dst, $src" %}
10029 ins_encode %{
10030 __ cvtss2sd ($dst$$XMMRegister, $src$$Address);
10031 %}
10032 ins_pipe(pipe_slow); // XXX
10033 %}
10035 instruct convD2F_reg_reg(regF dst, regD src)
10036 %{
10037 match(Set dst (ConvD2F src));
10039 format %{ "cvtsd2ss $dst, $src" %}
10040 ins_encode %{
10041 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister);
10042 %}
10043 ins_pipe(pipe_slow); // XXX
10044 %}
10046 instruct convD2F_reg_mem(regF dst, memory src)
10047 %{
10048 match(Set dst (ConvD2F (LoadD src)));
10050 format %{ "cvtsd2ss $dst, $src" %}
10051 ins_encode %{
10052 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address);
10053 %}
10054 ins_pipe(pipe_slow); // XXX
10055 %}
10057 // XXX do mem variants
10058 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr)
10059 %{
10060 match(Set dst (ConvF2I src));
10061 effect(KILL cr);
10063 format %{ "cvttss2sil $dst, $src\t# f2i\n\t"
10064 "cmpl $dst, #0x80000000\n\t"
10065 "jne,s done\n\t"
10066 "subq rsp, #8\n\t"
10067 "movss [rsp], $src\n\t"
10068 "call f2i_fixup\n\t"
10069 "popq $dst\n"
10070 "done: "%}
10071 ins_encode %{
10072 Label done;
10073 __ cvttss2sil($dst$$Register, $src$$XMMRegister);
10074 __ cmpl($dst$$Register, 0x80000000);
10075 __ jccb(Assembler::notEqual, done);
10076 __ subptr(rsp, 8);
10077 __ movflt(Address(rsp, 0), $src$$XMMRegister);
10078 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup())));
10079 __ pop($dst$$Register);
10080 __ bind(done);
10081 %}
10082 ins_pipe(pipe_slow);
10083 %}
10085 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr)
10086 %{
10087 match(Set dst (ConvF2L src));
10088 effect(KILL cr);
10090 format %{ "cvttss2siq $dst, $src\t# f2l\n\t"
10091 "cmpq $dst, [0x8000000000000000]\n\t"
10092 "jne,s done\n\t"
10093 "subq rsp, #8\n\t"
10094 "movss [rsp], $src\n\t"
10095 "call f2l_fixup\n\t"
10096 "popq $dst\n"
10097 "done: "%}
10098 ins_encode %{
10099 Label done;
10100 __ cvttss2siq($dst$$Register, $src$$XMMRegister);
10101 __ cmp64($dst$$Register,
10102 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
10103 __ jccb(Assembler::notEqual, done);
10104 __ subptr(rsp, 8);
10105 __ movflt(Address(rsp, 0), $src$$XMMRegister);
10106 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup())));
10107 __ pop($dst$$Register);
10108 __ bind(done);
10109 %}
10110 ins_pipe(pipe_slow);
10111 %}
10113 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr)
10114 %{
10115 match(Set dst (ConvD2I src));
10116 effect(KILL cr);
10118 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t"
10119 "cmpl $dst, #0x80000000\n\t"
10120 "jne,s done\n\t"
10121 "subq rsp, #8\n\t"
10122 "movsd [rsp], $src\n\t"
10123 "call d2i_fixup\n\t"
10124 "popq $dst\n"
10125 "done: "%}
10126 ins_encode %{
10127 Label done;
10128 __ cvttsd2sil($dst$$Register, $src$$XMMRegister);
10129 __ cmpl($dst$$Register, 0x80000000);
10130 __ jccb(Assembler::notEqual, done);
10131 __ subptr(rsp, 8);
10132 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
10133 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup())));
10134 __ pop($dst$$Register);
10135 __ bind(done);
10136 %}
10137 ins_pipe(pipe_slow);
10138 %}
10140 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr)
10141 %{
10142 match(Set dst (ConvD2L src));
10143 effect(KILL cr);
10145 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t"
10146 "cmpq $dst, [0x8000000000000000]\n\t"
10147 "jne,s done\n\t"
10148 "subq rsp, #8\n\t"
10149 "movsd [rsp], $src\n\t"
10150 "call d2l_fixup\n\t"
10151 "popq $dst\n"
10152 "done: "%}
10153 ins_encode %{
10154 Label done;
10155 __ cvttsd2siq($dst$$Register, $src$$XMMRegister);
10156 __ cmp64($dst$$Register,
10157 ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
10158 __ jccb(Assembler::notEqual, done);
10159 __ subptr(rsp, 8);
10160 __ movdbl(Address(rsp, 0), $src$$XMMRegister);
10161 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup())));
10162 __ pop($dst$$Register);
10163 __ bind(done);
10164 %}
10165 ins_pipe(pipe_slow);
10166 %}
10168 instruct convI2F_reg_reg(regF dst, rRegI src)
10169 %{
10170 predicate(!UseXmmI2F);
10171 match(Set dst (ConvI2F src));
10173 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10174 ins_encode %{
10175 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
10176 %}
10177 ins_pipe(pipe_slow); // XXX
10178 %}
10180 instruct convI2F_reg_mem(regF dst, memory src)
10181 %{
10182 match(Set dst (ConvI2F (LoadI src)));
10184 format %{ "cvtsi2ssl $dst, $src\t# i2f" %}
10185 ins_encode %{
10186 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address);
10187 %}
10188 ins_pipe(pipe_slow); // XXX
10189 %}
10191 instruct convI2D_reg_reg(regD dst, rRegI src)
10192 %{
10193 predicate(!UseXmmI2D);
10194 match(Set dst (ConvI2D src));
10196 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10197 ins_encode %{
10198 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
10199 %}
10200 ins_pipe(pipe_slow); // XXX
10201 %}
10203 instruct convI2D_reg_mem(regD dst, memory src)
10204 %{
10205 match(Set dst (ConvI2D (LoadI src)));
10207 format %{ "cvtsi2sdl $dst, $src\t# i2d" %}
10208 ins_encode %{
10209 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address);
10210 %}
10211 ins_pipe(pipe_slow); // XXX
10212 %}
10214 instruct convXI2F_reg(regF dst, rRegI src)
10215 %{
10216 predicate(UseXmmI2F);
10217 match(Set dst (ConvI2F src));
10219 format %{ "movdl $dst, $src\n\t"
10220 "cvtdq2psl $dst, $dst\t# i2f" %}
10221 ins_encode %{
10222 __ movdl($dst$$XMMRegister, $src$$Register);
10223 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
10224 %}
10225 ins_pipe(pipe_slow); // XXX
10226 %}
10228 instruct convXI2D_reg(regD dst, rRegI src)
10229 %{
10230 predicate(UseXmmI2D);
10231 match(Set dst (ConvI2D src));
10233 format %{ "movdl $dst, $src\n\t"
10234 "cvtdq2pdl $dst, $dst\t# i2d" %}
10235 ins_encode %{
10236 __ movdl($dst$$XMMRegister, $src$$Register);
10237 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
10238 %}
10239 ins_pipe(pipe_slow); // XXX
10240 %}
10242 instruct convL2F_reg_reg(regF dst, rRegL src)
10243 %{
10244 match(Set dst (ConvL2F src));
10246 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10247 ins_encode %{
10248 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register);
10249 %}
10250 ins_pipe(pipe_slow); // XXX
10251 %}
10253 instruct convL2F_reg_mem(regF dst, memory src)
10254 %{
10255 match(Set dst (ConvL2F (LoadL src)));
10257 format %{ "cvtsi2ssq $dst, $src\t# l2f" %}
10258 ins_encode %{
10259 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address);
10260 %}
10261 ins_pipe(pipe_slow); // XXX
10262 %}
10264 instruct convL2D_reg_reg(regD dst, rRegL src)
10265 %{
10266 match(Set dst (ConvL2D src));
10268 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10269 ins_encode %{
10270 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register);
10271 %}
10272 ins_pipe(pipe_slow); // XXX
10273 %}
10275 instruct convL2D_reg_mem(regD dst, memory src)
10276 %{
10277 match(Set dst (ConvL2D (LoadL src)));
10279 format %{ "cvtsi2sdq $dst, $src\t# l2d" %}
10280 ins_encode %{
10281 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address);
10282 %}
10283 ins_pipe(pipe_slow); // XXX
10284 %}
10286 instruct convI2L_reg_reg(rRegL dst, rRegI src)
10287 %{
10288 match(Set dst (ConvI2L src));
10290 ins_cost(125);
10291 format %{ "movslq $dst, $src\t# i2l" %}
10292 ins_encode %{
10293 __ movslq($dst$$Register, $src$$Register);
10294 %}
10295 ins_pipe(ialu_reg_reg);
10296 %}
10298 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src)
10299 // %{
10300 // match(Set dst (ConvI2L src));
10301 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 &&
10302 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0);
10303 // predicate(((const TypeNode*) n)->type()->is_long()->_hi ==
10304 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi &&
10305 // ((const TypeNode*) n)->type()->is_long()->_lo ==
10306 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo);
10308 // format %{ "movl $dst, $src\t# unsigned i2l" %}
10309 // ins_encode(enc_copy(dst, src));
10310 // // opcode(0x63); // needs REX.W
10311 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src));
10312 // ins_pipe(ialu_reg_reg);
10313 // %}
10315 // Zero-extend convert int to long
10316 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask)
10317 %{
10318 match(Set dst (AndL (ConvI2L src) mask));
10320 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10321 ins_encode %{
10322 if ($dst$$reg != $src$$reg) {
10323 __ movl($dst$$Register, $src$$Register);
10324 }
10325 %}
10326 ins_pipe(ialu_reg_reg);
10327 %}
10329 // Zero-extend convert int to long
10330 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask)
10331 %{
10332 match(Set dst (AndL (ConvI2L (LoadI src)) mask));
10334 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %}
10335 ins_encode %{
10336 __ movl($dst$$Register, $src$$Address);
10337 %}
10338 ins_pipe(ialu_reg_mem);
10339 %}
10341 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask)
10342 %{
10343 match(Set dst (AndL src mask));
10345 format %{ "movl $dst, $src\t# zero-extend long" %}
10346 ins_encode %{
10347 __ movl($dst$$Register, $src$$Register);
10348 %}
10349 ins_pipe(ialu_reg_reg);
10350 %}
10352 instruct convL2I_reg_reg(rRegI dst, rRegL src)
10353 %{
10354 match(Set dst (ConvL2I src));
10356 format %{ "movl $dst, $src\t# l2i" %}
10357 ins_encode %{
10358 __ movl($dst$$Register, $src$$Register);
10359 %}
10360 ins_pipe(ialu_reg_reg);
10361 %}
10364 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
10365 match(Set dst (MoveF2I src));
10366 effect(DEF dst, USE src);
10368 ins_cost(125);
10369 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %}
10370 ins_encode %{
10371 __ movl($dst$$Register, Address(rsp, $src$$disp));
10372 %}
10373 ins_pipe(ialu_reg_mem);
10374 %}
10376 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{
10377 match(Set dst (MoveI2F src));
10378 effect(DEF dst, USE src);
10380 ins_cost(125);
10381 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %}
10382 ins_encode %{
10383 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
10384 %}
10385 ins_pipe(pipe_slow);
10386 %}
10388 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{
10389 match(Set dst (MoveD2L src));
10390 effect(DEF dst, USE src);
10392 ins_cost(125);
10393 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %}
10394 ins_encode %{
10395 __ movq($dst$$Register, Address(rsp, $src$$disp));
10396 %}
10397 ins_pipe(ialu_reg_mem);
10398 %}
10400 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{
10401 predicate(!UseXmmLoadAndClearUpper);
10402 match(Set dst (MoveL2D src));
10403 effect(DEF dst, USE src);
10405 ins_cost(125);
10406 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %}
10407 ins_encode %{
10408 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10409 %}
10410 ins_pipe(pipe_slow);
10411 %}
10413 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{
10414 predicate(UseXmmLoadAndClearUpper);
10415 match(Set dst (MoveL2D src));
10416 effect(DEF dst, USE src);
10418 ins_cost(125);
10419 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %}
10420 ins_encode %{
10421 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp));
10422 %}
10423 ins_pipe(pipe_slow);
10424 %}
10427 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{
10428 match(Set dst (MoveF2I src));
10429 effect(DEF dst, USE src);
10431 ins_cost(95); // XXX
10432 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %}
10433 ins_encode %{
10434 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
10435 %}
10436 ins_pipe(pipe_slow);
10437 %}
10439 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
10440 match(Set dst (MoveI2F src));
10441 effect(DEF dst, USE src);
10443 ins_cost(100);
10444 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %}
10445 ins_encode %{
10446 __ movl(Address(rsp, $dst$$disp), $src$$Register);
10447 %}
10448 ins_pipe( ialu_mem_reg );
10449 %}
10451 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{
10452 match(Set dst (MoveD2L src));
10453 effect(DEF dst, USE src);
10455 ins_cost(95); // XXX
10456 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %}
10457 ins_encode %{
10458 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister);
10459 %}
10460 ins_pipe(pipe_slow);
10461 %}
10463 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{
10464 match(Set dst (MoveL2D src));
10465 effect(DEF dst, USE src);
10467 ins_cost(100);
10468 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %}
10469 ins_encode %{
10470 __ movq(Address(rsp, $dst$$disp), $src$$Register);
10471 %}
10472 ins_pipe(ialu_mem_reg);
10473 %}
10475 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{
10476 match(Set dst (MoveF2I src));
10477 effect(DEF dst, USE src);
10478 ins_cost(85);
10479 format %{ "movd $dst,$src\t# MoveF2I" %}
10480 ins_encode %{
10481 __ movdl($dst$$Register, $src$$XMMRegister);
10482 %}
10483 ins_pipe( pipe_slow );
10484 %}
10486 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{
10487 match(Set dst (MoveD2L src));
10488 effect(DEF dst, USE src);
10489 ins_cost(85);
10490 format %{ "movd $dst,$src\t# MoveD2L" %}
10491 ins_encode %{
10492 __ movdq($dst$$Register, $src$$XMMRegister);
10493 %}
10494 ins_pipe( pipe_slow );
10495 %}
10497 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
10498 match(Set dst (MoveI2F src));
10499 effect(DEF dst, USE src);
10500 ins_cost(100);
10501 format %{ "movd $dst,$src\t# MoveI2F" %}
10502 ins_encode %{
10503 __ movdl($dst$$XMMRegister, $src$$Register);
10504 %}
10505 ins_pipe( pipe_slow );
10506 %}
10508 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
10509 match(Set dst (MoveL2D src));
10510 effect(DEF dst, USE src);
10511 ins_cost(100);
10512 format %{ "movd $dst,$src\t# MoveL2D" %}
10513 ins_encode %{
10514 __ movdq($dst$$XMMRegister, $src$$Register);
10515 %}
10516 ins_pipe( pipe_slow );
10517 %}
10520 // =======================================================================
10521 // fast clearing of an array
10522 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10523 rFlagsReg cr)
10524 %{
10525 predicate(!UseFastStosb);
10526 match(Set dummy (ClearArray cnt base));
10527 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10529 format %{ "xorq rax, rax\t# ClearArray:\n\t"
10530 "rep stosq\t# Store rax to *rdi++ while rcx--" %}
10531 ins_encode %{
10532 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
10533 %}
10534 ins_pipe(pipe_slow);
10535 %}
10537 instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
10538 rFlagsReg cr)
10539 %{
10540 predicate(UseFastStosb);
10541 match(Set dummy (ClearArray cnt base));
10542 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
10543 format %{ "xorq rax, rax\t# ClearArray:\n\t"
10544 "shlq rcx,3\t# Convert doublewords to bytes\n\t"
10545 "rep stosb\t# Store rax to *rdi++ while rcx--" %}
10546 ins_encode %{
10547 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
10548 %}
10549 ins_pipe( pipe_slow );
10550 %}
10552 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2,
10553 rax_RegI result, regD tmp1, rFlagsReg cr)
10554 %{
10555 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
10556 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
10558 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %}
10559 ins_encode %{
10560 __ string_compare($str1$$Register, $str2$$Register,
10561 $cnt1$$Register, $cnt2$$Register, $result$$Register,
10562 $tmp1$$XMMRegister);
10563 %}
10564 ins_pipe( pipe_slow );
10565 %}
10567 // fast search of substring with known size.
10568 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2,
10569 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr)
10570 %{
10571 predicate(UseSSE42Intrinsics);
10572 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
10573 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr);
10575 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %}
10576 ins_encode %{
10577 int icnt2 = (int)$int_cnt2$$constant;
10578 if (icnt2 >= 8) {
10579 // IndexOf for constant substrings with size >= 8 elements
10580 // which don't need to be loaded through stack.
10581 __ string_indexofC8($str1$$Register, $str2$$Register,
10582 $cnt1$$Register, $cnt2$$Register,
10583 icnt2, $result$$Register,
10584 $vec$$XMMRegister, $tmp$$Register);
10585 } else {
10586 // Small strings are loaded through stack if they cross page boundary.
10587 __ string_indexof($str1$$Register, $str2$$Register,
10588 $cnt1$$Register, $cnt2$$Register,
10589 icnt2, $result$$Register,
10590 $vec$$XMMRegister, $tmp$$Register);
10591 }
10592 %}
10593 ins_pipe( pipe_slow );
10594 %}
10596 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2,
10597 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr)
10598 %{
10599 predicate(UseSSE42Intrinsics);
10600 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
10601 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr);
10603 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %}
10604 ins_encode %{
10605 __ string_indexof($str1$$Register, $str2$$Register,
10606 $cnt1$$Register, $cnt2$$Register,
10607 (-1), $result$$Register,
10608 $vec$$XMMRegister, $tmp$$Register);
10609 %}
10610 ins_pipe( pipe_slow );
10611 %}
10613 // fast string equals
10614 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result,
10615 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr)
10616 %{
10617 match(Set result (StrEquals (Binary str1 str2) cnt));
10618 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr);
10620 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %}
10621 ins_encode %{
10622 __ char_arrays_equals(false, $str1$$Register, $str2$$Register,
10623 $cnt$$Register, $result$$Register, $tmp3$$Register,
10624 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
10625 %}
10626 ins_pipe( pipe_slow );
10627 %}
10629 // fast array equals
10630 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result,
10631 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr)
10632 %{
10633 match(Set result (AryEq ary1 ary2));
10634 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
10635 //ins_cost(300);
10637 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
10638 ins_encode %{
10639 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
10640 $tmp3$$Register, $result$$Register, $tmp4$$Register,
10641 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
10642 %}
10643 ins_pipe( pipe_slow );
10644 %}
10646 // encode char[] to byte[] in ISO_8859_1
10647 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len,
10648 regD tmp1, regD tmp2, regD tmp3, regD tmp4,
10649 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{
10650 match(Set result (EncodeISOArray src (Binary dst len)));
10651 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr);
10653 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %}
10654 ins_encode %{
10655 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register,
10656 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister,
10657 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register);
10658 %}
10659 ins_pipe( pipe_slow );
10660 %}
10663 //----------Control Flow Instructions------------------------------------------
10664 // Signed compare Instructions
10666 // XXX more variants!!
10667 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2)
10668 %{
10669 match(Set cr (CmpI op1 op2));
10670 effect(DEF cr, USE op1, USE op2);
10672 format %{ "cmpl $op1, $op2" %}
10673 opcode(0x3B); /* Opcode 3B /r */
10674 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
10675 ins_pipe(ialu_cr_reg_reg);
10676 %}
10678 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2)
10679 %{
10680 match(Set cr (CmpI op1 op2));
10682 format %{ "cmpl $op1, $op2" %}
10683 opcode(0x81, 0x07); /* Opcode 81 /7 */
10684 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
10685 ins_pipe(ialu_cr_reg_imm);
10686 %}
10688 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2)
10689 %{
10690 match(Set cr (CmpI op1 (LoadI op2)));
10692 ins_cost(500); // XXX
10693 format %{ "cmpl $op1, $op2" %}
10694 opcode(0x3B); /* Opcode 3B /r */
10695 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
10696 ins_pipe(ialu_cr_reg_mem);
10697 %}
10699 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero)
10700 %{
10701 match(Set cr (CmpI src zero));
10703 format %{ "testl $src, $src" %}
10704 opcode(0x85);
10705 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
10706 ins_pipe(ialu_cr_reg_imm);
10707 %}
10709 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero)
10710 %{
10711 match(Set cr (CmpI (AndI src con) zero));
10713 format %{ "testl $src, $con" %}
10714 opcode(0xF7, 0x00);
10715 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con));
10716 ins_pipe(ialu_cr_reg_imm);
10717 %}
10719 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero)
10720 %{
10721 match(Set cr (CmpI (AndI src (LoadI mem)) zero));
10723 format %{ "testl $src, $mem" %}
10724 opcode(0x85);
10725 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem));
10726 ins_pipe(ialu_cr_reg_mem);
10727 %}
10729 // Unsigned compare Instructions; really, same as signed except they
10730 // produce an rFlagsRegU instead of rFlagsReg.
10731 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2)
10732 %{
10733 match(Set cr (CmpU op1 op2));
10735 format %{ "cmpl $op1, $op2\t# unsigned" %}
10736 opcode(0x3B); /* Opcode 3B /r */
10737 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2));
10738 ins_pipe(ialu_cr_reg_reg);
10739 %}
10741 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2)
10742 %{
10743 match(Set cr (CmpU op1 op2));
10745 format %{ "cmpl $op1, $op2\t# unsigned" %}
10746 opcode(0x81,0x07); /* Opcode 81 /7 */
10747 ins_encode(OpcSErm(op1, op2), Con8or32(op2));
10748 ins_pipe(ialu_cr_reg_imm);
10749 %}
10751 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2)
10752 %{
10753 match(Set cr (CmpU op1 (LoadI op2)));
10755 ins_cost(500); // XXX
10756 format %{ "cmpl $op1, $op2\t# unsigned" %}
10757 opcode(0x3B); /* Opcode 3B /r */
10758 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2));
10759 ins_pipe(ialu_cr_reg_mem);
10760 %}
10762 // // // Cisc-spilled version of cmpU_rReg
10763 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2)
10764 // //%{
10765 // // match(Set cr (CmpU (LoadI op1) op2));
10766 // //
10767 // // format %{ "CMPu $op1,$op2" %}
10768 // // ins_cost(500);
10769 // // opcode(0x39); /* Opcode 39 /r */
10770 // // ins_encode( OpcP, reg_mem( op1, op2) );
10771 // //%}
10773 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero)
10774 %{
10775 match(Set cr (CmpU src zero));
10777 format %{ "testl $src, $src\t# unsigned" %}
10778 opcode(0x85);
10779 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src));
10780 ins_pipe(ialu_cr_reg_imm);
10781 %}
10783 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2)
10784 %{
10785 match(Set cr (CmpP op1 op2));
10787 format %{ "cmpq $op1, $op2\t# ptr" %}
10788 opcode(0x3B); /* Opcode 3B /r */
10789 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
10790 ins_pipe(ialu_cr_reg_reg);
10791 %}
10793 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
10794 %{
10795 match(Set cr (CmpP op1 (LoadP op2)));
10797 ins_cost(500); // XXX
10798 format %{ "cmpq $op1, $op2\t# ptr" %}
10799 opcode(0x3B); /* Opcode 3B /r */
10800 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10801 ins_pipe(ialu_cr_reg_mem);
10802 %}
10804 // // // Cisc-spilled version of cmpP_rReg
10805 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2)
10806 // //%{
10807 // // match(Set cr (CmpP (LoadP op1) op2));
10808 // //
10809 // // format %{ "CMPu $op1,$op2" %}
10810 // // ins_cost(500);
10811 // // opcode(0x39); /* Opcode 39 /r */
10812 // // ins_encode( OpcP, reg_mem( op1, op2) );
10813 // //%}
10815 // XXX this is generalized by compP_rReg_mem???
10816 // Compare raw pointer (used in out-of-heap check).
10817 // Only works because non-oop pointers must be raw pointers
10818 // and raw pointers have no anti-dependencies.
10819 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
10820 %{
10821 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none);
10822 match(Set cr (CmpP op1 (LoadP op2)));
10824 format %{ "cmpq $op1, $op2\t# raw ptr" %}
10825 opcode(0x3B); /* Opcode 3B /r */
10826 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10827 ins_pipe(ialu_cr_reg_mem);
10828 %}
10830 // This will generate a signed flags result. This should be OK since
10831 // any compare to a zero should be eq/neq.
10832 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero)
10833 %{
10834 match(Set cr (CmpP src zero));
10836 format %{ "testq $src, $src\t# ptr" %}
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 // This will generate a signed flags result. This should be OK since
10843 // any compare to a zero should be eq/neq.
10844 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
10845 %{
10846 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL));
10847 match(Set cr (CmpP (LoadP op) zero));
10849 ins_cost(500); // XXX
10850 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %}
10851 opcode(0xF7); /* Opcode F7 /0 */
10852 ins_encode(REX_mem_wide(op),
10853 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF));
10854 ins_pipe(ialu_cr_reg_imm);
10855 %}
10857 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
10858 %{
10859 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL));
10860 match(Set cr (CmpP (LoadP mem) zero));
10862 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %}
10863 ins_encode %{
10864 __ cmpq(r12, $mem$$Address);
10865 %}
10866 ins_pipe(ialu_cr_reg_mem);
10867 %}
10869 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
10870 %{
10871 match(Set cr (CmpN op1 op2));
10873 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
10874 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %}
10875 ins_pipe(ialu_cr_reg_reg);
10876 %}
10878 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
10879 %{
10880 match(Set cr (CmpN src (LoadN mem)));
10882 format %{ "cmpl $src, $mem\t# compressed ptr" %}
10883 ins_encode %{
10884 __ cmpl($src$$Register, $mem$$Address);
10885 %}
10886 ins_pipe(ialu_cr_reg_mem);
10887 %}
10889 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{
10890 match(Set cr (CmpN op1 op2));
10892 format %{ "cmpl $op1, $op2\t# compressed ptr" %}
10893 ins_encode %{
10894 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant);
10895 %}
10896 ins_pipe(ialu_cr_reg_imm);
10897 %}
10899 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src)
10900 %{
10901 match(Set cr (CmpN src (LoadN mem)));
10903 format %{ "cmpl $mem, $src\t# compressed ptr" %}
10904 ins_encode %{
10905 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant);
10906 %}
10907 ins_pipe(ialu_cr_reg_mem);
10908 %}
10910 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{
10911 match(Set cr (CmpN op1 op2));
10913 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %}
10914 ins_encode %{
10915 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant);
10916 %}
10917 ins_pipe(ialu_cr_reg_imm);
10918 %}
10920 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src)
10921 %{
10922 match(Set cr (CmpN src (LoadNKlass mem)));
10924 format %{ "cmpl $mem, $src\t# compressed klass ptr" %}
10925 ins_encode %{
10926 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant);
10927 %}
10928 ins_pipe(ialu_cr_reg_mem);
10929 %}
10931 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
10932 match(Set cr (CmpN src zero));
10934 format %{ "testl $src, $src\t# compressed ptr" %}
10935 ins_encode %{ __ testl($src$$Register, $src$$Register); %}
10936 ins_pipe(ialu_cr_reg_imm);
10937 %}
10939 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero)
10940 %{
10941 predicate(Universe::narrow_oop_base() != NULL);
10942 match(Set cr (CmpN (LoadN mem) zero));
10944 ins_cost(500); // XXX
10945 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
10946 ins_encode %{
10947 __ cmpl($mem$$Address, (int)0xFFFFFFFF);
10948 %}
10949 ins_pipe(ialu_cr_reg_mem);
10950 %}
10952 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero)
10953 %{
10954 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL));
10955 match(Set cr (CmpN (LoadN mem) zero));
10957 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %}
10958 ins_encode %{
10959 __ cmpl(r12, $mem$$Address);
10960 %}
10961 ins_pipe(ialu_cr_reg_mem);
10962 %}
10964 // Yanked all unsigned pointer compare operations.
10965 // Pointer compares are done with CmpP which is already unsigned.
10967 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2)
10968 %{
10969 match(Set cr (CmpL op1 op2));
10971 format %{ "cmpq $op1, $op2" %}
10972 opcode(0x3B); /* Opcode 3B /r */
10973 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2));
10974 ins_pipe(ialu_cr_reg_reg);
10975 %}
10977 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2)
10978 %{
10979 match(Set cr (CmpL op1 op2));
10981 format %{ "cmpq $op1, $op2" %}
10982 opcode(0x81, 0x07); /* Opcode 81 /7 */
10983 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2));
10984 ins_pipe(ialu_cr_reg_imm);
10985 %}
10987 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2)
10988 %{
10989 match(Set cr (CmpL op1 (LoadL op2)));
10991 format %{ "cmpq $op1, $op2" %}
10992 opcode(0x3B); /* Opcode 3B /r */
10993 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2));
10994 ins_pipe(ialu_cr_reg_mem);
10995 %}
10997 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero)
10998 %{
10999 match(Set cr (CmpL src zero));
11001 format %{ "testq $src, $src" %}
11002 opcode(0x85);
11003 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src));
11004 ins_pipe(ialu_cr_reg_imm);
11005 %}
11007 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero)
11008 %{
11009 match(Set cr (CmpL (AndL src con) zero));
11011 format %{ "testq $src, $con\t# long" %}
11012 opcode(0xF7, 0x00);
11013 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con));
11014 ins_pipe(ialu_cr_reg_imm);
11015 %}
11017 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero)
11018 %{
11019 match(Set cr (CmpL (AndL src (LoadL mem)) zero));
11021 format %{ "testq $src, $mem" %}
11022 opcode(0x85);
11023 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem));
11024 ins_pipe(ialu_cr_reg_mem);
11025 %}
11027 // Manifest a CmpL result in an integer register. Very painful.
11028 // This is the test to avoid.
11029 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
11030 %{
11031 match(Set dst (CmpL3 src1 src2));
11032 effect(KILL flags);
11034 ins_cost(275); // XXX
11035 format %{ "cmpq $src1, $src2\t# CmpL3\n\t"
11036 "movl $dst, -1\n\t"
11037 "jl,s done\n\t"
11038 "setne $dst\n\t"
11039 "movzbl $dst, $dst\n\t"
11040 "done:" %}
11041 ins_encode(cmpl3_flag(src1, src2, dst));
11042 ins_pipe(pipe_slow);
11043 %}
11045 //----------Max and Min--------------------------------------------------------
11046 // Min Instructions
11048 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr)
11049 %{
11050 effect(USE_DEF dst, USE src, USE cr);
11052 format %{ "cmovlgt $dst, $src\t# min" %}
11053 opcode(0x0F, 0x4F);
11054 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
11055 ins_pipe(pipe_cmov_reg);
11056 %}
11059 instruct minI_rReg(rRegI dst, rRegI src)
11060 %{
11061 match(Set dst (MinI dst src));
11063 ins_cost(200);
11064 expand %{
11065 rFlagsReg cr;
11066 compI_rReg(cr, dst, src);
11067 cmovI_reg_g(dst, src, cr);
11068 %}
11069 %}
11071 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr)
11072 %{
11073 effect(USE_DEF dst, USE src, USE cr);
11075 format %{ "cmovllt $dst, $src\t# max" %}
11076 opcode(0x0F, 0x4C);
11077 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src));
11078 ins_pipe(pipe_cmov_reg);
11079 %}
11082 instruct maxI_rReg(rRegI dst, rRegI src)
11083 %{
11084 match(Set dst (MaxI dst src));
11086 ins_cost(200);
11087 expand %{
11088 rFlagsReg cr;
11089 compI_rReg(cr, dst, src);
11090 cmovI_reg_l(dst, src, cr);
11091 %}
11092 %}
11094 // ============================================================================
11095 // Branch Instructions
11097 // Jump Direct - Label defines a relative address from JMP+1
11098 instruct jmpDir(label labl)
11099 %{
11100 match(Goto);
11101 effect(USE labl);
11103 ins_cost(300);
11104 format %{ "jmp $labl" %}
11105 size(5);
11106 ins_encode %{
11107 Label* L = $labl$$label;
11108 __ jmp(*L, false); // Always long jump
11109 %}
11110 ins_pipe(pipe_jmp);
11111 %}
11113 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11114 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl)
11115 %{
11116 match(If cop cr);
11117 effect(USE labl);
11119 ins_cost(300);
11120 format %{ "j$cop $labl" %}
11121 size(6);
11122 ins_encode %{
11123 Label* L = $labl$$label;
11124 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11125 %}
11126 ins_pipe(pipe_jcc);
11127 %}
11129 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11130 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl)
11131 %{
11132 match(CountedLoopEnd cop cr);
11133 effect(USE labl);
11135 ins_cost(300);
11136 format %{ "j$cop $labl\t# loop end" %}
11137 size(6);
11138 ins_encode %{
11139 Label* L = $labl$$label;
11140 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11141 %}
11142 ins_pipe(pipe_jcc);
11143 %}
11145 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11146 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11147 match(CountedLoopEnd cop cmp);
11148 effect(USE labl);
11150 ins_cost(300);
11151 format %{ "j$cop,u $labl\t# loop end" %}
11152 size(6);
11153 ins_encode %{
11154 Label* L = $labl$$label;
11155 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11156 %}
11157 ins_pipe(pipe_jcc);
11158 %}
11160 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11161 match(CountedLoopEnd cop cmp);
11162 effect(USE labl);
11164 ins_cost(200);
11165 format %{ "j$cop,u $labl\t# loop end" %}
11166 size(6);
11167 ins_encode %{
11168 Label* L = $labl$$label;
11169 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11170 %}
11171 ins_pipe(pipe_jcc);
11172 %}
11174 // Jump Direct Conditional - using unsigned comparison
11175 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11176 match(If cop cmp);
11177 effect(USE labl);
11179 ins_cost(300);
11180 format %{ "j$cop,u $labl" %}
11181 size(6);
11182 ins_encode %{
11183 Label* L = $labl$$label;
11184 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11185 %}
11186 ins_pipe(pipe_jcc);
11187 %}
11189 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11190 match(If cop cmp);
11191 effect(USE labl);
11193 ins_cost(200);
11194 format %{ "j$cop,u $labl" %}
11195 size(6);
11196 ins_encode %{
11197 Label* L = $labl$$label;
11198 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump
11199 %}
11200 ins_pipe(pipe_jcc);
11201 %}
11203 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
11204 match(If cop cmp);
11205 effect(USE labl);
11207 ins_cost(200);
11208 format %{ $$template
11209 if ($cop$$cmpcode == Assembler::notEqual) {
11210 $$emit$$"jp,u $labl\n\t"
11211 $$emit$$"j$cop,u $labl"
11212 } else {
11213 $$emit$$"jp,u done\n\t"
11214 $$emit$$"j$cop,u $labl\n\t"
11215 $$emit$$"done:"
11216 }
11217 %}
11218 ins_encode %{
11219 Label* l = $labl$$label;
11220 if ($cop$$cmpcode == Assembler::notEqual) {
11221 __ jcc(Assembler::parity, *l, false);
11222 __ jcc(Assembler::notEqual, *l, false);
11223 } else if ($cop$$cmpcode == Assembler::equal) {
11224 Label done;
11225 __ jccb(Assembler::parity, done);
11226 __ jcc(Assembler::equal, *l, false);
11227 __ bind(done);
11228 } else {
11229 ShouldNotReachHere();
11230 }
11231 %}
11232 ins_pipe(pipe_jcc);
11233 %}
11235 // ============================================================================
11236 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary
11237 // superklass array for an instance of the superklass. Set a hidden
11238 // internal cache on a hit (cache is checked with exposed code in
11239 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The
11240 // encoding ALSO sets flags.
11242 instruct partialSubtypeCheck(rdi_RegP result,
11243 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
11244 rFlagsReg cr)
11245 %{
11246 match(Set result (PartialSubtypeCheck sub super));
11247 effect(KILL rcx, KILL cr);
11249 ins_cost(1100); // slightly larger than the next version
11250 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
11251 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t"
11252 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t"
11253 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t"
11254 "jne,s miss\t\t# Missed: rdi not-zero\n\t"
11255 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
11256 "xorq $result, $result\t\t Hit: rdi zero\n\t"
11257 "miss:\t" %}
11259 opcode(0x1); // Force a XOR of RDI
11260 ins_encode(enc_PartialSubtypeCheck());
11261 ins_pipe(pipe_slow);
11262 %}
11264 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr,
11265 rsi_RegP sub, rax_RegP super, rcx_RegI rcx,
11266 immP0 zero,
11267 rdi_RegP result)
11268 %{
11269 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero));
11270 effect(KILL rcx, KILL result);
11272 ins_cost(1000);
11273 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t"
11274 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t"
11275 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t"
11276 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t"
11277 "jne,s miss\t\t# Missed: flags nz\n\t"
11278 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t"
11279 "miss:\t" %}
11281 opcode(0x0); // No need to XOR RDI
11282 ins_encode(enc_PartialSubtypeCheck());
11283 ins_pipe(pipe_slow);
11284 %}
11286 // ============================================================================
11287 // Branch Instructions -- short offset versions
11288 //
11289 // These instructions are used to replace jumps of a long offset (the default
11290 // match) with jumps of a shorter offset. These instructions are all tagged
11291 // with the ins_short_branch attribute, which causes the ADLC to suppress the
11292 // match rules in general matching. Instead, the ADLC generates a conversion
11293 // method in the MachNode which can be used to do in-place replacement of the
11294 // long variant with the shorter variant. The compiler will determine if a
11295 // branch can be taken by the is_short_branch_offset() predicate in the machine
11296 // specific code section of the file.
11298 // Jump Direct - Label defines a relative address from JMP+1
11299 instruct jmpDir_short(label labl) %{
11300 match(Goto);
11301 effect(USE labl);
11303 ins_cost(300);
11304 format %{ "jmp,s $labl" %}
11305 size(2);
11306 ins_encode %{
11307 Label* L = $labl$$label;
11308 __ jmpb(*L);
11309 %}
11310 ins_pipe(pipe_jmp);
11311 ins_short_branch(1);
11312 %}
11314 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11315 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{
11316 match(If cop cr);
11317 effect(USE labl);
11319 ins_cost(300);
11320 format %{ "j$cop,s $labl" %}
11321 size(2);
11322 ins_encode %{
11323 Label* L = $labl$$label;
11324 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11325 %}
11326 ins_pipe(pipe_jcc);
11327 ins_short_branch(1);
11328 %}
11330 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11331 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{
11332 match(CountedLoopEnd cop cr);
11333 effect(USE labl);
11335 ins_cost(300);
11336 format %{ "j$cop,s $labl\t# loop end" %}
11337 size(2);
11338 ins_encode %{
11339 Label* L = $labl$$label;
11340 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11341 %}
11342 ins_pipe(pipe_jcc);
11343 ins_short_branch(1);
11344 %}
11346 // Jump Direct Conditional - Label defines a relative address from Jcc+1
11347 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11348 match(CountedLoopEnd cop cmp);
11349 effect(USE labl);
11351 ins_cost(300);
11352 format %{ "j$cop,us $labl\t# loop end" %}
11353 size(2);
11354 ins_encode %{
11355 Label* L = $labl$$label;
11356 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11357 %}
11358 ins_pipe(pipe_jcc);
11359 ins_short_branch(1);
11360 %}
11362 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11363 match(CountedLoopEnd cop cmp);
11364 effect(USE labl);
11366 ins_cost(300);
11367 format %{ "j$cop,us $labl\t# loop end" %}
11368 size(2);
11369 ins_encode %{
11370 Label* L = $labl$$label;
11371 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11372 %}
11373 ins_pipe(pipe_jcc);
11374 ins_short_branch(1);
11375 %}
11377 // Jump Direct Conditional - using unsigned comparison
11378 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{
11379 match(If cop cmp);
11380 effect(USE labl);
11382 ins_cost(300);
11383 format %{ "j$cop,us $labl" %}
11384 size(2);
11385 ins_encode %{
11386 Label* L = $labl$$label;
11387 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11388 %}
11389 ins_pipe(pipe_jcc);
11390 ins_short_branch(1);
11391 %}
11393 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{
11394 match(If cop cmp);
11395 effect(USE labl);
11397 ins_cost(300);
11398 format %{ "j$cop,us $labl" %}
11399 size(2);
11400 ins_encode %{
11401 Label* L = $labl$$label;
11402 __ jccb((Assembler::Condition)($cop$$cmpcode), *L);
11403 %}
11404 ins_pipe(pipe_jcc);
11405 ins_short_branch(1);
11406 %}
11408 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{
11409 match(If cop cmp);
11410 effect(USE labl);
11412 ins_cost(300);
11413 format %{ $$template
11414 if ($cop$$cmpcode == Assembler::notEqual) {
11415 $$emit$$"jp,u,s $labl\n\t"
11416 $$emit$$"j$cop,u,s $labl"
11417 } else {
11418 $$emit$$"jp,u,s done\n\t"
11419 $$emit$$"j$cop,u,s $labl\n\t"
11420 $$emit$$"done:"
11421 }
11422 %}
11423 size(4);
11424 ins_encode %{
11425 Label* l = $labl$$label;
11426 if ($cop$$cmpcode == Assembler::notEqual) {
11427 __ jccb(Assembler::parity, *l);
11428 __ jccb(Assembler::notEqual, *l);
11429 } else if ($cop$$cmpcode == Assembler::equal) {
11430 Label done;
11431 __ jccb(Assembler::parity, done);
11432 __ jccb(Assembler::equal, *l);
11433 __ bind(done);
11434 } else {
11435 ShouldNotReachHere();
11436 }
11437 %}
11438 ins_pipe(pipe_jcc);
11439 ins_short_branch(1);
11440 %}
11442 // ============================================================================
11443 // inlined locking and unlocking
11445 instruct cmpFastLock(rFlagsReg cr,
11446 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr)
11447 %{
11448 match(Set cr (FastLock object box));
11449 effect(TEMP tmp, TEMP scr, USE_KILL box);
11451 ins_cost(300);
11452 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %}
11453 ins_encode(Fast_Lock(object, box, tmp, scr));
11454 ins_pipe(pipe_slow);
11455 %}
11457 instruct cmpFastUnlock(rFlagsReg cr,
11458 rRegP object, rax_RegP box, rRegP tmp)
11459 %{
11460 match(Set cr (FastUnlock object box));
11461 effect(TEMP tmp, USE_KILL box);
11463 ins_cost(300);
11464 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %}
11465 ins_encode(Fast_Unlock(object, box, tmp));
11466 ins_pipe(pipe_slow);
11467 %}
11470 // ============================================================================
11471 // Safepoint Instructions
11472 instruct safePoint_poll(rFlagsReg cr)
11473 %{
11474 predicate(!Assembler::is_polling_page_far());
11475 match(SafePoint);
11476 effect(KILL cr);
11478 format %{ "testl rax, [rip + #offset_to_poll_page]\t"
11479 "# Safepoint: poll for GC" %}
11480 ins_cost(125);
11481 ins_encode %{
11482 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type);
11483 __ testl(rax, addr);
11484 %}
11485 ins_pipe(ialu_reg_mem);
11486 %}
11488 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
11489 %{
11490 predicate(Assembler::is_polling_page_far());
11491 match(SafePoint poll);
11492 effect(KILL cr, USE poll);
11494 format %{ "testl rax, [$poll]\t"
11495 "# Safepoint: poll for GC" %}
11496 ins_cost(125);
11497 ins_encode %{
11498 __ relocate(relocInfo::poll_type);
11499 __ testl(rax, Address($poll$$Register, 0));
11500 %}
11501 ins_pipe(ialu_reg_mem);
11502 %}
11504 // ============================================================================
11505 // Procedure Call/Return Instructions
11506 // Call Java Static Instruction
11507 // Note: If this code changes, the corresponding ret_addr_offset() and
11508 // compute_padding() functions will have to be adjusted.
11509 instruct CallStaticJavaDirect(method meth) %{
11510 match(CallStaticJava);
11511 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke());
11512 effect(USE meth);
11514 ins_cost(300);
11515 format %{ "call,static " %}
11516 opcode(0xE8); /* E8 cd */
11517 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog);
11518 ins_pipe(pipe_slow);
11519 ins_alignment(4);
11520 %}
11522 // Call Java Static Instruction (method handle version)
11523 // Note: If this code changes, the corresponding ret_addr_offset() and
11524 // compute_padding() functions will have to be adjusted.
11525 instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{
11526 match(CallStaticJava);
11527 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke());
11528 effect(USE meth);
11529 // RBP is saved by all callees (for interpreter stack correction).
11530 // We use it here for a similar purpose, in {preserve,restore}_SP.
11532 ins_cost(300);
11533 format %{ "call,static/MethodHandle " %}
11534 opcode(0xE8); /* E8 cd */
11535 ins_encode(clear_avx, preserve_SP,
11536 Java_Static_Call(meth),
11537 restore_SP,
11538 call_epilog);
11539 ins_pipe(pipe_slow);
11540 ins_alignment(4);
11541 %}
11543 // Call Java Dynamic Instruction
11544 // Note: If this code changes, the corresponding ret_addr_offset() and
11545 // compute_padding() functions will have to be adjusted.
11546 instruct CallDynamicJavaDirect(method meth)
11547 %{
11548 match(CallDynamicJava);
11549 effect(USE meth);
11551 ins_cost(300);
11552 format %{ "movq rax, #Universe::non_oop_word()\n\t"
11553 "call,dynamic " %}
11554 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog);
11555 ins_pipe(pipe_slow);
11556 ins_alignment(4);
11557 %}
11559 // Call Runtime Instruction
11560 instruct CallRuntimeDirect(method meth)
11561 %{
11562 match(CallRuntime);
11563 effect(USE meth);
11565 ins_cost(300);
11566 format %{ "call,runtime " %}
11567 ins_encode(clear_avx, Java_To_Runtime(meth));
11568 ins_pipe(pipe_slow);
11569 %}
11571 // Call runtime without safepoint
11572 instruct CallLeafDirect(method meth)
11573 %{
11574 match(CallLeaf);
11575 effect(USE meth);
11577 ins_cost(300);
11578 format %{ "call_leaf,runtime " %}
11579 ins_encode(clear_avx, Java_To_Runtime(meth));
11580 ins_pipe(pipe_slow);
11581 %}
11583 // Call runtime without safepoint
11584 instruct CallLeafNoFPDirect(method meth)
11585 %{
11586 match(CallLeafNoFP);
11587 effect(USE meth);
11589 ins_cost(300);
11590 format %{ "call_leaf_nofp,runtime " %}
11591 ins_encode(Java_To_Runtime(meth));
11592 ins_pipe(pipe_slow);
11593 %}
11595 // Return Instruction
11596 // Remove the return address & jump to it.
11597 // Notice: We always emit a nop after a ret to make sure there is room
11598 // for safepoint patching
11599 instruct Ret()
11600 %{
11601 match(Return);
11603 format %{ "ret" %}
11604 opcode(0xC3);
11605 ins_encode(OpcP);
11606 ins_pipe(pipe_jmp);
11607 %}
11609 // Tail Call; Jump from runtime stub to Java code.
11610 // Also known as an 'interprocedural jump'.
11611 // Target of jump will eventually return to caller.
11612 // TailJump below removes the return address.
11613 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop)
11614 %{
11615 match(TailCall jump_target method_oop);
11617 ins_cost(300);
11618 format %{ "jmp $jump_target\t# rbx holds method oop" %}
11619 opcode(0xFF, 0x4); /* Opcode FF /4 */
11620 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target));
11621 ins_pipe(pipe_jmp);
11622 %}
11624 // Tail Jump; remove the return address; jump to target.
11625 // TailCall above leaves the return address around.
11626 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop)
11627 %{
11628 match(TailJump jump_target ex_oop);
11630 ins_cost(300);
11631 format %{ "popq rdx\t# pop return address\n\t"
11632 "jmp $jump_target" %}
11633 opcode(0xFF, 0x4); /* Opcode FF /4 */
11634 ins_encode(Opcode(0x5a), // popq rdx
11635 REX_reg(jump_target), OpcP, reg_opc(jump_target));
11636 ins_pipe(pipe_jmp);
11637 %}
11639 // Create exception oop: created by stack-crawling runtime code.
11640 // Created exception is now available to this handler, and is setup
11641 // just prior to jumping to this handler. No code emitted.
11642 instruct CreateException(rax_RegP ex_oop)
11643 %{
11644 match(Set ex_oop (CreateEx));
11646 size(0);
11647 // use the following format syntax
11648 format %{ "# exception oop is in rax; no code emitted" %}
11649 ins_encode();
11650 ins_pipe(empty);
11651 %}
11653 // Rethrow exception:
11654 // The exception oop will come in the first argument position.
11655 // Then JUMP (not call) to the rethrow stub code.
11656 instruct RethrowException()
11657 %{
11658 match(Rethrow);
11660 // use the following format syntax
11661 format %{ "jmp rethrow_stub" %}
11662 ins_encode(enc_rethrow);
11663 ins_pipe(pipe_jmp);
11664 %}
11667 // ============================================================================
11668 // This name is KNOWN by the ADLC and cannot be changed.
11669 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type
11670 // for this guy.
11671 instruct tlsLoadP(r15_RegP dst) %{
11672 match(Set dst (ThreadLocal));
11673 effect(DEF dst);
11675 size(0);
11676 format %{ "# TLS is in R15" %}
11677 ins_encode( /*empty encoding*/ );
11678 ins_pipe(ialu_reg_reg);
11679 %}
11682 //----------PEEPHOLE RULES-----------------------------------------------------
11683 // These must follow all instruction definitions as they use the names
11684 // defined in the instructions definitions.
11685 //
11686 // peepmatch ( root_instr_name [preceding_instruction]* );
11687 //
11688 // peepconstraint %{
11689 // (instruction_number.operand_name relational_op instruction_number.operand_name
11690 // [, ...] );
11691 // // instruction numbers are zero-based using left to right order in peepmatch
11692 //
11693 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) );
11694 // // provide an instruction_number.operand_name for each operand that appears
11695 // // in the replacement instruction's match rule
11696 //
11697 // ---------VM FLAGS---------------------------------------------------------
11698 //
11699 // All peephole optimizations can be turned off using -XX:-OptoPeephole
11700 //
11701 // Each peephole rule is given an identifying number starting with zero and
11702 // increasing by one in the order seen by the parser. An individual peephole
11703 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
11704 // on the command-line.
11705 //
11706 // ---------CURRENT LIMITATIONS----------------------------------------------
11707 //
11708 // Only match adjacent instructions in same basic block
11709 // Only equality constraints
11710 // Only constraints between operands, not (0.dest_reg == RAX_enc)
11711 // Only one replacement instruction
11712 //
11713 // ---------EXAMPLE----------------------------------------------------------
11714 //
11715 // // pertinent parts of existing instructions in architecture description
11716 // instruct movI(rRegI dst, rRegI src)
11717 // %{
11718 // match(Set dst (CopyI src));
11719 // %}
11720 //
11721 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr)
11722 // %{
11723 // match(Set dst (AddI dst src));
11724 // effect(KILL cr);
11725 // %}
11726 //
11727 // // Change (inc mov) to lea
11728 // peephole %{
11729 // // increment preceeded by register-register move
11730 // peepmatch ( incI_rReg movI );
11731 // // require that the destination register of the increment
11732 // // match the destination register of the move
11733 // peepconstraint ( 0.dst == 1.dst );
11734 // // construct a replacement instruction that sets
11735 // // the destination to ( move's source register + one )
11736 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) );
11737 // %}
11738 //
11740 // Implementation no longer uses movX instructions since
11741 // machine-independent system no longer uses CopyX nodes.
11742 //
11743 // peephole
11744 // %{
11745 // peepmatch (incI_rReg movI);
11746 // peepconstraint (0.dst == 1.dst);
11747 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11748 // %}
11750 // peephole
11751 // %{
11752 // peepmatch (decI_rReg movI);
11753 // peepconstraint (0.dst == 1.dst);
11754 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11755 // %}
11757 // peephole
11758 // %{
11759 // peepmatch (addI_rReg_imm movI);
11760 // peepconstraint (0.dst == 1.dst);
11761 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src));
11762 // %}
11764 // peephole
11765 // %{
11766 // peepmatch (incL_rReg movL);
11767 // peepconstraint (0.dst == 1.dst);
11768 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11769 // %}
11771 // peephole
11772 // %{
11773 // peepmatch (decL_rReg movL);
11774 // peepconstraint (0.dst == 1.dst);
11775 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11776 // %}
11778 // peephole
11779 // %{
11780 // peepmatch (addL_rReg_imm movL);
11781 // peepconstraint (0.dst == 1.dst);
11782 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src));
11783 // %}
11785 // peephole
11786 // %{
11787 // peepmatch (addP_rReg_imm movP);
11788 // peepconstraint (0.dst == 1.dst);
11789 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src));
11790 // %}
11792 // // Change load of spilled value to only a spill
11793 // instruct storeI(memory mem, rRegI src)
11794 // %{
11795 // match(Set mem (StoreI mem src));
11796 // %}
11797 //
11798 // instruct loadI(rRegI dst, memory mem)
11799 // %{
11800 // match(Set dst (LoadI mem));
11801 // %}
11802 //
11804 peephole
11805 %{
11806 peepmatch (loadI storeI);
11807 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
11808 peepreplace (storeI(1.mem 1.mem 1.src));
11809 %}
11811 peephole
11812 %{
11813 peepmatch (loadL storeL);
11814 peepconstraint (1.src == 0.dst, 1.mem == 0.mem);
11815 peepreplace (storeL(1.mem 1.mem 1.src));
11816 %}
11818 //----------SMARTSPILL RULES---------------------------------------------------
11819 // These must follow all instruction definitions as they use the names
11820 // defined in the instructions definitions.