57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
59 //
60 // The encoding number is the actual bit-pattern placed into the opcodes.
61
62 // General Registers
63 // Previously set EBX, ESI, and EDI as save-on-entry for java code
64 // Turn off SOE in java-code due to frequent use of uncommon-traps.
65 // Now that allocator is better, turn on ESI and EDI as SOE registers.
66
67 reg_def EBX(SOC, SOE, Op_RegI, 3, rbx->as_VMReg());
68 reg_def ECX(SOC, SOC, Op_RegI, 1, rcx->as_VMReg());
69 reg_def ESI(SOC, SOE, Op_RegI, 6, rsi->as_VMReg());
70 reg_def EDI(SOC, SOE, Op_RegI, 7, rdi->as_VMReg());
71 // now that adapter frames are gone EBP is always saved and restored by the prolog/epilog code
72 reg_def EBP(NS, SOE, Op_RegI, 5, rbp->as_VMReg());
73 reg_def EDX(SOC, SOC, Op_RegI, 2, rdx->as_VMReg());
74 reg_def EAX(SOC, SOC, Op_RegI, 0, rax->as_VMReg());
75 reg_def ESP( NS, NS, Op_RegI, 4, rsp->as_VMReg());
76
77 // Special Registers
78 reg_def EFLAGS(SOC, SOC, 0, 8, VMRegImpl::Bad());
79
80 // Float registers. We treat TOS/FPR0 special. It is invisible to the
81 // allocator, and only shows up in the encodings.
82 reg_def FPR0L( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad());
83 reg_def FPR0H( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad());
84 // Ok so here's the trick FPR1 is really st(0) except in the midst
85 // of emission of assembly for a machnode. During the emission the fpu stack
86 // is pushed making FPR1 == st(1) temporarily. However at any safepoint
87 // the stack will not have this element so FPR1 == st(0) from the
88 // oopMap viewpoint. This same weirdness with numbering causes
89 // instruction encoding to have to play games with the register
90 // encode to correct for this 0/1 issue. See MachSpillCopyNode::implementation
91 // where it does flt->flt moves to see an example
92 //
93 reg_def FPR1L( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg());
94 reg_def FPR1H( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg()->next());
95 reg_def FPR2L( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg());
96 reg_def FPR2H( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg()->next());
97 reg_def FPR3L( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg());
98 reg_def FPR3H( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg()->next());
99 reg_def FPR4L( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg());
100 reg_def FPR4H( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg()->next());
101 reg_def FPR5L( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg());
102 reg_def FPR5H( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg()->next());
103 reg_def FPR6L( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg());
104 reg_def FPR6H( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg()->next());
105 reg_def FPR7L( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg());
106 reg_def FPR7H( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next());
107
108 // XMM registers. 128-bit registers or 4 words each, labeled a-d.
109 // Word a in each register holds a Float, words ab hold a Double.
110 // We currently do not use the SIMD capabilities, so registers cd
111 // are unused at the moment.
112 reg_def XMM0a( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg());
113 reg_def XMM0b( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next());
114 reg_def XMM1a( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg());
115 reg_def XMM1b( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next());
116 reg_def XMM2a( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg());
117 reg_def XMM2b( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next());
118 reg_def XMM3a( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg());
119 reg_def XMM3b( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next());
120 reg_def XMM4a( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg());
121 reg_def XMM4b( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next());
122 reg_def XMM5a( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg());
123 reg_def XMM5b( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next());
124 reg_def XMM6a( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg());
125 reg_def XMM6b( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next());
126 reg_def XMM7a( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg());
127 reg_def XMM7b( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next());
128
129 // Specify priority of register selection within phases of register
130 // allocation. Highest priority is first. A useful heuristic is to
131 // give registers a low priority when they are required by machine
132 // instructions, like EAX and EDX. Registers which are used as
133 // pairs must fall on an even boundary (witness the FPR#L's in this list).
134 // For the Intel integer registers, the equivalent Long pairs are
135 // EDX:EAX, EBX:ECX, and EDI:EBP.
136 alloc_class chunk0( ECX, EBX, EBP, EDI, EAX, EDX, ESI, ESP,
137 FPR0L, FPR0H, FPR1L, FPR1H, FPR2L, FPR2H,
138 FPR3L, FPR3H, FPR4L, FPR4H, FPR5L, FPR5H,
139 FPR6L, FPR6H, FPR7L, FPR7H );
140
141 alloc_class chunk1( XMM0a, XMM0b,
142 XMM1a, XMM1b,
143 XMM2a, XMM2b,
144 XMM3a, XMM3b,
145 XMM4a, XMM4b,
146 XMM5a, XMM5b,
147 XMM6a, XMM6b,
148 XMM7a, XMM7b, EFLAGS);
149
150
151 //----------Architecture Description Register Classes--------------------------
152 // Several register classes are automatically defined based upon information in
153 // this architecture description.
154 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ )
155 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ )
156 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
157 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
158 //
159 // Class for all registers
160 reg_class any_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX, ESP);
161 // Class for general registers
162 reg_class e_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX);
163 // Class for general registers which may be used for implicit null checks on win95
164 // Also safe for use by tailjump. We don't want to allocate in rbp,
165 reg_class e_reg_no_rbp(EAX, EDX, EDI, ESI, ECX, EBX);
166 // Class of "X" registers
167 reg_class x_reg(EBX, ECX, EDX, EAX);
168 // Class of registers that can appear in an address with no offset.
169 // EBP and ESP require an extra instruction byte for zero offset.
170 // Used in fast-unlock
171 reg_class p_reg(EDX, EDI, ESI, EBX);
172 // Class for general registers not including ECX
173 reg_class ncx_reg(EAX, EDX, EBP, EDI, ESI, EBX);
174 // Class for general registers not including EAX
175 reg_class nax_reg(EDX, EDI, ESI, ECX, EBX);
176 // Class for general registers not including EAX or EBX.
177 reg_class nabx_reg(EDX, EDI, ESI, ECX, EBP);
178 // Class of EAX (for multiply and divide operations)
179 reg_class eax_reg(EAX);
180 // Class of EBX (for atomic add)
181 reg_class ebx_reg(EBX);
182 // Class of ECX (for shift and JCXZ operations and cmpLTMask)
183 reg_class ecx_reg(ECX);
184 // Class of EDX (for multiply and divide operations)
185 reg_class edx_reg(EDX);
186 // Class of EDI (for synchronization)
187 reg_class edi_reg(EDI);
188 // Class of ESI (for synchronization)
189 reg_class esi_reg(ESI);
190 // Singleton class for interpreter's stack pointer
191 reg_class ebp_reg(EBP);
192 // Singleton class for stack pointer
193 reg_class sp_reg(ESP);
194 // Singleton class for instruction pointer
195 // reg_class ip_reg(EIP);
196 // Singleton class for condition codes
197 reg_class int_flags(EFLAGS);
198 // Class of integer register pairs
199 reg_class long_reg( EAX,EDX, ECX,EBX, EBP,EDI );
200 // Class of integer register pairs that aligns with calling convention
201 reg_class eadx_reg( EAX,EDX );
202 reg_class ebcx_reg( ECX,EBX );
203 // Not AX or DX, used in divides
204 reg_class nadx_reg( EBX,ECX,ESI,EDI,EBP );
205
206 // Floating point registers. Notice FPR0 is not a choice.
207 // FPR0 is not ever allocated; we use clever encodings to fake
208 // a 2-address instructions out of Intels FP stack.
209 reg_class flt_reg( FPR1L,FPR2L,FPR3L,FPR4L,FPR5L,FPR6L,FPR7L );
210
211 // make a register class for SSE registers
212 reg_class xmm_reg(XMM0a, XMM1a, XMM2a, XMM3a, XMM4a, XMM5a, XMM6a, XMM7a);
213
214 // make a double register class for SSE2 registers
215 reg_class xdb_reg(XMM0a,XMM0b, XMM1a,XMM1b, XMM2a,XMM2b, XMM3a,XMM3b,
216 XMM4a,XMM4b, XMM5a,XMM5b, XMM6a,XMM6b, XMM7a,XMM7b );
217
218 reg_class dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H,
219 FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H,
220 FPR7L,FPR7H );
221
222 reg_class flt_reg0( FPR1L );
223 reg_class dbl_reg0( FPR1L,FPR1H );
224 reg_class dbl_reg1( FPR2L,FPR2H );
225 reg_class dbl_notreg0( FPR2L,FPR2H, FPR3L,FPR3H, FPR4L,FPR4H,
226 FPR5L,FPR5H, FPR6L,FPR6H, FPR7L,FPR7H );
227
228 // XMM6 and XMM7 could be used as temporary registers for long, float and
229 // double values for SSE2.
230 reg_class xdb_reg6( XMM6a,XMM6b );
231 reg_class xdb_reg7( XMM7a,XMM7b );
232 %}
233
234
235 //----------SOURCE BLOCK-------------------------------------------------------
236 // This is a block of C++ code which provides values, functions, and
237 // definitions necessary in the rest of the architecture description
238 source_hpp %{
239 // Must be visible to the DFA in dfa_x86_32.cpp
240 extern bool is_operand_hi32_zero(Node* n);
241 %}
242
243 source %{
244 #define RELOC_IMM32 Assembler::imm_operand
245 #define RELOC_DISP32 Assembler::disp32_operand
246
247 #define __ _masm.
248
249 // How to find the high register of a Long pair, given the low register
250 #define HIGH_FROM_LOW(x) ((x)+2)
251
395 }
396 #endif
397 cbuf.relocate(cbuf.insts_mark(), rspec, format);
398 cbuf.insts()->emit_int32(d32);
399 }
400
401 // Access stack slot for load or store
402 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) {
403 emit_opcode( cbuf, opcode ); // (e.g., FILD [ESP+src])
404 if( -128 <= disp && disp <= 127 ) {
405 emit_rm( cbuf, 0x01, rm_field, ESP_enc ); // R/M byte
406 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte
407 emit_d8 (cbuf, disp); // Displacement // R/M byte
408 } else {
409 emit_rm( cbuf, 0x02, rm_field, ESP_enc ); // R/M byte
410 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte
411 emit_d32(cbuf, disp); // Displacement // R/M byte
412 }
413 }
414
415 // eRegI ereg, memory mem) %{ // emit_reg_mem
416 void encode_RegMem( CodeBuffer &cbuf, int reg_encoding, int base, int index, int scale, int displace, bool displace_is_oop ) {
417 // There is no index & no scale, use form without SIB byte
418 if ((index == 0x4) &&
419 (scale == 0) && (base != ESP_enc)) {
420 // If no displacement, mode is 0x0; unless base is [EBP]
421 if ( (displace == 0) && (base != EBP_enc) ) {
422 emit_rm(cbuf, 0x0, reg_encoding, base);
423 }
424 else { // If 8-bit displacement, mode 0x1
425 if ((displace >= -128) && (displace <= 127)
426 && !(displace_is_oop) ) {
427 emit_rm(cbuf, 0x1, reg_encoding, base);
428 emit_d8(cbuf, displace);
429 }
430 else { // If 32-bit displacement
431 if (base == -1) { // Special flag for absolute address
432 emit_rm(cbuf, 0x0, reg_encoding, 0x5);
433 // (manual lies; no SIB needed here)
434 if ( displace_is_oop ) {
435 emit_d32_reloc(cbuf, displace, relocInfo::oop_type, 1);
770 }
771 }
772 #ifndef PRODUCT
773 } else if (!do_size) {
774 if (size != 0) st->print("\n\t");
775 if (reg_lo+1 == reg_hi) { // double move?
776 if (is_load) st->print("%s %s,[ESP + #%d]",
777 UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
778 Matcher::regName[reg_lo], offset);
779 else st->print("MOVSD [ESP + #%d],%s",
780 offset, Matcher::regName[reg_lo]);
781 } else {
782 if (is_load) st->print("MOVSS %s,[ESP + #%d]",
783 Matcher::regName[reg_lo], offset);
784 else st->print("MOVSS [ESP + #%d],%s",
785 offset, Matcher::regName[reg_lo]);
786 }
787 #endif
788 }
789 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
790 // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes.
791 return size+5+offset_size;
792 }
793
794
795 static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
796 int src_hi, int dst_hi, int size, outputStream* st ) {
797 if (cbuf) {
798 MacroAssembler _masm(cbuf);
799 if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move?
800 __ movdbl(as_XMMRegister(Matcher::_regEncode[dst_lo]),
801 as_XMMRegister(Matcher::_regEncode[src_lo]));
802 } else {
803 __ movflt(as_XMMRegister(Matcher::_regEncode[dst_lo]),
804 as_XMMRegister(Matcher::_regEncode[src_lo]));
805 }
806 #ifndef PRODUCT
807 } else if (!do_size) {
808 if (size != 0) st->print("\n\t");
809 if (UseXmmRegToRegMoveAll) {//Use movaps,movapd to move between xmm registers
810 if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move?
811 st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
812 } else {
813 st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
814 }
815 } else {
816 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
817 st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
818 } else {
819 st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
820 }
821 }
822 #endif
823 }
824 // VEX_2bytes prefix is used if UseAVX > 0, and it takes the same 2 bytes.
825 // Only MOVAPS SSE prefix uses 1 byte.
826 int sz = 4;
827 if (!(src_lo+1 == src_hi && dst_lo+1 == dst_hi) &&
828 UseXmmRegToRegMoveAll && (UseAVX == 0)) sz = 3;
829 return size + sz;
830 }
831
832 static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
833 int src_hi, int dst_hi, int size, outputStream* st ) {
834 // 32-bit
835 if (cbuf) {
836 MacroAssembler _masm(cbuf);
837 __ movdl(as_XMMRegister(Matcher::_regEncode[dst_lo]),
838 as_Register(Matcher::_regEncode[src_lo]));
839 #ifndef PRODUCT
840 } else if (!do_size) {
841 st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
842 #endif
843 }
844 return 4;
886 #endif
887 }
888 size += 2;
889 }
890
891 int st_op = (src_lo != FPR1L_num) ? EBX_num /*store & pop*/ : EDX_num /*store no pop*/;
892 const char *op_str;
893 int op;
894 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double store?
895 op_str = (src_lo != FPR1L_num) ? "FSTP_D" : "FST_D ";
896 op = 0xDD;
897 } else { // 32-bit store
898 op_str = (src_lo != FPR1L_num) ? "FSTP_S" : "FST_S ";
899 op = 0xD9;
900 assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
901 }
902
903 return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
904 }
905
906 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
907 // Get registers to move
908 OptoReg::Name src_second = ra_->get_reg_second(in(1));
909 OptoReg::Name src_first = ra_->get_reg_first(in(1));
910 OptoReg::Name dst_second = ra_->get_reg_second(this );
911 OptoReg::Name dst_first = ra_->get_reg_first(this );
912
913 enum RC src_second_rc = rc_class(src_second);
914 enum RC src_first_rc = rc_class(src_first);
915 enum RC dst_second_rc = rc_class(dst_second);
916 enum RC dst_first_rc = rc_class(dst_first);
917
918 assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
919
920 // Generate spill code!
921 int size = 0;
922
923 if( src_first == dst_first && src_second == dst_second )
924 return size; // Self copy, no move
925
926 // --------------------------------------
927 // Check for mem-mem move. push/pop to move.
928 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
929 if( src_second == dst_first ) { // overlapping stack copy ranges
930 assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
931 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
932 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
933 src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits
934 }
935 // move low bits
936 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size, st);
937 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size, st);
938 if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
939 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
940 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
941 }
942 return size;
943 }
944
945 // --------------------------------------
1296 switch (opcode) {
1297 case Op_PopCountI:
1298 case Op_PopCountL:
1299 if (!UsePopCountInstruction)
1300 return false;
1301 break;
1302 }
1303
1304 return true; // Per default match rules are supported.
1305 }
1306
1307 int Matcher::regnum_to_fpu_offset(int regnum) {
1308 return regnum - 32; // The FP registers are in the second chunk
1309 }
1310
1311 // This is UltraSparc specific, true just means we have fast l2f conversion
1312 const bool Matcher::convL2FSupported(void) {
1313 return true;
1314 }
1315
1316 // Vector width in bytes
1317 const uint Matcher::vector_width_in_bytes(void) {
1318 return UseSSE >= 2 ? 8 : 0;
1319 }
1320
1321 // Vector ideal reg
1322 const uint Matcher::vector_ideal_reg(void) {
1323 return Op_RegD;
1324 }
1325
1326 // Is this branch offset short enough that a short branch can be used?
1327 //
1328 // NOTE: If the platform does not provide any short branch variants, then
1329 // this method should return false for offset 0.
1330 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1331 // The passed offset is relative to address of the branch.
1332 // On 86 a branch displacement is calculated relative to address
1333 // of a next instruction.
1334 offset -= br_size;
1335
1336 // the short version of jmpConUCF2 contains multiple branches,
1337 // making the reach slightly less
1338 if (rule == jmpConUCF2_rule)
1339 return (-126 <= offset && offset <= 125);
1340 return (-128 <= offset && offset <= 127);
1341 }
1342
1343 const bool Matcher::isSimpleConstant64(jlong value) {
1344 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1345 return false;
1435 node->_opnds[opcnt] = new_memory;
1436 }
1437
1438 // Advertise here if the CPU requires explicit rounding operations
1439 // to implement the UseStrictFP mode.
1440 const bool Matcher::strict_fp_requires_explicit_rounding = true;
1441
1442 // Are floats conerted to double when stored to stack during deoptimization?
1443 // On x32 it is stored with convertion only when FPU is used for floats.
1444 bool Matcher::float_in_double() { return (UseSSE == 0); }
1445
1446 // Do ints take an entire long register or just half?
1447 const bool Matcher::int_in_long = false;
1448
1449 // Return whether or not this register is ever used as an argument. This
1450 // function is used on startup to build the trampoline stubs in generateOptoStub.
1451 // Registers not mentioned will be killed by the VM call in the trampoline, and
1452 // arguments in those registers not be available to the callee.
1453 bool Matcher::can_be_java_arg( int reg ) {
1454 if( reg == ECX_num || reg == EDX_num ) return true;
1455 if( (reg == XMM0a_num || reg == XMM1a_num) && UseSSE>=1 ) return true;
1456 if( (reg == XMM0b_num || reg == XMM1b_num) && UseSSE>=2 ) return true;
1457 return false;
1458 }
1459
1460 bool Matcher::is_spillable_arg( int reg ) {
1461 return can_be_java_arg(reg);
1462 }
1463
1464 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1465 // Use hardware integer DIV instruction when
1466 // it is faster than a code which use multiply.
1467 // Only when constant divisor fits into 32 bit
1468 // (min_jint is excluded to get only correct
1469 // positive 32 bit values from negative).
1470 return VM_Version::has_fast_idiv() &&
1471 (divisor == (int)divisor && divisor != min_jint);
1472 }
1473
1474 // Register for DIVI projection of divmodI
1475 RegMask Matcher::divI_proj_mask() {
1548
1549 // Emit primary opcode
1550 enc_class OpcP %{
1551 emit_opcode(cbuf, $primary);
1552 %}
1553
1554 // Emit secondary opcode
1555 enc_class OpcS %{
1556 emit_opcode(cbuf, $secondary);
1557 %}
1558
1559 // Emit opcode directly
1560 enc_class Opcode(immI d8) %{
1561 emit_opcode(cbuf, $d8$$constant);
1562 %}
1563
1564 enc_class SizePrefix %{
1565 emit_opcode(cbuf,0x66);
1566 %}
1567
1568 enc_class RegReg (eRegI dst, eRegI src) %{ // RegReg(Many)
1569 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
1570 %}
1571
1572 enc_class OpcRegReg (immI opcode, eRegI dst, eRegI src) %{ // OpcRegReg(Many)
1573 emit_opcode(cbuf,$opcode$$constant);
1574 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
1575 %}
1576
1577 enc_class mov_r32_imm0( eRegI dst ) %{
1578 emit_opcode( cbuf, 0xB8 + $dst$$reg ); // 0xB8+ rd -- MOV r32 ,imm32
1579 emit_d32 ( cbuf, 0x0 ); // imm32==0x0
1580 %}
1581
1582 enc_class cdq_enc %{
1583 // Full implementation of Java idiv and irem; checks for
1584 // special case as described in JVM spec., p.243 & p.271.
1585 //
1586 // normal case special case
1587 //
1588 // input : rax,: dividend min_int
1589 // reg: divisor -1
1590 //
1591 // output: rax,: quotient (= rax, idiv reg) min_int
1592 // rdx: remainder (= rax, irem reg) 0
1593 //
1594 // Code sequnce:
1595 //
1596 // 81 F8 00 00 00 80 cmp rax,80000000h
1597 // 0F 85 0B 00 00 00 jne normal_case
1604 // done:
1605 //
1606 emit_opcode(cbuf,0x81); emit_d8(cbuf,0xF8);
1607 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00);
1608 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x80); // cmp rax,80000000h
1609 emit_opcode(cbuf,0x0F); emit_d8(cbuf,0x85);
1610 emit_opcode(cbuf,0x0B); emit_d8(cbuf,0x00);
1611 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); // jne normal_case
1612 emit_opcode(cbuf,0x33); emit_d8(cbuf,0xD2); // xor rdx,edx
1613 emit_opcode(cbuf,0x83); emit_d8(cbuf,0xF9); emit_d8(cbuf,0xFF); // cmp rcx,0FFh
1614 emit_opcode(cbuf,0x0F); emit_d8(cbuf,0x84);
1615 emit_opcode(cbuf,0x03); emit_d8(cbuf,0x00);
1616 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); // je done
1617 // normal_case:
1618 emit_opcode(cbuf,0x99); // cdq
1619 // idiv (note: must be emitted by the user of this rule)
1620 // normal:
1621 %}
1622
1623 // Dense encoding for older common ops
1624 enc_class Opc_plus(immI opcode, eRegI reg) %{
1625 emit_opcode(cbuf, $opcode$$constant + $reg$$reg);
1626 %}
1627
1628
1629 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
1630 enc_class OpcSE (immI imm) %{ // Emit primary opcode and set sign-extend bit
1631 // Check for 8-bit immediate, and set sign extend bit in opcode
1632 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) {
1633 emit_opcode(cbuf, $primary | 0x02);
1634 }
1635 else { // If 32-bit immediate
1636 emit_opcode(cbuf, $primary);
1637 }
1638 %}
1639
1640 enc_class OpcSErm (eRegI dst, immI imm) %{ // OpcSEr/m
1641 // Emit primary opcode and set sign-extend bit
1642 // Check for 8-bit immediate, and set sign extend bit in opcode
1643 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) {
1644 emit_opcode(cbuf, $primary | 0x02); }
1645 else { // If 32-bit immediate
1646 emit_opcode(cbuf, $primary);
1647 }
1648 // Emit r/m byte with secondary opcode, after primary opcode.
1649 emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
1650 %}
1651
1652 enc_class Con8or32 (immI imm) %{ // Con8or32(storeImmI), 8 or 32 bits
1653 // Check for 8-bit immediate, and set sign extend bit in opcode
1654 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) {
1655 $$$emit8$imm$$constant;
1656 }
1657 else { // If 32-bit immediate
1658 // Output immediate
1659 $$$emit32$imm$$constant;
1660 }
1665 // Check for 8-bit immediate, and set sign extend bit in opcode
1666 int con = (int)$imm$$constant; // Throw away top bits
1667 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary);
1668 // Emit r/m byte with secondary opcode, after primary opcode.
1669 emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
1670 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con);
1671 else emit_d32(cbuf,con);
1672 %}
1673
1674 enc_class Long_OpcSErm_Hi(eRegL dst, immL imm) %{
1675 // Emit primary opcode and set sign-extend bit
1676 // Check for 8-bit immediate, and set sign extend bit in opcode
1677 int con = (int)($imm$$constant >> 32); // Throw away bottom bits
1678 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary);
1679 // Emit r/m byte with tertiary opcode, after primary opcode.
1680 emit_rm(cbuf, 0x3, $tertiary, HIGH_FROM_LOW($dst$$reg));
1681 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con);
1682 else emit_d32(cbuf,con);
1683 %}
1684
1685 enc_class OpcSReg (eRegI dst) %{ // BSWAP
1686 emit_cc(cbuf, $secondary, $dst$$reg );
1687 %}
1688
1689 enc_class bswap_long_bytes(eRegL dst) %{ // BSWAP
1690 int destlo = $dst$$reg;
1691 int desthi = HIGH_FROM_LOW(destlo);
1692 // bswap lo
1693 emit_opcode(cbuf, 0x0F);
1694 emit_cc(cbuf, 0xC8, destlo);
1695 // bswap hi
1696 emit_opcode(cbuf, 0x0F);
1697 emit_cc(cbuf, 0xC8, desthi);
1698 // xchg lo and hi
1699 emit_opcode(cbuf, 0x87);
1700 emit_rm(cbuf, 0x3, destlo, desthi);
1701 %}
1702
1703 enc_class RegOpc (eRegI div) %{ // IDIV, IMOD, JMP indirect, ...
1704 emit_rm(cbuf, 0x3, $secondary, $div$$reg );
1705 %}
1706
1707 enc_class enc_cmov(cmpOp cop ) %{ // CMOV
1708 $$$emit8$primary;
1709 emit_cc(cbuf, $secondary, $cop$$cmpcode);
1710 %}
1711
1712 enc_class enc_cmov_dpr(cmpOp cop, regDPR src ) %{ // CMOV
1713 int op = 0xDA00 + $cop$$cmpcode + ($src$$reg-1);
1714 emit_d8(cbuf, op >> 8 );
1715 emit_d8(cbuf, op & 255);
1716 %}
1717
1718 // emulate a CMOV with a conditional branch around a MOV
1719 enc_class enc_cmov_branch( cmpOp cop, immI brOffs ) %{ // CMOV
1720 // Invert sense of branch from sense of CMOV
1721 emit_cc( cbuf, 0x70, ($cop$$cmpcode^1) );
1722 emit_d8( cbuf, $brOffs$$constant );
1723 %}
1874 // // int ic_encode = Matcher::_regEncode[ic_reg];
1875 // // int imo_reg = Matcher::interpreter_method_oop_reg();
1876 // // int imo_encode = Matcher::_regEncode[imo_reg];
1877 //
1878 // // // Interpreter expects method_oop in EBX, currently a callee-saved register,
1879 // // // so we load it immediately before the call
1880 // // emit_opcode(cbuf, 0x8B); // MOV imo_reg,ic_reg # method_oop
1881 // // emit_rm(cbuf, 0x03, imo_encode, ic_encode ); // R/M byte
1882 //
1883 // // xor rbp,ebp
1884 // emit_opcode(cbuf, 0x33);
1885 // emit_rm(cbuf, 0x3, EBP_enc, EBP_enc);
1886 //
1887 // // CALL to interpreter.
1888 // cbuf.set_insts_mark();
1889 // $$$emit8$primary;
1890 // emit_d32_reloc(cbuf, ($labl$$label - (int)(cbuf.insts_end()) - 4),
1891 // runtime_call_Relocation::spec(), RELOC_IMM32 );
1892 // %}
1893
1894 enc_class RegOpcImm (eRegI dst, immI8 shift) %{ // SHL, SAR, SHR
1895 $$$emit8$primary;
1896 emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
1897 $$$emit8$shift$$constant;
1898 %}
1899
1900 enc_class LdImmI (eRegI dst, immI src) %{ // Load Immediate
1901 // Load immediate does not have a zero or sign extended version
1902 // for 8-bit immediates
1903 emit_opcode(cbuf, 0xB8 + $dst$$reg);
1904 $$$emit32$src$$constant;
1905 %}
1906
1907 enc_class LdImmP (eRegI dst, immI src) %{ // Load Immediate
1908 // Load immediate does not have a zero or sign extended version
1909 // for 8-bit immediates
1910 emit_opcode(cbuf, $primary + $dst$$reg);
1911 $$$emit32$src$$constant;
1912 %}
1913
1914 enc_class LdImmL_Lo( eRegL dst, immL src) %{ // Load Immediate
1915 // Load immediate does not have a zero or sign extended version
1916 // for 8-bit immediates
1917 int dst_enc = $dst$$reg;
1918 int src_con = $src$$constant & 0x0FFFFFFFFL;
1919 if (src_con == 0) {
1920 // xor dst, dst
1921 emit_opcode(cbuf, 0x33);
1922 emit_rm(cbuf, 0x3, dst_enc, dst_enc);
1923 } else {
1924 emit_opcode(cbuf, $primary + dst_enc);
1925 emit_d32(cbuf, src_con);
1926 }
1927 %}
1928
1929 enc_class LdImmL_Hi( eRegL dst, immL src) %{ // Load Immediate
1930 // Load immediate does not have a zero or sign extended version
1931 // for 8-bit immediates
1932 int dst_enc = $dst$$reg + 2;
1933 int src_con = ((julong)($src$$constant)) >> 32;
1934 if (src_con == 0) {
1935 // xor dst, dst
1936 emit_opcode(cbuf, 0x33);
1937 emit_rm(cbuf, 0x3, dst_enc, dst_enc);
1938 } else {
1939 emit_opcode(cbuf, $primary + dst_enc);
1940 emit_d32(cbuf, src_con);
1941 }
1942 %}
1943
1944
1945 // Encode a reg-reg copy. If it is useless, then empty encoding.
1946 enc_class enc_Copy( eRegI dst, eRegI src ) %{
1947 encode_Copy( cbuf, $dst$$reg, $src$$reg );
1948 %}
1949
1950 enc_class enc_CopyL_Lo( eRegI dst, eRegL src ) %{
1951 encode_Copy( cbuf, $dst$$reg, $src$$reg );
1952 %}
1953
1954 enc_class RegReg (eRegI dst, eRegI src) %{ // RegReg(Many)
1955 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
1956 %}
1957
1958 enc_class RegReg_Lo(eRegL dst, eRegL src) %{ // RegReg(Many)
1959 $$$emit8$primary;
1960 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
1961 %}
1962
1963 enc_class RegReg_Hi(eRegL dst, eRegL src) %{ // RegReg(Many)
1964 $$$emit8$secondary;
1965 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg));
1966 %}
1967
1968 enc_class RegReg_Lo2(eRegL dst, eRegL src) %{ // RegReg(Many)
1969 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
1970 %}
1971
1972 enc_class RegReg_Hi2(eRegL dst, eRegL src) %{ // RegReg(Many)
1973 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg));
1974 %}
1975
1976 enc_class RegReg_HiLo( eRegL src, eRegI dst ) %{
1977 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($src$$reg));
1978 %}
1979
1980 enc_class Con32 (immI src) %{ // Con32(storeImmI)
1981 // Output immediate
1982 $$$emit32$src$$constant;
1983 %}
1984
1985 enc_class Con32FPR_as_bits(immFPR src) %{ // storeF_imm
1986 // Output Float immediate bits
1987 jfloat jf = $src$$constant;
1988 int jf_as_bits = jint_cast( jf );
1989 emit_d32(cbuf, jf_as_bits);
1990 %}
1991
1992 enc_class Con32F_as_bits(immF src) %{ // storeX_imm
1993 // Output Float immediate bits
1994 jfloat jf = $src$$constant;
1995 int jf_as_bits = jint_cast( jf );
1996 emit_d32(cbuf, jf_as_bits);
2051
2052 enc_class enc_flags_ne_to_boolean( iRegI res ) %{
2053 int res_encoding = $res$$reg;
2054
2055 // MOV res,0
2056 emit_opcode( cbuf, 0xB8 + res_encoding);
2057 emit_d32( cbuf, 0 );
2058 // JNE,s fail
2059 emit_opcode(cbuf,0x75);
2060 emit_d8(cbuf, 5 );
2061 // MOV res,1
2062 emit_opcode( cbuf, 0xB8 + res_encoding);
2063 emit_d32( cbuf, 1 );
2064 // fail:
2065 %}
2066
2067 enc_class set_instruction_start( ) %{
2068 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
2069 %}
2070
2071 enc_class RegMem (eRegI ereg, memory mem) %{ // emit_reg_mem
2072 int reg_encoding = $ereg$$reg;
2073 int base = $mem$$base;
2074 int index = $mem$$index;
2075 int scale = $mem$$scale;
2076 int displace = $mem$$disp;
2077 bool disp_is_oop = $mem->disp_is_oop();
2078 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
2079 %}
2080
2081 enc_class RegMem_Hi(eRegL ereg, memory mem) %{ // emit_reg_mem
2082 int reg_encoding = HIGH_FROM_LOW($ereg$$reg); // Hi register of pair, computed from lo
2083 int base = $mem$$base;
2084 int index = $mem$$index;
2085 int scale = $mem$$scale;
2086 int displace = $mem$$disp + 4; // Offset is 4 further in memory
2087 assert( !$mem->disp_is_oop(), "Cannot add 4 to oop" );
2088 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, false/*disp_is_oop*/);
2089 %}
2090
2091 enc_class move_long_small_shift( eRegL dst, immI_1_31 cnt ) %{
2115 %}
2116
2117 enc_class move_long_big_shift_clr( eRegL dst, immI_32_63 cnt ) %{
2118 int r1, r2;
2119 if( $secondary == 0x5 ) { r1 = $dst$$reg; r2 = HIGH_FROM_LOW($dst$$reg); }
2120 else { r2 = $dst$$reg; r1 = HIGH_FROM_LOW($dst$$reg); }
2121
2122 emit_opcode( cbuf, 0x8B ); // Move r1,r2
2123 emit_rm(cbuf, 0x3, r1, r2);
2124 if( $cnt$$constant > 32 ) { // Shift, if not by zero
2125 emit_opcode(cbuf,$primary);
2126 emit_rm(cbuf, 0x3, $secondary, r1);
2127 emit_d8(cbuf,$cnt$$constant-32);
2128 }
2129 emit_opcode(cbuf,0x33); // XOR r2,r2
2130 emit_rm(cbuf, 0x3, r2, r2);
2131 %}
2132
2133 // Clone of RegMem but accepts an extra parameter to access each
2134 // half of a double in memory; it never needs relocation info.
2135 enc_class Mov_MemD_half_to_Reg (immI opcode, memory mem, immI disp_for_half, eRegI rm_reg) %{
2136 emit_opcode(cbuf,$opcode$$constant);
2137 int reg_encoding = $rm_reg$$reg;
2138 int base = $mem$$base;
2139 int index = $mem$$index;
2140 int scale = $mem$$scale;
2141 int displace = $mem$$disp + $disp_for_half$$constant;
2142 bool disp_is_oop = false;
2143 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
2144 %}
2145
2146 // !!!!! Special Custom Code used by MemMove, and stack access instructions !!!!!
2147 //
2148 // Clone of RegMem except the RM-byte's reg/opcode field is an ADLC-time constant
2149 // and it never needs relocation information.
2150 // Frequently used to move data between FPU's Stack Top and memory.
2151 enc_class RMopc_Mem_no_oop (immI rm_opcode, memory mem) %{
2152 int rm_byte_opcode = $rm_opcode$$constant;
2153 int base = $mem$$base;
2154 int index = $mem$$index;
2155 int scale = $mem$$scale;
2156 int displace = $mem$$disp;
2157 assert( !$mem->disp_is_oop(), "No oops here because no relo info allowed" );
2158 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, false);
2159 %}
2160
2161 enc_class RMopc_Mem (immI rm_opcode, memory mem) %{
2162 int rm_byte_opcode = $rm_opcode$$constant;
2163 int base = $mem$$base;
2164 int index = $mem$$index;
2165 int scale = $mem$$scale;
2166 int displace = $mem$$disp;
2167 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
2168 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop);
2169 %}
2170
2171 enc_class RegLea (eRegI dst, eRegI src0, immI src1 ) %{ // emit_reg_lea
2172 int reg_encoding = $dst$$reg;
2173 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
2174 int index = 0x04; // 0x04 indicates no index
2175 int scale = 0x00; // 0x00 indicates no scale
2176 int displace = $src1$$constant; // 0x00 indicates no displacement
2177 bool disp_is_oop = false;
2178 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
2179 %}
2180
2181 enc_class min_enc (eRegI dst, eRegI src) %{ // MIN
2182 // Compare dst,src
2183 emit_opcode(cbuf,0x3B);
2184 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2185 // jmp dst < src around move
2186 emit_opcode(cbuf,0x7C);
2187 emit_d8(cbuf,2);
2188 // move dst,src
2189 emit_opcode(cbuf,0x8B);
2190 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2191 %}
2192
2193 enc_class max_enc (eRegI dst, eRegI src) %{ // MAX
2194 // Compare dst,src
2195 emit_opcode(cbuf,0x3B);
2196 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2197 // jmp dst > src around move
2198 emit_opcode(cbuf,0x7F);
2199 emit_d8(cbuf,2);
2200 // move dst,src
2201 emit_opcode(cbuf,0x8B);
2202 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2203 %}
2204
2205 enc_class enc_FPR_store(memory mem, regDPR src) %{
2206 // If src is FPR1, we can just FST to store it.
2207 // Else we need to FLD it to FPR1, then FSTP to store/pop it.
2208 int reg_encoding = 0x2; // Just store
2209 int base = $mem$$base;
2210 int index = $mem$$index;
2211 int scale = $mem$$scale;
2212 int displace = $mem$$disp;
2213 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
2214 if( $src$$reg != FPR1L_enc ) {
2215 reg_encoding = 0x3; // Store & pop
2216 emit_opcode( cbuf, 0xD9 ); // FLD (i.e., push it)
2217 emit_d8( cbuf, 0xC0-1+$src$$reg );
2218 }
2219 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
2220 emit_opcode(cbuf,$primary);
2221 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
2222 %}
2223
2224 enc_class neg_reg(eRegI dst) %{
2225 // NEG $dst
2226 emit_opcode(cbuf,0xF7);
2227 emit_rm(cbuf, 0x3, 0x03, $dst$$reg );
2228 %}
2229
2230 enc_class setLT_reg(eCXRegI dst) %{
2231 // SETLT $dst
2232 emit_opcode(cbuf,0x0F);
2233 emit_opcode(cbuf,0x9C);
2234 emit_rm( cbuf, 0x3, 0x4, $dst$$reg );
2235 %}
2236
2237 enc_class enc_cmpLTP(ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp) %{ // cadd_cmpLT
2238 int tmpReg = $tmp$$reg;
2239
2240 // SUB $p,$q
2241 emit_opcode(cbuf,0x2B);
2242 emit_rm(cbuf, 0x3, $p$$reg, $q$$reg);
2243 // SBB $tmp,$tmp
2244 emit_opcode(cbuf,0x1B);
2245 emit_rm(cbuf, 0x3, tmpReg, tmpReg);
2246 // AND $tmp,$y
2247 emit_opcode(cbuf,0x23);
2248 emit_rm(cbuf, 0x3, tmpReg, $y$$reg);
2249 // ADD $p,$tmp
2250 emit_opcode(cbuf,0x03);
2251 emit_rm(cbuf, 0x3, $p$$reg, tmpReg);
2252 %}
2253
2254 enc_class enc_cmpLTP_mem(eRegI p, eRegI q, memory mem, eCXRegI tmp) %{ // cadd_cmpLT
2255 int tmpReg = $tmp$$reg;
2256
2257 // SUB $p,$q
2258 emit_opcode(cbuf,0x2B);
2259 emit_rm(cbuf, 0x3, $p$$reg, $q$$reg);
2260 // SBB $tmp,$tmp
2261 emit_opcode(cbuf,0x1B);
2262 emit_rm(cbuf, 0x3, tmpReg, tmpReg);
2263 // AND $tmp,$y
2264 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
2265 emit_opcode(cbuf,0x23);
2266 int reg_encoding = tmpReg;
2267 int base = $mem$$base;
2268 int index = $mem$$index;
2269 int scale = $mem$$scale;
2270 int displace = $mem$$disp;
2271 bool disp_is_oop = $mem->disp_is_oop();
2272 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
2273 // ADD $p,$tmp
2274 emit_opcode(cbuf,0x03);
2373 emit_d8( cbuf, 0xC0-1+$dst$$reg ); // FLD ST(i-1)
2374 %}
2375
2376 enc_class strictfp_bias1( regDPR dst ) %{
2377 emit_opcode( cbuf, 0xDB ); // FLD m80real
2378 emit_opcode( cbuf, 0x2D );
2379 emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias1() );
2380 emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0
2381 emit_opcode( cbuf, 0xC8+$dst$$reg );
2382 %}
2383
2384 enc_class strictfp_bias2( regDPR dst ) %{
2385 emit_opcode( cbuf, 0xDB ); // FLD m80real
2386 emit_opcode( cbuf, 0x2D );
2387 emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias2() );
2388 emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0
2389 emit_opcode( cbuf, 0xC8+$dst$$reg );
2390 %}
2391
2392 // Special case for moving an integer register to a stack slot.
2393 enc_class OpcPRegSS( stackSlotI dst, eRegI src ) %{ // RegSS
2394 store_to_stackslot( cbuf, $primary, $src$$reg, $dst$$disp );
2395 %}
2396
2397 // Special case for moving a register to a stack slot.
2398 enc_class RegSS( stackSlotI dst, eRegI src ) %{ // RegSS
2399 // Opcode already emitted
2400 emit_rm( cbuf, 0x02, $src$$reg, ESP_enc ); // R/M byte
2401 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte
2402 emit_d32(cbuf, $dst$$disp); // Displacement
2403 %}
2404
2405 // Push the integer in stackSlot 'src' onto FP-stack
2406 enc_class Push_Mem_I( memory src ) %{ // FILD [ESP+src]
2407 store_to_stackslot( cbuf, $primary, $secondary, $src$$disp );
2408 %}
2409
2410 // Push FPU's TOS float to a stack-slot, and pop FPU-stack
2411 enc_class Pop_Mem_FPR( stackSlotF dst ) %{ // FSTP_S [ESP+dst]
2412 store_to_stackslot( cbuf, 0xD9, 0x03, $dst$$disp );
2413 %}
2414
2415 // Same as Pop_Mem_F except for opcode
2416 // Push FPU's TOS double to a stack-slot, and pop FPU-stack
2417 enc_class Pop_Mem_DPR( stackSlotD dst ) %{ // FSTP_D [ESP+dst]
2418 store_to_stackslot( cbuf, 0xDD, 0x03, $dst$$disp );
2623 emit_opcode( cbuf, 0x9E);
2624 // NOP // target for branch to avoid branch to branch
2625 emit_opcode( cbuf, 0x90);
2626 %}
2627
2628 // fnstsw_ax();
2629 // sahf();
2630 // movl(dst, nan_result);
2631 // jcc(Assembler::parity, exit);
2632 // movl(dst, less_result);
2633 // jcc(Assembler::below, exit);
2634 // movl(dst, equal_result);
2635 // jcc(Assembler::equal, exit);
2636 // movl(dst, greater_result);
2637
2638 // less_result = 1;
2639 // greater_result = -1;
2640 // equal_result = 0;
2641 // nan_result = -1;
2642
2643 enc_class CmpF_Result(eRegI dst) %{
2644 // fnstsw_ax();
2645 emit_opcode( cbuf, 0xDF);
2646 emit_opcode( cbuf, 0xE0);
2647 // sahf
2648 emit_opcode( cbuf, 0x9E);
2649 // movl(dst, nan_result);
2650 emit_opcode( cbuf, 0xB8 + $dst$$reg);
2651 emit_d32( cbuf, -1 );
2652 // jcc(Assembler::parity, exit);
2653 emit_opcode( cbuf, 0x7A );
2654 emit_d8 ( cbuf, 0x13 );
2655 // movl(dst, less_result);
2656 emit_opcode( cbuf, 0xB8 + $dst$$reg);
2657 emit_d32( cbuf, -1 );
2658 // jcc(Assembler::below, exit);
2659 emit_opcode( cbuf, 0x72 );
2660 emit_d8 ( cbuf, 0x0C );
2661 // movl(dst, equal_result);
2662 emit_opcode( cbuf, 0xB8 + $dst$$reg);
2663 emit_d32( cbuf, 0 );
2668 emit_opcode( cbuf, 0xB8 + $dst$$reg);
2669 emit_d32( cbuf, 1 );
2670 %}
2671
2672
2673 // Compare the longs and set flags
2674 // BROKEN! Do Not use as-is
2675 enc_class cmpl_test( eRegL src1, eRegL src2 ) %{
2676 // CMP $src1.hi,$src2.hi
2677 emit_opcode( cbuf, 0x3B );
2678 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) );
2679 // JNE,s done
2680 emit_opcode(cbuf,0x75);
2681 emit_d8(cbuf, 2 );
2682 // CMP $src1.lo,$src2.lo
2683 emit_opcode( cbuf, 0x3B );
2684 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg );
2685 // done:
2686 %}
2687
2688 enc_class convert_int_long( regL dst, eRegI src ) %{
2689 // mov $dst.lo,$src
2690 int dst_encoding = $dst$$reg;
2691 int src_encoding = $src$$reg;
2692 encode_Copy( cbuf, dst_encoding , src_encoding );
2693 // mov $dst.hi,$src
2694 encode_Copy( cbuf, HIGH_FROM_LOW(dst_encoding), src_encoding );
2695 // sar $dst.hi,31
2696 emit_opcode( cbuf, 0xC1 );
2697 emit_rm(cbuf, 0x3, 7, HIGH_FROM_LOW(dst_encoding) );
2698 emit_d8(cbuf, 0x1F );
2699 %}
2700
2701 enc_class convert_long_double( eRegL src ) %{
2702 // push $src.hi
2703 emit_opcode(cbuf, 0x50+HIGH_FROM_LOW($src$$reg));
2704 // push $src.lo
2705 emit_opcode(cbuf, 0x50+$src$$reg );
2706 // fild 64-bits at [SP]
2707 emit_opcode(cbuf,0xdf);
2708 emit_d8(cbuf, 0x6C);
2737 emit_opcode(cbuf,0xdf);
2738 emit_d8(cbuf, 0x6C);
2739 emit_d8(cbuf, 0x24);
2740 emit_d8(cbuf, 0x00);
2741 %}
2742
2743 enc_class long_int_multiply( eADXRegL dst, nadxRegI src) %{
2744 // Basic idea: long = (long)int * (long)int
2745 // IMUL EDX:EAX, src
2746 emit_opcode( cbuf, 0xF7 );
2747 emit_rm( cbuf, 0x3, 0x5, $src$$reg);
2748 %}
2749
2750 enc_class long_uint_multiply( eADXRegL dst, nadxRegI src) %{
2751 // Basic Idea: long = (int & 0xffffffffL) * (int & 0xffffffffL)
2752 // MUL EDX:EAX, src
2753 emit_opcode( cbuf, 0xF7 );
2754 emit_rm( cbuf, 0x3, 0x4, $src$$reg);
2755 %}
2756
2757 enc_class long_multiply( eADXRegL dst, eRegL src, eRegI tmp ) %{
2758 // Basic idea: lo(result) = lo(x_lo * y_lo)
2759 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi)
2760 // MOV $tmp,$src.lo
2761 encode_Copy( cbuf, $tmp$$reg, $src$$reg );
2762 // IMUL $tmp,EDX
2763 emit_opcode( cbuf, 0x0F );
2764 emit_opcode( cbuf, 0xAF );
2765 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) );
2766 // MOV EDX,$src.hi
2767 encode_Copy( cbuf, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg) );
2768 // IMUL EDX,EAX
2769 emit_opcode( cbuf, 0x0F );
2770 emit_opcode( cbuf, 0xAF );
2771 emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg );
2772 // ADD $tmp,EDX
2773 emit_opcode( cbuf, 0x03 );
2774 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) );
2775 // MUL EDX:EAX,$src.lo
2776 emit_opcode( cbuf, 0xF7 );
2777 emit_rm( cbuf, 0x3, 0x4, $src$$reg );
2778 // ADD EDX,ESI
2779 emit_opcode( cbuf, 0x03 );
2780 emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $tmp$$reg );
2781 %}
2782
2783 enc_class long_multiply_con( eADXRegL dst, immL_127 src, eRegI tmp ) %{
2784 // Basic idea: lo(result) = lo(src * y_lo)
2785 // hi(result) = hi(src * y_lo) + lo(src * y_hi)
2786 // IMUL $tmp,EDX,$src
2787 emit_opcode( cbuf, 0x6B );
2788 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) );
2789 emit_d8( cbuf, (int)$src$$constant );
2790 // MOV EDX,$src
2791 emit_opcode(cbuf, 0xB8 + EDX_enc);
2792 emit_d32( cbuf, (int)$src$$constant );
2793 // MUL EDX:EAX,EDX
2794 emit_opcode( cbuf, 0xF7 );
2795 emit_rm( cbuf, 0x3, 0x4, EDX_enc );
2796 // ADD EDX,ESI
2797 emit_opcode( cbuf, 0x03 );
2798 emit_rm( cbuf, 0x3, EDX_enc, $tmp$$reg );
2799 %}
2800
2801 enc_class long_div( eRegL src1, eRegL src2 ) %{
2802 // PUSH src1.hi
2803 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src1$$reg) );
2819
2820 enc_class long_mod( eRegL src1, eRegL src2 ) %{
2821 // PUSH src1.hi
2822 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src1$$reg) );
2823 // PUSH src1.lo
2824 emit_opcode(cbuf, 0x50+$src1$$reg );
2825 // PUSH src2.hi
2826 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src2$$reg) );
2827 // PUSH src2.lo
2828 emit_opcode(cbuf, 0x50+$src2$$reg );
2829 // CALL directly to the runtime
2830 cbuf.set_insts_mark();
2831 emit_opcode(cbuf,0xE8); // Call into runtime
2832 emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::lrem ) - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
2833 // Restore stack
2834 emit_opcode(cbuf, 0x83); // add SP, #framesize
2835 emit_rm(cbuf, 0x3, 0x00, ESP_enc);
2836 emit_d8(cbuf, 4*4);
2837 %}
2838
2839 enc_class long_cmp_flags0( eRegL src, eRegI tmp ) %{
2840 // MOV $tmp,$src.lo
2841 emit_opcode(cbuf, 0x8B);
2842 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg);
2843 // OR $tmp,$src.hi
2844 emit_opcode(cbuf, 0x0B);
2845 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg));
2846 %}
2847
2848 enc_class long_cmp_flags1( eRegL src1, eRegL src2 ) %{
2849 // CMP $src1.lo,$src2.lo
2850 emit_opcode( cbuf, 0x3B );
2851 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg );
2852 // JNE,s skip
2853 emit_cc(cbuf, 0x70, 0x5);
2854 emit_d8(cbuf,2);
2855 // CMP $src1.hi,$src2.hi
2856 emit_opcode( cbuf, 0x3B );
2857 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) );
2858 %}
2859
2860 enc_class long_cmp_flags2( eRegL src1, eRegL src2, eRegI tmp ) %{
2861 // CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits
2862 emit_opcode( cbuf, 0x3B );
2863 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg );
2864 // MOV $tmp,$src1.hi
2865 emit_opcode( cbuf, 0x8B );
2866 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src1$$reg) );
2867 // SBB $tmp,$src2.hi\t! Compute flags for long compare
2868 emit_opcode( cbuf, 0x1B );
2869 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src2$$reg) );
2870 %}
2871
2872 enc_class long_cmp_flags3( eRegL src, eRegI tmp ) %{
2873 // XOR $tmp,$tmp
2874 emit_opcode(cbuf,0x33); // XOR
2875 emit_rm(cbuf,0x3, $tmp$$reg, $tmp$$reg);
2876 // CMP $tmp,$src.lo
2877 emit_opcode( cbuf, 0x3B );
2878 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg );
2879 // SBB $tmp,$src.hi
2880 emit_opcode( cbuf, 0x1B );
2881 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg) );
2882 %}
2883
2884 // Sniff, sniff... smells like Gnu Superoptimizer
2885 enc_class neg_long( eRegL dst ) %{
2886 emit_opcode(cbuf,0xF7); // NEG hi
2887 emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg));
2888 emit_opcode(cbuf,0xF7); // NEG lo
2889 emit_rm (cbuf,0x3, 0x3, $dst$$reg );
2890 emit_opcode(cbuf,0x83); // SBB hi,0
2891 emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg));
2892 emit_d8 (cbuf,0 );
3745 // Body of function which returns an integer array locating
3746 // arguments either in registers or in stack slots. Passed an array
3747 // of ideal registers called "sig" and a "length" count. Stack-slot
3748 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3749 // arguments for a CALLEE. Incoming stack arguments are
3750 // automatically biased by the preserve_stack_slots field above.
3751 c_calling_convention %{
3752 // This is obviously always outgoing
3753 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length);
3754 %}
3755
3756 // Location of C & interpreter return values
3757 c_return_value %{
3758 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3759 static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num, EAX_num, FPR1L_num, FPR1L_num, EAX_num };
3760 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num };
3761
3762 // in SSE2+ mode we want to keep the FPU stack clean so pretend
3763 // that C functions return float and double results in XMM0.
3764 if( ideal_reg == Op_RegD && UseSSE>=2 )
3765 return OptoRegPair(XMM0b_num,XMM0a_num);
3766 if( ideal_reg == Op_RegF && UseSSE>=2 )
3767 return OptoRegPair(OptoReg::Bad,XMM0a_num);
3768
3769 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3770 %}
3771
3772 // Location of return values
3773 return_value %{
3774 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3775 static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num, EAX_num, FPR1L_num, FPR1L_num, EAX_num };
3776 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num };
3777 if( ideal_reg == Op_RegD && UseSSE>=2 )
3778 return OptoRegPair(XMM0b_num,XMM0a_num);
3779 if( ideal_reg == Op_RegF && UseSSE>=1 )
3780 return OptoRegPair(OptoReg::Bad,XMM0a_num);
3781 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3782 %}
3783
3784 %}
3785
3786 //----------ATTRIBUTES---------------------------------------------------------
3787 //----------Operand Attributes-------------------------------------------------
3788 op_attrib op_cost(0); // Required cost attribute
3789
3790 //----------Instruction Attributes---------------------------------------------
3791 ins_attrib ins_cost(100); // Required cost attribute
3792 ins_attrib ins_size(8); // Required size attribute (in bits)
3793 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
3794 // non-matching short branch variant of some
3795 // long branch?
3796 ins_attrib ins_alignment(1); // Required alignment attribute (must be a power of 2)
3797 // specifies the alignment that some part of the instruction (not
3798 // necessarily the start) requires. If > 1, a compute_padding()
3799 // function must be provided for the instruction
3800
4130 // Constant for byte-wide masking
4131 operand immI_255() %{
4132 predicate( n->get_int() == 255 );
4133 match(ConI);
4134
4135 format %{ %}
4136 interface(CONST_INTER);
4137 %}
4138
4139 // Constant for short-wide masking
4140 operand immI_65535() %{
4141 predicate(n->get_int() == 65535);
4142 match(ConI);
4143
4144 format %{ %}
4145 interface(CONST_INTER);
4146 %}
4147
4148 // Register Operands
4149 // Integer Register
4150 operand eRegI() %{
4151 constraint(ALLOC_IN_RC(e_reg));
4152 match(RegI);
4153 match(xRegI);
4154 match(eAXRegI);
4155 match(eBXRegI);
4156 match(eCXRegI);
4157 match(eDXRegI);
4158 match(eDIRegI);
4159 match(eSIRegI);
4160
4161 format %{ %}
4162 interface(REG_INTER);
4163 %}
4164
4165 // Subset of Integer Register
4166 operand xRegI(eRegI reg) %{
4167 constraint(ALLOC_IN_RC(x_reg));
4168 match(reg);
4169 match(eAXRegI);
4170 match(eBXRegI);
4171 match(eCXRegI);
4172 match(eDXRegI);
4173
4174 format %{ %}
4175 interface(REG_INTER);
4176 %}
4177
4178 // Special Registers
4179 operand eAXRegI(xRegI reg) %{
4180 constraint(ALLOC_IN_RC(eax_reg));
4181 match(reg);
4182 match(eRegI);
4183
4184 format %{ "EAX" %}
4185 interface(REG_INTER);
4186 %}
4187
4188 // Special Registers
4189 operand eBXRegI(xRegI reg) %{
4190 constraint(ALLOC_IN_RC(ebx_reg));
4191 match(reg);
4192 match(eRegI);
4193
4194 format %{ "EBX" %}
4195 interface(REG_INTER);
4196 %}
4197
4198 operand eCXRegI(xRegI reg) %{
4199 constraint(ALLOC_IN_RC(ecx_reg));
4200 match(reg);
4201 match(eRegI);
4202
4203 format %{ "ECX" %}
4204 interface(REG_INTER);
4205 %}
4206
4207 operand eDXRegI(xRegI reg) %{
4208 constraint(ALLOC_IN_RC(edx_reg));
4209 match(reg);
4210 match(eRegI);
4211
4212 format %{ "EDX" %}
4213 interface(REG_INTER);
4214 %}
4215
4216 operand eDIRegI(xRegI reg) %{
4217 constraint(ALLOC_IN_RC(edi_reg));
4218 match(reg);
4219 match(eRegI);
4220
4221 format %{ "EDI" %}
4222 interface(REG_INTER);
4223 %}
4224
4225 operand naxRegI() %{
4226 constraint(ALLOC_IN_RC(nax_reg));
4227 match(RegI);
4228 match(eCXRegI);
4229 match(eDXRegI);
4230 match(eSIRegI);
4231 match(eDIRegI);
4232
4233 format %{ %}
4234 interface(REG_INTER);
4235 %}
4236
4237 operand nadxRegI() %{
4238 constraint(ALLOC_IN_RC(nadx_reg));
4239 match(RegI);
4246 interface(REG_INTER);
4247 %}
4248
4249 operand ncxRegI() %{
4250 constraint(ALLOC_IN_RC(ncx_reg));
4251 match(RegI);
4252 match(eAXRegI);
4253 match(eDXRegI);
4254 match(eSIRegI);
4255 match(eDIRegI);
4256
4257 format %{ %}
4258 interface(REG_INTER);
4259 %}
4260
4261 // // This operand was used by cmpFastUnlock, but conflicted with 'object' reg
4262 // //
4263 operand eSIRegI(xRegI reg) %{
4264 constraint(ALLOC_IN_RC(esi_reg));
4265 match(reg);
4266 match(eRegI);
4267
4268 format %{ "ESI" %}
4269 interface(REG_INTER);
4270 %}
4271
4272 // Pointer Register
4273 operand anyRegP() %{
4274 constraint(ALLOC_IN_RC(any_reg));
4275 match(RegP);
4276 match(eAXRegP);
4277 match(eBXRegP);
4278 match(eCXRegP);
4279 match(eDIRegP);
4280 match(eRegP);
4281
4282 format %{ %}
4283 interface(REG_INTER);
4284 %}
4285
4286 operand eRegP() %{
4287 constraint(ALLOC_IN_RC(e_reg));
4288 match(RegP);
4289 match(eAXRegP);
4290 match(eBXRegP);
4291 match(eCXRegP);
4292 match(eDIRegP);
4293
4294 format %{ %}
4295 interface(REG_INTER);
4296 %}
4297
4298 // On windows95, EBP is not safe to use for implicit null tests.
4299 operand eRegP_no_EBP() %{
4300 constraint(ALLOC_IN_RC(e_reg_no_rbp));
4301 match(RegP);
4302 match(eAXRegP);
4303 match(eBXRegP);
4304 match(eCXRegP);
4305 match(eDIRegP);
4306
4307 op_cost(100);
4308 format %{ %}
4309 interface(REG_INTER);
4310 %}
4311
4312 operand naxRegP() %{
4313 constraint(ALLOC_IN_RC(nax_reg));
4314 match(RegP);
4315 match(eBXRegP);
4316 match(eDXRegP);
4317 match(eCXRegP);
4318 match(eSIRegP);
4319 match(eDIRegP);
4320
4460 match(RegFlags);
4461 format %{ "FLAGS_LTGE" %}
4462 interface(REG_INTER);
4463 %}
4464 operand flagsReg_long_EQNE() %{
4465 constraint(ALLOC_IN_RC(int_flags));
4466 match(RegFlags);
4467 format %{ "FLAGS_EQNE" %}
4468 interface(REG_INTER);
4469 %}
4470 operand flagsReg_long_LEGT() %{
4471 constraint(ALLOC_IN_RC(int_flags));
4472 match(RegFlags);
4473 format %{ "FLAGS_LEGT" %}
4474 interface(REG_INTER);
4475 %}
4476
4477 // Float register operands
4478 operand regDPR() %{
4479 predicate( UseSSE < 2 );
4480 constraint(ALLOC_IN_RC(dbl_reg));
4481 match(RegD);
4482 match(regDPR1);
4483 match(regDPR2);
4484 format %{ %}
4485 interface(REG_INTER);
4486 %}
4487
4488 operand regDPR1(regDPR reg) %{
4489 predicate( UseSSE < 2 );
4490 constraint(ALLOC_IN_RC(dbl_reg0));
4491 match(reg);
4492 format %{ "FPR1" %}
4493 interface(REG_INTER);
4494 %}
4495
4496 operand regDPR2(regDPR reg) %{
4497 predicate( UseSSE < 2 );
4498 constraint(ALLOC_IN_RC(dbl_reg1));
4499 match(reg);
4500 format %{ "FPR2" %}
4501 interface(REG_INTER);
4502 %}
4503
4504 operand regnotDPR1(regDPR reg) %{
4505 predicate( UseSSE < 2 );
4506 constraint(ALLOC_IN_RC(dbl_notreg0));
4507 match(reg);
4508 format %{ %}
4509 interface(REG_INTER);
4510 %}
4511
4512 // XMM Double register operands
4513 operand regD() %{
4514 predicate( UseSSE>=2 );
4515 constraint(ALLOC_IN_RC(xdb_reg));
4516 match(RegD);
4517 match(regD6);
4518 match(regD7);
4519 format %{ %}
4520 interface(REG_INTER);
4521 %}
4522
4523 // XMM6 double register operands
4524 operand regD6(regD reg) %{
4525 predicate( UseSSE>=2 );
4526 constraint(ALLOC_IN_RC(xdb_reg6));
4527 match(reg);
4528 format %{ "XMM6" %}
4529 interface(REG_INTER);
4530 %}
4531
4532 // XMM7 double register operands
4533 operand regD7(regD reg) %{
4534 predicate( UseSSE>=2 );
4535 constraint(ALLOC_IN_RC(xdb_reg7));
4536 match(reg);
4537 format %{ "XMM7" %}
4538 interface(REG_INTER);
4539 %}
4540
4541 // Float register operands
4542 operand regFPR() %{
4543 predicate( UseSSE < 2 );
4544 constraint(ALLOC_IN_RC(flt_reg));
4545 match(RegF);
4546 match(regFPR1);
4547 format %{ %}
4548 interface(REG_INTER);
4549 %}
4550
4551 // Float register operands
4552 operand regFPR1(regFPR reg) %{
4553 predicate( UseSSE < 2 );
4554 constraint(ALLOC_IN_RC(flt_reg0));
4555 match(reg);
4556 format %{ "FPR1" %}
4557 interface(REG_INTER);
4558 %}
4559
4560 // XMM register operands
4561 operand regF() %{
4562 predicate( UseSSE>=1 );
4563 constraint(ALLOC_IN_RC(xmm_reg));
4564 match(RegF);
4565 format %{ %}
4566 interface(REG_INTER);
4567 %}
4568
4569
4570 //----------Memory Operands----------------------------------------------------
4571 // Direct Memory Operand
4572 operand direct(immP addr) %{
4573 match(addr);
4574
4575 format %{ "[$addr]" %}
4576 interface(MEMORY_INTER) %{
4577 base(0xFFFFFFFF);
4578 index(0x4);
4579 scale(0x0);
4580 disp($addr);
4581 %}
4582 %}
4583
4584 // Indirect Memory Operand
4585 operand indirect(eRegP reg) %{
4586 constraint(ALLOC_IN_RC(e_reg));
4587 match(reg);
4588
4589 format %{ "[$reg]" %}
4590 interface(MEMORY_INTER) %{
4591 base($reg);
4592 index(0x4);
4593 scale(0x0);
4594 disp(0x0);
4595 %}
4596 %}
4597
4598 // Indirect Memory Plus Short Offset Operand
4599 operand indOffset8(eRegP reg, immI8 off) %{
4600 match(AddP reg off);
4601
4602 format %{ "[$reg + $off]" %}
4603 interface(MEMORY_INTER) %{
4604 base($reg);
4605 index(0x4);
4606 scale(0x0);
4607 disp($off);
4608 %}
4609 %}
4610
4611 // Indirect Memory Plus Long Offset Operand
4612 operand indOffset32(eRegP reg, immI off) %{
4613 match(AddP reg off);
4614
4615 format %{ "[$reg + $off]" %}
4616 interface(MEMORY_INTER) %{
4617 base($reg);
4618 index(0x4);
4619 scale(0x0);
4620 disp($off);
4621 %}
4622 %}
4623
4624 // Indirect Memory Plus Long Offset Operand
4625 operand indOffset32X(eRegI reg, immP off) %{
4626 match(AddP off reg);
4627
4628 format %{ "[$reg + $off]" %}
4629 interface(MEMORY_INTER) %{
4630 base($reg);
4631 index(0x4);
4632 scale(0x0);
4633 disp($off);
4634 %}
4635 %}
4636
4637 // Indirect Memory Plus Index Register Plus Offset Operand
4638 operand indIndexOffset(eRegP reg, eRegI ireg, immI off) %{
4639 match(AddP (AddP reg ireg) off);
4640
4641 op_cost(10);
4642 format %{"[$reg + $off + $ireg]" %}
4643 interface(MEMORY_INTER) %{
4644 base($reg);
4645 index($ireg);
4646 scale(0x0);
4647 disp($off);
4648 %}
4649 %}
4650
4651 // Indirect Memory Plus Index Register Plus Offset Operand
4652 operand indIndex(eRegP reg, eRegI ireg) %{
4653 match(AddP reg ireg);
4654
4655 op_cost(10);
4656 format %{"[$reg + $ireg]" %}
4657 interface(MEMORY_INTER) %{
4658 base($reg);
4659 index($ireg);
4660 scale(0x0);
4661 disp(0x0);
4662 %}
4663 %}
4664
4665 // // -------------------------------------------------------------------------
4666 // // 486 architecture doesn't support "scale * index + offset" with out a base
4667 // // -------------------------------------------------------------------------
4668 // // Scaled Memory Operands
4669 // // Indirect Memory Times Scale Plus Offset Operand
4670 // operand indScaleOffset(immP off, eRegI ireg, immI2 scale) %{
4671 // match(AddP off (LShiftI ireg scale));
4672 //
4673 // op_cost(10);
4674 // format %{"[$off + $ireg << $scale]" %}
4675 // interface(MEMORY_INTER) %{
4676 // base(0x4);
4677 // index($ireg);
4678 // scale($scale);
4679 // disp($off);
4680 // %}
4681 // %}
4682
4683 // Indirect Memory Times Scale Plus Index Register
4684 operand indIndexScale(eRegP reg, eRegI ireg, immI2 scale) %{
4685 match(AddP reg (LShiftI ireg scale));
4686
4687 op_cost(10);
4688 format %{"[$reg + $ireg << $scale]" %}
4689 interface(MEMORY_INTER) %{
4690 base($reg);
4691 index($ireg);
4692 scale($scale);
4693 disp(0x0);
4694 %}
4695 %}
4696
4697 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
4698 operand indIndexScaleOffset(eRegP reg, immI off, eRegI ireg, immI2 scale) %{
4699 match(AddP (AddP reg (LShiftI ireg scale)) off);
4700
4701 op_cost(10);
4702 format %{"[$reg + $off + $ireg << $scale]" %}
4703 interface(MEMORY_INTER) %{
4704 base($reg);
4705 index($ireg);
4706 scale($scale);
4707 disp($off);
4708 %}
4709 %}
4710
4711 //----------Load Long Memory Operands------------------------------------------
4712 // The load-long idiom will use it's address expression again after loading
4713 // the first word of the long. If the load-long destination overlaps with
4714 // registers used in the addressing expression, the 2nd half will be loaded
4715 // from a clobbered address. Fix this by requiring that load-long use
4716 // address registers that do not overlap with the load-long target.
4717
4718 // load-long support
4806 disp($reg); // Stack Offset
4807 %}
4808 %}
4809
4810 operand stackSlotL(sRegL reg) %{
4811 constraint(ALLOC_IN_RC(stack_slots));
4812 // No match rule because this operand is only generated in matching
4813 format %{ "[$reg]" %}
4814 interface(MEMORY_INTER) %{
4815 base(0x4); // ESP
4816 index(0x4); // No Index
4817 scale(0x0); // No Scale
4818 disp($reg); // Stack Offset
4819 %}
4820 %}
4821
4822 //----------Memory Operands - Win95 Implicit Null Variants----------------
4823 // Indirect Memory Operand
4824 operand indirect_win95_safe(eRegP_no_EBP reg)
4825 %{
4826 constraint(ALLOC_IN_RC(e_reg));
4827 match(reg);
4828
4829 op_cost(100);
4830 format %{ "[$reg]" %}
4831 interface(MEMORY_INTER) %{
4832 base($reg);
4833 index(0x4);
4834 scale(0x0);
4835 disp(0x0);
4836 %}
4837 %}
4838
4839 // Indirect Memory Plus Short Offset Operand
4840 operand indOffset8_win95_safe(eRegP_no_EBP reg, immI8 off)
4841 %{
4842 match(AddP reg off);
4843
4844 op_cost(100);
4845 format %{ "[$reg + $off]" %}
4846 interface(MEMORY_INTER) %{
4850 disp($off);
4851 %}
4852 %}
4853
4854 // Indirect Memory Plus Long Offset Operand
4855 operand indOffset32_win95_safe(eRegP_no_EBP reg, immI off)
4856 %{
4857 match(AddP reg off);
4858
4859 op_cost(100);
4860 format %{ "[$reg + $off]" %}
4861 interface(MEMORY_INTER) %{
4862 base($reg);
4863 index(0x4);
4864 scale(0x0);
4865 disp($off);
4866 %}
4867 %}
4868
4869 // Indirect Memory Plus Index Register Plus Offset Operand
4870 operand indIndexOffset_win95_safe(eRegP_no_EBP reg, eRegI ireg, immI off)
4871 %{
4872 match(AddP (AddP reg ireg) off);
4873
4874 op_cost(100);
4875 format %{"[$reg + $off + $ireg]" %}
4876 interface(MEMORY_INTER) %{
4877 base($reg);
4878 index($ireg);
4879 scale(0x0);
4880 disp($off);
4881 %}
4882 %}
4883
4884 // Indirect Memory Times Scale Plus Index Register
4885 operand indIndexScale_win95_safe(eRegP_no_EBP reg, eRegI ireg, immI2 scale)
4886 %{
4887 match(AddP reg (LShiftI ireg scale));
4888
4889 op_cost(100);
4890 format %{"[$reg + $ireg << $scale]" %}
4891 interface(MEMORY_INTER) %{
4892 base($reg);
4893 index($ireg);
4894 scale($scale);
4895 disp(0x0);
4896 %}
4897 %}
4898
4899 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
4900 operand indIndexScaleOffset_win95_safe(eRegP_no_EBP reg, immI off, eRegI ireg, immI2 scale)
4901 %{
4902 match(AddP (AddP reg (LShiftI ireg scale)) off);
4903
4904 op_cost(100);
4905 format %{"[$reg + $off + $ireg << $scale]" %}
4906 interface(MEMORY_INTER) %{
4907 base($reg);
4908 index($ireg);
4909 scale($scale);
4910 disp($off);
4911 %}
4912 %}
4913
4914 //----------Conditional Branch Operands----------------------------------------
4915 // Comparison Op - This is the operation of the comparison, and is limited to
4916 // the following set of codes:
4917 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
4918 //
4919 // Other attributes of the comparison, such as unsignedness, are specified
4920 // by the comparison instruction that sets a condition code flags register.
5069 ALU0, ALU1, ALU = ALU0 | ALU1 );
5070
5071 //----------PIPELINE DESCRIPTION-----------------------------------------------
5072 // Pipeline Description specifies the stages in the machine's pipeline
5073
5074 // Generic P2/P3 pipeline
5075 pipe_desc(S0, S1, S2, S3, S4, S5);
5076
5077 //----------PIPELINE CLASSES---------------------------------------------------
5078 // Pipeline Classes describe the stages in which input and output are
5079 // referenced by the hardware pipeline.
5080
5081 // Naming convention: ialu or fpu
5082 // Then: _reg
5083 // Then: _reg if there is a 2nd register
5084 // Then: _long if it's a pair of instructions implementing a long
5085 // Then: _fat if it requires the big decoder
5086 // Or: _mem if it requires the big decoder and a memory unit.
5087
5088 // Integer ALU reg operation
5089 pipe_class ialu_reg(eRegI dst) %{
5090 single_instruction;
5091 dst : S4(write);
5092 dst : S3(read);
5093 DECODE : S0; // any decoder
5094 ALU : S3; // any alu
5095 %}
5096
5097 // Long ALU reg operation
5098 pipe_class ialu_reg_long(eRegL dst) %{
5099 instruction_count(2);
5100 dst : S4(write);
5101 dst : S3(read);
5102 DECODE : S0(2); // any 2 decoders
5103 ALU : S3(2); // both alus
5104 %}
5105
5106 // Integer ALU reg operation using big decoder
5107 pipe_class ialu_reg_fat(eRegI dst) %{
5108 single_instruction;
5109 dst : S4(write);
5110 dst : S3(read);
5111 D0 : S0; // big decoder only
5112 ALU : S3; // any alu
5113 %}
5114
5115 // Long ALU reg operation using big decoder
5116 pipe_class ialu_reg_long_fat(eRegL dst) %{
5117 instruction_count(2);
5118 dst : S4(write);
5119 dst : S3(read);
5120 D0 : S0(2); // big decoder only; twice
5121 ALU : S3(2); // any 2 alus
5122 %}
5123
5124 // Integer ALU reg-reg operation
5125 pipe_class ialu_reg_reg(eRegI dst, eRegI src) %{
5126 single_instruction;
5127 dst : S4(write);
5128 src : S3(read);
5129 DECODE : S0; // any decoder
5130 ALU : S3; // any alu
5131 %}
5132
5133 // Long ALU reg-reg operation
5134 pipe_class ialu_reg_reg_long(eRegL dst, eRegL src) %{
5135 instruction_count(2);
5136 dst : S4(write);
5137 src : S3(read);
5138 DECODE : S0(2); // any 2 decoders
5139 ALU : S3(2); // both alus
5140 %}
5141
5142 // Integer ALU reg-reg operation
5143 pipe_class ialu_reg_reg_fat(eRegI dst, memory src) %{
5144 single_instruction;
5145 dst : S4(write);
5146 src : S3(read);
5147 D0 : S0; // big decoder only
5148 ALU : S3; // any alu
5149 %}
5150
5151 // Long ALU reg-reg operation
5152 pipe_class ialu_reg_reg_long_fat(eRegL dst, eRegL src) %{
5153 instruction_count(2);
5154 dst : S4(write);
5155 src : S3(read);
5156 D0 : S0(2); // big decoder only; twice
5157 ALU : S3(2); // both alus
5158 %}
5159
5160 // Integer ALU reg-mem operation
5161 pipe_class ialu_reg_mem(eRegI dst, memory mem) %{
5162 single_instruction;
5163 dst : S5(write);
5164 mem : S3(read);
5165 D0 : S0; // big decoder only
5166 ALU : S4; // any alu
5167 MEM : S3; // any mem
5168 %}
5169
5170 // Long ALU reg-mem operation
5171 pipe_class ialu_reg_long_mem(eRegL dst, load_long_memory mem) %{
5172 instruction_count(2);
5173 dst : S5(write);
5174 mem : S3(read);
5175 D0 : S0(2); // big decoder only; twice
5176 ALU : S4(2); // any 2 alus
5177 MEM : S3(2); // both mems
5178 %}
5179
5180 // Integer mem operation (prefetch)
5181 pipe_class ialu_mem(memory mem)
5182 %{
5183 single_instruction;
5184 mem : S3(read);
5185 D0 : S0; // big decoder only
5186 MEM : S3; // any mem
5187 %}
5188
5189 // Integer Store to Memory
5190 pipe_class ialu_mem_reg(memory mem, eRegI src) %{
5191 single_instruction;
5192 mem : S3(read);
5193 src : S5(read);
5194 D0 : S0; // big decoder only
5195 ALU : S4; // any alu
5196 MEM : S3;
5197 %}
5198
5199 // Long Store to Memory
5200 pipe_class ialu_mem_long_reg(memory mem, eRegL src) %{
5201 instruction_count(2);
5202 mem : S3(read);
5203 src : S5(read);
5204 D0 : S0(2); // big decoder only; twice
5205 ALU : S4(2); // any 2 alus
5206 MEM : S3(2); // Both mems
5207 %}
5208
5209 // Integer Store to Memory
5210 pipe_class ialu_mem_imm(memory mem) %{
5211 single_instruction;
5212 mem : S3(read);
5213 D0 : S0; // big decoder only
5214 ALU : S4; // any alu
5215 MEM : S3;
5216 %}
5217
5218 // Integer ALU0 reg-reg operation
5219 pipe_class ialu_reg_reg_alu0(eRegI dst, eRegI src) %{
5220 single_instruction;
5221 dst : S4(write);
5222 src : S3(read);
5223 D0 : S0; // Big decoder only
5224 ALU0 : S3; // only alu0
5225 %}
5226
5227 // Integer ALU0 reg-mem operation
5228 pipe_class ialu_reg_mem_alu0(eRegI dst, memory mem) %{
5229 single_instruction;
5230 dst : S5(write);
5231 mem : S3(read);
5232 D0 : S0; // big decoder only
5233 ALU0 : S4; // ALU0 only
5234 MEM : S3; // any mem
5235 %}
5236
5237 // Integer ALU reg-reg operation
5238 pipe_class ialu_cr_reg_reg(eFlagsReg cr, eRegI src1, eRegI src2) %{
5239 single_instruction;
5240 cr : S4(write);
5241 src1 : S3(read);
5242 src2 : S3(read);
5243 DECODE : S0; // any decoder
5244 ALU : S3; // any alu
5245 %}
5246
5247 // Integer ALU reg-imm operation
5248 pipe_class ialu_cr_reg_imm(eFlagsReg cr, eRegI src1) %{
5249 single_instruction;
5250 cr : S4(write);
5251 src1 : S3(read);
5252 DECODE : S0; // any decoder
5253 ALU : S3; // any alu
5254 %}
5255
5256 // Integer ALU reg-mem operation
5257 pipe_class ialu_cr_reg_mem(eFlagsReg cr, eRegI src1, memory src2) %{
5258 single_instruction;
5259 cr : S4(write);
5260 src1 : S3(read);
5261 src2 : S3(read);
5262 D0 : S0; // big decoder only
5263 ALU : S4; // any alu
5264 MEM : S3;
5265 %}
5266
5267 // Conditional move reg-reg
5268 pipe_class pipe_cmplt( eRegI p, eRegI q, eRegI y ) %{
5269 instruction_count(4);
5270 y : S4(read);
5271 q : S3(read);
5272 p : S3(read);
5273 DECODE : S0(4); // any decoder
5274 %}
5275
5276 // Conditional move reg-reg
5277 pipe_class pipe_cmov_reg( eRegI dst, eRegI src, eFlagsReg cr ) %{
5278 single_instruction;
5279 dst : S4(write);
5280 src : S3(read);
5281 cr : S3(read);
5282 DECODE : S0; // any decoder
5283 %}
5284
5285 // Conditional move reg-mem
5286 pipe_class pipe_cmov_mem( eFlagsReg cr, eRegI dst, memory src) %{
5287 single_instruction;
5288 dst : S4(write);
5289 src : S3(read);
5290 cr : S3(read);
5291 DECODE : S0; // any decoder
5292 MEM : S3;
5293 %}
5294
5295 // Conditional move reg-reg long
5296 pipe_class pipe_cmov_reg_long( eFlagsReg cr, eRegL dst, eRegL src) %{
5297 single_instruction;
5298 dst : S4(write);
5299 src : S3(read);
5300 cr : S3(read);
5301 DECODE : S0(2); // any 2 decoders
5302 %}
5303
5304 // Conditional move double reg-reg
5305 pipe_class pipe_cmovDPR_reg( eFlagsReg cr, regDPR1 dst, regDPR src) %{
5306 single_instruction;
5517 // match -- States which machine-independent subtree may be replaced
5518 // by this instruction.
5519 // ins_cost -- The estimated cost of this instruction is used by instruction
5520 // selection to identify a minimum cost tree of machine
5521 // instructions that matches a tree of machine-independent
5522 // instructions.
5523 // format -- A string providing the disassembly for this instruction.
5524 // The value of an instruction's operand may be inserted
5525 // by referring to it with a '$' prefix.
5526 // opcode -- Three instruction opcodes may be provided. These are referred
5527 // to within an encode class as $primary, $secondary, and $tertiary
5528 // respectively. The primary opcode is commonly used to
5529 // indicate the type of machine instruction, while secondary
5530 // and tertiary are often used for prefix options or addressing
5531 // modes.
5532 // ins_encode -- A list of encode classes with parameters. The encode class
5533 // name must have been defined in an 'enc_class' specification
5534 // in the encode section of the architecture description.
5535
5536 //----------BSWAP-Instruction--------------------------------------------------
5537 instruct bytes_reverse_int(eRegI dst) %{
5538 match(Set dst (ReverseBytesI dst));
5539
5540 format %{ "BSWAP $dst" %}
5541 opcode(0x0F, 0xC8);
5542 ins_encode( OpcP, OpcSReg(dst) );
5543 ins_pipe( ialu_reg );
5544 %}
5545
5546 instruct bytes_reverse_long(eRegL dst) %{
5547 match(Set dst (ReverseBytesL dst));
5548
5549 format %{ "BSWAP $dst.lo\n\t"
5550 "BSWAP $dst.hi\n\t"
5551 "XCHG $dst.lo $dst.hi" %}
5552
5553 ins_cost(125);
5554 ins_encode( bswap_long_bytes(dst) );
5555 ins_pipe( ialu_reg_reg);
5556 %}
5557
5558 instruct bytes_reverse_unsigned_short(eRegI dst) %{
5559 match(Set dst (ReverseBytesUS dst));
5560
5561 format %{ "BSWAP $dst\n\t"
5562 "SHR $dst,16\n\t" %}
5563 ins_encode %{
5564 __ bswapl($dst$$Register);
5565 __ shrl($dst$$Register, 16);
5566 %}
5567 ins_pipe( ialu_reg );
5568 %}
5569
5570 instruct bytes_reverse_short(eRegI dst) %{
5571 match(Set dst (ReverseBytesS dst));
5572
5573 format %{ "BSWAP $dst\n\t"
5574 "SAR $dst,16\n\t" %}
5575 ins_encode %{
5576 __ bswapl($dst$$Register);
5577 __ sarl($dst$$Register, 16);
5578 %}
5579 ins_pipe( ialu_reg );
5580 %}
5581
5582
5583 //---------- Zeros Count Instructions ------------------------------------------
5584
5585 instruct countLeadingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{
5586 predicate(UseCountLeadingZerosInstruction);
5587 match(Set dst (CountLeadingZerosI src));
5588 effect(KILL cr);
5589
5590 format %{ "LZCNT $dst, $src\t# count leading zeros (int)" %}
5591 ins_encode %{
5592 __ lzcntl($dst$$Register, $src$$Register);
5593 %}
5594 ins_pipe(ialu_reg);
5595 %}
5596
5597 instruct countLeadingZerosI_bsr(eRegI dst, eRegI src, eFlagsReg cr) %{
5598 predicate(!UseCountLeadingZerosInstruction);
5599 match(Set dst (CountLeadingZerosI src));
5600 effect(KILL cr);
5601
5602 format %{ "BSR $dst, $src\t# count leading zeros (int)\n\t"
5603 "JNZ skip\n\t"
5604 "MOV $dst, -1\n"
5605 "skip:\n\t"
5606 "NEG $dst\n\t"
5607 "ADD $dst, 31" %}
5608 ins_encode %{
5609 Register Rdst = $dst$$Register;
5610 Register Rsrc = $src$$Register;
5611 Label skip;
5612 __ bsrl(Rdst, Rsrc);
5613 __ jccb(Assembler::notZero, skip);
5614 __ movl(Rdst, -1);
5615 __ bind(skip);
5616 __ negl(Rdst);
5617 __ addl(Rdst, BitsPerInt - 1);
5618 %}
5619 ins_pipe(ialu_reg);
5620 %}
5621
5622 instruct countLeadingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
5623 predicate(UseCountLeadingZerosInstruction);
5624 match(Set dst (CountLeadingZerosL src));
5625 effect(TEMP dst, KILL cr);
5626
5627 format %{ "LZCNT $dst, $src.hi\t# count leading zeros (long)\n\t"
5628 "JNC done\n\t"
5629 "LZCNT $dst, $src.lo\n\t"
5630 "ADD $dst, 32\n"
5631 "done:" %}
5632 ins_encode %{
5633 Register Rdst = $dst$$Register;
5634 Register Rsrc = $src$$Register;
5635 Label done;
5636 __ lzcntl(Rdst, HIGH_FROM_LOW(Rsrc));
5637 __ jccb(Assembler::carryClear, done);
5638 __ lzcntl(Rdst, Rsrc);
5639 __ addl(Rdst, BitsPerInt);
5640 __ bind(done);
5641 %}
5642 ins_pipe(ialu_reg);
5643 %}
5644
5645 instruct countLeadingZerosL_bsr(eRegI dst, eRegL src, eFlagsReg cr) %{
5646 predicate(!UseCountLeadingZerosInstruction);
5647 match(Set dst (CountLeadingZerosL src));
5648 effect(TEMP dst, KILL cr);
5649
5650 format %{ "BSR $dst, $src.hi\t# count leading zeros (long)\n\t"
5651 "JZ msw_is_zero\n\t"
5652 "ADD $dst, 32\n\t"
5653 "JMP not_zero\n"
5654 "msw_is_zero:\n\t"
5655 "BSR $dst, $src.lo\n\t"
5656 "JNZ not_zero\n\t"
5657 "MOV $dst, -1\n"
5658 "not_zero:\n\t"
5659 "NEG $dst\n\t"
5660 "ADD $dst, 63\n" %}
5661 ins_encode %{
5662 Register Rdst = $dst$$Register;
5663 Register Rsrc = $src$$Register;
5664 Label msw_is_zero;
5665 Label not_zero;
5666 __ bsrl(Rdst, HIGH_FROM_LOW(Rsrc));
5667 __ jccb(Assembler::zero, msw_is_zero);
5668 __ addl(Rdst, BitsPerInt);
5669 __ jmpb(not_zero);
5670 __ bind(msw_is_zero);
5671 __ bsrl(Rdst, Rsrc);
5672 __ jccb(Assembler::notZero, not_zero);
5673 __ movl(Rdst, -1);
5674 __ bind(not_zero);
5675 __ negl(Rdst);
5676 __ addl(Rdst, BitsPerLong - 1);
5677 %}
5678 ins_pipe(ialu_reg);
5679 %}
5680
5681 instruct countTrailingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{
5682 match(Set dst (CountTrailingZerosI src));
5683 effect(KILL cr);
5684
5685 format %{ "BSF $dst, $src\t# count trailing zeros (int)\n\t"
5686 "JNZ done\n\t"
5687 "MOV $dst, 32\n"
5688 "done:" %}
5689 ins_encode %{
5690 Register Rdst = $dst$$Register;
5691 Label done;
5692 __ bsfl(Rdst, $src$$Register);
5693 __ jccb(Assembler::notZero, done);
5694 __ movl(Rdst, BitsPerInt);
5695 __ bind(done);
5696 %}
5697 ins_pipe(ialu_reg);
5698 %}
5699
5700 instruct countTrailingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
5701 match(Set dst (CountTrailingZerosL src));
5702 effect(TEMP dst, KILL cr);
5703
5704 format %{ "BSF $dst, $src.lo\t# count trailing zeros (long)\n\t"
5705 "JNZ done\n\t"
5706 "BSF $dst, $src.hi\n\t"
5707 "JNZ msw_not_zero\n\t"
5708 "MOV $dst, 32\n"
5709 "msw_not_zero:\n\t"
5710 "ADD $dst, 32\n"
5711 "done:" %}
5712 ins_encode %{
5713 Register Rdst = $dst$$Register;
5714 Register Rsrc = $src$$Register;
5715 Label msw_not_zero;
5716 Label done;
5717 __ bsfl(Rdst, Rsrc);
5718 __ jccb(Assembler::notZero, done);
5719 __ bsfl(Rdst, HIGH_FROM_LOW(Rsrc));
5720 __ jccb(Assembler::notZero, msw_not_zero);
5721 __ movl(Rdst, BitsPerInt);
5722 __ bind(msw_not_zero);
5723 __ addl(Rdst, BitsPerInt);
5724 __ bind(done);
5725 %}
5726 ins_pipe(ialu_reg);
5727 %}
5728
5729
5730 //---------- Population Count Instructions -------------------------------------
5731
5732 instruct popCountI(eRegI dst, eRegI src) %{
5733 predicate(UsePopCountInstruction);
5734 match(Set dst (PopCountI src));
5735
5736 format %{ "POPCNT $dst, $src" %}
5737 ins_encode %{
5738 __ popcntl($dst$$Register, $src$$Register);
5739 %}
5740 ins_pipe(ialu_reg);
5741 %}
5742
5743 instruct popCountI_mem(eRegI dst, memory mem) %{
5744 predicate(UsePopCountInstruction);
5745 match(Set dst (PopCountI (LoadI mem)));
5746
5747 format %{ "POPCNT $dst, $mem" %}
5748 ins_encode %{
5749 __ popcntl($dst$$Register, $mem$$Address);
5750 %}
5751 ins_pipe(ialu_reg);
5752 %}
5753
5754 // Note: Long.bitCount(long) returns an int.
5755 instruct popCountL(eRegI dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
5756 predicate(UsePopCountInstruction);
5757 match(Set dst (PopCountL src));
5758 effect(KILL cr, TEMP tmp, TEMP dst);
5759
5760 format %{ "POPCNT $dst, $src.lo\n\t"
5761 "POPCNT $tmp, $src.hi\n\t"
5762 "ADD $dst, $tmp" %}
5763 ins_encode %{
5764 __ popcntl($dst$$Register, $src$$Register);
5765 __ popcntl($tmp$$Register, HIGH_FROM_LOW($src$$Register));
5766 __ addl($dst$$Register, $tmp$$Register);
5767 %}
5768 ins_pipe(ialu_reg);
5769 %}
5770
5771 // Note: Long.bitCount(long) returns an int.
5772 instruct popCountL_mem(eRegI dst, memory mem, eRegI tmp, eFlagsReg cr) %{
5773 predicate(UsePopCountInstruction);
5774 match(Set dst (PopCountL (LoadL mem)));
5775 effect(KILL cr, TEMP tmp, TEMP dst);
5776
5777 format %{ "POPCNT $dst, $mem\n\t"
5778 "POPCNT $tmp, $mem+4\n\t"
5779 "ADD $dst, $tmp" %}
5780 ins_encode %{
5781 //__ popcntl($dst$$Register, $mem$$Address$$first);
5782 //__ popcntl($tmp$$Register, $mem$$Address$$second);
5783 __ popcntl($dst$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false));
5784 __ popcntl($tmp$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false));
5785 __ addl($dst$$Register, $tmp$$Register);
5786 %}
5787 ins_pipe(ialu_reg);
5788 %}
5789
5790
5791 //----------Load/Store/Move Instructions---------------------------------------
5792 //----------Load Instructions--------------------------------------------------
5856 %}
5857
5858 // Load Unsigned Byte (8 bit UNsigned) with mask into Long Register
5859 instruct loadUB2L_immI8(eRegL dst, memory mem, immI8 mask, eFlagsReg cr) %{
5860 match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
5861 effect(KILL cr);
5862
5863 format %{ "MOVZX8 $dst.lo,$mem\t# ubyte & 8-bit mask -> long\n\t"
5864 "XOR $dst.hi,$dst.hi\n\t"
5865 "AND $dst.lo,$mask" %}
5866 ins_encode %{
5867 Register Rdst = $dst$$Register;
5868 __ movzbl(Rdst, $mem$$Address);
5869 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
5870 __ andl(Rdst, $mask$$constant);
5871 %}
5872 ins_pipe(ialu_reg_mem);
5873 %}
5874
5875 // Load Short (16bit signed)
5876 instruct loadS(eRegI dst, memory mem) %{
5877 match(Set dst (LoadS mem));
5878
5879 ins_cost(125);
5880 format %{ "MOVSX $dst,$mem\t# short" %}
5881
5882 ins_encode %{
5883 __ movswl($dst$$Register, $mem$$Address);
5884 %}
5885
5886 ins_pipe(ialu_reg_mem);
5887 %}
5888
5889 // Load Short (16 bit signed) to Byte (8 bit signed)
5890 instruct loadS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
5891 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
5892
5893 ins_cost(125);
5894 format %{ "MOVSX $dst, $mem\t# short -> byte" %}
5895 ins_encode %{
5896 __ movsbl($dst$$Register, $mem$$Address);
5897 %}
5898 ins_pipe(ialu_reg_mem);
5899 %}
5900
5901 // Load Short (16bit signed) into Long Register
5902 instruct loadS2L(eRegL dst, memory mem, eFlagsReg cr) %{
5903 match(Set dst (ConvI2L (LoadS mem)));
5904 effect(KILL cr);
5905
5906 ins_cost(375);
5907 format %{ "MOVSX $dst.lo,$mem\t# short -> long\n\t"
5908 "MOV $dst.hi,$dst.lo\n\t"
5909 "SAR $dst.hi,15" %}
5910
5911 ins_encode %{
5912 __ movswl($dst$$Register, $mem$$Address);
5913 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
5914 __ sarl(HIGH_FROM_LOW($dst$$Register), 15); // 16+1 MSB are already signed extended.
5915 %}
5916
5917 ins_pipe(ialu_reg_mem);
5918 %}
5919
5920 // Load Unsigned Short/Char (16bit unsigned)
5921 instruct loadUS(eRegI dst, memory mem) %{
5922 match(Set dst (LoadUS mem));
5923
5924 ins_cost(125);
5925 format %{ "MOVZX $dst,$mem\t# ushort/char -> int" %}
5926
5927 ins_encode %{
5928 __ movzwl($dst$$Register, $mem$$Address);
5929 %}
5930
5931 ins_pipe(ialu_reg_mem);
5932 %}
5933
5934 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
5935 instruct loadUS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
5936 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
5937
5938 ins_cost(125);
5939 format %{ "MOVSX $dst, $mem\t# ushort -> byte" %}
5940 ins_encode %{
5941 __ movsbl($dst$$Register, $mem$$Address);
5942 %}
5943 ins_pipe(ialu_reg_mem);
5944 %}
5945
5946 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
5947 instruct loadUS2L(eRegL dst, memory mem, eFlagsReg cr) %{
5948 match(Set dst (ConvI2L (LoadUS mem)));
5949 effect(KILL cr);
5950
5951 ins_cost(250);
5952 format %{ "MOVZX $dst.lo,$mem\t# ushort/char -> long\n\t"
5953 "XOR $dst.hi,$dst.hi" %}
5954
5955 ins_encode %{
5976 %}
5977
5978 // Load Unsigned Short/Char (16 bit UNsigned) with a 16-bit mask into Long Register
5979 instruct loadUS2L_immI16(eRegL dst, memory mem, immI16 mask, eFlagsReg cr) %{
5980 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
5981 effect(KILL cr);
5982
5983 format %{ "MOVZX $dst.lo, $mem\t# ushort/char & 16-bit mask -> long\n\t"
5984 "XOR $dst.hi,$dst.hi\n\t"
5985 "AND $dst.lo,$mask" %}
5986 ins_encode %{
5987 Register Rdst = $dst$$Register;
5988 __ movzwl(Rdst, $mem$$Address);
5989 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
5990 __ andl(Rdst, $mask$$constant);
5991 %}
5992 ins_pipe(ialu_reg_mem);
5993 %}
5994
5995 // Load Integer
5996 instruct loadI(eRegI dst, memory mem) %{
5997 match(Set dst (LoadI mem));
5998
5999 ins_cost(125);
6000 format %{ "MOV $dst,$mem\t# int" %}
6001
6002 ins_encode %{
6003 __ movl($dst$$Register, $mem$$Address);
6004 %}
6005
6006 ins_pipe(ialu_reg_mem);
6007 %}
6008
6009 // Load Integer (32 bit signed) to Byte (8 bit signed)
6010 instruct loadI2B(eRegI dst, memory mem, immI_24 twentyfour) %{
6011 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
6012
6013 ins_cost(125);
6014 format %{ "MOVSX $dst, $mem\t# int -> byte" %}
6015 ins_encode %{
6016 __ movsbl($dst$$Register, $mem$$Address);
6017 %}
6018 ins_pipe(ialu_reg_mem);
6019 %}
6020
6021 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
6022 instruct loadI2UB(eRegI dst, memory mem, immI_255 mask) %{
6023 match(Set dst (AndI (LoadI mem) mask));
6024
6025 ins_cost(125);
6026 format %{ "MOVZX $dst, $mem\t# int -> ubyte" %}
6027 ins_encode %{
6028 __ movzbl($dst$$Register, $mem$$Address);
6029 %}
6030 ins_pipe(ialu_reg_mem);
6031 %}
6032
6033 // Load Integer (32 bit signed) to Short (16 bit signed)
6034 instruct loadI2S(eRegI dst, memory mem, immI_16 sixteen) %{
6035 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
6036
6037 ins_cost(125);
6038 format %{ "MOVSX $dst, $mem\t# int -> short" %}
6039 ins_encode %{
6040 __ movswl($dst$$Register, $mem$$Address);
6041 %}
6042 ins_pipe(ialu_reg_mem);
6043 %}
6044
6045 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
6046 instruct loadI2US(eRegI dst, memory mem, immI_65535 mask) %{
6047 match(Set dst (AndI (LoadI mem) mask));
6048
6049 ins_cost(125);
6050 format %{ "MOVZX $dst, $mem\t# int -> ushort/char" %}
6051 ins_encode %{
6052 __ movzwl($dst$$Register, $mem$$Address);
6053 %}
6054 ins_pipe(ialu_reg_mem);
6055 %}
6056
6057 // Load Integer into Long Register
6058 instruct loadI2L(eRegL dst, memory mem, eFlagsReg cr) %{
6059 match(Set dst (ConvI2L (LoadI mem)));
6060 effect(KILL cr);
6061
6062 ins_cost(375);
6063 format %{ "MOV $dst.lo,$mem\t# int -> long\n\t"
6064 "MOV $dst.hi,$dst.lo\n\t"
6065 "SAR $dst.hi,31" %}
6066
6187
6188 instruct loadLX_reg_volatile(eRegL dst, memory mem, regD tmp) %{
6189 predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access());
6190 match(Set dst (LoadL mem));
6191 effect(TEMP tmp);
6192 ins_cost(160);
6193 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
6194 "MOVD $dst.lo,$tmp\n\t"
6195 "PSRLQ $tmp,32\n\t"
6196 "MOVD $dst.hi,$tmp" %}
6197 ins_encode %{
6198 __ movdbl($tmp$$XMMRegister, $mem$$Address);
6199 __ movdl($dst$$Register, $tmp$$XMMRegister);
6200 __ psrlq($tmp$$XMMRegister, 32);
6201 __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister);
6202 %}
6203 ins_pipe( pipe_slow );
6204 %}
6205
6206 // Load Range
6207 instruct loadRange(eRegI dst, memory mem) %{
6208 match(Set dst (LoadRange mem));
6209
6210 ins_cost(125);
6211 format %{ "MOV $dst,$mem" %}
6212 opcode(0x8B);
6213 ins_encode( OpcP, RegMem(dst,mem));
6214 ins_pipe( ialu_reg_mem );
6215 %}
6216
6217
6218 // Load Pointer
6219 instruct loadP(eRegP dst, memory mem) %{
6220 match(Set dst (LoadP mem));
6221
6222 ins_cost(125);
6223 format %{ "MOV $dst,$mem" %}
6224 opcode(0x8B);
6225 ins_encode( OpcP, RegMem(dst,mem));
6226 ins_pipe( ialu_reg_mem );
6227 %}
6284 ins_encode %{
6285 __ movflt ($dst$$XMMRegister, $mem$$Address);
6286 %}
6287 ins_pipe( pipe_slow );
6288 %}
6289
6290 // Load Float
6291 instruct loadFPR(regFPR dst, memory mem) %{
6292 predicate(UseSSE==0);
6293 match(Set dst (LoadF mem));
6294
6295 ins_cost(150);
6296 format %{ "FLD_S ST,$mem\n\t"
6297 "FSTP $dst" %}
6298 opcode(0xD9); /* D9 /0 */
6299 ins_encode( OpcP, RMopc_Mem(0x00,mem),
6300 Pop_Reg_FPR(dst) );
6301 ins_pipe( fpu_reg_mem );
6302 %}
6303
6304 // Load Aligned Packed Byte to XMM register
6305 instruct loadA8B(regD dst, memory mem) %{
6306 predicate(UseSSE>=1);
6307 match(Set dst (Load8B mem));
6308 ins_cost(125);
6309 format %{ "MOVQ $dst,$mem\t! packed8B" %}
6310 ins_encode %{
6311 __ movq($dst$$XMMRegister, $mem$$Address);
6312 %}
6313 ins_pipe( pipe_slow );
6314 %}
6315
6316 // Load Aligned Packed Short to XMM register
6317 instruct loadA4S(regD dst, memory mem) %{
6318 predicate(UseSSE>=1);
6319 match(Set dst (Load4S mem));
6320 ins_cost(125);
6321 format %{ "MOVQ $dst,$mem\t! packed4S" %}
6322 ins_encode %{
6323 __ movq($dst$$XMMRegister, $mem$$Address);
6324 %}
6325 ins_pipe( pipe_slow );
6326 %}
6327
6328 // Load Aligned Packed Char to XMM register
6329 instruct loadA4C(regD dst, memory mem) %{
6330 predicate(UseSSE>=1);
6331 match(Set dst (Load4C mem));
6332 ins_cost(125);
6333 format %{ "MOVQ $dst,$mem\t! packed4C" %}
6334 ins_encode %{
6335 __ movq($dst$$XMMRegister, $mem$$Address);
6336 %}
6337 ins_pipe( pipe_slow );
6338 %}
6339
6340 // Load Aligned Packed Integer to XMM register
6341 instruct load2IU(regD dst, memory mem) %{
6342 predicate(UseSSE>=1);
6343 match(Set dst (Load2I mem));
6344 ins_cost(125);
6345 format %{ "MOVQ $dst,$mem\t! packed2I" %}
6346 ins_encode %{
6347 __ movq($dst$$XMMRegister, $mem$$Address);
6348 %}
6349 ins_pipe( pipe_slow );
6350 %}
6351
6352 // Load Aligned Packed Single to XMM
6353 instruct loadA2F(regD dst, memory mem) %{
6354 predicate(UseSSE>=1);
6355 match(Set dst (Load2F mem));
6356 ins_cost(145);
6357 format %{ "MOVQ $dst,$mem\t! packed2F" %}
6358 ins_encode %{
6359 __ movq($dst$$XMMRegister, $mem$$Address);
6360 %}
6361 ins_pipe( pipe_slow );
6362 %}
6363
6364 // Load Effective Address
6365 instruct leaP8(eRegP dst, indOffset8 mem) %{
6366 match(Set dst mem);
6367
6368 ins_cost(110);
6369 format %{ "LEA $dst,$mem" %}
6370 opcode(0x8D);
6371 ins_encode( OpcP, RegMem(dst,mem));
6372 ins_pipe( ialu_reg_reg_fat );
6373 %}
6374
6375 instruct leaP32(eRegP dst, indOffset32 mem) %{
6376 match(Set dst mem);
6377
6378 ins_cost(110);
6379 format %{ "LEA $dst,$mem" %}
6380 opcode(0x8D);
6381 ins_encode( OpcP, RegMem(dst,mem));
6382 ins_pipe( ialu_reg_reg_fat );
6383 %}
6396 match(Set dst mem);
6397
6398 ins_cost(110);
6399 format %{ "LEA $dst,$mem" %}
6400 opcode(0x8D);
6401 ins_encode( OpcP, RegMem(dst,mem));
6402 ins_pipe( ialu_reg_reg_fat );
6403 %}
6404
6405 instruct leaPIdxScaleOff(eRegP dst, indIndexScaleOffset mem) %{
6406 match(Set dst mem);
6407
6408 ins_cost(110);
6409 format %{ "LEA $dst,$mem" %}
6410 opcode(0x8D);
6411 ins_encode( OpcP, RegMem(dst,mem));
6412 ins_pipe( ialu_reg_reg_fat );
6413 %}
6414
6415 // Load Constant
6416 instruct loadConI(eRegI dst, immI src) %{
6417 match(Set dst src);
6418
6419 format %{ "MOV $dst,$src" %}
6420 ins_encode( LdImmI(dst, src) );
6421 ins_pipe( ialu_reg_fat );
6422 %}
6423
6424 // Load Constant zero
6425 instruct loadConI0(eRegI dst, immI0 src, eFlagsReg cr) %{
6426 match(Set dst src);
6427 effect(KILL cr);
6428
6429 ins_cost(50);
6430 format %{ "XOR $dst,$dst" %}
6431 opcode(0x33); /* + rd */
6432 ins_encode( OpcP, RegReg( dst, dst ) );
6433 ins_pipe( ialu_reg );
6434 %}
6435
6436 instruct loadConP(eRegP dst, immP src) %{
6437 match(Set dst src);
6438
6439 format %{ "MOV $dst,$src" %}
6440 opcode(0xB8); /* + rd */
6441 ins_encode( LdImmP(dst, src) );
6442 ins_pipe( ialu_reg_fat );
6443 %}
6444
6445 instruct loadConL(eRegL dst, immL src, eFlagsReg cr) %{
6573 ins_cost(125);
6574 format %{ "MOVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
6575 ins_encode %{
6576 __ movdbl($dst$$XMMRegister, $constantaddress($con));
6577 %}
6578 ins_pipe(pipe_slow);
6579 %}
6580
6581 // The instruction usage is guarded by predicate in operand immD0().
6582 instruct loadConD0(regD dst, immD0 src) %{
6583 match(Set dst src);
6584 ins_cost(100);
6585 format %{ "XORPD $dst,$dst\t# double 0.0" %}
6586 ins_encode %{
6587 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
6588 %}
6589 ins_pipe( pipe_slow );
6590 %}
6591
6592 // Load Stack Slot
6593 instruct loadSSI(eRegI dst, stackSlotI src) %{
6594 match(Set dst src);
6595 ins_cost(125);
6596
6597 format %{ "MOV $dst,$src" %}
6598 opcode(0x8B);
6599 ins_encode( OpcP, RegMem(dst,src));
6600 ins_pipe( ialu_reg_mem );
6601 %}
6602
6603 instruct loadSSL(eRegL dst, stackSlotL src) %{
6604 match(Set dst src);
6605
6606 ins_cost(200);
6607 format %{ "MOV $dst,$src.lo\n\t"
6608 "MOV $dst+4,$src.hi" %}
6609 opcode(0x8B, 0x8B);
6610 ins_encode( OpcP, RegMem( dst, src ), OpcS, RegMem_Hi( dst, src ) );
6611 ins_pipe( ialu_mem_long_reg );
6612 %}
6613
6800 ins_encode %{
6801 __ prefetcht2($mem$$Address);
6802 %}
6803 ins_pipe(ialu_mem);
6804 %}
6805
6806 //----------Store Instructions-------------------------------------------------
6807
6808 // Store Byte
6809 instruct storeB(memory mem, xRegI src) %{
6810 match(Set mem (StoreB mem src));
6811
6812 ins_cost(125);
6813 format %{ "MOV8 $mem,$src" %}
6814 opcode(0x88);
6815 ins_encode( OpcP, RegMem( src, mem ) );
6816 ins_pipe( ialu_mem_reg );
6817 %}
6818
6819 // Store Char/Short
6820 instruct storeC(memory mem, eRegI src) %{
6821 match(Set mem (StoreC mem src));
6822
6823 ins_cost(125);
6824 format %{ "MOV16 $mem,$src" %}
6825 opcode(0x89, 0x66);
6826 ins_encode( OpcS, OpcP, RegMem( src, mem ) );
6827 ins_pipe( ialu_mem_reg );
6828 %}
6829
6830 // Store Integer
6831 instruct storeI(memory mem, eRegI src) %{
6832 match(Set mem (StoreI mem src));
6833
6834 ins_cost(125);
6835 format %{ "MOV $mem,$src" %}
6836 opcode(0x89);
6837 ins_encode( OpcP, RegMem( src, mem ) );
6838 ins_pipe( ialu_mem_reg );
6839 %}
6840
6841 // Store Long
6842 instruct storeL(long_memory mem, eRegL src) %{
6843 predicate(!((StoreLNode*)n)->require_atomic_access());
6844 match(Set mem (StoreL mem src));
6845
6846 ins_cost(200);
6847 format %{ "MOV $mem,$src.lo\n\t"
6848 "MOV $mem+4,$src.hi" %}
6849 opcode(0x89, 0x89);
6850 ins_encode( OpcP, RegMem( src, mem ), OpcS, RegMem_Hi( src, mem ) );
6851 ins_pipe( ialu_mem_long_reg );
6955 match(Set mem (StoreP mem src));
6956
6957 ins_cost(150);
6958 format %{ "MOV $mem,$src" %}
6959 opcode(0xC7); /* C7 /0 */
6960 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32( src ));
6961 ins_pipe( ialu_mem_imm );
6962 %}
6963
6964 // Store Byte Immediate
6965 instruct storeImmB(memory mem, immI8 src) %{
6966 match(Set mem (StoreB mem src));
6967
6968 ins_cost(150);
6969 format %{ "MOV8 $mem,$src" %}
6970 opcode(0xC6); /* C6 /0 */
6971 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src ));
6972 ins_pipe( ialu_mem_imm );
6973 %}
6974
6975 // Store Aligned Packed Byte XMM register to memory
6976 instruct storeA8B(memory mem, regD src) %{
6977 predicate(UseSSE>=1);
6978 match(Set mem (Store8B mem src));
6979 ins_cost(145);
6980 format %{ "MOVQ $mem,$src\t! packed8B" %}
6981 ins_encode %{
6982 __ movq($mem$$Address, $src$$XMMRegister);
6983 %}
6984 ins_pipe( pipe_slow );
6985 %}
6986
6987 // Store Aligned Packed Char/Short XMM register to memory
6988 instruct storeA4C(memory mem, regD src) %{
6989 predicate(UseSSE>=1);
6990 match(Set mem (Store4C mem src));
6991 ins_cost(145);
6992 format %{ "MOVQ $mem,$src\t! packed4C" %}
6993 ins_encode %{
6994 __ movq($mem$$Address, $src$$XMMRegister);
6995 %}
6996 ins_pipe( pipe_slow );
6997 %}
6998
6999 // Store Aligned Packed Integer XMM register to memory
7000 instruct storeA2I(memory mem, regD src) %{
7001 predicate(UseSSE>=1);
7002 match(Set mem (Store2I mem src));
7003 ins_cost(145);
7004 format %{ "MOVQ $mem,$src\t! packed2I" %}
7005 ins_encode %{
7006 __ movq($mem$$Address, $src$$XMMRegister);
7007 %}
7008 ins_pipe( pipe_slow );
7009 %}
7010
7011 // Store CMS card-mark Immediate
7012 instruct storeImmCM(memory mem, immI8 src) %{
7013 match(Set mem (StoreCM mem src));
7014
7015 ins_cost(150);
7016 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %}
7017 opcode(0xC6); /* C6 /0 */
7018 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src ));
7019 ins_pipe( ialu_mem_imm );
7020 %}
7021
7022 // Store Double
7023 instruct storeDPR( memory mem, regDPR1 src) %{
7024 predicate(UseSSE<=1);
7025 match(Set mem (StoreD mem src));
7026
7027 ins_cost(100);
7028 format %{ "FST_D $mem,$src" %}
7029 opcode(0xDD); /* DD /2 */
7030 ins_encode( enc_FPR_store(mem,src) );
7052 format %{ "MOVSD $mem,$src" %}
7053 ins_encode %{
7054 __ movdbl($mem$$Address, $src$$XMMRegister);
7055 %}
7056 ins_pipe( pipe_slow );
7057 %}
7058
7059 // Store XMM register to memory (single-precision floating point)
7060 // MOVSS instruction
7061 instruct storeF(memory mem, regF src) %{
7062 predicate(UseSSE>=1);
7063 match(Set mem (StoreF mem src));
7064 ins_cost(95);
7065 format %{ "MOVSS $mem,$src" %}
7066 ins_encode %{
7067 __ movflt($mem$$Address, $src$$XMMRegister);
7068 %}
7069 ins_pipe( pipe_slow );
7070 %}
7071
7072 // Store Aligned Packed Single Float XMM register to memory
7073 instruct storeA2F(memory mem, regD src) %{
7074 predicate(UseSSE>=1);
7075 match(Set mem (Store2F mem src));
7076 ins_cost(145);
7077 format %{ "MOVQ $mem,$src\t! packed2F" %}
7078 ins_encode %{
7079 __ movq($mem$$Address, $src$$XMMRegister);
7080 %}
7081 ins_pipe( pipe_slow );
7082 %}
7083
7084 // Store Float
7085 instruct storeFPR( memory mem, regFPR1 src) %{
7086 predicate(UseSSE==0);
7087 match(Set mem (StoreF mem src));
7088
7089 ins_cost(100);
7090 format %{ "FST_S $mem,$src" %}
7091 opcode(0xD9); /* D9 /2 */
7092 ins_encode( enc_FPR_store(mem,src) );
7093 ins_pipe( fpu_mem_reg );
7094 %}
7095
7096 // Store Float does rounding on x86
7097 instruct storeFPR_rounded( memory mem, regFPR1 src) %{
7098 predicate(UseSSE==0);
7099 match(Set mem (StoreF mem (RoundFloat src)));
7100
7101 ins_cost(100);
7102 format %{ "FST_S $mem,$src\t# round" %}
7103 opcode(0xD9); /* D9 /2 */
7125 ins_cost(50);
7126 format %{ "MOV $mem,$src\t# store float" %}
7127 opcode(0xC7); /* C7 /0 */
7128 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32FPR_as_bits( src ));
7129 ins_pipe( ialu_mem_imm );
7130 %}
7131
7132 // Store immediate Float value (it is faster than store from XMM register)
7133 // The instruction usage is guarded by predicate in operand immF().
7134 instruct storeF_imm( memory mem, immF src) %{
7135 match(Set mem (StoreF mem src));
7136
7137 ins_cost(50);
7138 format %{ "MOV $mem,$src\t# store float" %}
7139 opcode(0xC7); /* C7 /0 */
7140 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32F_as_bits( src ));
7141 ins_pipe( ialu_mem_imm );
7142 %}
7143
7144 // Store Integer to stack slot
7145 instruct storeSSI(stackSlotI dst, eRegI src) %{
7146 match(Set dst src);
7147
7148 ins_cost(100);
7149 format %{ "MOV $dst,$src" %}
7150 opcode(0x89);
7151 ins_encode( OpcPRegSS( dst, src ) );
7152 ins_pipe( ialu_mem_reg );
7153 %}
7154
7155 // Store Integer to stack slot
7156 instruct storeSSP(stackSlotP dst, eRegP src) %{
7157 match(Set dst src);
7158
7159 ins_cost(100);
7160 format %{ "MOV $dst,$src" %}
7161 opcode(0x89);
7162 ins_encode( OpcPRegSS( dst, src ) );
7163 ins_pipe( ialu_mem_reg );
7164 %}
7165
7250
7251 instruct membar_storestore() %{
7252 match(MemBarStoreStore);
7253 ins_cost(0);
7254
7255 size(0);
7256 format %{ "MEMBAR-storestore (empty encoding)" %}
7257 ins_encode( );
7258 ins_pipe(empty);
7259 %}
7260
7261 //----------Move Instructions--------------------------------------------------
7262 instruct castX2P(eAXRegP dst, eAXRegI src) %{
7263 match(Set dst (CastX2P src));
7264 format %{ "# X2P $dst, $src" %}
7265 ins_encode( /*empty encoding*/ );
7266 ins_cost(0);
7267 ins_pipe(empty);
7268 %}
7269
7270 instruct castP2X(eRegI dst, eRegP src ) %{
7271 match(Set dst (CastP2X src));
7272 ins_cost(50);
7273 format %{ "MOV $dst, $src\t# CastP2X" %}
7274 ins_encode( enc_Copy( dst, src) );
7275 ins_pipe( ialu_reg_reg );
7276 %}
7277
7278 //----------Conditional Move---------------------------------------------------
7279 // Conditional move
7280 instruct jmovI_reg(cmpOp cop, eFlagsReg cr, eRegI dst, eRegI src) %{
7281 predicate(!VM_Version::supports_cmov() );
7282 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7283 ins_cost(200);
7284 format %{ "J$cop,us skip\t# signed cmove\n\t"
7285 "MOV $dst,$src\n"
7286 "skip:" %}
7287 ins_encode %{
7288 Label Lskip;
7289 // Invert sense of branch from sense of CMOV
7290 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7291 __ movl($dst$$Register, $src$$Register);
7292 __ bind(Lskip);
7293 %}
7294 ins_pipe( pipe_cmov_reg );
7295 %}
7296
7297 instruct jmovI_regU(cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src) %{
7298 predicate(!VM_Version::supports_cmov() );
7299 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7300 ins_cost(200);
7301 format %{ "J$cop,us skip\t# unsigned cmove\n\t"
7302 "MOV $dst,$src\n"
7303 "skip:" %}
7304 ins_encode %{
7305 Label Lskip;
7306 // Invert sense of branch from sense of CMOV
7307 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7308 __ movl($dst$$Register, $src$$Register);
7309 __ bind(Lskip);
7310 %}
7311 ins_pipe( pipe_cmov_reg );
7312 %}
7313
7314 instruct cmovI_reg(eRegI dst, eRegI src, eFlagsReg cr, cmpOp cop ) %{
7315 predicate(VM_Version::supports_cmov() );
7316 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7317 ins_cost(200);
7318 format %{ "CMOV$cop $dst,$src" %}
7319 opcode(0x0F,0x40);
7320 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
7321 ins_pipe( pipe_cmov_reg );
7322 %}
7323
7324 instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{
7325 predicate(VM_Version::supports_cmov() );
7326 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7327 ins_cost(200);
7328 format %{ "CMOV$cop $dst,$src" %}
7329 opcode(0x0F,0x40);
7330 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
7331 ins_pipe( pipe_cmov_reg );
7332 %}
7333
7334 instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{
7335 predicate(VM_Version::supports_cmov() );
7336 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7337 ins_cost(200);
7338 expand %{
7339 cmovI_regU(cop, cr, dst, src);
7340 %}
7341 %}
7342
7343 // Conditional move
7344 instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
7345 predicate(VM_Version::supports_cmov() );
7346 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7347 ins_cost(250);
7348 format %{ "CMOV$cop $dst,$src" %}
7349 opcode(0x0F,0x40);
7350 ins_encode( enc_cmov(cop), RegMem( dst, src ) );
7351 ins_pipe( pipe_cmov_mem );
7352 %}
7353
7354 // Conditional move
7355 instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
7356 predicate(VM_Version::supports_cmov() );
7357 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7358 ins_cost(250);
7359 format %{ "CMOV$cop $dst,$src" %}
7360 opcode(0x0F,0x40);
7361 ins_encode( enc_cmov(cop), RegMem( dst, src ) );
7362 ins_pipe( pipe_cmov_mem );
7363 %}
7364
7365 instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{
7366 predicate(VM_Version::supports_cmov() );
7367 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7368 ins_cost(250);
7369 expand %{
7370 cmovI_memU(cop, cr, dst, src);
7371 %}
7372 %}
7373
7374 // Conditional move
7375 instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
7376 predicate(VM_Version::supports_cmov() );
7377 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7378 ins_cost(200);
7379 format %{ "CMOV$cop $dst,$src\t# ptr" %}
7380 opcode(0x0F,0x40);
7381 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
7382 ins_pipe( pipe_cmov_reg );
7383 %}
7384
7385 // Conditional move (non-P6 version)
7599 ins_cost(200);
7600 format %{ "CMOV$cop $dst.lo,$src.lo\n\t"
7601 "CMOV$cop $dst.hi,$src.hi" %}
7602 opcode(0x0F,0x40);
7603 ins_encode( enc_cmov(cop), RegReg_Lo2( dst, src ), enc_cmov(cop), RegReg_Hi2( dst, src ) );
7604 ins_pipe( pipe_cmov_reg_long );
7605 %}
7606
7607 instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
7608 predicate(VM_Version::supports_cmov() );
7609 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7610 ins_cost(200);
7611 expand %{
7612 cmovL_regU(cop, cr, dst, src);
7613 %}
7614 %}
7615
7616 //----------Arithmetic Instructions--------------------------------------------
7617 //----------Addition Instructions----------------------------------------------
7618 // Integer Addition Instructions
7619 instruct addI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
7620 match(Set dst (AddI dst src));
7621 effect(KILL cr);
7622
7623 size(2);
7624 format %{ "ADD $dst,$src" %}
7625 opcode(0x03);
7626 ins_encode( OpcP, RegReg( dst, src) );
7627 ins_pipe( ialu_reg_reg );
7628 %}
7629
7630 instruct addI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
7631 match(Set dst (AddI dst src));
7632 effect(KILL cr);
7633
7634 format %{ "ADD $dst,$src" %}
7635 opcode(0x81, 0x00); /* /0 id */
7636 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
7637 ins_pipe( ialu_reg );
7638 %}
7639
7640 instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
7641 predicate(UseIncDec);
7642 match(Set dst (AddI dst src));
7643 effect(KILL cr);
7644
7645 size(1);
7646 format %{ "INC $dst" %}
7647 opcode(0x40); /* */
7648 ins_encode( Opc_plus( primary, dst ) );
7649 ins_pipe( ialu_reg );
7650 %}
7651
7652 instruct leaI_eReg_immI(eRegI dst, eRegI src0, immI src1) %{
7653 match(Set dst (AddI src0 src1));
7654 ins_cost(110);
7655
7656 format %{ "LEA $dst,[$src0 + $src1]" %}
7657 opcode(0x8D); /* 0x8D /r */
7658 ins_encode( OpcP, RegLea( dst, src0, src1 ) );
7659 ins_pipe( ialu_reg_reg );
7660 %}
7661
7662 instruct leaP_eReg_immI(eRegP dst, eRegP src0, immI src1) %{
7663 match(Set dst (AddP src0 src1));
7664 ins_cost(110);
7665
7666 format %{ "LEA $dst,[$src0 + $src1]\t# ptr" %}
7667 opcode(0x8D); /* 0x8D /r */
7668 ins_encode( OpcP, RegLea( dst, src0, src1 ) );
7669 ins_pipe( ialu_reg_reg );
7670 %}
7671
7672 instruct decI_eReg(eRegI dst, immI_M1 src, eFlagsReg cr) %{
7673 predicate(UseIncDec);
7674 match(Set dst (AddI dst src));
7675 effect(KILL cr);
7676
7677 size(1);
7678 format %{ "DEC $dst" %}
7679 opcode(0x48); /* */
7680 ins_encode( Opc_plus( primary, dst ) );
7681 ins_pipe( ialu_reg );
7682 %}
7683
7684 instruct addP_eReg(eRegP dst, eRegI src, eFlagsReg cr) %{
7685 match(Set dst (AddP dst src));
7686 effect(KILL cr);
7687
7688 size(2);
7689 format %{ "ADD $dst,$src" %}
7690 opcode(0x03);
7691 ins_encode( OpcP, RegReg( dst, src) );
7692 ins_pipe( ialu_reg_reg );
7693 %}
7694
7695 instruct addP_eReg_imm(eRegP dst, immI src, eFlagsReg cr) %{
7696 match(Set dst (AddP dst src));
7697 effect(KILL cr);
7698
7699 format %{ "ADD $dst,$src" %}
7700 opcode(0x81,0x00); /* Opcode 81 /0 id */
7701 // ins_encode( RegImm( dst, src) );
7702 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
7703 ins_pipe( ialu_reg );
7704 %}
7705
7706 instruct addI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
7707 match(Set dst (AddI dst (LoadI src)));
7708 effect(KILL cr);
7709
7710 ins_cost(125);
7711 format %{ "ADD $dst,$src" %}
7712 opcode(0x03);
7713 ins_encode( OpcP, RegMem( dst, src) );
7714 ins_pipe( ialu_reg_mem );
7715 %}
7716
7717 instruct addI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
7718 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7719 effect(KILL cr);
7720
7721 ins_cost(150);
7722 format %{ "ADD $dst,$src" %}
7723 opcode(0x01); /* Opcode 01 /r */
7724 ins_encode( OpcP, RegMem( src, dst ) );
7725 ins_pipe( ialu_mem_reg );
7726 %}
7727
7728 // Add Memory with Immediate
7729 instruct addI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
7730 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7731 effect(KILL cr);
7732
7733 ins_cost(125);
7734 format %{ "ADD $dst,$src" %}
7735 opcode(0x81); /* Opcode 81 /0 id */
7736 ins_encode( OpcSE( src ), RMopc_Mem(0x00,dst), Con8or32( src ) );
7737 ins_pipe( ialu_mem_imm );
7759 ins_pipe( ialu_mem_imm );
7760 %}
7761
7762
7763 instruct checkCastPP( eRegP dst ) %{
7764 match(Set dst (CheckCastPP dst));
7765
7766 size(0);
7767 format %{ "#checkcastPP of $dst" %}
7768 ins_encode( /*empty encoding*/ );
7769 ins_pipe( empty );
7770 %}
7771
7772 instruct castPP( eRegP dst ) %{
7773 match(Set dst (CastPP dst));
7774 format %{ "#castPP of $dst" %}
7775 ins_encode( /*empty encoding*/ );
7776 ins_pipe( empty );
7777 %}
7778
7779 instruct castII( eRegI dst ) %{
7780 match(Set dst (CastII dst));
7781 format %{ "#castII of $dst" %}
7782 ins_encode( /*empty encoding*/ );
7783 ins_cost(0);
7784 ins_pipe( empty );
7785 %}
7786
7787
7788 // Load-locked - same as a regular pointer load when used with compare-swap
7789 instruct loadPLocked(eRegP dst, memory mem) %{
7790 match(Set dst (LoadPLocked mem));
7791
7792 ins_cost(125);
7793 format %{ "MOV $dst,$mem\t# Load ptr. locked" %}
7794 opcode(0x8B);
7795 ins_encode( OpcP, RegMem(dst,mem));
7796 ins_pipe( ialu_reg_mem );
7797 %}
7798
7799 // LoadLong-locked - same as a volatile long load when used with compare-swap
7837 __ psrlq($tmp$$XMMRegister, 32);
7838 __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister);
7839 %}
7840 ins_pipe( pipe_slow );
7841 %}
7842
7843 // Conditional-store of the updated heap-top.
7844 // Used during allocation of the shared heap.
7845 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
7846 instruct storePConditional( memory heap_top_ptr, eAXRegP oldval, eRegP newval, eFlagsReg cr ) %{
7847 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
7848 // EAX is killed if there is contention, but then it's also unused.
7849 // In the common case of no contention, EAX holds the new oop address.
7850 format %{ "CMPXCHG $heap_top_ptr,$newval\t# If EAX==$heap_top_ptr Then store $newval into $heap_top_ptr" %}
7851 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval,heap_top_ptr) );
7852 ins_pipe( pipe_cmpxchg );
7853 %}
7854
7855 // Conditional-store of an int value.
7856 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
7857 instruct storeIConditional( memory mem, eAXRegI oldval, eRegI newval, eFlagsReg cr ) %{
7858 match(Set cr (StoreIConditional mem (Binary oldval newval)));
7859 effect(KILL oldval);
7860 format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
7861 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) );
7862 ins_pipe( pipe_cmpxchg );
7863 %}
7864
7865 // Conditional-store of a long value.
7866 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel.
7867 instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
7868 match(Set cr (StoreLConditional mem (Binary oldval newval)));
7869 effect(KILL oldval);
7870 format %{ "XCHG EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t"
7871 "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t"
7872 "XCHG EBX,ECX"
7873 %}
7874 ins_encode %{
7875 // Note: we need to swap rbx, and rcx before and after the
7876 // cmpxchg8 instruction because the instruction uses
7877 // rcx as the high order word of the new value to store but
7878 // our register encoding uses rbx.
7879 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
7880 if( os::is_MP() )
7881 __ lock();
7882 __ cmpxchg8($mem$$Address);
7883 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
7884 %}
7885 ins_pipe( pipe_cmpxchg );
7886 %}
7887
7888 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7889
7890 instruct compareAndSwapL( eRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
7891 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7892 effect(KILL cr, KILL oldval);
7893 format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
7894 "MOV $res,0\n\t"
7895 "JNE,s fail\n\t"
7896 "MOV $res,1\n"
7897 "fail:" %}
7898 ins_encode( enc_cmpxchg8(mem_ptr),
7899 enc_flags_ne_to_boolean(res) );
7900 ins_pipe( pipe_cmpxchg );
7901 %}
7902
7903 instruct compareAndSwapP( eRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{
7904 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7905 effect(KILL cr, KILL oldval);
7906 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
7907 "MOV $res,0\n\t"
7908 "JNE,s fail\n\t"
7909 "MOV $res,1\n"
7910 "fail:" %}
7911 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) );
7912 ins_pipe( pipe_cmpxchg );
7913 %}
7914
7915 instruct compareAndSwapI( eRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
7916 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
7917 effect(KILL cr, KILL oldval);
7918 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
7919 "MOV $res,0\n\t"
7920 "JNE,s fail\n\t"
7921 "MOV $res,1\n"
7922 "fail:" %}
7923 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) );
7924 ins_pipe( pipe_cmpxchg );
7925 %}
7926
7927 //----------Subtraction Instructions-------------------------------------------
7928 // Integer Subtraction Instructions
7929 instruct subI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
7930 match(Set dst (SubI dst src));
7931 effect(KILL cr);
7932
7933 size(2);
7934 format %{ "SUB $dst,$src" %}
7935 opcode(0x2B);
7936 ins_encode( OpcP, RegReg( dst, src) );
7937 ins_pipe( ialu_reg_reg );
7938 %}
7939
7940 instruct subI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
7941 match(Set dst (SubI dst src));
7942 effect(KILL cr);
7943
7944 format %{ "SUB $dst,$src" %}
7945 opcode(0x81,0x05); /* Opcode 81 /5 */
7946 // ins_encode( RegImm( dst, src) );
7947 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
7948 ins_pipe( ialu_reg );
7949 %}
7950
7951 instruct subI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
7952 match(Set dst (SubI dst (LoadI src)));
7953 effect(KILL cr);
7954
7955 ins_cost(125);
7956 format %{ "SUB $dst,$src" %}
7957 opcode(0x2B);
7958 ins_encode( OpcP, RegMem( dst, src) );
7959 ins_pipe( ialu_reg_mem );
7960 %}
7961
7962 instruct subI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
7963 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
7964 effect(KILL cr);
7965
7966 ins_cost(150);
7967 format %{ "SUB $dst,$src" %}
7968 opcode(0x29); /* Opcode 29 /r */
7969 ins_encode( OpcP, RegMem( src, dst ) );
7970 ins_pipe( ialu_mem_reg );
7971 %}
7972
7973 // Subtract from a pointer
7974 instruct subP_eReg(eRegP dst, eRegI src, immI0 zero, eFlagsReg cr) %{
7975 match(Set dst (AddP dst (SubI zero src)));
7976 effect(KILL cr);
7977
7978 size(2);
7979 format %{ "SUB $dst,$src" %}
7980 opcode(0x2B);
7981 ins_encode( OpcP, RegReg( dst, src) );
7982 ins_pipe( ialu_reg_reg );
7983 %}
7984
7985 instruct negI_eReg(eRegI dst, immI0 zero, eFlagsReg cr) %{
7986 match(Set dst (SubI zero dst));
7987 effect(KILL cr);
7988
7989 size(2);
7990 format %{ "NEG $dst" %}
7991 opcode(0xF7,0x03); // Opcode F7 /3
7992 ins_encode( OpcP, RegOpc( dst ) );
7993 ins_pipe( ialu_reg );
7994 %}
7995
7996
7997 //----------Multiplication/Division Instructions-------------------------------
7998 // Integer Multiplication Instructions
7999 // Multiply Register
8000 instruct mulI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
8001 match(Set dst (MulI dst src));
8002 effect(KILL cr);
8003
8004 size(3);
8005 ins_cost(300);
8006 format %{ "IMUL $dst,$src" %}
8007 opcode(0xAF, 0x0F);
8008 ins_encode( OpcS, OpcP, RegReg( dst, src) );
8009 ins_pipe( ialu_reg_reg_alu0 );
8010 %}
8011
8012 // Multiply 32-bit Immediate
8013 instruct mulI_eReg_imm(eRegI dst, eRegI src, immI imm, eFlagsReg cr) %{
8014 match(Set dst (MulI src imm));
8015 effect(KILL cr);
8016
8017 ins_cost(300);
8018 format %{ "IMUL $dst,$src,$imm" %}
8019 opcode(0x69); /* 69 /r id */
8020 ins_encode( OpcSE(imm), RegReg( dst, src ), Con8or32( imm ) );
8021 ins_pipe( ialu_reg_reg_alu0 );
8022 %}
8023
8024 instruct loadConL_low_only(eADXRegL_low_only dst, immL32 src, eFlagsReg cr) %{
8025 match(Set dst src);
8026 effect(KILL cr);
8027
8028 // Note that this is artificially increased to make it more expensive than loadConL
8029 ins_cost(250);
8030 format %{ "MOV EAX,$src\t// low word only" %}
8031 opcode(0xB8);
8032 ins_encode( LdImmL_Lo(dst, src) );
8033 ins_pipe( ialu_reg_fat );
8049 ins_pipe( pipe_slow );
8050 %}
8051
8052 // Multiply by 32-bit Immediate, taking the shifted high order results
8053 instruct mulI_imm_RShift_high(eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32_63 cnt, eFlagsReg cr) %{
8054 match(Set dst (ConvL2I (RShiftL (MulL (ConvI2L src1) src2) cnt)));
8055 predicate( _kids[0]->_kids[0]->_kids[1]->_leaf->Opcode() == Op_ConL &&
8056 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() >= min_jint &&
8057 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() <= max_jint );
8058 effect(USE src1, KILL cr);
8059
8060 // Note that this is adjusted by 150 to compensate for the overcosting of loadConL_low_only
8061 ins_cost(1*100 + 1*400 - 150);
8062 format %{ "IMUL EDX:EAX,$src1\n\t"
8063 "SAR EDX,$cnt-32" %}
8064 ins_encode( multiply_con_and_shift_high( dst, src1, src2, cnt, cr ) );
8065 ins_pipe( pipe_slow );
8066 %}
8067
8068 // Multiply Memory 32-bit Immediate
8069 instruct mulI_mem_imm(eRegI dst, memory src, immI imm, eFlagsReg cr) %{
8070 match(Set dst (MulI (LoadI src) imm));
8071 effect(KILL cr);
8072
8073 ins_cost(300);
8074 format %{ "IMUL $dst,$src,$imm" %}
8075 opcode(0x69); /* 69 /r id */
8076 ins_encode( OpcSE(imm), RegMem( dst, src ), Con8or32( imm ) );
8077 ins_pipe( ialu_reg_mem_alu0 );
8078 %}
8079
8080 // Multiply Memory
8081 instruct mulI(eRegI dst, memory src, eFlagsReg cr) %{
8082 match(Set dst (MulI dst (LoadI src)));
8083 effect(KILL cr);
8084
8085 ins_cost(350);
8086 format %{ "IMUL $dst,$src" %}
8087 opcode(0xAF, 0x0F);
8088 ins_encode( OpcS, OpcP, RegMem( dst, src) );
8089 ins_pipe( ialu_reg_mem_alu0 );
8090 %}
8091
8092 // Multiply Register Int to Long
8093 instruct mulI2L(eADXRegL dst, eAXRegI src, nadxRegI src1, eFlagsReg flags) %{
8094 // Basic Idea: long = (long)int * (long)int
8095 match(Set dst (MulL (ConvI2L src) (ConvI2L src1)));
8096 effect(DEF dst, USE src, USE src1, KILL flags);
8097
8098 ins_cost(300);
8099 format %{ "IMUL $dst,$src1" %}
8100
8101 ins_encode( long_int_multiply( dst, src1 ) );
8102 ins_pipe( ialu_reg_reg_alu0 );
8103 %}
8104
8105 instruct mulIS_eReg(eADXRegL dst, immL_32bits mask, eFlagsReg flags, eAXRegI src, nadxRegI src1) %{
8106 // Basic Idea: long = (int & 0xffffffffL) * (int & 0xffffffffL)
8107 match(Set dst (MulL (AndL (ConvI2L src) mask) (AndL (ConvI2L src1) mask)));
8108 effect(KILL flags);
8109
8110 ins_cost(300);
8111 format %{ "MUL $dst,$src1" %}
8112
8113 ins_encode( long_uint_multiply(dst, src1) );
8114 ins_pipe( ialu_reg_reg_alu0 );
8115 %}
8116
8117 // Multiply Register Long
8118 instruct mulL_eReg(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
8119 match(Set dst (MulL dst src));
8120 effect(KILL cr, TEMP tmp);
8121 ins_cost(4*100+3*400);
8122 // Basic idea: lo(result) = lo(x_lo * y_lo)
8123 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi)
8124 format %{ "MOV $tmp,$src.lo\n\t"
8125 "IMUL $tmp,EDX\n\t"
8126 "MOV EDX,$src.hi\n\t"
8127 "IMUL EDX,EAX\n\t"
8128 "ADD $tmp,EDX\n\t"
8129 "MUL EDX:EAX,$src.lo\n\t"
8130 "ADD EDX,$tmp" %}
8131 ins_encode( long_multiply( dst, src, tmp ) );
8132 ins_pipe( pipe_slow );
8133 %}
8134
8135 // Multiply Register Long where the left operand's high 32 bits are zero
8136 instruct mulL_eReg_lhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
8137 predicate(is_operand_hi32_zero(n->in(1)));
8138 match(Set dst (MulL dst src));
8139 effect(KILL cr, TEMP tmp);
8140 ins_cost(2*100+2*400);
8141 // Basic idea: lo(result) = lo(x_lo * y_lo)
8142 // hi(result) = hi(x_lo * y_lo) + lo(x_lo * y_hi) where lo(x_hi * y_lo) = 0 because x_hi = 0
8143 format %{ "MOV $tmp,$src.hi\n\t"
8144 "IMUL $tmp,EAX\n\t"
8145 "MUL EDX:EAX,$src.lo\n\t"
8146 "ADD EDX,$tmp" %}
8147 ins_encode %{
8148 __ movl($tmp$$Register, HIGH_FROM_LOW($src$$Register));
8149 __ imull($tmp$$Register, rax);
8150 __ mull($src$$Register);
8151 __ addl(rdx, $tmp$$Register);
8152 %}
8153 ins_pipe( pipe_slow );
8154 %}
8155
8156 // Multiply Register Long where the right operand's high 32 bits are zero
8157 instruct mulL_eReg_rhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
8158 predicate(is_operand_hi32_zero(n->in(2)));
8159 match(Set dst (MulL dst src));
8160 effect(KILL cr, TEMP tmp);
8161 ins_cost(2*100+2*400);
8162 // Basic idea: lo(result) = lo(x_lo * y_lo)
8163 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) where lo(x_lo * y_hi) = 0 because y_hi = 0
8164 format %{ "MOV $tmp,$src.lo\n\t"
8165 "IMUL $tmp,EDX\n\t"
8166 "MUL EDX:EAX,$src.lo\n\t"
8167 "ADD EDX,$tmp" %}
8168 ins_encode %{
8169 __ movl($tmp$$Register, $src$$Register);
8170 __ imull($tmp$$Register, rdx);
8171 __ mull($src$$Register);
8172 __ addl(rdx, $tmp$$Register);
8173 %}
8174 ins_pipe( pipe_slow );
8175 %}
8176
8177 // Multiply Register Long where the left and the right operands' high 32 bits are zero
8178 instruct mulL_eReg_hi0(eADXRegL dst, eRegL src, eFlagsReg cr) %{
8179 predicate(is_operand_hi32_zero(n->in(1)) && is_operand_hi32_zero(n->in(2)));
8180 match(Set dst (MulL dst src));
8181 effect(KILL cr);
8182 ins_cost(1*400);
8183 // Basic idea: lo(result) = lo(x_lo * y_lo)
8184 // hi(result) = hi(x_lo * y_lo) where lo(x_hi * y_lo) = 0 and lo(x_lo * y_hi) = 0 because x_hi = 0 and y_hi = 0
8185 format %{ "MUL EDX:EAX,$src.lo\n\t" %}
8186 ins_encode %{
8187 __ mull($src$$Register);
8188 %}
8189 ins_pipe( pipe_slow );
8190 %}
8191
8192 // Multiply Register Long by small constant
8193 instruct mulL_eReg_con(eADXRegL dst, immL_127 src, eRegI tmp, eFlagsReg cr) %{
8194 match(Set dst (MulL dst src));
8195 effect(KILL cr, TEMP tmp);
8196 ins_cost(2*100+2*400);
8197 size(12);
8198 // Basic idea: lo(result) = lo(src * EAX)
8199 // hi(result) = hi(src * EAX) + lo(src * EDX)
8200 format %{ "IMUL $tmp,EDX,$src\n\t"
8201 "MOV EDX,$src\n\t"
8202 "MUL EDX\t# EDX*EAX -> EDX:EAX\n\t"
8203 "ADD EDX,$tmp" %}
8204 ins_encode( long_multiply_con( dst, src, tmp ) );
8205 ins_pipe( pipe_slow );
8206 %}
8207
8208 // Integer DIV with Register
8209 instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{
8210 match(Set rax (DivI rax div));
8211 effect(KILL rdx, KILL cr);
8212 size(26);
8213 ins_cost(30*100+10*100);
8271 ins_encode( cdq_enc, OpcP, RegOpc(div) );
8272 ins_pipe( ialu_reg_reg_alu0 );
8273 %}
8274
8275 // Remainder Register Long
8276 instruct modL_eReg( eADXRegL dst, eRegL src1, eRegL src2, eFlagsReg cr, eCXRegI cx, eBXRegI bx ) %{
8277 match(Set dst (ModL src1 src2));
8278 effect( KILL cr, KILL cx, KILL bx );
8279 ins_cost(10000);
8280 format %{ "PUSH $src1.hi\n\t"
8281 "PUSH $src1.lo\n\t"
8282 "PUSH $src2.hi\n\t"
8283 "PUSH $src2.lo\n\t"
8284 "CALL SharedRuntime::lrem\n\t"
8285 "ADD ESP,16" %}
8286 ins_encode( long_mod(src1,src2) );
8287 ins_pipe( pipe_slow );
8288 %}
8289
8290 // Divide Register Long (no special case since divisor != -1)
8291 instruct divL_eReg_imm32( eADXRegL dst, immL32 imm, eRegI tmp, eRegI tmp2, eFlagsReg cr ) %{
8292 match(Set dst (DivL dst imm));
8293 effect( TEMP tmp, TEMP tmp2, KILL cr );
8294 ins_cost(1000);
8295 format %{ "MOV $tmp,abs($imm) # ldiv EDX:EAX,$imm\n\t"
8296 "XOR $tmp2,$tmp2\n\t"
8297 "CMP $tmp,EDX\n\t"
8298 "JA,s fast\n\t"
8299 "MOV $tmp2,EAX\n\t"
8300 "MOV EAX,EDX\n\t"
8301 "MOV EDX,0\n\t"
8302 "JLE,s pos\n\t"
8303 "LNEG EAX : $tmp2\n\t"
8304 "DIV $tmp # unsigned division\n\t"
8305 "XCHG EAX,$tmp2\n\t"
8306 "DIV $tmp\n\t"
8307 "LNEG $tmp2 : EAX\n\t"
8308 "JMP,s done\n"
8309 "pos:\n\t"
8310 "DIV $tmp\n\t"
8311 "XCHG EAX,$tmp2\n"
8342
8343 __ bind(Lpos);
8344 __ divl($tmp$$Register); // Use unsigned division
8345 __ xchgl($dst$$Register, $tmp2$$Register);
8346 // Fallthrow for final divide, tmp2 has 32 bit hi result
8347
8348 __ bind(Lfast);
8349 // fast path: src is positive
8350 __ divl($tmp$$Register); // Use unsigned division
8351
8352 __ bind(Ldone);
8353 __ movl(HIGH_FROM_LOW($dst$$Register),$tmp2$$Register);
8354 if (con < 0) {
8355 __ lneg(HIGH_FROM_LOW($dst$$Register), $dst$$Register);
8356 }
8357 %}
8358 ins_pipe( pipe_slow );
8359 %}
8360
8361 // Remainder Register Long (remainder fit into 32 bits)
8362 instruct modL_eReg_imm32( eADXRegL dst, immL32 imm, eRegI tmp, eRegI tmp2, eFlagsReg cr ) %{
8363 match(Set dst (ModL dst imm));
8364 effect( TEMP tmp, TEMP tmp2, KILL cr );
8365 ins_cost(1000);
8366 format %{ "MOV $tmp,abs($imm) # lrem EDX:EAX,$imm\n\t"
8367 "CMP $tmp,EDX\n\t"
8368 "JA,s fast\n\t"
8369 "MOV $tmp2,EAX\n\t"
8370 "MOV EAX,EDX\n\t"
8371 "MOV EDX,0\n\t"
8372 "JLE,s pos\n\t"
8373 "LNEG EAX : $tmp2\n\t"
8374 "DIV $tmp # unsigned division\n\t"
8375 "MOV EAX,$tmp2\n\t"
8376 "DIV $tmp\n\t"
8377 "NEG EDX\n\t"
8378 "JMP,s done\n"
8379 "pos:\n\t"
8380 "DIV $tmp\n\t"
8381 "MOV EAX,$tmp2\n"
8382 "fast:\n\t"
8410 __ jmpb(Ldone);
8411
8412 __ bind(Lpos);
8413 __ divl($tmp$$Register);
8414 __ movl($dst$$Register, $tmp2$$Register);
8415
8416 __ bind(Lfast);
8417 // fast path: src is positive
8418 __ divl($tmp$$Register);
8419
8420 __ bind(Ldone);
8421 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
8422 __ sarl(HIGH_FROM_LOW($dst$$Register), 31); // result sign
8423
8424 %}
8425 ins_pipe( pipe_slow );
8426 %}
8427
8428 // Integer Shift Instructions
8429 // Shift Left by one
8430 instruct shlI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{
8431 match(Set dst (LShiftI dst shift));
8432 effect(KILL cr);
8433
8434 size(2);
8435 format %{ "SHL $dst,$shift" %}
8436 opcode(0xD1, 0x4); /* D1 /4 */
8437 ins_encode( OpcP, RegOpc( dst ) );
8438 ins_pipe( ialu_reg );
8439 %}
8440
8441 // Shift Left by 8-bit immediate
8442 instruct salI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
8443 match(Set dst (LShiftI dst shift));
8444 effect(KILL cr);
8445
8446 size(3);
8447 format %{ "SHL $dst,$shift" %}
8448 opcode(0xC1, 0x4); /* C1 /4 ib */
8449 ins_encode( RegOpcImm( dst, shift) );
8450 ins_pipe( ialu_reg );
8451 %}
8452
8453 // Shift Left by variable
8454 instruct salI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{
8455 match(Set dst (LShiftI dst shift));
8456 effect(KILL cr);
8457
8458 size(2);
8459 format %{ "SHL $dst,$shift" %}
8460 opcode(0xD3, 0x4); /* D3 /4 */
8461 ins_encode( OpcP, RegOpc( dst ) );
8462 ins_pipe( ialu_reg_reg );
8463 %}
8464
8465 // Arithmetic shift right by one
8466 instruct sarI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{
8467 match(Set dst (RShiftI dst shift));
8468 effect(KILL cr);
8469
8470 size(2);
8471 format %{ "SAR $dst,$shift" %}
8472 opcode(0xD1, 0x7); /* D1 /7 */
8473 ins_encode( OpcP, RegOpc( dst ) );
8474 ins_pipe( ialu_reg );
8475 %}
8476
8477 // Arithmetic shift right by one
8478 instruct sarI_mem_1(memory dst, immI1 shift, eFlagsReg cr) %{
8479 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8480 effect(KILL cr);
8481 format %{ "SAR $dst,$shift" %}
8482 opcode(0xD1, 0x7); /* D1 /7 */
8483 ins_encode( OpcP, RMopc_Mem(secondary,dst) );
8484 ins_pipe( ialu_mem_imm );
8485 %}
8486
8487 // Arithmetic Shift Right by 8-bit immediate
8488 instruct sarI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
8489 match(Set dst (RShiftI dst shift));
8490 effect(KILL cr);
8491
8492 size(3);
8493 format %{ "SAR $dst,$shift" %}
8494 opcode(0xC1, 0x7); /* C1 /7 ib */
8495 ins_encode( RegOpcImm( dst, shift ) );
8496 ins_pipe( ialu_mem_imm );
8497 %}
8498
8499 // Arithmetic Shift Right by 8-bit immediate
8500 instruct sarI_mem_imm(memory dst, immI8 shift, eFlagsReg cr) %{
8501 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8502 effect(KILL cr);
8503
8504 format %{ "SAR $dst,$shift" %}
8505 opcode(0xC1, 0x7); /* C1 /7 ib */
8506 ins_encode( OpcP, RMopc_Mem(secondary, dst ), Con8or32( shift ) );
8507 ins_pipe( ialu_mem_imm );
8508 %}
8509
8510 // Arithmetic Shift Right by variable
8511 instruct sarI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{
8512 match(Set dst (RShiftI dst shift));
8513 effect(KILL cr);
8514
8515 size(2);
8516 format %{ "SAR $dst,$shift" %}
8517 opcode(0xD3, 0x7); /* D3 /7 */
8518 ins_encode( OpcP, RegOpc( dst ) );
8519 ins_pipe( ialu_reg_reg );
8520 %}
8521
8522 // Logical shift right by one
8523 instruct shrI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{
8524 match(Set dst (URShiftI dst shift));
8525 effect(KILL cr);
8526
8527 size(2);
8528 format %{ "SHR $dst,$shift" %}
8529 opcode(0xD1, 0x5); /* D1 /5 */
8530 ins_encode( OpcP, RegOpc( dst ) );
8531 ins_pipe( ialu_reg );
8532 %}
8533
8534 // Logical Shift Right by 8-bit immediate
8535 instruct shrI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
8536 match(Set dst (URShiftI dst shift));
8537 effect(KILL cr);
8538
8539 size(3);
8540 format %{ "SHR $dst,$shift" %}
8541 opcode(0xC1, 0x5); /* C1 /5 ib */
8542 ins_encode( RegOpcImm( dst, shift) );
8543 ins_pipe( ialu_reg );
8544 %}
8545
8546
8547 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
8548 // This idiom is used by the compiler for the i2b bytecode.
8549 instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour) %{
8550 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
8551
8552 size(3);
8553 format %{ "MOVSX $dst,$src :8" %}
8554 ins_encode %{
8555 __ movsbl($dst$$Register, $src$$Register);
8556 %}
8557 ins_pipe(ialu_reg_reg);
8558 %}
8559
8560 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
8561 // This idiom is used by the compiler the i2s bytecode.
8562 instruct i2s(eRegI dst, xRegI src, immI_16 sixteen) %{
8563 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
8564
8565 size(3);
8566 format %{ "MOVSX $dst,$src :16" %}
8567 ins_encode %{
8568 __ movswl($dst$$Register, $src$$Register);
8569 %}
8570 ins_pipe(ialu_reg_reg);
8571 %}
8572
8573
8574 // Logical Shift Right by variable
8575 instruct shrI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{
8576 match(Set dst (URShiftI dst shift));
8577 effect(KILL cr);
8578
8579 size(2);
8580 format %{ "SHR $dst,$shift" %}
8581 opcode(0xD3, 0x5); /* D3 /5 */
8582 ins_encode( OpcP, RegOpc( dst ) );
8583 ins_pipe( ialu_reg_reg );
8584 %}
8585
8586
8587 //----------Logical Instructions-----------------------------------------------
8588 //----------Integer Logical Instructions---------------------------------------
8589 // And Instructions
8590 // And Register with Register
8591 instruct andI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
8592 match(Set dst (AndI dst src));
8593 effect(KILL cr);
8594
8595 size(2);
8596 format %{ "AND $dst,$src" %}
8597 opcode(0x23);
8598 ins_encode( OpcP, RegReg( dst, src) );
8599 ins_pipe( ialu_reg_reg );
8600 %}
8601
8602 // And Register with Immediate
8603 instruct andI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
8604 match(Set dst (AndI dst src));
8605 effect(KILL cr);
8606
8607 format %{ "AND $dst,$src" %}
8608 opcode(0x81,0x04); /* Opcode 81 /4 */
8609 // ins_encode( RegImm( dst, src) );
8610 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
8611 ins_pipe( ialu_reg );
8612 %}
8613
8614 // And Register with Memory
8615 instruct andI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
8616 match(Set dst (AndI dst (LoadI src)));
8617 effect(KILL cr);
8618
8619 ins_cost(125);
8620 format %{ "AND $dst,$src" %}
8621 opcode(0x23);
8622 ins_encode( OpcP, RegMem( dst, src) );
8623 ins_pipe( ialu_reg_mem );
8624 %}
8625
8626 // And Memory with Register
8627 instruct andI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
8628 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
8629 effect(KILL cr);
8630
8631 ins_cost(150);
8632 format %{ "AND $dst,$src" %}
8633 opcode(0x21); /* Opcode 21 /r */
8634 ins_encode( OpcP, RegMem( src, dst ) );
8635 ins_pipe( ialu_mem_reg );
8636 %}
8637
8638 // And Memory with Immediate
8639 instruct andI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
8640 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
8641 effect(KILL cr);
8642
8643 ins_cost(125);
8644 format %{ "AND $dst,$src" %}
8645 opcode(0x81, 0x4); /* Opcode 81 /4 id */
8646 // ins_encode( MemImm( dst, src) );
8647 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) );
8648 ins_pipe( ialu_mem_imm );
8649 %}
8650
8651 // Or Instructions
8652 // Or Register with Register
8653 instruct orI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
8654 match(Set dst (OrI dst src));
8655 effect(KILL cr);
8656
8657 size(2);
8658 format %{ "OR $dst,$src" %}
8659 opcode(0x0B);
8660 ins_encode( OpcP, RegReg( dst, src) );
8661 ins_pipe( ialu_reg_reg );
8662 %}
8663
8664 instruct orI_eReg_castP2X(eRegI dst, eRegP src, eFlagsReg cr) %{
8665 match(Set dst (OrI dst (CastP2X src)));
8666 effect(KILL cr);
8667
8668 size(2);
8669 format %{ "OR $dst,$src" %}
8670 opcode(0x0B);
8671 ins_encode( OpcP, RegReg( dst, src) );
8672 ins_pipe( ialu_reg_reg );
8673 %}
8674
8675
8676 // Or Register with Immediate
8677 instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
8678 match(Set dst (OrI dst src));
8679 effect(KILL cr);
8680
8681 format %{ "OR $dst,$src" %}
8682 opcode(0x81,0x01); /* Opcode 81 /1 id */
8683 // ins_encode( RegImm( dst, src) );
8684 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
8685 ins_pipe( ialu_reg );
8686 %}
8687
8688 // Or Register with Memory
8689 instruct orI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
8690 match(Set dst (OrI dst (LoadI src)));
8691 effect(KILL cr);
8692
8693 ins_cost(125);
8694 format %{ "OR $dst,$src" %}
8695 opcode(0x0B);
8696 ins_encode( OpcP, RegMem( dst, src) );
8697 ins_pipe( ialu_reg_mem );
8698 %}
8699
8700 // Or Memory with Register
8701 instruct orI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
8702 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
8703 effect(KILL cr);
8704
8705 ins_cost(150);
8706 format %{ "OR $dst,$src" %}
8707 opcode(0x09); /* Opcode 09 /r */
8708 ins_encode( OpcP, RegMem( src, dst ) );
8709 ins_pipe( ialu_mem_reg );
8710 %}
8711
8712 // Or Memory with Immediate
8713 instruct orI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
8714 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
8715 effect(KILL cr);
8716
8717 ins_cost(125);
8718 format %{ "OR $dst,$src" %}
8719 opcode(0x81,0x1); /* Opcode 81 /1 id */
8720 // ins_encode( MemImm( dst, src) );
8721 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) );
8722 ins_pipe( ialu_mem_imm );
8723 %}
8724
8725 // ROL/ROR
8726 // ROL expand
8727 instruct rolI_eReg_imm1(eRegI dst, immI1 shift, eFlagsReg cr) %{
8728 effect(USE_DEF dst, USE shift, KILL cr);
8729
8730 format %{ "ROL $dst, $shift" %}
8731 opcode(0xD1, 0x0); /* Opcode D1 /0 */
8732 ins_encode( OpcP, RegOpc( dst ));
8733 ins_pipe( ialu_reg );
8734 %}
8735
8736 instruct rolI_eReg_imm8(eRegI dst, immI8 shift, eFlagsReg cr) %{
8737 effect(USE_DEF dst, USE shift, KILL cr);
8738
8739 format %{ "ROL $dst, $shift" %}
8740 opcode(0xC1, 0x0); /*Opcode /C1 /0 */
8741 ins_encode( RegOpcImm(dst, shift) );
8742 ins_pipe(ialu_reg);
8743 %}
8744
8745 instruct rolI_eReg_CL(ncxRegI dst, eCXRegI shift, eFlagsReg cr) %{
8746 effect(USE_DEF dst, USE shift, KILL cr);
8747
8748 format %{ "ROL $dst, $shift" %}
8749 opcode(0xD3, 0x0); /* Opcode D3 /0 */
8750 ins_encode(OpcP, RegOpc(dst));
8751 ins_pipe( ialu_reg_reg );
8752 %}
8753 // end of ROL expand
8754
8755 // ROL 32bit by one once
8756 instruct rolI_eReg_i1(eRegI dst, immI1 lshift, immI_M1 rshift, eFlagsReg cr) %{
8757 match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8758
8759 expand %{
8760 rolI_eReg_imm1(dst, lshift, cr);
8761 %}
8762 %}
8763
8764 // ROL 32bit var by imm8 once
8765 instruct rolI_eReg_i8(eRegI dst, immI8 lshift, immI8 rshift, eFlagsReg cr) %{
8766 predicate( 0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8767 match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8768
8769 expand %{
8770 rolI_eReg_imm8(dst, lshift, cr);
8771 %}
8772 %}
8773
8774 // ROL 32bit var by var once
8775 instruct rolI_eReg_Var_C0(ncxRegI dst, eCXRegI shift, immI0 zero, eFlagsReg cr) %{
8776 match(Set dst ( OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift))));
8777
8778 expand %{
8779 rolI_eReg_CL(dst, shift, cr);
8780 %}
8781 %}
8782
8783 // ROL 32bit var by var once
8784 instruct rolI_eReg_Var_C32(ncxRegI dst, eCXRegI shift, immI_32 c32, eFlagsReg cr) %{
8785 match(Set dst ( OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift))));
8786
8787 expand %{
8788 rolI_eReg_CL(dst, shift, cr);
8789 %}
8790 %}
8791
8792 // ROR expand
8793 instruct rorI_eReg_imm1(eRegI dst, immI1 shift, eFlagsReg cr) %{
8794 effect(USE_DEF dst, USE shift, KILL cr);
8795
8796 format %{ "ROR $dst, $shift" %}
8797 opcode(0xD1,0x1); /* Opcode D1 /1 */
8798 ins_encode( OpcP, RegOpc( dst ) );
8799 ins_pipe( ialu_reg );
8800 %}
8801
8802 instruct rorI_eReg_imm8(eRegI dst, immI8 shift, eFlagsReg cr) %{
8803 effect (USE_DEF dst, USE shift, KILL cr);
8804
8805 format %{ "ROR $dst, $shift" %}
8806 opcode(0xC1, 0x1); /* Opcode /C1 /1 ib */
8807 ins_encode( RegOpcImm(dst, shift) );
8808 ins_pipe( ialu_reg );
8809 %}
8810
8811 instruct rorI_eReg_CL(ncxRegI dst, eCXRegI shift, eFlagsReg cr)%{
8812 effect(USE_DEF dst, USE shift, KILL cr);
8813
8814 format %{ "ROR $dst, $shift" %}
8815 opcode(0xD3, 0x1); /* Opcode D3 /1 */
8816 ins_encode(OpcP, RegOpc(dst));
8817 ins_pipe( ialu_reg_reg );
8818 %}
8819 // end of ROR expand
8820
8821 // ROR right once
8822 instruct rorI_eReg_i1(eRegI dst, immI1 rshift, immI_M1 lshift, eFlagsReg cr) %{
8823 match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8824
8825 expand %{
8826 rorI_eReg_imm1(dst, rshift, cr);
8827 %}
8828 %}
8829
8830 // ROR 32bit by immI8 once
8831 instruct rorI_eReg_i8(eRegI dst, immI8 rshift, immI8 lshift, eFlagsReg cr) %{
8832 predicate( 0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8833 match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8834
8835 expand %{
8836 rorI_eReg_imm8(dst, rshift, cr);
8837 %}
8838 %}
8839
8840 // ROR 32bit var by var once
8841 instruct rorI_eReg_Var_C0(ncxRegI dst, eCXRegI shift, immI0 zero, eFlagsReg cr) %{
8842 match(Set dst ( OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift))));
8843
8844 expand %{
8845 rorI_eReg_CL(dst, shift, cr);
8846 %}
8847 %}
8848
8849 // ROR 32bit var by var once
8850 instruct rorI_eReg_Var_C32(ncxRegI dst, eCXRegI shift, immI_32 c32, eFlagsReg cr) %{
8851 match(Set dst ( OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift))));
8852
8853 expand %{
8854 rorI_eReg_CL(dst, shift, cr);
8855 %}
8856 %}
8857
8858 // Xor Instructions
8859 // Xor Register with Register
8860 instruct xorI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
8861 match(Set dst (XorI dst src));
8862 effect(KILL cr);
8863
8864 size(2);
8865 format %{ "XOR $dst,$src" %}
8866 opcode(0x33);
8867 ins_encode( OpcP, RegReg( dst, src) );
8868 ins_pipe( ialu_reg_reg );
8869 %}
8870
8871 // Xor Register with Immediate -1
8872 instruct xorI_eReg_im1(eRegI dst, immI_M1 imm) %{
8873 match(Set dst (XorI dst imm));
8874
8875 size(2);
8876 format %{ "NOT $dst" %}
8877 ins_encode %{
8878 __ notl($dst$$Register);
8879 %}
8880 ins_pipe( ialu_reg );
8881 %}
8882
8883 // Xor Register with Immediate
8884 instruct xorI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
8885 match(Set dst (XorI dst src));
8886 effect(KILL cr);
8887
8888 format %{ "XOR $dst,$src" %}
8889 opcode(0x81,0x06); /* Opcode 81 /6 id */
8890 // ins_encode( RegImm( dst, src) );
8891 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
8892 ins_pipe( ialu_reg );
8893 %}
8894
8895 // Xor Register with Memory
8896 instruct xorI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
8897 match(Set dst (XorI dst (LoadI src)));
8898 effect(KILL cr);
8899
8900 ins_cost(125);
8901 format %{ "XOR $dst,$src" %}
8902 opcode(0x33);
8903 ins_encode( OpcP, RegMem(dst, src) );
8904 ins_pipe( ialu_reg_mem );
8905 %}
8906
8907 // Xor Memory with Register
8908 instruct xorI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
8909 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
8910 effect(KILL cr);
8911
8912 ins_cost(150);
8913 format %{ "XOR $dst,$src" %}
8914 opcode(0x31); /* Opcode 31 /r */
8915 ins_encode( OpcP, RegMem( src, dst ) );
8916 ins_pipe( ialu_mem_reg );
8917 %}
8918
8919 // Xor Memory with Immediate
8920 instruct xorI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
8921 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
8922 effect(KILL cr);
8923
8924 ins_cost(125);
8925 format %{ "XOR $dst,$src" %}
8926 opcode(0x81,0x6); /* Opcode 81 /6 id */
8927 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) );
8928 ins_pipe( ialu_mem_imm );
8929 %}
8930
8931 //----------Convert Int to Boolean---------------------------------------------
8932
8933 instruct movI_nocopy(eRegI dst, eRegI src) %{
8934 effect( DEF dst, USE src );
8935 format %{ "MOV $dst,$src" %}
8936 ins_encode( enc_Copy( dst, src) );
8937 ins_pipe( ialu_reg_reg );
8938 %}
8939
8940 instruct ci2b( eRegI dst, eRegI src, eFlagsReg cr ) %{
8941 effect( USE_DEF dst, USE src, KILL cr );
8942
8943 size(4);
8944 format %{ "NEG $dst\n\t"
8945 "ADC $dst,$src" %}
8946 ins_encode( neg_reg(dst),
8947 OpcRegReg(0x13,dst,src) );
8948 ins_pipe( ialu_reg_reg_long );
8949 %}
8950
8951 instruct convI2B( eRegI dst, eRegI src, eFlagsReg cr ) %{
8952 match(Set dst (Conv2B src));
8953
8954 expand %{
8955 movI_nocopy(dst,src);
8956 ci2b(dst,src,cr);
8957 %}
8958 %}
8959
8960 instruct movP_nocopy(eRegI dst, eRegP src) %{
8961 effect( DEF dst, USE src );
8962 format %{ "MOV $dst,$src" %}
8963 ins_encode( enc_Copy( dst, src) );
8964 ins_pipe( ialu_reg_reg );
8965 %}
8966
8967 instruct cp2b( eRegI dst, eRegP src, eFlagsReg cr ) %{
8968 effect( USE_DEF dst, USE src, KILL cr );
8969 format %{ "NEG $dst\n\t"
8970 "ADC $dst,$src" %}
8971 ins_encode( neg_reg(dst),
8972 OpcRegReg(0x13,dst,src) );
8973 ins_pipe( ialu_reg_reg_long );
8974 %}
8975
8976 instruct convP2B( eRegI dst, eRegP src, eFlagsReg cr ) %{
8977 match(Set dst (Conv2B src));
8978
8979 expand %{
8980 movP_nocopy(dst,src);
8981 cp2b(dst,src,cr);
8982 %}
8983 %}
8984
8985 instruct cmpLTMask( eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr ) %{
8986 match(Set dst (CmpLTMask p q));
8987 effect( KILL cr );
8988 ins_cost(400);
8989
8990 // SETlt can only use low byte of EAX,EBX, ECX, or EDX as destination
8991 format %{ "XOR $dst,$dst\n\t"
8992 "CMP $p,$q\n\t"
8993 "SETlt $dst\n\t"
8994 "NEG $dst" %}
8995 ins_encode( OpcRegReg(0x33,dst,dst),
8996 OpcRegReg(0x3B,p,q),
8997 setLT_reg(dst), neg_reg(dst) );
8998 ins_pipe( pipe_slow );
8999 %}
9000
9001 instruct cmpLTMask0( eRegI dst, immI0 zero, eFlagsReg cr ) %{
9002 match(Set dst (CmpLTMask dst zero));
9003 effect( DEF dst, KILL cr );
9004 ins_cost(100);
9005
9006 format %{ "SAR $dst,31" %}
9007 opcode(0xC1, 0x7); /* C1 /7 ib */
9008 ins_encode( RegOpcImm( dst, 0x1F ) );
9009 ins_pipe( ialu_reg );
9010 %}
9011
9012
9013 instruct cadd_cmpLTMask( ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp, eFlagsReg cr ) %{
9014 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
9015 effect( KILL tmp, KILL cr );
9016 ins_cost(400);
9017 // annoyingly, $tmp has no edges so you cant ask for it in
9018 // any format or encoding
9019 format %{ "SUB $p,$q\n\t"
9020 "SBB ECX,ECX\n\t"
9021 "AND ECX,$y\n\t"
9453 instruct cmpDPR_cc(eFlagsRegU cr, regDPR src1, regDPR src2, eAXRegI rax) %{
9454 predicate(UseSSE<=1);
9455 match(Set cr (CmpD src1 src2));
9456 effect(KILL rax);
9457 ins_cost(200);
9458 format %{ "FLD $src1\n\t"
9459 "FCOMp $src2\n\t"
9460 "FNSTSW AX\n\t"
9461 "TEST AX,0x400\n\t"
9462 "JZ,s flags\n\t"
9463 "MOV AH,1\t# unordered treat as LT\n"
9464 "flags:\tSAHF" %}
9465 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
9466 ins_encode( Push_Reg_DPR(src1),
9467 OpcP, RegOpc(src2),
9468 fpu_flags);
9469 ins_pipe( pipe_slow );
9470 %}
9471
9472 // Compare vs zero into -1,0,1
9473 instruct cmpDPR_0(eRegI dst, regDPR src1, immDPR0 zero, eAXRegI rax, eFlagsReg cr) %{
9474 predicate(UseSSE<=1);
9475 match(Set dst (CmpD3 src1 zero));
9476 effect(KILL cr, KILL rax);
9477 ins_cost(280);
9478 format %{ "FTSTD $dst,$src1" %}
9479 opcode(0xE4, 0xD9);
9480 ins_encode( Push_Reg_DPR(src1),
9481 OpcS, OpcP, PopFPU,
9482 CmpF_Result(dst));
9483 ins_pipe( pipe_slow );
9484 %}
9485
9486 // Compare into -1,0,1
9487 instruct cmpDPR_reg(eRegI dst, regDPR src1, regDPR src2, eAXRegI rax, eFlagsReg cr) %{
9488 predicate(UseSSE<=1);
9489 match(Set dst (CmpD3 src1 src2));
9490 effect(KILL cr, KILL rax);
9491 ins_cost(300);
9492 format %{ "FCMPD $dst,$src1,$src2" %}
9493 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
9494 ins_encode( Push_Reg_DPR(src1),
9495 OpcP, RegOpc(src2),
9496 CmpF_Result(dst));
9497 ins_pipe( pipe_slow );
9498 %}
9499
9500 // float compare and set condition codes in EFLAGS by XMM regs
9501 instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2) %{
9502 predicate(UseSSE>=2);
9503 match(Set cr (CmpD src1 src2));
9504 ins_cost(145);
9505 format %{ "UCOMISD $src1,$src2\n\t"
9506 "JNP,s exit\n\t"
9507 "PUSHF\t# saw NaN, set CF\n\t"
10245 instruct cmpFPR_cc(eFlagsRegU cr, regFPR src1, regFPR src2, eAXRegI rax) %{
10246 predicate(UseSSE == 0);
10247 match(Set cr (CmpF src1 src2));
10248 effect(KILL rax);
10249 ins_cost(200);
10250 format %{ "FLD $src1\n\t"
10251 "FCOMp $src2\n\t"
10252 "FNSTSW AX\n\t"
10253 "TEST AX,0x400\n\t"
10254 "JZ,s flags\n\t"
10255 "MOV AH,1\t# unordered treat as LT\n"
10256 "flags:\tSAHF" %}
10257 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
10258 ins_encode( Push_Reg_DPR(src1),
10259 OpcP, RegOpc(src2),
10260 fpu_flags);
10261 ins_pipe( pipe_slow );
10262 %}
10263
10264 // Compare vs zero into -1,0,1
10265 instruct cmpFPR_0(eRegI dst, regFPR src1, immFPR0 zero, eAXRegI rax, eFlagsReg cr) %{
10266 predicate(UseSSE == 0);
10267 match(Set dst (CmpF3 src1 zero));
10268 effect(KILL cr, KILL rax);
10269 ins_cost(280);
10270 format %{ "FTSTF $dst,$src1" %}
10271 opcode(0xE4, 0xD9);
10272 ins_encode( Push_Reg_DPR(src1),
10273 OpcS, OpcP, PopFPU,
10274 CmpF_Result(dst));
10275 ins_pipe( pipe_slow );
10276 %}
10277
10278 // Compare into -1,0,1
10279 instruct cmpFPR_reg(eRegI dst, regFPR src1, regFPR src2, eAXRegI rax, eFlagsReg cr) %{
10280 predicate(UseSSE == 0);
10281 match(Set dst (CmpF3 src1 src2));
10282 effect(KILL cr, KILL rax);
10283 ins_cost(300);
10284 format %{ "FCMPF $dst,$src1,$src2" %}
10285 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
10286 ins_encode( Push_Reg_DPR(src1),
10287 OpcP, RegOpc(src2),
10288 CmpF_Result(dst));
10289 ins_pipe( pipe_slow );
10290 %}
10291
10292 // float compare and set condition codes in EFLAGS by XMM regs
10293 instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2) %{
10294 predicate(UseSSE>=1);
10295 match(Set cr (CmpF src1 src2));
10296 ins_cost(145);
10297 format %{ "UCOMISS $src1,$src2\n\t"
10298 "JNP,s exit\n\t"
10299 "PUSHF\t# saw NaN, set CF\n\t"
11179 __ subptr(rsp, 4);
11180 __ movflt(Address(rsp, 0), $src$$XMMRegister);
11181 __ fld_s(Address(rsp, 0));
11182 __ addptr(rsp, 4);
11183 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::d2l_wrapper())));
11184 __ bind(fast);
11185 %}
11186 ins_pipe( pipe_slow );
11187 %}
11188
11189 instruct convI2DPR_reg(regDPR dst, stackSlotI src) %{
11190 predicate( UseSSE<=1 );
11191 match(Set dst (ConvI2D src));
11192 format %{ "FILD $src\n\t"
11193 "FSTP $dst" %}
11194 opcode(0xDB, 0x0); /* DB /0 */
11195 ins_encode(Push_Mem_I(src), Pop_Reg_DPR(dst));
11196 ins_pipe( fpu_reg_mem );
11197 %}
11198
11199 instruct convI2D_reg(regD dst, eRegI src) %{
11200 predicate( UseSSE>=2 && !UseXmmI2D );
11201 match(Set dst (ConvI2D src));
11202 format %{ "CVTSI2SD $dst,$src" %}
11203 ins_encode %{
11204 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
11205 %}
11206 ins_pipe( pipe_slow );
11207 %}
11208
11209 instruct convI2D_mem(regD dst, memory mem) %{
11210 predicate( UseSSE>=2 );
11211 match(Set dst (ConvI2D (LoadI mem)));
11212 format %{ "CVTSI2SD $dst,$mem" %}
11213 ins_encode %{
11214 __ cvtsi2sdl ($dst$$XMMRegister, $mem$$Address);
11215 %}
11216 ins_pipe( pipe_slow );
11217 %}
11218
11219 instruct convXI2D_reg(regD dst, eRegI src)
11220 %{
11221 predicate( UseSSE>=2 && UseXmmI2D );
11222 match(Set dst (ConvI2D src));
11223
11224 format %{ "MOVD $dst,$src\n\t"
11225 "CVTDQ2PD $dst,$dst\t# i2d" %}
11226 ins_encode %{
11227 __ movdl($dst$$XMMRegister, $src$$Register);
11228 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
11229 %}
11230 ins_pipe(pipe_slow); // XXX
11231 %}
11232
11233 instruct convI2DPR_mem(regDPR dst, memory mem) %{
11234 predicate( UseSSE<=1 && !Compile::current()->select_24_bit_instr());
11235 match(Set dst (ConvI2D (LoadI mem)));
11236 format %{ "FILD $mem\n\t"
11237 "FSTP $dst" %}
11238 opcode(0xDB); /* DB /0 */
11239 ins_encode( OpcP, RMopc_Mem(0x00,mem),
11287 "FSTP $dst" %}
11288 opcode(0xDB, 0x0); /* DB /0 */
11289 ins_encode( Push_Mem_I(src),
11290 Pop_Reg_FPR(dst));
11291 ins_pipe( fpu_reg_mem );
11292 %}
11293
11294 // This instruction does not round to 24-bits
11295 instruct convI2FPR_mem(regFPR dst, memory mem) %{
11296 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr());
11297 match(Set dst (ConvI2F (LoadI mem)));
11298 format %{ "FILD $mem\n\t"
11299 "FSTP $dst" %}
11300 opcode(0xDB); /* DB /0 */
11301 ins_encode( OpcP, RMopc_Mem(0x00,mem),
11302 Pop_Reg_FPR(dst));
11303 ins_pipe( fpu_reg_mem );
11304 %}
11305
11306 // Convert an int to a float in xmm; no rounding step needed.
11307 instruct convI2F_reg(regF dst, eRegI src) %{
11308 predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F );
11309 match(Set dst (ConvI2F src));
11310 format %{ "CVTSI2SS $dst, $src" %}
11311 ins_encode %{
11312 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
11313 %}
11314 ins_pipe( pipe_slow );
11315 %}
11316
11317 instruct convXI2F_reg(regF dst, eRegI src)
11318 %{
11319 predicate( UseSSE>=2 && UseXmmI2F );
11320 match(Set dst (ConvI2F src));
11321
11322 format %{ "MOVD $dst,$src\n\t"
11323 "CVTDQ2PS $dst,$dst\t# i2f" %}
11324 ins_encode %{
11325 __ movdl($dst$$XMMRegister, $src$$Register);
11326 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
11327 %}
11328 ins_pipe(pipe_slow); // XXX
11329 %}
11330
11331 instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{
11332 match(Set dst (ConvI2L src));
11333 effect(KILL cr);
11334 ins_cost(375);
11335 format %{ "MOV $dst.lo,$src\n\t"
11336 "MOV $dst.hi,$src\n\t"
11337 "SAR $dst.hi,31" %}
11338 ins_encode(convert_int_long(dst,src));
11339 ins_pipe( ialu_reg_reg_long );
11340 %}
11341
11342 // Zero-extend convert int to long
11343 instruct convI2L_reg_zex(eRegL dst, eRegI src, immL_32bits mask, eFlagsReg flags ) %{
11344 match(Set dst (AndL (ConvI2L src) mask) );
11345 effect( KILL flags );
11346 ins_cost(250);
11347 format %{ "MOV $dst.lo,$src\n\t"
11348 "XOR $dst.hi,$dst.hi" %}
11349 opcode(0x33); // XOR
11350 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) );
11351 ins_pipe( ialu_reg_reg_long );
11352 %}
11353
11354 // Zero-extend long
11355 instruct zerox_long(eRegL dst, eRegL src, immL_32bits mask, eFlagsReg flags ) %{
11356 match(Set dst (AndL src mask) );
11357 effect( KILL flags );
11358 ins_cost(250);
11359 format %{ "MOV $dst.lo,$src.lo\n\t"
11360 "XOR $dst.hi,$dst.hi\n\t" %}
11361 opcode(0x33); // XOR
11362 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) );
11363 ins_pipe( ialu_reg_reg_long );
11403 "MOVSS $dst,[ESP]\n\t"
11404 "ADD ESP,8" %}
11405 opcode(0xDF, 0x5); /* DF /5 */
11406 ins_encode(convert_long_double2(src), Push_ResultF(dst,0x8));
11407 ins_pipe( pipe_slow );
11408 %}
11409
11410 instruct convL2FPR_reg( stackSlotF dst, eRegL src, eFlagsReg cr) %{
11411 match(Set dst (ConvL2F src));
11412 effect( KILL cr );
11413 format %{ "PUSH $src.hi\t# Convert long to single float\n\t"
11414 "PUSH $src.lo\n\t"
11415 "FILD ST,[ESP + #0]\n\t"
11416 "ADD ESP,8\n\t"
11417 "FSTP_S $dst\t# F-round" %}
11418 opcode(0xDF, 0x5); /* DF /5 */
11419 ins_encode(convert_long_double(src), Pop_Mem_FPR(dst));
11420 ins_pipe( pipe_slow );
11421 %}
11422
11423 instruct convL2I_reg( eRegI dst, eRegL src ) %{
11424 match(Set dst (ConvL2I src));
11425 effect( DEF dst, USE src );
11426 format %{ "MOV $dst,$src.lo" %}
11427 ins_encode(enc_CopyL_Lo(dst,src));
11428 ins_pipe( ialu_reg_reg );
11429 %}
11430
11431
11432 instruct MoveF2I_stack_reg(eRegI dst, stackSlotF src) %{
11433 match(Set dst (MoveF2I src));
11434 effect( DEF dst, USE src );
11435 ins_cost(100);
11436 format %{ "MOV $dst,$src\t# MoveF2I_stack_reg" %}
11437 ins_encode %{
11438 __ movl($dst$$Register, Address(rsp, $src$$disp));
11439 %}
11440 ins_pipe( ialu_reg_mem );
11441 %}
11442
11443 instruct MoveFPR2I_reg_stack(stackSlotI dst, regFPR src) %{
11444 predicate(UseSSE==0);
11445 match(Set dst (MoveF2I src));
11446 effect( DEF dst, USE src );
11447
11448 ins_cost(125);
11449 format %{ "FST_S $dst,$src\t# MoveF2I_reg_stack" %}
11450 ins_encode( Pop_Mem_Reg_FPR(dst, src) );
11451 ins_pipe( fpu_mem_reg );
11452 %}
11453
11454 instruct MoveF2I_reg_stack_sse(stackSlotI dst, regF src) %{
11455 predicate(UseSSE>=1);
11456 match(Set dst (MoveF2I src));
11457 effect( DEF dst, USE src );
11458
11459 ins_cost(95);
11460 format %{ "MOVSS $dst,$src\t# MoveF2I_reg_stack_sse" %}
11461 ins_encode %{
11462 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
11463 %}
11464 ins_pipe( pipe_slow );
11465 %}
11466
11467 instruct MoveF2I_reg_reg_sse(eRegI dst, regF src) %{
11468 predicate(UseSSE>=2);
11469 match(Set dst (MoveF2I src));
11470 effect( DEF dst, USE src );
11471 ins_cost(85);
11472 format %{ "MOVD $dst,$src\t# MoveF2I_reg_reg_sse" %}
11473 ins_encode %{
11474 __ movdl($dst$$Register, $src$$XMMRegister);
11475 %}
11476 ins_pipe( pipe_slow );
11477 %}
11478
11479 instruct MoveI2F_reg_stack(stackSlotF dst, eRegI src) %{
11480 match(Set dst (MoveI2F src));
11481 effect( DEF dst, USE src );
11482
11483 ins_cost(100);
11484 format %{ "MOV $dst,$src\t# MoveI2F_reg_stack" %}
11485 ins_encode %{
11486 __ movl(Address(rsp, $dst$$disp), $src$$Register);
11487 %}
11488 ins_pipe( ialu_mem_reg );
11489 %}
11490
11491
11492 instruct MoveI2FPR_stack_reg(regFPR dst, stackSlotI src) %{
11493 predicate(UseSSE==0);
11494 match(Set dst (MoveI2F src));
11495 effect(DEF dst, USE src);
11496
11497 ins_cost(125);
11498 format %{ "FLD_S $src\n\t"
11499 "FSTP $dst\t# MoveI2F_stack_reg" %}
11500 opcode(0xD9); /* D9 /0, FLD m32real */
11501 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src),
11502 Pop_Reg_FPR(dst) );
11503 ins_pipe( fpu_reg_mem );
11504 %}
11505
11506 instruct MoveI2F_stack_reg_sse(regF dst, stackSlotI src) %{
11507 predicate(UseSSE>=1);
11508 match(Set dst (MoveI2F src));
11509 effect( DEF dst, USE src );
11510
11511 ins_cost(95);
11512 format %{ "MOVSS $dst,$src\t# MoveI2F_stack_reg_sse" %}
11513 ins_encode %{
11514 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
11515 %}
11516 ins_pipe( pipe_slow );
11517 %}
11518
11519 instruct MoveI2F_reg_reg_sse(regF dst, eRegI src) %{
11520 predicate(UseSSE>=2);
11521 match(Set dst (MoveI2F src));
11522 effect( DEF dst, USE src );
11523
11524 ins_cost(85);
11525 format %{ "MOVD $dst,$src\t# MoveI2F_reg_reg_sse" %}
11526 ins_encode %{
11527 __ movdl($dst$$XMMRegister, $src$$Register);
11528 %}
11529 ins_pipe( pipe_slow );
11530 %}
11531
11532 instruct MoveD2L_stack_reg(eRegL dst, stackSlotD src) %{
11533 match(Set dst (MoveD2L src));
11534 effect(DEF dst, USE src);
11535
11536 ins_cost(250);
11537 format %{ "MOV $dst.lo,$src\n\t"
11538 "MOV $dst.hi,$src+4\t# MoveD2L_stack_reg" %}
11539 opcode(0x8B, 0x8B);
11633 %}
11634 ins_pipe( pipe_slow );
11635 %}
11636
11637 instruct MoveL2D_reg_reg_sse(regD dst, eRegL src, regD tmp) %{
11638 predicate(UseSSE>=2);
11639 match(Set dst (MoveL2D src));
11640 effect(TEMP dst, USE src, TEMP tmp);
11641 ins_cost(85);
11642 format %{ "MOVD $dst,$src.lo\n\t"
11643 "MOVD $tmp,$src.hi\n\t"
11644 "PUNPCKLDQ $dst,$tmp\t# MoveL2D_reg_reg_sse" %}
11645 ins_encode %{
11646 __ movdl($dst$$XMMRegister, $src$$Register);
11647 __ movdl($tmp$$XMMRegister, HIGH_FROM_LOW($src$$Register));
11648 __ punpckldq($dst$$XMMRegister, $tmp$$XMMRegister);
11649 %}
11650 ins_pipe( pipe_slow );
11651 %}
11652
11653 // Replicate scalar to packed byte (1 byte) values in xmm
11654 instruct Repl8B_reg(regD dst, regD src) %{
11655 predicate(UseSSE>=2);
11656 match(Set dst (Replicate8B src));
11657 format %{ "MOVDQA $dst,$src\n\t"
11658 "PUNPCKLBW $dst,$dst\n\t"
11659 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
11660 ins_encode %{
11661 if ($dst$$reg != $src$$reg) {
11662 __ movdqa($dst$$XMMRegister, $src$$XMMRegister);
11663 }
11664 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
11665 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
11666 %}
11667 ins_pipe( pipe_slow );
11668 %}
11669
11670 // Replicate scalar to packed byte (1 byte) values in xmm
11671 instruct Repl8B_eRegI(regD dst, eRegI src) %{
11672 predicate(UseSSE>=2);
11673 match(Set dst (Replicate8B src));
11674 format %{ "MOVD $dst,$src\n\t"
11675 "PUNPCKLBW $dst,$dst\n\t"
11676 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
11677 ins_encode %{
11678 __ movdl($dst$$XMMRegister, $src$$Register);
11679 __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
11680 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
11681 %}
11682 ins_pipe( pipe_slow );
11683 %}
11684
11685 // Replicate scalar zero to packed byte (1 byte) values in xmm
11686 instruct Repl8B_immI0(regD dst, immI0 zero) %{
11687 predicate(UseSSE>=2);
11688 match(Set dst (Replicate8B zero));
11689 format %{ "PXOR $dst,$dst\t! replicate8B" %}
11690 ins_encode %{
11691 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
11692 %}
11693 ins_pipe( fpu_reg_reg );
11694 %}
11695
11696 // Replicate scalar to packed shore (2 byte) values in xmm
11697 instruct Repl4S_reg(regD dst, regD src) %{
11698 predicate(UseSSE>=2);
11699 match(Set dst (Replicate4S src));
11700 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
11701 ins_encode %{
11702 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
11703 %}
11704 ins_pipe( fpu_reg_reg );
11705 %}
11706
11707 // Replicate scalar to packed shore (2 byte) values in xmm
11708 instruct Repl4S_eRegI(regD dst, eRegI src) %{
11709 predicate(UseSSE>=2);
11710 match(Set dst (Replicate4S src));
11711 format %{ "MOVD $dst,$src\n\t"
11712 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
11713 ins_encode %{
11714 __ movdl($dst$$XMMRegister, $src$$Register);
11715 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
11716 %}
11717 ins_pipe( fpu_reg_reg );
11718 %}
11719
11720 // Replicate scalar zero to packed short (2 byte) values in xmm
11721 instruct Repl4S_immI0(regD dst, immI0 zero) %{
11722 predicate(UseSSE>=2);
11723 match(Set dst (Replicate4S zero));
11724 format %{ "PXOR $dst,$dst\t! replicate4S" %}
11725 ins_encode %{
11726 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
11727 %}
11728 ins_pipe( fpu_reg_reg );
11729 %}
11730
11731 // Replicate scalar to packed char (2 byte) values in xmm
11732 instruct Repl4C_reg(regD dst, regD src) %{
11733 predicate(UseSSE>=2);
11734 match(Set dst (Replicate4C src));
11735 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
11736 ins_encode %{
11737 __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
11738 %}
11739 ins_pipe( fpu_reg_reg );
11740 %}
11741
11742 // Replicate scalar to packed char (2 byte) values in xmm
11743 instruct Repl4C_eRegI(regD dst, eRegI src) %{
11744 predicate(UseSSE>=2);
11745 match(Set dst (Replicate4C src));
11746 format %{ "MOVD $dst,$src\n\t"
11747 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
11748 ins_encode %{
11749 __ movdl($dst$$XMMRegister, $src$$Register);
11750 __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
11751 %}
11752 ins_pipe( fpu_reg_reg );
11753 %}
11754
11755 // Replicate scalar zero to packed char (2 byte) values in xmm
11756 instruct Repl4C_immI0(regD dst, immI0 zero) %{
11757 predicate(UseSSE>=2);
11758 match(Set dst (Replicate4C zero));
11759 format %{ "PXOR $dst,$dst\t! replicate4C" %}
11760 ins_encode %{
11761 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
11762 %}
11763 ins_pipe( fpu_reg_reg );
11764 %}
11765
11766 // Replicate scalar to packed integer (4 byte) values in xmm
11767 instruct Repl2I_reg(regD dst, regD src) %{
11768 predicate(UseSSE>=2);
11769 match(Set dst (Replicate2I src));
11770 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
11771 ins_encode %{
11772 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
11773 %}
11774 ins_pipe( fpu_reg_reg );
11775 %}
11776
11777 // Replicate scalar to packed integer (4 byte) values in xmm
11778 instruct Repl2I_eRegI(regD dst, eRegI src) %{
11779 predicate(UseSSE>=2);
11780 match(Set dst (Replicate2I src));
11781 format %{ "MOVD $dst,$src\n\t"
11782 "PSHUFD $dst,$dst,0x00\t! replicate2I" %}
11783 ins_encode %{
11784 __ movdl($dst$$XMMRegister, $src$$Register);
11785 __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
11786 %}
11787 ins_pipe( fpu_reg_reg );
11788 %}
11789
11790 // Replicate scalar zero to packed integer (2 byte) values in xmm
11791 instruct Repl2I_immI0(regD dst, immI0 zero) %{
11792 predicate(UseSSE>=2);
11793 match(Set dst (Replicate2I zero));
11794 format %{ "PXOR $dst,$dst\t! replicate2I" %}
11795 ins_encode %{
11796 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
11797 %}
11798 ins_pipe( fpu_reg_reg );
11799 %}
11800
11801 // Replicate scalar to packed single precision floating point values in xmm
11802 instruct Repl2F_reg(regD dst, regD src) %{
11803 predicate(UseSSE>=2);
11804 match(Set dst (Replicate2F src));
11805 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11806 ins_encode %{
11807 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
11808 %}
11809 ins_pipe( fpu_reg_reg );
11810 %}
11811
11812 // Replicate scalar to packed single precision floating point values in xmm
11813 instruct Repl2F_regF(regD dst, regF src) %{
11814 predicate(UseSSE>=2);
11815 match(Set dst (Replicate2F src));
11816 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
11817 ins_encode %{
11818 __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
11819 %}
11820 ins_pipe( fpu_reg_reg );
11821 %}
11822
11823 // Replicate scalar to packed single precision floating point values in xmm
11824 instruct Repl2F_immF0(regD dst, immF0 zero) %{
11825 predicate(UseSSE>=2);
11826 match(Set dst (Replicate2F zero));
11827 format %{ "PXOR $dst,$dst\t! replicate2F" %}
11828 ins_encode %{
11829 __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
11830 %}
11831 ins_pipe( fpu_reg_reg );
11832 %}
11833
11834 // =======================================================================
11835 // fast clearing of an array
11836 instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
11837 match(Set dummy (ClearArray cnt base));
11838 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
11839 format %{ "SHL ECX,1\t# Convert doublewords to words\n\t"
11840 "XOR EAX,EAX\n\t"
11841 "REP STOS\t# store EAX into [EDI++] while ECX--" %}
11842 opcode(0,0x4);
11843 ins_encode( Opcode(0xD1), RegOpc(ECX),
11844 OpcRegReg(0x33,EAX,EAX),
11845 Opcode(0xF3), Opcode(0xAB) );
11846 ins_pipe( pipe_slow );
11847 %}
11848
11849 instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
11850 eAXRegI result, regD tmp1, eFlagsReg cr) %{
11851 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11852 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11853
11921
11922 // fast array equals
11923 instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
11924 regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
11925 %{
11926 match(Set result (AryEq ary1 ary2));
11927 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
11928 //ins_cost(300);
11929
11930 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
11931 ins_encode %{
11932 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
11933 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11934 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11935 %}
11936 ins_pipe( pipe_slow );
11937 %}
11938
11939 //----------Control Flow Instructions------------------------------------------
11940 // Signed compare Instructions
11941 instruct compI_eReg(eFlagsReg cr, eRegI op1, eRegI op2) %{
11942 match(Set cr (CmpI op1 op2));
11943 effect( DEF cr, USE op1, USE op2 );
11944 format %{ "CMP $op1,$op2" %}
11945 opcode(0x3B); /* Opcode 3B /r */
11946 ins_encode( OpcP, RegReg( op1, op2) );
11947 ins_pipe( ialu_cr_reg_reg );
11948 %}
11949
11950 instruct compI_eReg_imm(eFlagsReg cr, eRegI op1, immI op2) %{
11951 match(Set cr (CmpI op1 op2));
11952 effect( DEF cr, USE op1 );
11953 format %{ "CMP $op1,$op2" %}
11954 opcode(0x81,0x07); /* Opcode 81 /7 */
11955 // ins_encode( RegImm( op1, op2) ); /* Was CmpImm */
11956 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) );
11957 ins_pipe( ialu_cr_reg_imm );
11958 %}
11959
11960 // Cisc-spilled version of cmpI_eReg
11961 instruct compI_eReg_mem(eFlagsReg cr, eRegI op1, memory op2) %{
11962 match(Set cr (CmpI op1 (LoadI op2)));
11963
11964 format %{ "CMP $op1,$op2" %}
11965 ins_cost(500);
11966 opcode(0x3B); /* Opcode 3B /r */
11967 ins_encode( OpcP, RegMem( op1, op2) );
11968 ins_pipe( ialu_cr_reg_mem );
11969 %}
11970
11971 instruct testI_reg( eFlagsReg cr, eRegI src, immI0 zero ) %{
11972 match(Set cr (CmpI src zero));
11973 effect( DEF cr, USE src );
11974
11975 format %{ "TEST $src,$src" %}
11976 opcode(0x85);
11977 ins_encode( OpcP, RegReg( src, src ) );
11978 ins_pipe( ialu_cr_reg_imm );
11979 %}
11980
11981 instruct testI_reg_imm( eFlagsReg cr, eRegI src, immI con, immI0 zero ) %{
11982 match(Set cr (CmpI (AndI src con) zero));
11983
11984 format %{ "TEST $src,$con" %}
11985 opcode(0xF7,0x00);
11986 ins_encode( OpcP, RegOpc(src), Con32(con) );
11987 ins_pipe( ialu_cr_reg_imm );
11988 %}
11989
11990 instruct testI_reg_mem( eFlagsReg cr, eRegI src, memory mem, immI0 zero ) %{
11991 match(Set cr (CmpI (AndI src mem) zero));
11992
11993 format %{ "TEST $src,$mem" %}
11994 opcode(0x85);
11995 ins_encode( OpcP, RegMem( src, mem ) );
11996 ins_pipe( ialu_cr_reg_mem );
11997 %}
11998
11999 // Unsigned compare Instructions; really, same as signed except they
12000 // produce an eFlagsRegU instead of eFlagsReg.
12001 instruct compU_eReg(eFlagsRegU cr, eRegI op1, eRegI op2) %{
12002 match(Set cr (CmpU op1 op2));
12003
12004 format %{ "CMPu $op1,$op2" %}
12005 opcode(0x3B); /* Opcode 3B /r */
12006 ins_encode( OpcP, RegReg( op1, op2) );
12007 ins_pipe( ialu_cr_reg_reg );
12008 %}
12009
12010 instruct compU_eReg_imm(eFlagsRegU cr, eRegI op1, immI op2) %{
12011 match(Set cr (CmpU op1 op2));
12012
12013 format %{ "CMPu $op1,$op2" %}
12014 opcode(0x81,0x07); /* Opcode 81 /7 */
12015 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) );
12016 ins_pipe( ialu_cr_reg_imm );
12017 %}
12018
12019 // // Cisc-spilled version of cmpU_eReg
12020 instruct compU_eReg_mem(eFlagsRegU cr, eRegI op1, memory op2) %{
12021 match(Set cr (CmpU op1 (LoadI op2)));
12022
12023 format %{ "CMPu $op1,$op2" %}
12024 ins_cost(500);
12025 opcode(0x3B); /* Opcode 3B /r */
12026 ins_encode( OpcP, RegMem( op1, op2) );
12027 ins_pipe( ialu_cr_reg_mem );
12028 %}
12029
12030 // // Cisc-spilled version of cmpU_eReg
12031 //instruct compU_mem_eReg(eFlagsRegU cr, memory op1, eRegI op2) %{
12032 // match(Set cr (CmpU (LoadI op1) op2));
12033 //
12034 // format %{ "CMPu $op1,$op2" %}
12035 // ins_cost(500);
12036 // opcode(0x39); /* Opcode 39 /r */
12037 // ins_encode( OpcP, RegMem( op1, op2) );
12038 //%}
12039
12040 instruct testU_reg( eFlagsRegU cr, eRegI src, immI0 zero ) %{
12041 match(Set cr (CmpU src zero));
12042
12043 format %{ "TESTu $src,$src" %}
12044 opcode(0x85);
12045 ins_encode( OpcP, RegReg( src, src ) );
12046 ins_pipe( ialu_cr_reg_imm );
12047 %}
12048
12049 // Unsigned pointer compare Instructions
12050 instruct compP_eReg(eFlagsRegU cr, eRegP op1, eRegP op2) %{
12051 match(Set cr (CmpP op1 op2));
12052
12053 format %{ "CMPu $op1,$op2" %}
12054 opcode(0x3B); /* Opcode 3B /r */
12055 ins_encode( OpcP, RegReg( op1, op2) );
12056 ins_pipe( ialu_cr_reg_reg );
12057 %}
12058
12059 instruct compP_eReg_imm(eFlagsRegU cr, eRegP op1, immP op2) %{
12060 match(Set cr (CmpP op1 op2));
12116 // since any compare to a zero should be eq/neq.
12117 instruct testP_Reg_mem( eFlagsReg cr, memory op, immI0 zero ) %{
12118 match(Set cr (CmpP (LoadP op) zero));
12119
12120 format %{ "TEST $op,0xFFFFFFFF" %}
12121 ins_cost(500);
12122 opcode(0xF7); /* Opcode F7 /0 */
12123 ins_encode( OpcP, RMopc_Mem(0x00,op), Con_d32(0xFFFFFFFF) );
12124 ins_pipe( ialu_cr_reg_imm );
12125 %}
12126
12127 // Yanked all unsigned pointer compare operations.
12128 // Pointer compares are done with CmpP which is already unsigned.
12129
12130 //----------Max and Min--------------------------------------------------------
12131 // Min Instructions
12132 ////
12133 // *** Min and Max using the conditional move are slower than the
12134 // *** branch version on a Pentium III.
12135 // // Conditional move for min
12136 //instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
12137 // effect( USE_DEF op2, USE op1, USE cr );
12138 // format %{ "CMOVlt $op2,$op1\t! min" %}
12139 // opcode(0x4C,0x0F);
12140 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
12141 // ins_pipe( pipe_cmov_reg );
12142 //%}
12143 //
12144 //// Min Register with Register (P6 version)
12145 //instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
12146 // predicate(VM_Version::supports_cmov() );
12147 // match(Set op2 (MinI op1 op2));
12148 // ins_cost(200);
12149 // expand %{
12150 // eFlagsReg cr;
12151 // compI_eReg(cr,op1,op2);
12152 // cmovI_reg_lt(op2,op1,cr);
12153 // %}
12154 //%}
12155
12156 // Min Register with Register (generic version)
12157 instruct minI_eReg(eRegI dst, eRegI src, eFlagsReg flags) %{
12158 match(Set dst (MinI dst src));
12159 effect(KILL flags);
12160 ins_cost(300);
12161
12162 format %{ "MIN $dst,$src" %}
12163 opcode(0xCC);
12164 ins_encode( min_enc(dst,src) );
12165 ins_pipe( pipe_slow );
12166 %}
12167
12168 // Max Register with Register
12169 // *** Min and Max using the conditional move are slower than the
12170 // *** branch version on a Pentium III.
12171 // // Conditional move for max
12172 //instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
12173 // effect( USE_DEF op2, USE op1, USE cr );
12174 // format %{ "CMOVgt $op2,$op1\t! max" %}
12175 // opcode(0x4F,0x0F);
12176 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
12177 // ins_pipe( pipe_cmov_reg );
12178 //%}
12179 //
12180 // // Max Register with Register (P6 version)
12181 //instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
12182 // predicate(VM_Version::supports_cmov() );
12183 // match(Set op2 (MaxI op1 op2));
12184 // ins_cost(200);
12185 // expand %{
12186 // eFlagsReg cr;
12187 // compI_eReg(cr,op1,op2);
12188 // cmovI_reg_gt(op2,op1,cr);
12189 // %}
12190 //%}
12191
12192 // Max Register with Register (generic version)
12193 instruct maxI_eReg(eRegI dst, eRegI src, eFlagsReg flags) %{
12194 match(Set dst (MaxI dst src));
12195 effect(KILL flags);
12196 ins_cost(300);
12197
12198 format %{ "MAX $dst,$src" %}
12199 opcode(0xCC);
12200 ins_encode( max_enc(dst,src) );
12201 ins_pipe( pipe_slow );
12202 %}
12203
12204 // ============================================================================
12205 // Counted Loop limit node which represents exact final iterator value.
12206 // Note: the resulting value should fit into integer range since
12207 // counted loops have limit check on overflow.
12208 instruct loopLimit_eReg(eAXRegI limit, nadxRegI init, immI stride, eDXRegI limit_hi, nadxRegI tmp, eFlagsReg flags) %{
12209 match(Set limit (LoopLimit (Binary init limit) stride));
12210 effect(TEMP limit_hi, TEMP tmp, KILL flags);
12211 ins_cost(300);
12212
12213 format %{ "loopLimit $init,$limit,$stride # $limit = $init + $stride *( $limit - $init + $stride -1)/ $stride, kills $limit_hi" %}
12234 __ lneg($limit_hi$$Register, $limit$$Register);
12235 __ movl($tmp$$Register, -strd);
12236 }
12237 // signed devision: (EAX:EDX) / pos_stride
12238 __ idivl($tmp$$Register);
12239 if (strd < 0) {
12240 // restore sign
12241 __ negl($tmp$$Register);
12242 }
12243 // (EAX) * stride
12244 __ mull($tmp$$Register);
12245 // + init (ignore upper bits)
12246 __ addl($limit$$Register, $init$$Register);
12247 %}
12248 ins_pipe( pipe_slow );
12249 %}
12250
12251 // ============================================================================
12252 // Branch Instructions
12253 // Jump Table
12254 instruct jumpXtnd(eRegI switch_val) %{
12255 match(Jump switch_val);
12256 ins_cost(350);
12257 format %{ "JMP [$constantaddress](,$switch_val,1)\n\t" %}
12258 ins_encode %{
12259 // Jump to Address(table_base + switch_reg)
12260 Address index(noreg, $switch_val$$Register, Address::times_1);
12261 __ jump(ArrayAddress($constantaddress, index));
12262 %}
12263 ins_pipe(pipe_jmp);
12264 %}
12265
12266 // Jump Direct - Label defines a relative address from JMP+1
12267 instruct jmpDir(label labl) %{
12268 match(Goto);
12269 effect(USE labl);
12270
12271 ins_cost(300);
12272 format %{ "JMP $labl" %}
12273 size(5);
12274 ins_encode %{
12652 %}
12653 ins_pipe( pipe_slow );
12654 %}
12655
12656 //======
12657 // Manifest a CmpL result in the normal flags. Only good for LT or GE
12658 // compares. Can be used for LE or GT compares by reversing arguments.
12659 // NOT GOOD FOR EQ/NE tests.
12660 instruct cmpL_zero_flags_LTGE( flagsReg_long_LTGE flags, eRegL src, immL0 zero ) %{
12661 match( Set flags (CmpL src zero ));
12662 ins_cost(100);
12663 format %{ "TEST $src.hi,$src.hi" %}
12664 opcode(0x85);
12665 ins_encode( OpcP, RegReg_Hi2( src, src ) );
12666 ins_pipe( ialu_cr_reg_reg );
12667 %}
12668
12669 // Manifest a CmpL result in the normal flags. Only good for LT or GE
12670 // compares. Can be used for LE or GT compares by reversing arguments.
12671 // NOT GOOD FOR EQ/NE tests.
12672 instruct cmpL_reg_flags_LTGE( flagsReg_long_LTGE flags, eRegL src1, eRegL src2, eRegI tmp ) %{
12673 match( Set flags (CmpL src1 src2 ));
12674 effect( TEMP tmp );
12675 ins_cost(300);
12676 format %{ "CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t"
12677 "MOV $tmp,$src1.hi\n\t"
12678 "SBB $tmp,$src2.hi\t! Compute flags for long compare" %}
12679 ins_encode( long_cmp_flags2( src1, src2, tmp ) );
12680 ins_pipe( ialu_cr_reg_reg );
12681 %}
12682
12683 // Long compares reg < zero/req OR reg >= zero/req.
12684 // Just a wrapper for a normal branch, plus the predicate test.
12685 instruct cmpL_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, label labl) %{
12686 match(If cmp flags);
12687 effect(USE labl);
12688 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
12689 expand %{
12690 jmpCon(cmp,flags,labl); // JLT or JGE...
12691 %}
12692 %}
12698 ins_cost(400);
12699 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12700 "CMOV$cmp $dst.hi,$src.hi" %}
12701 opcode(0x0F,0x40);
12702 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12703 ins_pipe( pipe_cmov_reg_long );
12704 %}
12705
12706 instruct cmovLL_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, load_long_memory src) %{
12707 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12708 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
12709 ins_cost(500);
12710 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12711 "CMOV$cmp $dst.hi,$src.hi" %}
12712 opcode(0x0F,0x40);
12713 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );
12714 ins_pipe( pipe_cmov_reg_long );
12715 %}
12716
12717 // Compare 2 longs and CMOVE ints.
12718 instruct cmovII_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegI dst, eRegI src) %{
12719 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
12720 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
12721 ins_cost(200);
12722 format %{ "CMOV$cmp $dst,$src" %}
12723 opcode(0x0F,0x40);
12724 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12725 ins_pipe( pipe_cmov_reg );
12726 %}
12727
12728 instruct cmovII_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegI dst, memory src) %{
12729 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
12730 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
12731 ins_cost(250);
12732 format %{ "CMOV$cmp $dst,$src" %}
12733 opcode(0x0F,0x40);
12734 ins_encode( enc_cmov(cmp), RegMem( dst, src ) );
12735 ins_pipe( pipe_cmov_mem );
12736 %}
12737
12738 // Compare 2 longs and CMOVE ints.
12739 instruct cmovPP_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegP dst, eRegP src) %{
12740 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
12741 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src)));
12742 ins_cost(200);
12743 format %{ "CMOV$cmp $dst,$src" %}
12744 opcode(0x0F,0x40);
12745 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12746 ins_pipe( pipe_cmov_reg );
12747 %}
12748
12769 instruct cmovFFPR_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regFPR dst, regFPR src) %{
12770 predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
12771 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
12772 ins_cost(200);
12773 expand %{
12774 fcmovFPR_regS(cmp,flags,dst,src);
12775 %}
12776 %}
12777
12778 instruct cmovFF_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regF dst, regF src) %{
12779 predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
12780 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
12781 ins_cost(200);
12782 expand %{
12783 fcmovF_regS(cmp,flags,dst,src);
12784 %}
12785 %}
12786
12787 //======
12788 // Manifest a CmpL result in the normal flags. Only good for EQ/NE compares.
12789 instruct cmpL_zero_flags_EQNE( flagsReg_long_EQNE flags, eRegL src, immL0 zero, eRegI tmp ) %{
12790 match( Set flags (CmpL src zero ));
12791 effect(TEMP tmp);
12792 ins_cost(200);
12793 format %{ "MOV $tmp,$src.lo\n\t"
12794 "OR $tmp,$src.hi\t! Long is EQ/NE 0?" %}
12795 ins_encode( long_cmp_flags0( src, tmp ) );
12796 ins_pipe( ialu_reg_reg_long );
12797 %}
12798
12799 // Manifest a CmpL result in the normal flags. Only good for EQ/NE compares.
12800 instruct cmpL_reg_flags_EQNE( flagsReg_long_EQNE flags, eRegL src1, eRegL src2 ) %{
12801 match( Set flags (CmpL src1 src2 ));
12802 ins_cost(200+300);
12803 format %{ "CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t"
12804 "JNE,s skip\n\t"
12805 "CMP $src1.hi,$src2.hi\n\t"
12806 "skip:\t" %}
12807 ins_encode( long_cmp_flags1( src1, src2 ) );
12808 ins_pipe( ialu_cr_reg_reg );
12809 %}
12826 ins_cost(400);
12827 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12828 "CMOV$cmp $dst.hi,$src.hi" %}
12829 opcode(0x0F,0x40);
12830 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12831 ins_pipe( pipe_cmov_reg_long );
12832 %}
12833
12834 instruct cmovLL_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, load_long_memory src) %{
12835 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12836 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
12837 ins_cost(500);
12838 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12839 "CMOV$cmp $dst.hi,$src.hi" %}
12840 opcode(0x0F,0x40);
12841 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );
12842 ins_pipe( pipe_cmov_reg_long );
12843 %}
12844
12845 // Compare 2 longs and CMOVE ints.
12846 instruct cmovII_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegI dst, eRegI src) %{
12847 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
12848 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
12849 ins_cost(200);
12850 format %{ "CMOV$cmp $dst,$src" %}
12851 opcode(0x0F,0x40);
12852 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12853 ins_pipe( pipe_cmov_reg );
12854 %}
12855
12856 instruct cmovII_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegI dst, memory src) %{
12857 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
12858 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
12859 ins_cost(250);
12860 format %{ "CMOV$cmp $dst,$src" %}
12861 opcode(0x0F,0x40);
12862 ins_encode( enc_cmov(cmp), RegMem( dst, src ) );
12863 ins_pipe( pipe_cmov_mem );
12864 %}
12865
12866 // Compare 2 longs and CMOVE ints.
12867 instruct cmovPP_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegP dst, eRegP src) %{
12868 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
12869 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src)));
12870 ins_cost(200);
12871 format %{ "CMOV$cmp $dst,$src" %}
12872 opcode(0x0F,0x40);
12873 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12874 ins_pipe( pipe_cmov_reg );
12875 %}
12876
12898 predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
12899 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
12900 ins_cost(200);
12901 expand %{
12902 fcmovFPR_regS(cmp,flags,dst,src);
12903 %}
12904 %}
12905
12906 instruct cmovFF_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regF dst, regF src) %{
12907 predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
12908 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
12909 ins_cost(200);
12910 expand %{
12911 fcmovF_regS(cmp,flags,dst,src);
12912 %}
12913 %}
12914
12915 //======
12916 // Manifest a CmpL result in the normal flags. Only good for LE or GT compares.
12917 // Same as cmpL_reg_flags_LEGT except must negate src
12918 instruct cmpL_zero_flags_LEGT( flagsReg_long_LEGT flags, eRegL src, immL0 zero, eRegI tmp ) %{
12919 match( Set flags (CmpL src zero ));
12920 effect( TEMP tmp );
12921 ins_cost(300);
12922 format %{ "XOR $tmp,$tmp\t# Long compare for -$src < 0, use commuted test\n\t"
12923 "CMP $tmp,$src.lo\n\t"
12924 "SBB $tmp,$src.hi\n\t" %}
12925 ins_encode( long_cmp_flags3(src, tmp) );
12926 ins_pipe( ialu_reg_reg_long );
12927 %}
12928
12929 // Manifest a CmpL result in the normal flags. Only good for LE or GT compares.
12930 // Same as cmpL_reg_flags_LTGE except operands swapped. Swapping operands
12931 // requires a commuted test to get the same result.
12932 instruct cmpL_reg_flags_LEGT( flagsReg_long_LEGT flags, eRegL src1, eRegL src2, eRegI tmp ) %{
12933 match( Set flags (CmpL src1 src2 ));
12934 effect( TEMP tmp );
12935 ins_cost(300);
12936 format %{ "CMP $src2.lo,$src1.lo\t! Long compare, swapped operands, use with commuted test\n\t"
12937 "MOV $tmp,$src2.hi\n\t"
12938 "SBB $tmp,$src1.hi\t! Compute flags for long compare" %}
12939 ins_encode( long_cmp_flags2( src2, src1, tmp ) );
12940 ins_pipe( ialu_cr_reg_reg );
12941 %}
12942
12943 // Long compares reg < zero/req OR reg >= zero/req.
12944 // Just a wrapper for a normal branch, plus the predicate test
12945 instruct cmpL_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, label labl) %{
12946 match(If cmp flags);
12947 effect(USE labl);
12948 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
12949 ins_cost(300);
12950 expand %{
12951 jmpCon(cmp,flags,labl); // JGT or JLE...
12952 %}
12959 ins_cost(400);
12960 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12961 "CMOV$cmp $dst.hi,$src.hi" %}
12962 opcode(0x0F,0x40);
12963 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12964 ins_pipe( pipe_cmov_reg_long );
12965 %}
12966
12967 instruct cmovLL_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, load_long_memory src) %{
12968 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12969 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
12970 ins_cost(500);
12971 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12972 "CMOV$cmp $dst.hi,$src.hi+4" %}
12973 opcode(0x0F,0x40);
12974 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );
12975 ins_pipe( pipe_cmov_reg_long );
12976 %}
12977
12978 // Compare 2 longs and CMOVE ints.
12979 instruct cmovII_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegI dst, eRegI src) %{
12980 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
12981 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
12982 ins_cost(200);
12983 format %{ "CMOV$cmp $dst,$src" %}
12984 opcode(0x0F,0x40);
12985 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12986 ins_pipe( pipe_cmov_reg );
12987 %}
12988
12989 instruct cmovII_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegI dst, memory src) %{
12990 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
12991 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
12992 ins_cost(250);
12993 format %{ "CMOV$cmp $dst,$src" %}
12994 opcode(0x0F,0x40);
12995 ins_encode( enc_cmov(cmp), RegMem( dst, src ) );
12996 ins_pipe( pipe_cmov_mem );
12997 %}
12998
12999 // Compare 2 longs and CMOVE ptrs.
13000 instruct cmovPP_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegP dst, eRegP src) %{
13001 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
13002 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src)));
13003 ins_cost(200);
13004 format %{ "CMOV$cmp $dst,$src" %}
13005 opcode(0x0F,0x40);
13006 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
13007 ins_pipe( pipe_cmov_reg );
13008 %}
13009
13298 //
13299 // ---------VM FLAGS---------------------------------------------------------
13300 //
13301 // All peephole optimizations can be turned off using -XX:-OptoPeephole
13302 //
13303 // Each peephole rule is given an identifying number starting with zero and
13304 // increasing by one in the order seen by the parser. An individual peephole
13305 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
13306 // on the command-line.
13307 //
13308 // ---------CURRENT LIMITATIONS----------------------------------------------
13309 //
13310 // Only match adjacent instructions in same basic block
13311 // Only equality constraints
13312 // Only constraints between operands, not (0.dest_reg == EAX_enc)
13313 // Only one replacement instruction
13314 //
13315 // ---------EXAMPLE----------------------------------------------------------
13316 //
13317 // // pertinent parts of existing instructions in architecture description
13318 // instruct movI(eRegI dst, eRegI src) %{
13319 // match(Set dst (CopyI src));
13320 // %}
13321 //
13322 // instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
13323 // match(Set dst (AddI dst src));
13324 // effect(KILL cr);
13325 // %}
13326 //
13327 // // Change (inc mov) to lea
13328 // peephole %{
13329 // // increment preceeded by register-register move
13330 // peepmatch ( incI_eReg movI );
13331 // // require that the destination register of the increment
13332 // // match the destination register of the move
13333 // peepconstraint ( 0.dst == 1.dst );
13334 // // construct a replacement instruction that sets
13335 // // the destination to ( move's source register + one )
13336 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13337 // %}
13338 //
13339 // Implementation no longer uses movX instructions since
13340 // machine-independent system no longer uses CopyX nodes.
13341 //
13342 // peephole %{
13347 //
13348 // peephole %{
13349 // peepmatch ( decI_eReg movI );
13350 // peepconstraint ( 0.dst == 1.dst );
13351 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13352 // %}
13353 //
13354 // peephole %{
13355 // peepmatch ( addI_eReg_imm movI );
13356 // peepconstraint ( 0.dst == 1.dst );
13357 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13358 // %}
13359 //
13360 // peephole %{
13361 // peepmatch ( addP_eReg_imm movP );
13362 // peepconstraint ( 0.dst == 1.dst );
13363 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
13364 // %}
13365
13366 // // Change load of spilled value to only a spill
13367 // instruct storeI(memory mem, eRegI src) %{
13368 // match(Set mem (StoreI mem src));
13369 // %}
13370 //
13371 // instruct loadI(eRegI dst, memory mem) %{
13372 // match(Set dst (LoadI mem));
13373 // %}
13374 //
13375 peephole %{
13376 peepmatch ( loadI storeI );
13377 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
13378 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
13379 %}
13380
13381 //----------SMARTSPILL RULES---------------------------------------------------
13382 // These must follow all instruction definitions as they use the names
13383 // defined in the instructions definitions.
|
57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI.
59 //
60 // The encoding number is the actual bit-pattern placed into the opcodes.
61
62 // General Registers
63 // Previously set EBX, ESI, and EDI as save-on-entry for java code
64 // Turn off SOE in java-code due to frequent use of uncommon-traps.
65 // Now that allocator is better, turn on ESI and EDI as SOE registers.
66
67 reg_def EBX(SOC, SOE, Op_RegI, 3, rbx->as_VMReg());
68 reg_def ECX(SOC, SOC, Op_RegI, 1, rcx->as_VMReg());
69 reg_def ESI(SOC, SOE, Op_RegI, 6, rsi->as_VMReg());
70 reg_def EDI(SOC, SOE, Op_RegI, 7, rdi->as_VMReg());
71 // now that adapter frames are gone EBP is always saved and restored by the prolog/epilog code
72 reg_def EBP(NS, SOE, Op_RegI, 5, rbp->as_VMReg());
73 reg_def EDX(SOC, SOC, Op_RegI, 2, rdx->as_VMReg());
74 reg_def EAX(SOC, SOC, Op_RegI, 0, rax->as_VMReg());
75 reg_def ESP( NS, NS, Op_RegI, 4, rsp->as_VMReg());
76
77 // Float registers. We treat TOS/FPR0 special. It is invisible to the
78 // allocator, and only shows up in the encodings.
79 reg_def FPR0L( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad());
80 reg_def FPR0H( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad());
81 // Ok so here's the trick FPR1 is really st(0) except in the midst
82 // of emission of assembly for a machnode. During the emission the fpu stack
83 // is pushed making FPR1 == st(1) temporarily. However at any safepoint
84 // the stack will not have this element so FPR1 == st(0) from the
85 // oopMap viewpoint. This same weirdness with numbering causes
86 // instruction encoding to have to play games with the register
87 // encode to correct for this 0/1 issue. See MachSpillCopyNode::implementation
88 // where it does flt->flt moves to see an example
89 //
90 reg_def FPR1L( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg());
91 reg_def FPR1H( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg()->next());
92 reg_def FPR2L( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg());
93 reg_def FPR2H( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg()->next());
94 reg_def FPR3L( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg());
95 reg_def FPR3H( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg()->next());
96 reg_def FPR4L( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg());
97 reg_def FPR4H( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg()->next());
98 reg_def FPR5L( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg());
99 reg_def FPR5H( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg()->next());
100 reg_def FPR6L( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg());
101 reg_def FPR6H( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg()->next());
102 reg_def FPR7L( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg());
103 reg_def FPR7H( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next());
104
105 // Specify priority of register selection within phases of register
106 // allocation. Highest priority is first. A useful heuristic is to
107 // give registers a low priority when they are required by machine
108 // instructions, like EAX and EDX. Registers which are used as
109 // pairs must fall on an even boundary (witness the FPR#L's in this list).
110 // For the Intel integer registers, the equivalent Long pairs are
111 // EDX:EAX, EBX:ECX, and EDI:EBP.
112 alloc_class chunk0( ECX, EBX, EBP, EDI, EAX, EDX, ESI, ESP,
113 FPR0L, FPR0H, FPR1L, FPR1H, FPR2L, FPR2H,
114 FPR3L, FPR3H, FPR4L, FPR4H, FPR5L, FPR5H,
115 FPR6L, FPR6H, FPR7L, FPR7H );
116
117
118 //----------Architecture Description Register Classes--------------------------
119 // Several register classes are automatically defined based upon information in
120 // this architecture description.
121 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ )
122 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ )
123 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
124 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
125 //
126 // Class for all registers
127 reg_class any_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX, ESP);
128 // Class for general registers
129 reg_class int_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX);
130 // Class for general registers which may be used for implicit null checks on win95
131 // Also safe for use by tailjump. We don't want to allocate in rbp,
132 reg_class int_reg_no_rbp(EAX, EDX, EDI, ESI, ECX, EBX);
133 // Class of "X" registers
134 reg_class int_x_reg(EBX, ECX, EDX, EAX);
135 // Class of registers that can appear in an address with no offset.
136 // EBP and ESP require an extra instruction byte for zero offset.
137 // Used in fast-unlock
138 reg_class p_reg(EDX, EDI, ESI, EBX);
139 // Class for general registers not including ECX
140 reg_class ncx_reg(EAX, EDX, EBP, EDI, ESI, EBX);
141 // Class for general registers not including EAX
142 reg_class nax_reg(EDX, EDI, ESI, ECX, EBX);
143 // Class for general registers not including EAX or EBX.
144 reg_class nabx_reg(EDX, EDI, ESI, ECX, EBP);
145 // Class of EAX (for multiply and divide operations)
146 reg_class eax_reg(EAX);
147 // Class of EBX (for atomic add)
148 reg_class ebx_reg(EBX);
149 // Class of ECX (for shift and JCXZ operations and cmpLTMask)
150 reg_class ecx_reg(ECX);
151 // Class of EDX (for multiply and divide operations)
152 reg_class edx_reg(EDX);
153 // Class of EDI (for synchronization)
154 reg_class edi_reg(EDI);
155 // Class of ESI (for synchronization)
156 reg_class esi_reg(ESI);
157 // Singleton class for interpreter's stack pointer
158 reg_class ebp_reg(EBP);
159 // Singleton class for stack pointer
160 reg_class sp_reg(ESP);
161 // Singleton class for instruction pointer
162 // reg_class ip_reg(EIP);
163 // Class of integer register pairs
164 reg_class long_reg( EAX,EDX, ECX,EBX, EBP,EDI );
165 // Class of integer register pairs that aligns with calling convention
166 reg_class eadx_reg( EAX,EDX );
167 reg_class ebcx_reg( ECX,EBX );
168 // Not AX or DX, used in divides
169 reg_class nadx_reg( EBX,ECX,ESI,EDI,EBP );
170
171 // Floating point registers. Notice FPR0 is not a choice.
172 // FPR0 is not ever allocated; we use clever encodings to fake
173 // a 2-address instructions out of Intels FP stack.
174 reg_class fp_flt_reg( FPR1L,FPR2L,FPR3L,FPR4L,FPR5L,FPR6L,FPR7L );
175
176 reg_class fp_dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H,
177 FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H,
178 FPR7L,FPR7H );
179
180 reg_class fp_flt_reg0( FPR1L );
181 reg_class fp_dbl_reg0( FPR1L,FPR1H );
182 reg_class fp_dbl_reg1( FPR2L,FPR2H );
183 reg_class fp_dbl_notreg0( FPR2L,FPR2H, FPR3L,FPR3H, FPR4L,FPR4H,
184 FPR5L,FPR5H, FPR6L,FPR6H, FPR7L,FPR7H );
185
186 %}
187
188
189 //----------SOURCE BLOCK-------------------------------------------------------
190 // This is a block of C++ code which provides values, functions, and
191 // definitions necessary in the rest of the architecture description
192 source_hpp %{
193 // Must be visible to the DFA in dfa_x86_32.cpp
194 extern bool is_operand_hi32_zero(Node* n);
195 %}
196
197 source %{
198 #define RELOC_IMM32 Assembler::imm_operand
199 #define RELOC_DISP32 Assembler::disp32_operand
200
201 #define __ _masm.
202
203 // How to find the high register of a Long pair, given the low register
204 #define HIGH_FROM_LOW(x) ((x)+2)
205
349 }
350 #endif
351 cbuf.relocate(cbuf.insts_mark(), rspec, format);
352 cbuf.insts()->emit_int32(d32);
353 }
354
355 // Access stack slot for load or store
356 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) {
357 emit_opcode( cbuf, opcode ); // (e.g., FILD [ESP+src])
358 if( -128 <= disp && disp <= 127 ) {
359 emit_rm( cbuf, 0x01, rm_field, ESP_enc ); // R/M byte
360 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte
361 emit_d8 (cbuf, disp); // Displacement // R/M byte
362 } else {
363 emit_rm( cbuf, 0x02, rm_field, ESP_enc ); // R/M byte
364 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte
365 emit_d32(cbuf, disp); // Displacement // R/M byte
366 }
367 }
368
369 // rRegI ereg, memory mem) %{ // emit_reg_mem
370 void encode_RegMem( CodeBuffer &cbuf, int reg_encoding, int base, int index, int scale, int displace, bool displace_is_oop ) {
371 // There is no index & no scale, use form without SIB byte
372 if ((index == 0x4) &&
373 (scale == 0) && (base != ESP_enc)) {
374 // If no displacement, mode is 0x0; unless base is [EBP]
375 if ( (displace == 0) && (base != EBP_enc) ) {
376 emit_rm(cbuf, 0x0, reg_encoding, base);
377 }
378 else { // If 8-bit displacement, mode 0x1
379 if ((displace >= -128) && (displace <= 127)
380 && !(displace_is_oop) ) {
381 emit_rm(cbuf, 0x1, reg_encoding, base);
382 emit_d8(cbuf, displace);
383 }
384 else { // If 32-bit displacement
385 if (base == -1) { // Special flag for absolute address
386 emit_rm(cbuf, 0x0, reg_encoding, 0x5);
387 // (manual lies; no SIB needed here)
388 if ( displace_is_oop ) {
389 emit_d32_reloc(cbuf, displace, relocInfo::oop_type, 1);
724 }
725 }
726 #ifndef PRODUCT
727 } else if (!do_size) {
728 if (size != 0) st->print("\n\t");
729 if (reg_lo+1 == reg_hi) { // double move?
730 if (is_load) st->print("%s %s,[ESP + #%d]",
731 UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD",
732 Matcher::regName[reg_lo], offset);
733 else st->print("MOVSD [ESP + #%d],%s",
734 offset, Matcher::regName[reg_lo]);
735 } else {
736 if (is_load) st->print("MOVSS %s,[ESP + #%d]",
737 Matcher::regName[reg_lo], offset);
738 else st->print("MOVSS [ESP + #%d],%s",
739 offset, Matcher::regName[reg_lo]);
740 }
741 #endif
742 }
743 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
744 // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes as SIMD prefix.
745 return size+5+offset_size;
746 }
747
748
749 static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
750 int src_hi, int dst_hi, int size, outputStream* st ) {
751 if (cbuf) {
752 MacroAssembler _masm(cbuf);
753 if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move?
754 __ movdbl(as_XMMRegister(Matcher::_regEncode[dst_lo]),
755 as_XMMRegister(Matcher::_regEncode[src_lo]));
756 } else {
757 __ movflt(as_XMMRegister(Matcher::_regEncode[dst_lo]),
758 as_XMMRegister(Matcher::_regEncode[src_lo]));
759 }
760 #ifndef PRODUCT
761 } else if (!do_size) {
762 if (size != 0) st->print("\n\t");
763 if (UseXmmRegToRegMoveAll) {//Use movaps,movapd to move between xmm registers
764 if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move?
765 st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
766 } else {
767 st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
768 }
769 } else {
770 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move?
771 st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
772 } else {
773 st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
774 }
775 }
776 #endif
777 }
778 // VEX_2bytes prefix is used if UseAVX > 0, and it takes the same 2 bytes as SIMD prefix.
779 // Only MOVAPS SSE prefix uses 1 byte.
780 int sz = 4;
781 if (!(src_lo+1 == src_hi && dst_lo+1 == dst_hi) &&
782 UseXmmRegToRegMoveAll && (UseAVX == 0)) sz = 3;
783 return size + sz;
784 }
785
786 static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
787 int src_hi, int dst_hi, int size, outputStream* st ) {
788 // 32-bit
789 if (cbuf) {
790 MacroAssembler _masm(cbuf);
791 __ movdl(as_XMMRegister(Matcher::_regEncode[dst_lo]),
792 as_Register(Matcher::_regEncode[src_lo]));
793 #ifndef PRODUCT
794 } else if (!do_size) {
795 st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
796 #endif
797 }
798 return 4;
840 #endif
841 }
842 size += 2;
843 }
844
845 int st_op = (src_lo != FPR1L_num) ? EBX_num /*store & pop*/ : EDX_num /*store no pop*/;
846 const char *op_str;
847 int op;
848 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double store?
849 op_str = (src_lo != FPR1L_num) ? "FSTP_D" : "FST_D ";
850 op = 0xDD;
851 } else { // 32-bit store
852 op_str = (src_lo != FPR1L_num) ? "FSTP_S" : "FST_S ";
853 op = 0xD9;
854 assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" );
855 }
856
857 return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
858 }
859
860 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad.
861 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
862 int src_hi, int dst_hi, uint ireg, outputStream* st);
863
864 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
865 int stack_offset, int reg, uint ireg, outputStream* st);
866
867 static int vec_stack_to_stack_helper(CodeBuffer *cbuf, bool do_size, int src_offset,
868 int dst_offset, uint ireg, outputStream* st) {
869 int calc_size = 0;
870 int src_offset_size = (src_offset == 0) ? 0 : ((src_offset < 0x80) ? 1 : 4);
871 int dst_offset_size = (dst_offset == 0) ? 0 : ((dst_offset < 0x80) ? 1 : 4);
872 switch (ireg) {
873 case Op_VecS:
874 calc_size = 3+src_offset_size + 3+dst_offset_size;
875 break;
876 case Op_VecD:
877 calc_size = 3+src_offset_size + 3+dst_offset_size;
878 src_offset += 4;
879 dst_offset += 4;
880 src_offset_size = (src_offset == 0) ? 0 : ((src_offset < 0x80) ? 1 : 4);
881 dst_offset_size = (dst_offset == 0) ? 0 : ((dst_offset < 0x80) ? 1 : 4);
882 calc_size += 3+src_offset_size + 3+dst_offset_size;
883 break;
884 case Op_VecX:
885 calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size;
886 break;
887 case Op_VecY:
888 calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size;
889 break;
890 default:
891 ShouldNotReachHere();
892 }
893 if (cbuf) {
894 MacroAssembler _masm(cbuf);
895 int offset = __ offset();
896 switch (ireg) {
897 case Op_VecS:
898 __ pushl(Address(rsp, src_offset));
899 __ popl (Address(rsp, dst_offset));
900 break;
901 case Op_VecD:
902 __ pushl(Address(rsp, src_offset));
903 __ popl (Address(rsp, dst_offset));
904 __ pushl(Address(rsp, src_offset+4));
905 __ popl (Address(rsp, dst_offset+4));
906 break;
907 case Op_VecX:
908 __ movdqu(Address(rsp, -16), xmm0);
909 __ movdqu(xmm0, Address(rsp, src_offset));
910 __ movdqu(Address(rsp, dst_offset), xmm0);
911 __ movdqu(xmm0, Address(rsp, -16));
912 break;
913 case Op_VecY:
914 __ vmovdqu(Address(rsp, -32), xmm0);
915 __ vmovdqu(xmm0, Address(rsp, src_offset));
916 __ vmovdqu(Address(rsp, dst_offset), xmm0);
917 __ vmovdqu(xmm0, Address(rsp, -32));
918 break;
919 default:
920 ShouldNotReachHere();
921 }
922 int size = __ offset() - offset;
923 assert(size == calc_size, "incorrect size calculattion");
924 return size;
925 #ifndef PRODUCT
926 } else if (!do_size) {
927 switch (ireg) {
928 case Op_VecS:
929 st->print("pushl [rsp + #%d]\t# 32-bit mem-mem spill\n\t"
930 "popl [rsp + #%d]",
931 src_offset, dst_offset);
932 break;
933 case Op_VecD:
934 st->print("pushl [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
935 "popq [rsp + #%d]\n\t"
936 "pushl [rsp + #%d]\n\t"
937 "popq [rsp + #%d]",
938 src_offset, dst_offset, src_offset+4, dst_offset+4);
939 break;
940 case Op_VecX:
941 st->print("movdqu [rsp - #16], xmm0\t# 128-bit mem-mem spill\n\t"
942 "movdqu xmm0, [rsp + #%d]\n\t"
943 "movdqu [rsp + #%d], xmm0\n\t"
944 "movdqu xmm0, [rsp - #16]",
945 src_offset, dst_offset);
946 break;
947 case Op_VecY:
948 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
949 "vmovdqu xmm0, [rsp + #%d]\n\t"
950 "vmovdqu [rsp + #%d], xmm0\n\t"
951 "vmovdqu xmm0, [rsp - #32]",
952 src_offset, dst_offset);
953 break;
954 default:
955 ShouldNotReachHere();
956 }
957 #endif
958 }
959 return calc_size;
960 }
961
962 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
963 // Get registers to move
964 OptoReg::Name src_second = ra_->get_reg_second(in(1));
965 OptoReg::Name src_first = ra_->get_reg_first(in(1));
966 OptoReg::Name dst_second = ra_->get_reg_second(this );
967 OptoReg::Name dst_first = ra_->get_reg_first(this );
968
969 enum RC src_second_rc = rc_class(src_second);
970 enum RC src_first_rc = rc_class(src_first);
971 enum RC dst_second_rc = rc_class(dst_second);
972 enum RC dst_first_rc = rc_class(dst_first);
973
974 assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" );
975
976 // Generate spill code!
977 int size = 0;
978
979 if( src_first == dst_first && src_second == dst_second )
980 return size; // Self copy, no move
981
982 if (bottom_type()->isa_vect() != NULL) {
983 uint ireg = ideal_reg();
984 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
985 assert((src_first_rc != rc_float && dst_first_rc != rc_float), "sanity");
986 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
987 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
988 // mem -> mem
989 int src_offset = ra_->reg2offset(src_first);
990 int dst_offset = ra_->reg2offset(dst_first);
991 return vec_stack_to_stack_helper(cbuf, do_size, src_offset, dst_offset, ireg, st);
992 } else if (src_first_rc == rc_xmm && dst_first_rc == rc_xmm ) {
993 return vec_mov_helper(cbuf, do_size, src_first, dst_first, src_second, dst_second, ireg, st);
994 } else if (src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
995 int stack_offset = ra_->reg2offset(dst_first);
996 return vec_spill_helper(cbuf, do_size, false, stack_offset, src_first, ireg, st);
997 } else if (src_first_rc == rc_stack && dst_first_rc == rc_xmm ) {
998 int stack_offset = ra_->reg2offset(src_first);
999 return vec_spill_helper(cbuf, do_size, true, stack_offset, dst_first, ireg, st);
1000 } else {
1001 ShouldNotReachHere();
1002 }
1003 }
1004
1005 // --------------------------------------
1006 // Check for mem-mem move. push/pop to move.
1007 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
1008 if( src_second == dst_first ) { // overlapping stack copy ranges
1009 assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" );
1010 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
1011 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
1012 src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits
1013 }
1014 // move low bits
1015 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size, st);
1016 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size, st);
1017 if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits
1018 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st);
1019 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st);
1020 }
1021 return size;
1022 }
1023
1024 // --------------------------------------
1375 switch (opcode) {
1376 case Op_PopCountI:
1377 case Op_PopCountL:
1378 if (!UsePopCountInstruction)
1379 return false;
1380 break;
1381 }
1382
1383 return true; // Per default match rules are supported.
1384 }
1385
1386 int Matcher::regnum_to_fpu_offset(int regnum) {
1387 return regnum - 32; // The FP registers are in the second chunk
1388 }
1389
1390 // This is UltraSparc specific, true just means we have fast l2f conversion
1391 const bool Matcher::convL2FSupported(void) {
1392 return true;
1393 }
1394
1395 // Is this branch offset short enough that a short branch can be used?
1396 //
1397 // NOTE: If the platform does not provide any short branch variants, then
1398 // this method should return false for offset 0.
1399 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) {
1400 // The passed offset is relative to address of the branch.
1401 // On 86 a branch displacement is calculated relative to address
1402 // of a next instruction.
1403 offset -= br_size;
1404
1405 // the short version of jmpConUCF2 contains multiple branches,
1406 // making the reach slightly less
1407 if (rule == jmpConUCF2_rule)
1408 return (-126 <= offset && offset <= 125);
1409 return (-128 <= offset && offset <= 127);
1410 }
1411
1412 const bool Matcher::isSimpleConstant64(jlong value) {
1413 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?.
1414 return false;
1504 node->_opnds[opcnt] = new_memory;
1505 }
1506
1507 // Advertise here if the CPU requires explicit rounding operations
1508 // to implement the UseStrictFP mode.
1509 const bool Matcher::strict_fp_requires_explicit_rounding = true;
1510
1511 // Are floats conerted to double when stored to stack during deoptimization?
1512 // On x32 it is stored with convertion only when FPU is used for floats.
1513 bool Matcher::float_in_double() { return (UseSSE == 0); }
1514
1515 // Do ints take an entire long register or just half?
1516 const bool Matcher::int_in_long = false;
1517
1518 // Return whether or not this register is ever used as an argument. This
1519 // function is used on startup to build the trampoline stubs in generateOptoStub.
1520 // Registers not mentioned will be killed by the VM call in the trampoline, and
1521 // arguments in those registers not be available to the callee.
1522 bool Matcher::can_be_java_arg( int reg ) {
1523 if( reg == ECX_num || reg == EDX_num ) return true;
1524 if( (reg == XMM0_num || reg == XMM1_num ) && UseSSE>=1 ) return true;
1525 if( (reg == XMM0b_num || reg == XMM1b_num) && UseSSE>=2 ) return true;
1526 return false;
1527 }
1528
1529 bool Matcher::is_spillable_arg( int reg ) {
1530 return can_be_java_arg(reg);
1531 }
1532
1533 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) {
1534 // Use hardware integer DIV instruction when
1535 // it is faster than a code which use multiply.
1536 // Only when constant divisor fits into 32 bit
1537 // (min_jint is excluded to get only correct
1538 // positive 32 bit values from negative).
1539 return VM_Version::has_fast_idiv() &&
1540 (divisor == (int)divisor && divisor != min_jint);
1541 }
1542
1543 // Register for DIVI projection of divmodI
1544 RegMask Matcher::divI_proj_mask() {
1617
1618 // Emit primary opcode
1619 enc_class OpcP %{
1620 emit_opcode(cbuf, $primary);
1621 %}
1622
1623 // Emit secondary opcode
1624 enc_class OpcS %{
1625 emit_opcode(cbuf, $secondary);
1626 %}
1627
1628 // Emit opcode directly
1629 enc_class Opcode(immI d8) %{
1630 emit_opcode(cbuf, $d8$$constant);
1631 %}
1632
1633 enc_class SizePrefix %{
1634 emit_opcode(cbuf,0x66);
1635 %}
1636
1637 enc_class RegReg (rRegI dst, rRegI src) %{ // RegReg(Many)
1638 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
1639 %}
1640
1641 enc_class OpcRegReg (immI opcode, rRegI dst, rRegI src) %{ // OpcRegReg(Many)
1642 emit_opcode(cbuf,$opcode$$constant);
1643 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
1644 %}
1645
1646 enc_class mov_r32_imm0( rRegI dst ) %{
1647 emit_opcode( cbuf, 0xB8 + $dst$$reg ); // 0xB8+ rd -- MOV r32 ,imm32
1648 emit_d32 ( cbuf, 0x0 ); // imm32==0x0
1649 %}
1650
1651 enc_class cdq_enc %{
1652 // Full implementation of Java idiv and irem; checks for
1653 // special case as described in JVM spec., p.243 & p.271.
1654 //
1655 // normal case special case
1656 //
1657 // input : rax,: dividend min_int
1658 // reg: divisor -1
1659 //
1660 // output: rax,: quotient (= rax, idiv reg) min_int
1661 // rdx: remainder (= rax, irem reg) 0
1662 //
1663 // Code sequnce:
1664 //
1665 // 81 F8 00 00 00 80 cmp rax,80000000h
1666 // 0F 85 0B 00 00 00 jne normal_case
1673 // done:
1674 //
1675 emit_opcode(cbuf,0x81); emit_d8(cbuf,0xF8);
1676 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00);
1677 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x80); // cmp rax,80000000h
1678 emit_opcode(cbuf,0x0F); emit_d8(cbuf,0x85);
1679 emit_opcode(cbuf,0x0B); emit_d8(cbuf,0x00);
1680 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); // jne normal_case
1681 emit_opcode(cbuf,0x33); emit_d8(cbuf,0xD2); // xor rdx,edx
1682 emit_opcode(cbuf,0x83); emit_d8(cbuf,0xF9); emit_d8(cbuf,0xFF); // cmp rcx,0FFh
1683 emit_opcode(cbuf,0x0F); emit_d8(cbuf,0x84);
1684 emit_opcode(cbuf,0x03); emit_d8(cbuf,0x00);
1685 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); // je done
1686 // normal_case:
1687 emit_opcode(cbuf,0x99); // cdq
1688 // idiv (note: must be emitted by the user of this rule)
1689 // normal:
1690 %}
1691
1692 // Dense encoding for older common ops
1693 enc_class Opc_plus(immI opcode, rRegI reg) %{
1694 emit_opcode(cbuf, $opcode$$constant + $reg$$reg);
1695 %}
1696
1697
1698 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension
1699 enc_class OpcSE (immI imm) %{ // Emit primary opcode and set sign-extend bit
1700 // Check for 8-bit immediate, and set sign extend bit in opcode
1701 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) {
1702 emit_opcode(cbuf, $primary | 0x02);
1703 }
1704 else { // If 32-bit immediate
1705 emit_opcode(cbuf, $primary);
1706 }
1707 %}
1708
1709 enc_class OpcSErm (rRegI dst, immI imm) %{ // OpcSEr/m
1710 // Emit primary opcode and set sign-extend bit
1711 // Check for 8-bit immediate, and set sign extend bit in opcode
1712 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) {
1713 emit_opcode(cbuf, $primary | 0x02); }
1714 else { // If 32-bit immediate
1715 emit_opcode(cbuf, $primary);
1716 }
1717 // Emit r/m byte with secondary opcode, after primary opcode.
1718 emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
1719 %}
1720
1721 enc_class Con8or32 (immI imm) %{ // Con8or32(storeImmI), 8 or 32 bits
1722 // Check for 8-bit immediate, and set sign extend bit in opcode
1723 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) {
1724 $$$emit8$imm$$constant;
1725 }
1726 else { // If 32-bit immediate
1727 // Output immediate
1728 $$$emit32$imm$$constant;
1729 }
1734 // Check for 8-bit immediate, and set sign extend bit in opcode
1735 int con = (int)$imm$$constant; // Throw away top bits
1736 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary);
1737 // Emit r/m byte with secondary opcode, after primary opcode.
1738 emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
1739 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con);
1740 else emit_d32(cbuf,con);
1741 %}
1742
1743 enc_class Long_OpcSErm_Hi(eRegL dst, immL imm) %{
1744 // Emit primary opcode and set sign-extend bit
1745 // Check for 8-bit immediate, and set sign extend bit in opcode
1746 int con = (int)($imm$$constant >> 32); // Throw away bottom bits
1747 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary);
1748 // Emit r/m byte with tertiary opcode, after primary opcode.
1749 emit_rm(cbuf, 0x3, $tertiary, HIGH_FROM_LOW($dst$$reg));
1750 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con);
1751 else emit_d32(cbuf,con);
1752 %}
1753
1754 enc_class OpcSReg (rRegI dst) %{ // BSWAP
1755 emit_cc(cbuf, $secondary, $dst$$reg );
1756 %}
1757
1758 enc_class bswap_long_bytes(eRegL dst) %{ // BSWAP
1759 int destlo = $dst$$reg;
1760 int desthi = HIGH_FROM_LOW(destlo);
1761 // bswap lo
1762 emit_opcode(cbuf, 0x0F);
1763 emit_cc(cbuf, 0xC8, destlo);
1764 // bswap hi
1765 emit_opcode(cbuf, 0x0F);
1766 emit_cc(cbuf, 0xC8, desthi);
1767 // xchg lo and hi
1768 emit_opcode(cbuf, 0x87);
1769 emit_rm(cbuf, 0x3, destlo, desthi);
1770 %}
1771
1772 enc_class RegOpc (rRegI div) %{ // IDIV, IMOD, JMP indirect, ...
1773 emit_rm(cbuf, 0x3, $secondary, $div$$reg );
1774 %}
1775
1776 enc_class enc_cmov(cmpOp cop ) %{ // CMOV
1777 $$$emit8$primary;
1778 emit_cc(cbuf, $secondary, $cop$$cmpcode);
1779 %}
1780
1781 enc_class enc_cmov_dpr(cmpOp cop, regDPR src ) %{ // CMOV
1782 int op = 0xDA00 + $cop$$cmpcode + ($src$$reg-1);
1783 emit_d8(cbuf, op >> 8 );
1784 emit_d8(cbuf, op & 255);
1785 %}
1786
1787 // emulate a CMOV with a conditional branch around a MOV
1788 enc_class enc_cmov_branch( cmpOp cop, immI brOffs ) %{ // CMOV
1789 // Invert sense of branch from sense of CMOV
1790 emit_cc( cbuf, 0x70, ($cop$$cmpcode^1) );
1791 emit_d8( cbuf, $brOffs$$constant );
1792 %}
1943 // // int ic_encode = Matcher::_regEncode[ic_reg];
1944 // // int imo_reg = Matcher::interpreter_method_oop_reg();
1945 // // int imo_encode = Matcher::_regEncode[imo_reg];
1946 //
1947 // // // Interpreter expects method_oop in EBX, currently a callee-saved register,
1948 // // // so we load it immediately before the call
1949 // // emit_opcode(cbuf, 0x8B); // MOV imo_reg,ic_reg # method_oop
1950 // // emit_rm(cbuf, 0x03, imo_encode, ic_encode ); // R/M byte
1951 //
1952 // // xor rbp,ebp
1953 // emit_opcode(cbuf, 0x33);
1954 // emit_rm(cbuf, 0x3, EBP_enc, EBP_enc);
1955 //
1956 // // CALL to interpreter.
1957 // cbuf.set_insts_mark();
1958 // $$$emit8$primary;
1959 // emit_d32_reloc(cbuf, ($labl$$label - (int)(cbuf.insts_end()) - 4),
1960 // runtime_call_Relocation::spec(), RELOC_IMM32 );
1961 // %}
1962
1963 enc_class RegOpcImm (rRegI dst, immI8 shift) %{ // SHL, SAR, SHR
1964 $$$emit8$primary;
1965 emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
1966 $$$emit8$shift$$constant;
1967 %}
1968
1969 enc_class LdImmI (rRegI dst, immI src) %{ // Load Immediate
1970 // Load immediate does not have a zero or sign extended version
1971 // for 8-bit immediates
1972 emit_opcode(cbuf, 0xB8 + $dst$$reg);
1973 $$$emit32$src$$constant;
1974 %}
1975
1976 enc_class LdImmP (rRegI dst, immI src) %{ // Load Immediate
1977 // Load immediate does not have a zero or sign extended version
1978 // for 8-bit immediates
1979 emit_opcode(cbuf, $primary + $dst$$reg);
1980 $$$emit32$src$$constant;
1981 %}
1982
1983 enc_class LdImmL_Lo( eRegL dst, immL src) %{ // Load Immediate
1984 // Load immediate does not have a zero or sign extended version
1985 // for 8-bit immediates
1986 int dst_enc = $dst$$reg;
1987 int src_con = $src$$constant & 0x0FFFFFFFFL;
1988 if (src_con == 0) {
1989 // xor dst, dst
1990 emit_opcode(cbuf, 0x33);
1991 emit_rm(cbuf, 0x3, dst_enc, dst_enc);
1992 } else {
1993 emit_opcode(cbuf, $primary + dst_enc);
1994 emit_d32(cbuf, src_con);
1995 }
1996 %}
1997
1998 enc_class LdImmL_Hi( eRegL dst, immL src) %{ // Load Immediate
1999 // Load immediate does not have a zero or sign extended version
2000 // for 8-bit immediates
2001 int dst_enc = $dst$$reg + 2;
2002 int src_con = ((julong)($src$$constant)) >> 32;
2003 if (src_con == 0) {
2004 // xor dst, dst
2005 emit_opcode(cbuf, 0x33);
2006 emit_rm(cbuf, 0x3, dst_enc, dst_enc);
2007 } else {
2008 emit_opcode(cbuf, $primary + dst_enc);
2009 emit_d32(cbuf, src_con);
2010 }
2011 %}
2012
2013
2014 // Encode a reg-reg copy. If it is useless, then empty encoding.
2015 enc_class enc_Copy( rRegI dst, rRegI src ) %{
2016 encode_Copy( cbuf, $dst$$reg, $src$$reg );
2017 %}
2018
2019 enc_class enc_CopyL_Lo( rRegI dst, eRegL src ) %{
2020 encode_Copy( cbuf, $dst$$reg, $src$$reg );
2021 %}
2022
2023 enc_class RegReg (rRegI dst, rRegI src) %{ // RegReg(Many)
2024 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2025 %}
2026
2027 enc_class RegReg_Lo(eRegL dst, eRegL src) %{ // RegReg(Many)
2028 $$$emit8$primary;
2029 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2030 %}
2031
2032 enc_class RegReg_Hi(eRegL dst, eRegL src) %{ // RegReg(Many)
2033 $$$emit8$secondary;
2034 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg));
2035 %}
2036
2037 enc_class RegReg_Lo2(eRegL dst, eRegL src) %{ // RegReg(Many)
2038 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2039 %}
2040
2041 enc_class RegReg_Hi2(eRegL dst, eRegL src) %{ // RegReg(Many)
2042 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg));
2043 %}
2044
2045 enc_class RegReg_HiLo( eRegL src, rRegI dst ) %{
2046 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($src$$reg));
2047 %}
2048
2049 enc_class Con32 (immI src) %{ // Con32(storeImmI)
2050 // Output immediate
2051 $$$emit32$src$$constant;
2052 %}
2053
2054 enc_class Con32FPR_as_bits(immFPR src) %{ // storeF_imm
2055 // Output Float immediate bits
2056 jfloat jf = $src$$constant;
2057 int jf_as_bits = jint_cast( jf );
2058 emit_d32(cbuf, jf_as_bits);
2059 %}
2060
2061 enc_class Con32F_as_bits(immF src) %{ // storeX_imm
2062 // Output Float immediate bits
2063 jfloat jf = $src$$constant;
2064 int jf_as_bits = jint_cast( jf );
2065 emit_d32(cbuf, jf_as_bits);
2120
2121 enc_class enc_flags_ne_to_boolean( iRegI res ) %{
2122 int res_encoding = $res$$reg;
2123
2124 // MOV res,0
2125 emit_opcode( cbuf, 0xB8 + res_encoding);
2126 emit_d32( cbuf, 0 );
2127 // JNE,s fail
2128 emit_opcode(cbuf,0x75);
2129 emit_d8(cbuf, 5 );
2130 // MOV res,1
2131 emit_opcode( cbuf, 0xB8 + res_encoding);
2132 emit_d32( cbuf, 1 );
2133 // fail:
2134 %}
2135
2136 enc_class set_instruction_start( ) %{
2137 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
2138 %}
2139
2140 enc_class RegMem (rRegI ereg, memory mem) %{ // emit_reg_mem
2141 int reg_encoding = $ereg$$reg;
2142 int base = $mem$$base;
2143 int index = $mem$$index;
2144 int scale = $mem$$scale;
2145 int displace = $mem$$disp;
2146 bool disp_is_oop = $mem->disp_is_oop();
2147 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
2148 %}
2149
2150 enc_class RegMem_Hi(eRegL ereg, memory mem) %{ // emit_reg_mem
2151 int reg_encoding = HIGH_FROM_LOW($ereg$$reg); // Hi register of pair, computed from lo
2152 int base = $mem$$base;
2153 int index = $mem$$index;
2154 int scale = $mem$$scale;
2155 int displace = $mem$$disp + 4; // Offset is 4 further in memory
2156 assert( !$mem->disp_is_oop(), "Cannot add 4 to oop" );
2157 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, false/*disp_is_oop*/);
2158 %}
2159
2160 enc_class move_long_small_shift( eRegL dst, immI_1_31 cnt ) %{
2184 %}
2185
2186 enc_class move_long_big_shift_clr( eRegL dst, immI_32_63 cnt ) %{
2187 int r1, r2;
2188 if( $secondary == 0x5 ) { r1 = $dst$$reg; r2 = HIGH_FROM_LOW($dst$$reg); }
2189 else { r2 = $dst$$reg; r1 = HIGH_FROM_LOW($dst$$reg); }
2190
2191 emit_opcode( cbuf, 0x8B ); // Move r1,r2
2192 emit_rm(cbuf, 0x3, r1, r2);
2193 if( $cnt$$constant > 32 ) { // Shift, if not by zero
2194 emit_opcode(cbuf,$primary);
2195 emit_rm(cbuf, 0x3, $secondary, r1);
2196 emit_d8(cbuf,$cnt$$constant-32);
2197 }
2198 emit_opcode(cbuf,0x33); // XOR r2,r2
2199 emit_rm(cbuf, 0x3, r2, r2);
2200 %}
2201
2202 // Clone of RegMem but accepts an extra parameter to access each
2203 // half of a double in memory; it never needs relocation info.
2204 enc_class Mov_MemD_half_to_Reg (immI opcode, memory mem, immI disp_for_half, rRegI rm_reg) %{
2205 emit_opcode(cbuf,$opcode$$constant);
2206 int reg_encoding = $rm_reg$$reg;
2207 int base = $mem$$base;
2208 int index = $mem$$index;
2209 int scale = $mem$$scale;
2210 int displace = $mem$$disp + $disp_for_half$$constant;
2211 bool disp_is_oop = false;
2212 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
2213 %}
2214
2215 // !!!!! Special Custom Code used by MemMove, and stack access instructions !!!!!
2216 //
2217 // Clone of RegMem except the RM-byte's reg/opcode field is an ADLC-time constant
2218 // and it never needs relocation information.
2219 // Frequently used to move data between FPU's Stack Top and memory.
2220 enc_class RMopc_Mem_no_oop (immI rm_opcode, memory mem) %{
2221 int rm_byte_opcode = $rm_opcode$$constant;
2222 int base = $mem$$base;
2223 int index = $mem$$index;
2224 int scale = $mem$$scale;
2225 int displace = $mem$$disp;
2226 assert( !$mem->disp_is_oop(), "No oops here because no relo info allowed" );
2227 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, false);
2228 %}
2229
2230 enc_class RMopc_Mem (immI rm_opcode, memory mem) %{
2231 int rm_byte_opcode = $rm_opcode$$constant;
2232 int base = $mem$$base;
2233 int index = $mem$$index;
2234 int scale = $mem$$scale;
2235 int displace = $mem$$disp;
2236 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
2237 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop);
2238 %}
2239
2240 enc_class RegLea (rRegI dst, rRegI src0, immI src1 ) %{ // emit_reg_lea
2241 int reg_encoding = $dst$$reg;
2242 int base = $src0$$reg; // 0xFFFFFFFF indicates no base
2243 int index = 0x04; // 0x04 indicates no index
2244 int scale = 0x00; // 0x00 indicates no scale
2245 int displace = $src1$$constant; // 0x00 indicates no displacement
2246 bool disp_is_oop = false;
2247 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
2248 %}
2249
2250 enc_class min_enc (rRegI dst, rRegI src) %{ // MIN
2251 // Compare dst,src
2252 emit_opcode(cbuf,0x3B);
2253 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2254 // jmp dst < src around move
2255 emit_opcode(cbuf,0x7C);
2256 emit_d8(cbuf,2);
2257 // move dst,src
2258 emit_opcode(cbuf,0x8B);
2259 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2260 %}
2261
2262 enc_class max_enc (rRegI dst, rRegI src) %{ // MAX
2263 // Compare dst,src
2264 emit_opcode(cbuf,0x3B);
2265 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2266 // jmp dst > src around move
2267 emit_opcode(cbuf,0x7F);
2268 emit_d8(cbuf,2);
2269 // move dst,src
2270 emit_opcode(cbuf,0x8B);
2271 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
2272 %}
2273
2274 enc_class enc_FPR_store(memory mem, regDPR src) %{
2275 // If src is FPR1, we can just FST to store it.
2276 // Else we need to FLD it to FPR1, then FSTP to store/pop it.
2277 int reg_encoding = 0x2; // Just store
2278 int base = $mem$$base;
2279 int index = $mem$$index;
2280 int scale = $mem$$scale;
2281 int displace = $mem$$disp;
2282 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals
2283 if( $src$$reg != FPR1L_enc ) {
2284 reg_encoding = 0x3; // Store & pop
2285 emit_opcode( cbuf, 0xD9 ); // FLD (i.e., push it)
2286 emit_d8( cbuf, 0xC0-1+$src$$reg );
2287 }
2288 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
2289 emit_opcode(cbuf,$primary);
2290 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
2291 %}
2292
2293 enc_class neg_reg(rRegI dst) %{
2294 // NEG $dst
2295 emit_opcode(cbuf,0xF7);
2296 emit_rm(cbuf, 0x3, 0x03, $dst$$reg );
2297 %}
2298
2299 enc_class setLT_reg(eCXRegI dst) %{
2300 // SETLT $dst
2301 emit_opcode(cbuf,0x0F);
2302 emit_opcode(cbuf,0x9C);
2303 emit_rm( cbuf, 0x3, 0x4, $dst$$reg );
2304 %}
2305
2306 enc_class enc_cmpLTP(ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp) %{ // cadd_cmpLT
2307 int tmpReg = $tmp$$reg;
2308
2309 // SUB $p,$q
2310 emit_opcode(cbuf,0x2B);
2311 emit_rm(cbuf, 0x3, $p$$reg, $q$$reg);
2312 // SBB $tmp,$tmp
2313 emit_opcode(cbuf,0x1B);
2314 emit_rm(cbuf, 0x3, tmpReg, tmpReg);
2315 // AND $tmp,$y
2316 emit_opcode(cbuf,0x23);
2317 emit_rm(cbuf, 0x3, tmpReg, $y$$reg);
2318 // ADD $p,$tmp
2319 emit_opcode(cbuf,0x03);
2320 emit_rm(cbuf, 0x3, $p$$reg, tmpReg);
2321 %}
2322
2323 enc_class enc_cmpLTP_mem(rRegI p, rRegI q, memory mem, eCXRegI tmp) %{ // cadd_cmpLT
2324 int tmpReg = $tmp$$reg;
2325
2326 // SUB $p,$q
2327 emit_opcode(cbuf,0x2B);
2328 emit_rm(cbuf, 0x3, $p$$reg, $q$$reg);
2329 // SBB $tmp,$tmp
2330 emit_opcode(cbuf,0x1B);
2331 emit_rm(cbuf, 0x3, tmpReg, tmpReg);
2332 // AND $tmp,$y
2333 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand
2334 emit_opcode(cbuf,0x23);
2335 int reg_encoding = tmpReg;
2336 int base = $mem$$base;
2337 int index = $mem$$index;
2338 int scale = $mem$$scale;
2339 int displace = $mem$$disp;
2340 bool disp_is_oop = $mem->disp_is_oop();
2341 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
2342 // ADD $p,$tmp
2343 emit_opcode(cbuf,0x03);
2442 emit_d8( cbuf, 0xC0-1+$dst$$reg ); // FLD ST(i-1)
2443 %}
2444
2445 enc_class strictfp_bias1( regDPR dst ) %{
2446 emit_opcode( cbuf, 0xDB ); // FLD m80real
2447 emit_opcode( cbuf, 0x2D );
2448 emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias1() );
2449 emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0
2450 emit_opcode( cbuf, 0xC8+$dst$$reg );
2451 %}
2452
2453 enc_class strictfp_bias2( regDPR dst ) %{
2454 emit_opcode( cbuf, 0xDB ); // FLD m80real
2455 emit_opcode( cbuf, 0x2D );
2456 emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias2() );
2457 emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0
2458 emit_opcode( cbuf, 0xC8+$dst$$reg );
2459 %}
2460
2461 // Special case for moving an integer register to a stack slot.
2462 enc_class OpcPRegSS( stackSlotI dst, rRegI src ) %{ // RegSS
2463 store_to_stackslot( cbuf, $primary, $src$$reg, $dst$$disp );
2464 %}
2465
2466 // Special case for moving a register to a stack slot.
2467 enc_class RegSS( stackSlotI dst, rRegI src ) %{ // RegSS
2468 // Opcode already emitted
2469 emit_rm( cbuf, 0x02, $src$$reg, ESP_enc ); // R/M byte
2470 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte
2471 emit_d32(cbuf, $dst$$disp); // Displacement
2472 %}
2473
2474 // Push the integer in stackSlot 'src' onto FP-stack
2475 enc_class Push_Mem_I( memory src ) %{ // FILD [ESP+src]
2476 store_to_stackslot( cbuf, $primary, $secondary, $src$$disp );
2477 %}
2478
2479 // Push FPU's TOS float to a stack-slot, and pop FPU-stack
2480 enc_class Pop_Mem_FPR( stackSlotF dst ) %{ // FSTP_S [ESP+dst]
2481 store_to_stackslot( cbuf, 0xD9, 0x03, $dst$$disp );
2482 %}
2483
2484 // Same as Pop_Mem_F except for opcode
2485 // Push FPU's TOS double to a stack-slot, and pop FPU-stack
2486 enc_class Pop_Mem_DPR( stackSlotD dst ) %{ // FSTP_D [ESP+dst]
2487 store_to_stackslot( cbuf, 0xDD, 0x03, $dst$$disp );
2692 emit_opcode( cbuf, 0x9E);
2693 // NOP // target for branch to avoid branch to branch
2694 emit_opcode( cbuf, 0x90);
2695 %}
2696
2697 // fnstsw_ax();
2698 // sahf();
2699 // movl(dst, nan_result);
2700 // jcc(Assembler::parity, exit);
2701 // movl(dst, less_result);
2702 // jcc(Assembler::below, exit);
2703 // movl(dst, equal_result);
2704 // jcc(Assembler::equal, exit);
2705 // movl(dst, greater_result);
2706
2707 // less_result = 1;
2708 // greater_result = -1;
2709 // equal_result = 0;
2710 // nan_result = -1;
2711
2712 enc_class CmpF_Result(rRegI dst) %{
2713 // fnstsw_ax();
2714 emit_opcode( cbuf, 0xDF);
2715 emit_opcode( cbuf, 0xE0);
2716 // sahf
2717 emit_opcode( cbuf, 0x9E);
2718 // movl(dst, nan_result);
2719 emit_opcode( cbuf, 0xB8 + $dst$$reg);
2720 emit_d32( cbuf, -1 );
2721 // jcc(Assembler::parity, exit);
2722 emit_opcode( cbuf, 0x7A );
2723 emit_d8 ( cbuf, 0x13 );
2724 // movl(dst, less_result);
2725 emit_opcode( cbuf, 0xB8 + $dst$$reg);
2726 emit_d32( cbuf, -1 );
2727 // jcc(Assembler::below, exit);
2728 emit_opcode( cbuf, 0x72 );
2729 emit_d8 ( cbuf, 0x0C );
2730 // movl(dst, equal_result);
2731 emit_opcode( cbuf, 0xB8 + $dst$$reg);
2732 emit_d32( cbuf, 0 );
2737 emit_opcode( cbuf, 0xB8 + $dst$$reg);
2738 emit_d32( cbuf, 1 );
2739 %}
2740
2741
2742 // Compare the longs and set flags
2743 // BROKEN! Do Not use as-is
2744 enc_class cmpl_test( eRegL src1, eRegL src2 ) %{
2745 // CMP $src1.hi,$src2.hi
2746 emit_opcode( cbuf, 0x3B );
2747 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) );
2748 // JNE,s done
2749 emit_opcode(cbuf,0x75);
2750 emit_d8(cbuf, 2 );
2751 // CMP $src1.lo,$src2.lo
2752 emit_opcode( cbuf, 0x3B );
2753 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg );
2754 // done:
2755 %}
2756
2757 enc_class convert_int_long( regL dst, rRegI src ) %{
2758 // mov $dst.lo,$src
2759 int dst_encoding = $dst$$reg;
2760 int src_encoding = $src$$reg;
2761 encode_Copy( cbuf, dst_encoding , src_encoding );
2762 // mov $dst.hi,$src
2763 encode_Copy( cbuf, HIGH_FROM_LOW(dst_encoding), src_encoding );
2764 // sar $dst.hi,31
2765 emit_opcode( cbuf, 0xC1 );
2766 emit_rm(cbuf, 0x3, 7, HIGH_FROM_LOW(dst_encoding) );
2767 emit_d8(cbuf, 0x1F );
2768 %}
2769
2770 enc_class convert_long_double( eRegL src ) %{
2771 // push $src.hi
2772 emit_opcode(cbuf, 0x50+HIGH_FROM_LOW($src$$reg));
2773 // push $src.lo
2774 emit_opcode(cbuf, 0x50+$src$$reg );
2775 // fild 64-bits at [SP]
2776 emit_opcode(cbuf,0xdf);
2777 emit_d8(cbuf, 0x6C);
2806 emit_opcode(cbuf,0xdf);
2807 emit_d8(cbuf, 0x6C);
2808 emit_d8(cbuf, 0x24);
2809 emit_d8(cbuf, 0x00);
2810 %}
2811
2812 enc_class long_int_multiply( eADXRegL dst, nadxRegI src) %{
2813 // Basic idea: long = (long)int * (long)int
2814 // IMUL EDX:EAX, src
2815 emit_opcode( cbuf, 0xF7 );
2816 emit_rm( cbuf, 0x3, 0x5, $src$$reg);
2817 %}
2818
2819 enc_class long_uint_multiply( eADXRegL dst, nadxRegI src) %{
2820 // Basic Idea: long = (int & 0xffffffffL) * (int & 0xffffffffL)
2821 // MUL EDX:EAX, src
2822 emit_opcode( cbuf, 0xF7 );
2823 emit_rm( cbuf, 0x3, 0x4, $src$$reg);
2824 %}
2825
2826 enc_class long_multiply( eADXRegL dst, eRegL src, rRegI tmp ) %{
2827 // Basic idea: lo(result) = lo(x_lo * y_lo)
2828 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi)
2829 // MOV $tmp,$src.lo
2830 encode_Copy( cbuf, $tmp$$reg, $src$$reg );
2831 // IMUL $tmp,EDX
2832 emit_opcode( cbuf, 0x0F );
2833 emit_opcode( cbuf, 0xAF );
2834 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) );
2835 // MOV EDX,$src.hi
2836 encode_Copy( cbuf, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg) );
2837 // IMUL EDX,EAX
2838 emit_opcode( cbuf, 0x0F );
2839 emit_opcode( cbuf, 0xAF );
2840 emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg );
2841 // ADD $tmp,EDX
2842 emit_opcode( cbuf, 0x03 );
2843 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) );
2844 // MUL EDX:EAX,$src.lo
2845 emit_opcode( cbuf, 0xF7 );
2846 emit_rm( cbuf, 0x3, 0x4, $src$$reg );
2847 // ADD EDX,ESI
2848 emit_opcode( cbuf, 0x03 );
2849 emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $tmp$$reg );
2850 %}
2851
2852 enc_class long_multiply_con( eADXRegL dst, immL_127 src, rRegI tmp ) %{
2853 // Basic idea: lo(result) = lo(src * y_lo)
2854 // hi(result) = hi(src * y_lo) + lo(src * y_hi)
2855 // IMUL $tmp,EDX,$src
2856 emit_opcode( cbuf, 0x6B );
2857 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) );
2858 emit_d8( cbuf, (int)$src$$constant );
2859 // MOV EDX,$src
2860 emit_opcode(cbuf, 0xB8 + EDX_enc);
2861 emit_d32( cbuf, (int)$src$$constant );
2862 // MUL EDX:EAX,EDX
2863 emit_opcode( cbuf, 0xF7 );
2864 emit_rm( cbuf, 0x3, 0x4, EDX_enc );
2865 // ADD EDX,ESI
2866 emit_opcode( cbuf, 0x03 );
2867 emit_rm( cbuf, 0x3, EDX_enc, $tmp$$reg );
2868 %}
2869
2870 enc_class long_div( eRegL src1, eRegL src2 ) %{
2871 // PUSH src1.hi
2872 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src1$$reg) );
2888
2889 enc_class long_mod( eRegL src1, eRegL src2 ) %{
2890 // PUSH src1.hi
2891 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src1$$reg) );
2892 // PUSH src1.lo
2893 emit_opcode(cbuf, 0x50+$src1$$reg );
2894 // PUSH src2.hi
2895 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src2$$reg) );
2896 // PUSH src2.lo
2897 emit_opcode(cbuf, 0x50+$src2$$reg );
2898 // CALL directly to the runtime
2899 cbuf.set_insts_mark();
2900 emit_opcode(cbuf,0xE8); // Call into runtime
2901 emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::lrem ) - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 );
2902 // Restore stack
2903 emit_opcode(cbuf, 0x83); // add SP, #framesize
2904 emit_rm(cbuf, 0x3, 0x00, ESP_enc);
2905 emit_d8(cbuf, 4*4);
2906 %}
2907
2908 enc_class long_cmp_flags0( eRegL src, rRegI tmp ) %{
2909 // MOV $tmp,$src.lo
2910 emit_opcode(cbuf, 0x8B);
2911 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg);
2912 // OR $tmp,$src.hi
2913 emit_opcode(cbuf, 0x0B);
2914 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg));
2915 %}
2916
2917 enc_class long_cmp_flags1( eRegL src1, eRegL src2 ) %{
2918 // CMP $src1.lo,$src2.lo
2919 emit_opcode( cbuf, 0x3B );
2920 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg );
2921 // JNE,s skip
2922 emit_cc(cbuf, 0x70, 0x5);
2923 emit_d8(cbuf,2);
2924 // CMP $src1.hi,$src2.hi
2925 emit_opcode( cbuf, 0x3B );
2926 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) );
2927 %}
2928
2929 enc_class long_cmp_flags2( eRegL src1, eRegL src2, rRegI tmp ) %{
2930 // CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits
2931 emit_opcode( cbuf, 0x3B );
2932 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg );
2933 // MOV $tmp,$src1.hi
2934 emit_opcode( cbuf, 0x8B );
2935 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src1$$reg) );
2936 // SBB $tmp,$src2.hi\t! Compute flags for long compare
2937 emit_opcode( cbuf, 0x1B );
2938 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src2$$reg) );
2939 %}
2940
2941 enc_class long_cmp_flags3( eRegL src, rRegI tmp ) %{
2942 // XOR $tmp,$tmp
2943 emit_opcode(cbuf,0x33); // XOR
2944 emit_rm(cbuf,0x3, $tmp$$reg, $tmp$$reg);
2945 // CMP $tmp,$src.lo
2946 emit_opcode( cbuf, 0x3B );
2947 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg );
2948 // SBB $tmp,$src.hi
2949 emit_opcode( cbuf, 0x1B );
2950 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg) );
2951 %}
2952
2953 // Sniff, sniff... smells like Gnu Superoptimizer
2954 enc_class neg_long( eRegL dst ) %{
2955 emit_opcode(cbuf,0xF7); // NEG hi
2956 emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg));
2957 emit_opcode(cbuf,0xF7); // NEG lo
2958 emit_rm (cbuf,0x3, 0x3, $dst$$reg );
2959 emit_opcode(cbuf,0x83); // SBB hi,0
2960 emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg));
2961 emit_d8 (cbuf,0 );
3814 // Body of function which returns an integer array locating
3815 // arguments either in registers or in stack slots. Passed an array
3816 // of ideal registers called "sig" and a "length" count. Stack-slot
3817 // offsets are based on outgoing arguments, i.e. a CALLER setting up
3818 // arguments for a CALLEE. Incoming stack arguments are
3819 // automatically biased by the preserve_stack_slots field above.
3820 c_calling_convention %{
3821 // This is obviously always outgoing
3822 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length);
3823 %}
3824
3825 // Location of C & interpreter return values
3826 c_return_value %{
3827 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3828 static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num, EAX_num, FPR1L_num, FPR1L_num, EAX_num };
3829 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num };
3830
3831 // in SSE2+ mode we want to keep the FPU stack clean so pretend
3832 // that C functions return float and double results in XMM0.
3833 if( ideal_reg == Op_RegD && UseSSE>=2 )
3834 return OptoRegPair(XMM0b_num,XMM0_num);
3835 if( ideal_reg == Op_RegF && UseSSE>=2 )
3836 return OptoRegPair(OptoReg::Bad,XMM0_num);
3837
3838 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3839 %}
3840
3841 // Location of return values
3842 return_value %{
3843 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
3844 static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num, EAX_num, FPR1L_num, FPR1L_num, EAX_num };
3845 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num };
3846 if( ideal_reg == Op_RegD && UseSSE>=2 )
3847 return OptoRegPair(XMM0b_num,XMM0_num);
3848 if( ideal_reg == Op_RegF && UseSSE>=1 )
3849 return OptoRegPair(OptoReg::Bad,XMM0_num);
3850 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
3851 %}
3852
3853 %}
3854
3855 //----------ATTRIBUTES---------------------------------------------------------
3856 //----------Operand Attributes-------------------------------------------------
3857 op_attrib op_cost(0); // Required cost attribute
3858
3859 //----------Instruction Attributes---------------------------------------------
3860 ins_attrib ins_cost(100); // Required cost attribute
3861 ins_attrib ins_size(8); // Required size attribute (in bits)
3862 ins_attrib ins_short_branch(0); // Required flag: is this instruction a
3863 // non-matching short branch variant of some
3864 // long branch?
3865 ins_attrib ins_alignment(1); // Required alignment attribute (must be a power of 2)
3866 // specifies the alignment that some part of the instruction (not
3867 // necessarily the start) requires. If > 1, a compute_padding()
3868 // function must be provided for the instruction
3869
4199 // Constant for byte-wide masking
4200 operand immI_255() %{
4201 predicate( n->get_int() == 255 );
4202 match(ConI);
4203
4204 format %{ %}
4205 interface(CONST_INTER);
4206 %}
4207
4208 // Constant for short-wide masking
4209 operand immI_65535() %{
4210 predicate(n->get_int() == 65535);
4211 match(ConI);
4212
4213 format %{ %}
4214 interface(CONST_INTER);
4215 %}
4216
4217 // Register Operands
4218 // Integer Register
4219 operand rRegI() %{
4220 constraint(ALLOC_IN_RC(int_reg));
4221 match(RegI);
4222 match(xRegI);
4223 match(eAXRegI);
4224 match(eBXRegI);
4225 match(eCXRegI);
4226 match(eDXRegI);
4227 match(eDIRegI);
4228 match(eSIRegI);
4229
4230 format %{ %}
4231 interface(REG_INTER);
4232 %}
4233
4234 // Subset of Integer Register
4235 operand xRegI(rRegI reg) %{
4236 constraint(ALLOC_IN_RC(int_x_reg));
4237 match(reg);
4238 match(eAXRegI);
4239 match(eBXRegI);
4240 match(eCXRegI);
4241 match(eDXRegI);
4242
4243 format %{ %}
4244 interface(REG_INTER);
4245 %}
4246
4247 // Special Registers
4248 operand eAXRegI(xRegI reg) %{
4249 constraint(ALLOC_IN_RC(eax_reg));
4250 match(reg);
4251 match(rRegI);
4252
4253 format %{ "EAX" %}
4254 interface(REG_INTER);
4255 %}
4256
4257 // Special Registers
4258 operand eBXRegI(xRegI reg) %{
4259 constraint(ALLOC_IN_RC(ebx_reg));
4260 match(reg);
4261 match(rRegI);
4262
4263 format %{ "EBX" %}
4264 interface(REG_INTER);
4265 %}
4266
4267 operand eCXRegI(xRegI reg) %{
4268 constraint(ALLOC_IN_RC(ecx_reg));
4269 match(reg);
4270 match(rRegI);
4271
4272 format %{ "ECX" %}
4273 interface(REG_INTER);
4274 %}
4275
4276 operand eDXRegI(xRegI reg) %{
4277 constraint(ALLOC_IN_RC(edx_reg));
4278 match(reg);
4279 match(rRegI);
4280
4281 format %{ "EDX" %}
4282 interface(REG_INTER);
4283 %}
4284
4285 operand eDIRegI(xRegI reg) %{
4286 constraint(ALLOC_IN_RC(edi_reg));
4287 match(reg);
4288 match(rRegI);
4289
4290 format %{ "EDI" %}
4291 interface(REG_INTER);
4292 %}
4293
4294 operand naxRegI() %{
4295 constraint(ALLOC_IN_RC(nax_reg));
4296 match(RegI);
4297 match(eCXRegI);
4298 match(eDXRegI);
4299 match(eSIRegI);
4300 match(eDIRegI);
4301
4302 format %{ %}
4303 interface(REG_INTER);
4304 %}
4305
4306 operand nadxRegI() %{
4307 constraint(ALLOC_IN_RC(nadx_reg));
4308 match(RegI);
4315 interface(REG_INTER);
4316 %}
4317
4318 operand ncxRegI() %{
4319 constraint(ALLOC_IN_RC(ncx_reg));
4320 match(RegI);
4321 match(eAXRegI);
4322 match(eDXRegI);
4323 match(eSIRegI);
4324 match(eDIRegI);
4325
4326 format %{ %}
4327 interface(REG_INTER);
4328 %}
4329
4330 // // This operand was used by cmpFastUnlock, but conflicted with 'object' reg
4331 // //
4332 operand eSIRegI(xRegI reg) %{
4333 constraint(ALLOC_IN_RC(esi_reg));
4334 match(reg);
4335 match(rRegI);
4336
4337 format %{ "ESI" %}
4338 interface(REG_INTER);
4339 %}
4340
4341 // Pointer Register
4342 operand anyRegP() %{
4343 constraint(ALLOC_IN_RC(any_reg));
4344 match(RegP);
4345 match(eAXRegP);
4346 match(eBXRegP);
4347 match(eCXRegP);
4348 match(eDIRegP);
4349 match(eRegP);
4350
4351 format %{ %}
4352 interface(REG_INTER);
4353 %}
4354
4355 operand eRegP() %{
4356 constraint(ALLOC_IN_RC(int_reg));
4357 match(RegP);
4358 match(eAXRegP);
4359 match(eBXRegP);
4360 match(eCXRegP);
4361 match(eDIRegP);
4362
4363 format %{ %}
4364 interface(REG_INTER);
4365 %}
4366
4367 // On windows95, EBP is not safe to use for implicit null tests.
4368 operand eRegP_no_EBP() %{
4369 constraint(ALLOC_IN_RC(int_reg_no_rbp));
4370 match(RegP);
4371 match(eAXRegP);
4372 match(eBXRegP);
4373 match(eCXRegP);
4374 match(eDIRegP);
4375
4376 op_cost(100);
4377 format %{ %}
4378 interface(REG_INTER);
4379 %}
4380
4381 operand naxRegP() %{
4382 constraint(ALLOC_IN_RC(nax_reg));
4383 match(RegP);
4384 match(eBXRegP);
4385 match(eDXRegP);
4386 match(eCXRegP);
4387 match(eSIRegP);
4388 match(eDIRegP);
4389
4529 match(RegFlags);
4530 format %{ "FLAGS_LTGE" %}
4531 interface(REG_INTER);
4532 %}
4533 operand flagsReg_long_EQNE() %{
4534 constraint(ALLOC_IN_RC(int_flags));
4535 match(RegFlags);
4536 format %{ "FLAGS_EQNE" %}
4537 interface(REG_INTER);
4538 %}
4539 operand flagsReg_long_LEGT() %{
4540 constraint(ALLOC_IN_RC(int_flags));
4541 match(RegFlags);
4542 format %{ "FLAGS_LEGT" %}
4543 interface(REG_INTER);
4544 %}
4545
4546 // Float register operands
4547 operand regDPR() %{
4548 predicate( UseSSE < 2 );
4549 constraint(ALLOC_IN_RC(fp_dbl_reg));
4550 match(RegD);
4551 match(regDPR1);
4552 match(regDPR2);
4553 format %{ %}
4554 interface(REG_INTER);
4555 %}
4556
4557 operand regDPR1(regDPR reg) %{
4558 predicate( UseSSE < 2 );
4559 constraint(ALLOC_IN_RC(fp_dbl_reg0));
4560 match(reg);
4561 format %{ "FPR1" %}
4562 interface(REG_INTER);
4563 %}
4564
4565 operand regDPR2(regDPR reg) %{
4566 predicate( UseSSE < 2 );
4567 constraint(ALLOC_IN_RC(fp_dbl_reg1));
4568 match(reg);
4569 format %{ "FPR2" %}
4570 interface(REG_INTER);
4571 %}
4572
4573 operand regnotDPR1(regDPR reg) %{
4574 predicate( UseSSE < 2 );
4575 constraint(ALLOC_IN_RC(fp_dbl_notreg0));
4576 match(reg);
4577 format %{ %}
4578 interface(REG_INTER);
4579 %}
4580
4581 // Float register operands
4582 operand regFPR() %{
4583 predicate( UseSSE < 2 );
4584 constraint(ALLOC_IN_RC(fp_flt_reg));
4585 match(RegF);
4586 match(regFPR1);
4587 format %{ %}
4588 interface(REG_INTER);
4589 %}
4590
4591 // Float register operands
4592 operand regFPR1(regFPR reg) %{
4593 predicate( UseSSE < 2 );
4594 constraint(ALLOC_IN_RC(fp_flt_reg0));
4595 match(reg);
4596 format %{ "FPR1" %}
4597 interface(REG_INTER);
4598 %}
4599
4600 // XMM Float register operands
4601 operand regF() %{
4602 predicate( UseSSE>=1 );
4603 constraint(ALLOC_IN_RC(float_reg));
4604 match(RegF);
4605 format %{ %}
4606 interface(REG_INTER);
4607 %}
4608
4609 // XMM Double register operands
4610 operand regD() %{
4611 predicate( UseSSE>=2 );
4612 constraint(ALLOC_IN_RC(double_reg));
4613 match(RegD);
4614 format %{ %}
4615 interface(REG_INTER);
4616 %}
4617
4618
4619 //----------Memory Operands----------------------------------------------------
4620 // Direct Memory Operand
4621 operand direct(immP addr) %{
4622 match(addr);
4623
4624 format %{ "[$addr]" %}
4625 interface(MEMORY_INTER) %{
4626 base(0xFFFFFFFF);
4627 index(0x4);
4628 scale(0x0);
4629 disp($addr);
4630 %}
4631 %}
4632
4633 // Indirect Memory Operand
4634 operand indirect(eRegP reg) %{
4635 constraint(ALLOC_IN_RC(int_reg));
4636 match(reg);
4637
4638 format %{ "[$reg]" %}
4639 interface(MEMORY_INTER) %{
4640 base($reg);
4641 index(0x4);
4642 scale(0x0);
4643 disp(0x0);
4644 %}
4645 %}
4646
4647 // Indirect Memory Plus Short Offset Operand
4648 operand indOffset8(eRegP reg, immI8 off) %{
4649 match(AddP reg off);
4650
4651 format %{ "[$reg + $off]" %}
4652 interface(MEMORY_INTER) %{
4653 base($reg);
4654 index(0x4);
4655 scale(0x0);
4656 disp($off);
4657 %}
4658 %}
4659
4660 // Indirect Memory Plus Long Offset Operand
4661 operand indOffset32(eRegP reg, immI off) %{
4662 match(AddP reg off);
4663
4664 format %{ "[$reg + $off]" %}
4665 interface(MEMORY_INTER) %{
4666 base($reg);
4667 index(0x4);
4668 scale(0x0);
4669 disp($off);
4670 %}
4671 %}
4672
4673 // Indirect Memory Plus Long Offset Operand
4674 operand indOffset32X(rRegI reg, immP off) %{
4675 match(AddP off reg);
4676
4677 format %{ "[$reg + $off]" %}
4678 interface(MEMORY_INTER) %{
4679 base($reg);
4680 index(0x4);
4681 scale(0x0);
4682 disp($off);
4683 %}
4684 %}
4685
4686 // Indirect Memory Plus Index Register Plus Offset Operand
4687 operand indIndexOffset(eRegP reg, rRegI ireg, immI off) %{
4688 match(AddP (AddP reg ireg) off);
4689
4690 op_cost(10);
4691 format %{"[$reg + $off + $ireg]" %}
4692 interface(MEMORY_INTER) %{
4693 base($reg);
4694 index($ireg);
4695 scale(0x0);
4696 disp($off);
4697 %}
4698 %}
4699
4700 // Indirect Memory Plus Index Register Plus Offset Operand
4701 operand indIndex(eRegP reg, rRegI ireg) %{
4702 match(AddP reg ireg);
4703
4704 op_cost(10);
4705 format %{"[$reg + $ireg]" %}
4706 interface(MEMORY_INTER) %{
4707 base($reg);
4708 index($ireg);
4709 scale(0x0);
4710 disp(0x0);
4711 %}
4712 %}
4713
4714 // // -------------------------------------------------------------------------
4715 // // 486 architecture doesn't support "scale * index + offset" with out a base
4716 // // -------------------------------------------------------------------------
4717 // // Scaled Memory Operands
4718 // // Indirect Memory Times Scale Plus Offset Operand
4719 // operand indScaleOffset(immP off, rRegI ireg, immI2 scale) %{
4720 // match(AddP off (LShiftI ireg scale));
4721 //
4722 // op_cost(10);
4723 // format %{"[$off + $ireg << $scale]" %}
4724 // interface(MEMORY_INTER) %{
4725 // base(0x4);
4726 // index($ireg);
4727 // scale($scale);
4728 // disp($off);
4729 // %}
4730 // %}
4731
4732 // Indirect Memory Times Scale Plus Index Register
4733 operand indIndexScale(eRegP reg, rRegI ireg, immI2 scale) %{
4734 match(AddP reg (LShiftI ireg scale));
4735
4736 op_cost(10);
4737 format %{"[$reg + $ireg << $scale]" %}
4738 interface(MEMORY_INTER) %{
4739 base($reg);
4740 index($ireg);
4741 scale($scale);
4742 disp(0x0);
4743 %}
4744 %}
4745
4746 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
4747 operand indIndexScaleOffset(eRegP reg, immI off, rRegI ireg, immI2 scale) %{
4748 match(AddP (AddP reg (LShiftI ireg scale)) off);
4749
4750 op_cost(10);
4751 format %{"[$reg + $off + $ireg << $scale]" %}
4752 interface(MEMORY_INTER) %{
4753 base($reg);
4754 index($ireg);
4755 scale($scale);
4756 disp($off);
4757 %}
4758 %}
4759
4760 //----------Load Long Memory Operands------------------------------------------
4761 // The load-long idiom will use it's address expression again after loading
4762 // the first word of the long. If the load-long destination overlaps with
4763 // registers used in the addressing expression, the 2nd half will be loaded
4764 // from a clobbered address. Fix this by requiring that load-long use
4765 // address registers that do not overlap with the load-long target.
4766
4767 // load-long support
4855 disp($reg); // Stack Offset
4856 %}
4857 %}
4858
4859 operand stackSlotL(sRegL reg) %{
4860 constraint(ALLOC_IN_RC(stack_slots));
4861 // No match rule because this operand is only generated in matching
4862 format %{ "[$reg]" %}
4863 interface(MEMORY_INTER) %{
4864 base(0x4); // ESP
4865 index(0x4); // No Index
4866 scale(0x0); // No Scale
4867 disp($reg); // Stack Offset
4868 %}
4869 %}
4870
4871 //----------Memory Operands - Win95 Implicit Null Variants----------------
4872 // Indirect Memory Operand
4873 operand indirect_win95_safe(eRegP_no_EBP reg)
4874 %{
4875 constraint(ALLOC_IN_RC(int_reg));
4876 match(reg);
4877
4878 op_cost(100);
4879 format %{ "[$reg]" %}
4880 interface(MEMORY_INTER) %{
4881 base($reg);
4882 index(0x4);
4883 scale(0x0);
4884 disp(0x0);
4885 %}
4886 %}
4887
4888 // Indirect Memory Plus Short Offset Operand
4889 operand indOffset8_win95_safe(eRegP_no_EBP reg, immI8 off)
4890 %{
4891 match(AddP reg off);
4892
4893 op_cost(100);
4894 format %{ "[$reg + $off]" %}
4895 interface(MEMORY_INTER) %{
4899 disp($off);
4900 %}
4901 %}
4902
4903 // Indirect Memory Plus Long Offset Operand
4904 operand indOffset32_win95_safe(eRegP_no_EBP reg, immI off)
4905 %{
4906 match(AddP reg off);
4907
4908 op_cost(100);
4909 format %{ "[$reg + $off]" %}
4910 interface(MEMORY_INTER) %{
4911 base($reg);
4912 index(0x4);
4913 scale(0x0);
4914 disp($off);
4915 %}
4916 %}
4917
4918 // Indirect Memory Plus Index Register Plus Offset Operand
4919 operand indIndexOffset_win95_safe(eRegP_no_EBP reg, rRegI ireg, immI off)
4920 %{
4921 match(AddP (AddP reg ireg) off);
4922
4923 op_cost(100);
4924 format %{"[$reg + $off + $ireg]" %}
4925 interface(MEMORY_INTER) %{
4926 base($reg);
4927 index($ireg);
4928 scale(0x0);
4929 disp($off);
4930 %}
4931 %}
4932
4933 // Indirect Memory Times Scale Plus Index Register
4934 operand indIndexScale_win95_safe(eRegP_no_EBP reg, rRegI ireg, immI2 scale)
4935 %{
4936 match(AddP reg (LShiftI ireg scale));
4937
4938 op_cost(100);
4939 format %{"[$reg + $ireg << $scale]" %}
4940 interface(MEMORY_INTER) %{
4941 base($reg);
4942 index($ireg);
4943 scale($scale);
4944 disp(0x0);
4945 %}
4946 %}
4947
4948 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
4949 operand indIndexScaleOffset_win95_safe(eRegP_no_EBP reg, immI off, rRegI ireg, immI2 scale)
4950 %{
4951 match(AddP (AddP reg (LShiftI ireg scale)) off);
4952
4953 op_cost(100);
4954 format %{"[$reg + $off + $ireg << $scale]" %}
4955 interface(MEMORY_INTER) %{
4956 base($reg);
4957 index($ireg);
4958 scale($scale);
4959 disp($off);
4960 %}
4961 %}
4962
4963 //----------Conditional Branch Operands----------------------------------------
4964 // Comparison Op - This is the operation of the comparison, and is limited to
4965 // the following set of codes:
4966 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=)
4967 //
4968 // Other attributes of the comparison, such as unsignedness, are specified
4969 // by the comparison instruction that sets a condition code flags register.
5118 ALU0, ALU1, ALU = ALU0 | ALU1 );
5119
5120 //----------PIPELINE DESCRIPTION-----------------------------------------------
5121 // Pipeline Description specifies the stages in the machine's pipeline
5122
5123 // Generic P2/P3 pipeline
5124 pipe_desc(S0, S1, S2, S3, S4, S5);
5125
5126 //----------PIPELINE CLASSES---------------------------------------------------
5127 // Pipeline Classes describe the stages in which input and output are
5128 // referenced by the hardware pipeline.
5129
5130 // Naming convention: ialu or fpu
5131 // Then: _reg
5132 // Then: _reg if there is a 2nd register
5133 // Then: _long if it's a pair of instructions implementing a long
5134 // Then: _fat if it requires the big decoder
5135 // Or: _mem if it requires the big decoder and a memory unit.
5136
5137 // Integer ALU reg operation
5138 pipe_class ialu_reg(rRegI dst) %{
5139 single_instruction;
5140 dst : S4(write);
5141 dst : S3(read);
5142 DECODE : S0; // any decoder
5143 ALU : S3; // any alu
5144 %}
5145
5146 // Long ALU reg operation
5147 pipe_class ialu_reg_long(eRegL dst) %{
5148 instruction_count(2);
5149 dst : S4(write);
5150 dst : S3(read);
5151 DECODE : S0(2); // any 2 decoders
5152 ALU : S3(2); // both alus
5153 %}
5154
5155 // Integer ALU reg operation using big decoder
5156 pipe_class ialu_reg_fat(rRegI dst) %{
5157 single_instruction;
5158 dst : S4(write);
5159 dst : S3(read);
5160 D0 : S0; // big decoder only
5161 ALU : S3; // any alu
5162 %}
5163
5164 // Long ALU reg operation using big decoder
5165 pipe_class ialu_reg_long_fat(eRegL dst) %{
5166 instruction_count(2);
5167 dst : S4(write);
5168 dst : S3(read);
5169 D0 : S0(2); // big decoder only; twice
5170 ALU : S3(2); // any 2 alus
5171 %}
5172
5173 // Integer ALU reg-reg operation
5174 pipe_class ialu_reg_reg(rRegI dst, rRegI src) %{
5175 single_instruction;
5176 dst : S4(write);
5177 src : S3(read);
5178 DECODE : S0; // any decoder
5179 ALU : S3; // any alu
5180 %}
5181
5182 // Long ALU reg-reg operation
5183 pipe_class ialu_reg_reg_long(eRegL dst, eRegL src) %{
5184 instruction_count(2);
5185 dst : S4(write);
5186 src : S3(read);
5187 DECODE : S0(2); // any 2 decoders
5188 ALU : S3(2); // both alus
5189 %}
5190
5191 // Integer ALU reg-reg operation
5192 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) %{
5193 single_instruction;
5194 dst : S4(write);
5195 src : S3(read);
5196 D0 : S0; // big decoder only
5197 ALU : S3; // any alu
5198 %}
5199
5200 // Long ALU reg-reg operation
5201 pipe_class ialu_reg_reg_long_fat(eRegL dst, eRegL src) %{
5202 instruction_count(2);
5203 dst : S4(write);
5204 src : S3(read);
5205 D0 : S0(2); // big decoder only; twice
5206 ALU : S3(2); // both alus
5207 %}
5208
5209 // Integer ALU reg-mem operation
5210 pipe_class ialu_reg_mem(rRegI dst, memory mem) %{
5211 single_instruction;
5212 dst : S5(write);
5213 mem : S3(read);
5214 D0 : S0; // big decoder only
5215 ALU : S4; // any alu
5216 MEM : S3; // any mem
5217 %}
5218
5219 // Long ALU reg-mem operation
5220 pipe_class ialu_reg_long_mem(eRegL dst, load_long_memory mem) %{
5221 instruction_count(2);
5222 dst : S5(write);
5223 mem : S3(read);
5224 D0 : S0(2); // big decoder only; twice
5225 ALU : S4(2); // any 2 alus
5226 MEM : S3(2); // both mems
5227 %}
5228
5229 // Integer mem operation (prefetch)
5230 pipe_class ialu_mem(memory mem)
5231 %{
5232 single_instruction;
5233 mem : S3(read);
5234 D0 : S0; // big decoder only
5235 MEM : S3; // any mem
5236 %}
5237
5238 // Integer Store to Memory
5239 pipe_class ialu_mem_reg(memory mem, rRegI src) %{
5240 single_instruction;
5241 mem : S3(read);
5242 src : S5(read);
5243 D0 : S0; // big decoder only
5244 ALU : S4; // any alu
5245 MEM : S3;
5246 %}
5247
5248 // Long Store to Memory
5249 pipe_class ialu_mem_long_reg(memory mem, eRegL src) %{
5250 instruction_count(2);
5251 mem : S3(read);
5252 src : S5(read);
5253 D0 : S0(2); // big decoder only; twice
5254 ALU : S4(2); // any 2 alus
5255 MEM : S3(2); // Both mems
5256 %}
5257
5258 // Integer Store to Memory
5259 pipe_class ialu_mem_imm(memory mem) %{
5260 single_instruction;
5261 mem : S3(read);
5262 D0 : S0; // big decoder only
5263 ALU : S4; // any alu
5264 MEM : S3;
5265 %}
5266
5267 // Integer ALU0 reg-reg operation
5268 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) %{
5269 single_instruction;
5270 dst : S4(write);
5271 src : S3(read);
5272 D0 : S0; // Big decoder only
5273 ALU0 : S3; // only alu0
5274 %}
5275
5276 // Integer ALU0 reg-mem operation
5277 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) %{
5278 single_instruction;
5279 dst : S5(write);
5280 mem : S3(read);
5281 D0 : S0; // big decoder only
5282 ALU0 : S4; // ALU0 only
5283 MEM : S3; // any mem
5284 %}
5285
5286 // Integer ALU reg-reg operation
5287 pipe_class ialu_cr_reg_reg(eFlagsReg cr, rRegI src1, rRegI src2) %{
5288 single_instruction;
5289 cr : S4(write);
5290 src1 : S3(read);
5291 src2 : S3(read);
5292 DECODE : S0; // any decoder
5293 ALU : S3; // any alu
5294 %}
5295
5296 // Integer ALU reg-imm operation
5297 pipe_class ialu_cr_reg_imm(eFlagsReg cr, rRegI src1) %{
5298 single_instruction;
5299 cr : S4(write);
5300 src1 : S3(read);
5301 DECODE : S0; // any decoder
5302 ALU : S3; // any alu
5303 %}
5304
5305 // Integer ALU reg-mem operation
5306 pipe_class ialu_cr_reg_mem(eFlagsReg cr, rRegI src1, memory src2) %{
5307 single_instruction;
5308 cr : S4(write);
5309 src1 : S3(read);
5310 src2 : S3(read);
5311 D0 : S0; // big decoder only
5312 ALU : S4; // any alu
5313 MEM : S3;
5314 %}
5315
5316 // Conditional move reg-reg
5317 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y ) %{
5318 instruction_count(4);
5319 y : S4(read);
5320 q : S3(read);
5321 p : S3(read);
5322 DECODE : S0(4); // any decoder
5323 %}
5324
5325 // Conditional move reg-reg
5326 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, eFlagsReg cr ) %{
5327 single_instruction;
5328 dst : S4(write);
5329 src : S3(read);
5330 cr : S3(read);
5331 DECODE : S0; // any decoder
5332 %}
5333
5334 // Conditional move reg-mem
5335 pipe_class pipe_cmov_mem( eFlagsReg cr, rRegI dst, memory src) %{
5336 single_instruction;
5337 dst : S4(write);
5338 src : S3(read);
5339 cr : S3(read);
5340 DECODE : S0; // any decoder
5341 MEM : S3;
5342 %}
5343
5344 // Conditional move reg-reg long
5345 pipe_class pipe_cmov_reg_long( eFlagsReg cr, eRegL dst, eRegL src) %{
5346 single_instruction;
5347 dst : S4(write);
5348 src : S3(read);
5349 cr : S3(read);
5350 DECODE : S0(2); // any 2 decoders
5351 %}
5352
5353 // Conditional move double reg-reg
5354 pipe_class pipe_cmovDPR_reg( eFlagsReg cr, regDPR1 dst, regDPR src) %{
5355 single_instruction;
5566 // match -- States which machine-independent subtree may be replaced
5567 // by this instruction.
5568 // ins_cost -- The estimated cost of this instruction is used by instruction
5569 // selection to identify a minimum cost tree of machine
5570 // instructions that matches a tree of machine-independent
5571 // instructions.
5572 // format -- A string providing the disassembly for this instruction.
5573 // The value of an instruction's operand may be inserted
5574 // by referring to it with a '$' prefix.
5575 // opcode -- Three instruction opcodes may be provided. These are referred
5576 // to within an encode class as $primary, $secondary, and $tertiary
5577 // respectively. The primary opcode is commonly used to
5578 // indicate the type of machine instruction, while secondary
5579 // and tertiary are often used for prefix options or addressing
5580 // modes.
5581 // ins_encode -- A list of encode classes with parameters. The encode class
5582 // name must have been defined in an 'enc_class' specification
5583 // in the encode section of the architecture description.
5584
5585 //----------BSWAP-Instruction--------------------------------------------------
5586 instruct bytes_reverse_int(rRegI dst) %{
5587 match(Set dst (ReverseBytesI dst));
5588
5589 format %{ "BSWAP $dst" %}
5590 opcode(0x0F, 0xC8);
5591 ins_encode( OpcP, OpcSReg(dst) );
5592 ins_pipe( ialu_reg );
5593 %}
5594
5595 instruct bytes_reverse_long(eRegL dst) %{
5596 match(Set dst (ReverseBytesL dst));
5597
5598 format %{ "BSWAP $dst.lo\n\t"
5599 "BSWAP $dst.hi\n\t"
5600 "XCHG $dst.lo $dst.hi" %}
5601
5602 ins_cost(125);
5603 ins_encode( bswap_long_bytes(dst) );
5604 ins_pipe( ialu_reg_reg);
5605 %}
5606
5607 instruct bytes_reverse_unsigned_short(rRegI dst) %{
5608 match(Set dst (ReverseBytesUS dst));
5609
5610 format %{ "BSWAP $dst\n\t"
5611 "SHR $dst,16\n\t" %}
5612 ins_encode %{
5613 __ bswapl($dst$$Register);
5614 __ shrl($dst$$Register, 16);
5615 %}
5616 ins_pipe( ialu_reg );
5617 %}
5618
5619 instruct bytes_reverse_short(rRegI dst) %{
5620 match(Set dst (ReverseBytesS dst));
5621
5622 format %{ "BSWAP $dst\n\t"
5623 "SAR $dst,16\n\t" %}
5624 ins_encode %{
5625 __ bswapl($dst$$Register);
5626 __ sarl($dst$$Register, 16);
5627 %}
5628 ins_pipe( ialu_reg );
5629 %}
5630
5631
5632 //---------- Zeros Count Instructions ------------------------------------------
5633
5634 instruct countLeadingZerosI(rRegI dst, rRegI src, eFlagsReg cr) %{
5635 predicate(UseCountLeadingZerosInstruction);
5636 match(Set dst (CountLeadingZerosI src));
5637 effect(KILL cr);
5638
5639 format %{ "LZCNT $dst, $src\t# count leading zeros (int)" %}
5640 ins_encode %{
5641 __ lzcntl($dst$$Register, $src$$Register);
5642 %}
5643 ins_pipe(ialu_reg);
5644 %}
5645
5646 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, eFlagsReg cr) %{
5647 predicate(!UseCountLeadingZerosInstruction);
5648 match(Set dst (CountLeadingZerosI src));
5649 effect(KILL cr);
5650
5651 format %{ "BSR $dst, $src\t# count leading zeros (int)\n\t"
5652 "JNZ skip\n\t"
5653 "MOV $dst, -1\n"
5654 "skip:\n\t"
5655 "NEG $dst\n\t"
5656 "ADD $dst, 31" %}
5657 ins_encode %{
5658 Register Rdst = $dst$$Register;
5659 Register Rsrc = $src$$Register;
5660 Label skip;
5661 __ bsrl(Rdst, Rsrc);
5662 __ jccb(Assembler::notZero, skip);
5663 __ movl(Rdst, -1);
5664 __ bind(skip);
5665 __ negl(Rdst);
5666 __ addl(Rdst, BitsPerInt - 1);
5667 %}
5668 ins_pipe(ialu_reg);
5669 %}
5670
5671 instruct countLeadingZerosL(rRegI dst, eRegL src, eFlagsReg cr) %{
5672 predicate(UseCountLeadingZerosInstruction);
5673 match(Set dst (CountLeadingZerosL src));
5674 effect(TEMP dst, KILL cr);
5675
5676 format %{ "LZCNT $dst, $src.hi\t# count leading zeros (long)\n\t"
5677 "JNC done\n\t"
5678 "LZCNT $dst, $src.lo\n\t"
5679 "ADD $dst, 32\n"
5680 "done:" %}
5681 ins_encode %{
5682 Register Rdst = $dst$$Register;
5683 Register Rsrc = $src$$Register;
5684 Label done;
5685 __ lzcntl(Rdst, HIGH_FROM_LOW(Rsrc));
5686 __ jccb(Assembler::carryClear, done);
5687 __ lzcntl(Rdst, Rsrc);
5688 __ addl(Rdst, BitsPerInt);
5689 __ bind(done);
5690 %}
5691 ins_pipe(ialu_reg);
5692 %}
5693
5694 instruct countLeadingZerosL_bsr(rRegI dst, eRegL src, eFlagsReg cr) %{
5695 predicate(!UseCountLeadingZerosInstruction);
5696 match(Set dst (CountLeadingZerosL src));
5697 effect(TEMP dst, KILL cr);
5698
5699 format %{ "BSR $dst, $src.hi\t# count leading zeros (long)\n\t"
5700 "JZ msw_is_zero\n\t"
5701 "ADD $dst, 32\n\t"
5702 "JMP not_zero\n"
5703 "msw_is_zero:\n\t"
5704 "BSR $dst, $src.lo\n\t"
5705 "JNZ not_zero\n\t"
5706 "MOV $dst, -1\n"
5707 "not_zero:\n\t"
5708 "NEG $dst\n\t"
5709 "ADD $dst, 63\n" %}
5710 ins_encode %{
5711 Register Rdst = $dst$$Register;
5712 Register Rsrc = $src$$Register;
5713 Label msw_is_zero;
5714 Label not_zero;
5715 __ bsrl(Rdst, HIGH_FROM_LOW(Rsrc));
5716 __ jccb(Assembler::zero, msw_is_zero);
5717 __ addl(Rdst, BitsPerInt);
5718 __ jmpb(not_zero);
5719 __ bind(msw_is_zero);
5720 __ bsrl(Rdst, Rsrc);
5721 __ jccb(Assembler::notZero, not_zero);
5722 __ movl(Rdst, -1);
5723 __ bind(not_zero);
5724 __ negl(Rdst);
5725 __ addl(Rdst, BitsPerLong - 1);
5726 %}
5727 ins_pipe(ialu_reg);
5728 %}
5729
5730 instruct countTrailingZerosI(rRegI dst, rRegI src, eFlagsReg cr) %{
5731 match(Set dst (CountTrailingZerosI src));
5732 effect(KILL cr);
5733
5734 format %{ "BSF $dst, $src\t# count trailing zeros (int)\n\t"
5735 "JNZ done\n\t"
5736 "MOV $dst, 32\n"
5737 "done:" %}
5738 ins_encode %{
5739 Register Rdst = $dst$$Register;
5740 Label done;
5741 __ bsfl(Rdst, $src$$Register);
5742 __ jccb(Assembler::notZero, done);
5743 __ movl(Rdst, BitsPerInt);
5744 __ bind(done);
5745 %}
5746 ins_pipe(ialu_reg);
5747 %}
5748
5749 instruct countTrailingZerosL(rRegI dst, eRegL src, eFlagsReg cr) %{
5750 match(Set dst (CountTrailingZerosL src));
5751 effect(TEMP dst, KILL cr);
5752
5753 format %{ "BSF $dst, $src.lo\t# count trailing zeros (long)\n\t"
5754 "JNZ done\n\t"
5755 "BSF $dst, $src.hi\n\t"
5756 "JNZ msw_not_zero\n\t"
5757 "MOV $dst, 32\n"
5758 "msw_not_zero:\n\t"
5759 "ADD $dst, 32\n"
5760 "done:" %}
5761 ins_encode %{
5762 Register Rdst = $dst$$Register;
5763 Register Rsrc = $src$$Register;
5764 Label msw_not_zero;
5765 Label done;
5766 __ bsfl(Rdst, Rsrc);
5767 __ jccb(Assembler::notZero, done);
5768 __ bsfl(Rdst, HIGH_FROM_LOW(Rsrc));
5769 __ jccb(Assembler::notZero, msw_not_zero);
5770 __ movl(Rdst, BitsPerInt);
5771 __ bind(msw_not_zero);
5772 __ addl(Rdst, BitsPerInt);
5773 __ bind(done);
5774 %}
5775 ins_pipe(ialu_reg);
5776 %}
5777
5778
5779 //---------- Population Count Instructions -------------------------------------
5780
5781 instruct popCountI(rRegI dst, rRegI src) %{
5782 predicate(UsePopCountInstruction);
5783 match(Set dst (PopCountI src));
5784
5785 format %{ "POPCNT $dst, $src" %}
5786 ins_encode %{
5787 __ popcntl($dst$$Register, $src$$Register);
5788 %}
5789 ins_pipe(ialu_reg);
5790 %}
5791
5792 instruct popCountI_mem(rRegI dst, memory mem) %{
5793 predicate(UsePopCountInstruction);
5794 match(Set dst (PopCountI (LoadI mem)));
5795
5796 format %{ "POPCNT $dst, $mem" %}
5797 ins_encode %{
5798 __ popcntl($dst$$Register, $mem$$Address);
5799 %}
5800 ins_pipe(ialu_reg);
5801 %}
5802
5803 // Note: Long.bitCount(long) returns an int.
5804 instruct popCountL(rRegI dst, eRegL src, rRegI tmp, eFlagsReg cr) %{
5805 predicate(UsePopCountInstruction);
5806 match(Set dst (PopCountL src));
5807 effect(KILL cr, TEMP tmp, TEMP dst);
5808
5809 format %{ "POPCNT $dst, $src.lo\n\t"
5810 "POPCNT $tmp, $src.hi\n\t"
5811 "ADD $dst, $tmp" %}
5812 ins_encode %{
5813 __ popcntl($dst$$Register, $src$$Register);
5814 __ popcntl($tmp$$Register, HIGH_FROM_LOW($src$$Register));
5815 __ addl($dst$$Register, $tmp$$Register);
5816 %}
5817 ins_pipe(ialu_reg);
5818 %}
5819
5820 // Note: Long.bitCount(long) returns an int.
5821 instruct popCountL_mem(rRegI dst, memory mem, rRegI tmp, eFlagsReg cr) %{
5822 predicate(UsePopCountInstruction);
5823 match(Set dst (PopCountL (LoadL mem)));
5824 effect(KILL cr, TEMP tmp, TEMP dst);
5825
5826 format %{ "POPCNT $dst, $mem\n\t"
5827 "POPCNT $tmp, $mem+4\n\t"
5828 "ADD $dst, $tmp" %}
5829 ins_encode %{
5830 //__ popcntl($dst$$Register, $mem$$Address$$first);
5831 //__ popcntl($tmp$$Register, $mem$$Address$$second);
5832 __ popcntl($dst$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false));
5833 __ popcntl($tmp$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false));
5834 __ addl($dst$$Register, $tmp$$Register);
5835 %}
5836 ins_pipe(ialu_reg);
5837 %}
5838
5839
5840 //----------Load/Store/Move Instructions---------------------------------------
5841 //----------Load Instructions--------------------------------------------------
5905 %}
5906
5907 // Load Unsigned Byte (8 bit UNsigned) with mask into Long Register
5908 instruct loadUB2L_immI8(eRegL dst, memory mem, immI8 mask, eFlagsReg cr) %{
5909 match(Set dst (ConvI2L (AndI (LoadUB mem) mask)));
5910 effect(KILL cr);
5911
5912 format %{ "MOVZX8 $dst.lo,$mem\t# ubyte & 8-bit mask -> long\n\t"
5913 "XOR $dst.hi,$dst.hi\n\t"
5914 "AND $dst.lo,$mask" %}
5915 ins_encode %{
5916 Register Rdst = $dst$$Register;
5917 __ movzbl(Rdst, $mem$$Address);
5918 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
5919 __ andl(Rdst, $mask$$constant);
5920 %}
5921 ins_pipe(ialu_reg_mem);
5922 %}
5923
5924 // Load Short (16bit signed)
5925 instruct loadS(rRegI dst, memory mem) %{
5926 match(Set dst (LoadS mem));
5927
5928 ins_cost(125);
5929 format %{ "MOVSX $dst,$mem\t# short" %}
5930
5931 ins_encode %{
5932 __ movswl($dst$$Register, $mem$$Address);
5933 %}
5934
5935 ins_pipe(ialu_reg_mem);
5936 %}
5937
5938 // Load Short (16 bit signed) to Byte (8 bit signed)
5939 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
5940 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
5941
5942 ins_cost(125);
5943 format %{ "MOVSX $dst, $mem\t# short -> byte" %}
5944 ins_encode %{
5945 __ movsbl($dst$$Register, $mem$$Address);
5946 %}
5947 ins_pipe(ialu_reg_mem);
5948 %}
5949
5950 // Load Short (16bit signed) into Long Register
5951 instruct loadS2L(eRegL dst, memory mem, eFlagsReg cr) %{
5952 match(Set dst (ConvI2L (LoadS mem)));
5953 effect(KILL cr);
5954
5955 ins_cost(375);
5956 format %{ "MOVSX $dst.lo,$mem\t# short -> long\n\t"
5957 "MOV $dst.hi,$dst.lo\n\t"
5958 "SAR $dst.hi,15" %}
5959
5960 ins_encode %{
5961 __ movswl($dst$$Register, $mem$$Address);
5962 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register.
5963 __ sarl(HIGH_FROM_LOW($dst$$Register), 15); // 16+1 MSB are already signed extended.
5964 %}
5965
5966 ins_pipe(ialu_reg_mem);
5967 %}
5968
5969 // Load Unsigned Short/Char (16bit unsigned)
5970 instruct loadUS(rRegI dst, memory mem) %{
5971 match(Set dst (LoadUS mem));
5972
5973 ins_cost(125);
5974 format %{ "MOVZX $dst,$mem\t# ushort/char -> int" %}
5975
5976 ins_encode %{
5977 __ movzwl($dst$$Register, $mem$$Address);
5978 %}
5979
5980 ins_pipe(ialu_reg_mem);
5981 %}
5982
5983 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
5984 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
5985 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
5986
5987 ins_cost(125);
5988 format %{ "MOVSX $dst, $mem\t# ushort -> byte" %}
5989 ins_encode %{
5990 __ movsbl($dst$$Register, $mem$$Address);
5991 %}
5992 ins_pipe(ialu_reg_mem);
5993 %}
5994
5995 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register
5996 instruct loadUS2L(eRegL dst, memory mem, eFlagsReg cr) %{
5997 match(Set dst (ConvI2L (LoadUS mem)));
5998 effect(KILL cr);
5999
6000 ins_cost(250);
6001 format %{ "MOVZX $dst.lo,$mem\t# ushort/char -> long\n\t"
6002 "XOR $dst.hi,$dst.hi" %}
6003
6004 ins_encode %{
6025 %}
6026
6027 // Load Unsigned Short/Char (16 bit UNsigned) with a 16-bit mask into Long Register
6028 instruct loadUS2L_immI16(eRegL dst, memory mem, immI16 mask, eFlagsReg cr) %{
6029 match(Set dst (ConvI2L (AndI (LoadUS mem) mask)));
6030 effect(KILL cr);
6031
6032 format %{ "MOVZX $dst.lo, $mem\t# ushort/char & 16-bit mask -> long\n\t"
6033 "XOR $dst.hi,$dst.hi\n\t"
6034 "AND $dst.lo,$mask" %}
6035 ins_encode %{
6036 Register Rdst = $dst$$Register;
6037 __ movzwl(Rdst, $mem$$Address);
6038 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst));
6039 __ andl(Rdst, $mask$$constant);
6040 %}
6041 ins_pipe(ialu_reg_mem);
6042 %}
6043
6044 // Load Integer
6045 instruct loadI(rRegI dst, memory mem) %{
6046 match(Set dst (LoadI mem));
6047
6048 ins_cost(125);
6049 format %{ "MOV $dst,$mem\t# int" %}
6050
6051 ins_encode %{
6052 __ movl($dst$$Register, $mem$$Address);
6053 %}
6054
6055 ins_pipe(ialu_reg_mem);
6056 %}
6057
6058 // Load Integer (32 bit signed) to Byte (8 bit signed)
6059 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
6060 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
6061
6062 ins_cost(125);
6063 format %{ "MOVSX $dst, $mem\t# int -> byte" %}
6064 ins_encode %{
6065 __ movsbl($dst$$Register, $mem$$Address);
6066 %}
6067 ins_pipe(ialu_reg_mem);
6068 %}
6069
6070 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
6071 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
6072 match(Set dst (AndI (LoadI mem) mask));
6073
6074 ins_cost(125);
6075 format %{ "MOVZX $dst, $mem\t# int -> ubyte" %}
6076 ins_encode %{
6077 __ movzbl($dst$$Register, $mem$$Address);
6078 %}
6079 ins_pipe(ialu_reg_mem);
6080 %}
6081
6082 // Load Integer (32 bit signed) to Short (16 bit signed)
6083 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
6084 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
6085
6086 ins_cost(125);
6087 format %{ "MOVSX $dst, $mem\t# int -> short" %}
6088 ins_encode %{
6089 __ movswl($dst$$Register, $mem$$Address);
6090 %}
6091 ins_pipe(ialu_reg_mem);
6092 %}
6093
6094 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
6095 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
6096 match(Set dst (AndI (LoadI mem) mask));
6097
6098 ins_cost(125);
6099 format %{ "MOVZX $dst, $mem\t# int -> ushort/char" %}
6100 ins_encode %{
6101 __ movzwl($dst$$Register, $mem$$Address);
6102 %}
6103 ins_pipe(ialu_reg_mem);
6104 %}
6105
6106 // Load Integer into Long Register
6107 instruct loadI2L(eRegL dst, memory mem, eFlagsReg cr) %{
6108 match(Set dst (ConvI2L (LoadI mem)));
6109 effect(KILL cr);
6110
6111 ins_cost(375);
6112 format %{ "MOV $dst.lo,$mem\t# int -> long\n\t"
6113 "MOV $dst.hi,$dst.lo\n\t"
6114 "SAR $dst.hi,31" %}
6115
6236
6237 instruct loadLX_reg_volatile(eRegL dst, memory mem, regD tmp) %{
6238 predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access());
6239 match(Set dst (LoadL mem));
6240 effect(TEMP tmp);
6241 ins_cost(160);
6242 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t"
6243 "MOVD $dst.lo,$tmp\n\t"
6244 "PSRLQ $tmp,32\n\t"
6245 "MOVD $dst.hi,$tmp" %}
6246 ins_encode %{
6247 __ movdbl($tmp$$XMMRegister, $mem$$Address);
6248 __ movdl($dst$$Register, $tmp$$XMMRegister);
6249 __ psrlq($tmp$$XMMRegister, 32);
6250 __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister);
6251 %}
6252 ins_pipe( pipe_slow );
6253 %}
6254
6255 // Load Range
6256 instruct loadRange(rRegI dst, memory mem) %{
6257 match(Set dst (LoadRange mem));
6258
6259 ins_cost(125);
6260 format %{ "MOV $dst,$mem" %}
6261 opcode(0x8B);
6262 ins_encode( OpcP, RegMem(dst,mem));
6263 ins_pipe( ialu_reg_mem );
6264 %}
6265
6266
6267 // Load Pointer
6268 instruct loadP(eRegP dst, memory mem) %{
6269 match(Set dst (LoadP mem));
6270
6271 ins_cost(125);
6272 format %{ "MOV $dst,$mem" %}
6273 opcode(0x8B);
6274 ins_encode( OpcP, RegMem(dst,mem));
6275 ins_pipe( ialu_reg_mem );
6276 %}
6333 ins_encode %{
6334 __ movflt ($dst$$XMMRegister, $mem$$Address);
6335 %}
6336 ins_pipe( pipe_slow );
6337 %}
6338
6339 // Load Float
6340 instruct loadFPR(regFPR dst, memory mem) %{
6341 predicate(UseSSE==0);
6342 match(Set dst (LoadF mem));
6343
6344 ins_cost(150);
6345 format %{ "FLD_S ST,$mem\n\t"
6346 "FSTP $dst" %}
6347 opcode(0xD9); /* D9 /0 */
6348 ins_encode( OpcP, RMopc_Mem(0x00,mem),
6349 Pop_Reg_FPR(dst) );
6350 ins_pipe( fpu_reg_mem );
6351 %}
6352
6353 // Load Effective Address
6354 instruct leaP8(eRegP dst, indOffset8 mem) %{
6355 match(Set dst mem);
6356
6357 ins_cost(110);
6358 format %{ "LEA $dst,$mem" %}
6359 opcode(0x8D);
6360 ins_encode( OpcP, RegMem(dst,mem));
6361 ins_pipe( ialu_reg_reg_fat );
6362 %}
6363
6364 instruct leaP32(eRegP dst, indOffset32 mem) %{
6365 match(Set dst mem);
6366
6367 ins_cost(110);
6368 format %{ "LEA $dst,$mem" %}
6369 opcode(0x8D);
6370 ins_encode( OpcP, RegMem(dst,mem));
6371 ins_pipe( ialu_reg_reg_fat );
6372 %}
6385 match(Set dst mem);
6386
6387 ins_cost(110);
6388 format %{ "LEA $dst,$mem" %}
6389 opcode(0x8D);
6390 ins_encode( OpcP, RegMem(dst,mem));
6391 ins_pipe( ialu_reg_reg_fat );
6392 %}
6393
6394 instruct leaPIdxScaleOff(eRegP dst, indIndexScaleOffset mem) %{
6395 match(Set dst mem);
6396
6397 ins_cost(110);
6398 format %{ "LEA $dst,$mem" %}
6399 opcode(0x8D);
6400 ins_encode( OpcP, RegMem(dst,mem));
6401 ins_pipe( ialu_reg_reg_fat );
6402 %}
6403
6404 // Load Constant
6405 instruct loadConI(rRegI dst, immI src) %{
6406 match(Set dst src);
6407
6408 format %{ "MOV $dst,$src" %}
6409 ins_encode( LdImmI(dst, src) );
6410 ins_pipe( ialu_reg_fat );
6411 %}
6412
6413 // Load Constant zero
6414 instruct loadConI0(rRegI dst, immI0 src, eFlagsReg cr) %{
6415 match(Set dst src);
6416 effect(KILL cr);
6417
6418 ins_cost(50);
6419 format %{ "XOR $dst,$dst" %}
6420 opcode(0x33); /* + rd */
6421 ins_encode( OpcP, RegReg( dst, dst ) );
6422 ins_pipe( ialu_reg );
6423 %}
6424
6425 instruct loadConP(eRegP dst, immP src) %{
6426 match(Set dst src);
6427
6428 format %{ "MOV $dst,$src" %}
6429 opcode(0xB8); /* + rd */
6430 ins_encode( LdImmP(dst, src) );
6431 ins_pipe( ialu_reg_fat );
6432 %}
6433
6434 instruct loadConL(eRegL dst, immL src, eFlagsReg cr) %{
6562 ins_cost(125);
6563 format %{ "MOVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %}
6564 ins_encode %{
6565 __ movdbl($dst$$XMMRegister, $constantaddress($con));
6566 %}
6567 ins_pipe(pipe_slow);
6568 %}
6569
6570 // The instruction usage is guarded by predicate in operand immD0().
6571 instruct loadConD0(regD dst, immD0 src) %{
6572 match(Set dst src);
6573 ins_cost(100);
6574 format %{ "XORPD $dst,$dst\t# double 0.0" %}
6575 ins_encode %{
6576 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister);
6577 %}
6578 ins_pipe( pipe_slow );
6579 %}
6580
6581 // Load Stack Slot
6582 instruct loadSSI(rRegI dst, stackSlotI src) %{
6583 match(Set dst src);
6584 ins_cost(125);
6585
6586 format %{ "MOV $dst,$src" %}
6587 opcode(0x8B);
6588 ins_encode( OpcP, RegMem(dst,src));
6589 ins_pipe( ialu_reg_mem );
6590 %}
6591
6592 instruct loadSSL(eRegL dst, stackSlotL src) %{
6593 match(Set dst src);
6594
6595 ins_cost(200);
6596 format %{ "MOV $dst,$src.lo\n\t"
6597 "MOV $dst+4,$src.hi" %}
6598 opcode(0x8B, 0x8B);
6599 ins_encode( OpcP, RegMem( dst, src ), OpcS, RegMem_Hi( dst, src ) );
6600 ins_pipe( ialu_mem_long_reg );
6601 %}
6602
6789 ins_encode %{
6790 __ prefetcht2($mem$$Address);
6791 %}
6792 ins_pipe(ialu_mem);
6793 %}
6794
6795 //----------Store Instructions-------------------------------------------------
6796
6797 // Store Byte
6798 instruct storeB(memory mem, xRegI src) %{
6799 match(Set mem (StoreB mem src));
6800
6801 ins_cost(125);
6802 format %{ "MOV8 $mem,$src" %}
6803 opcode(0x88);
6804 ins_encode( OpcP, RegMem( src, mem ) );
6805 ins_pipe( ialu_mem_reg );
6806 %}
6807
6808 // Store Char/Short
6809 instruct storeC(memory mem, rRegI src) %{
6810 match(Set mem (StoreC mem src));
6811
6812 ins_cost(125);
6813 format %{ "MOV16 $mem,$src" %}
6814 opcode(0x89, 0x66);
6815 ins_encode( OpcS, OpcP, RegMem( src, mem ) );
6816 ins_pipe( ialu_mem_reg );
6817 %}
6818
6819 // Store Integer
6820 instruct storeI(memory mem, rRegI src) %{
6821 match(Set mem (StoreI mem src));
6822
6823 ins_cost(125);
6824 format %{ "MOV $mem,$src" %}
6825 opcode(0x89);
6826 ins_encode( OpcP, RegMem( src, mem ) );
6827 ins_pipe( ialu_mem_reg );
6828 %}
6829
6830 // Store Long
6831 instruct storeL(long_memory mem, eRegL src) %{
6832 predicate(!((StoreLNode*)n)->require_atomic_access());
6833 match(Set mem (StoreL mem src));
6834
6835 ins_cost(200);
6836 format %{ "MOV $mem,$src.lo\n\t"
6837 "MOV $mem+4,$src.hi" %}
6838 opcode(0x89, 0x89);
6839 ins_encode( OpcP, RegMem( src, mem ), OpcS, RegMem_Hi( src, mem ) );
6840 ins_pipe( ialu_mem_long_reg );
6944 match(Set mem (StoreP mem src));
6945
6946 ins_cost(150);
6947 format %{ "MOV $mem,$src" %}
6948 opcode(0xC7); /* C7 /0 */
6949 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32( src ));
6950 ins_pipe( ialu_mem_imm );
6951 %}
6952
6953 // Store Byte Immediate
6954 instruct storeImmB(memory mem, immI8 src) %{
6955 match(Set mem (StoreB mem src));
6956
6957 ins_cost(150);
6958 format %{ "MOV8 $mem,$src" %}
6959 opcode(0xC6); /* C6 /0 */
6960 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src ));
6961 ins_pipe( ialu_mem_imm );
6962 %}
6963
6964 // Store CMS card-mark Immediate
6965 instruct storeImmCM(memory mem, immI8 src) %{
6966 match(Set mem (StoreCM mem src));
6967
6968 ins_cost(150);
6969 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %}
6970 opcode(0xC6); /* C6 /0 */
6971 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src ));
6972 ins_pipe( ialu_mem_imm );
6973 %}
6974
6975 // Store Double
6976 instruct storeDPR( memory mem, regDPR1 src) %{
6977 predicate(UseSSE<=1);
6978 match(Set mem (StoreD mem src));
6979
6980 ins_cost(100);
6981 format %{ "FST_D $mem,$src" %}
6982 opcode(0xDD); /* DD /2 */
6983 ins_encode( enc_FPR_store(mem,src) );
7005 format %{ "MOVSD $mem,$src" %}
7006 ins_encode %{
7007 __ movdbl($mem$$Address, $src$$XMMRegister);
7008 %}
7009 ins_pipe( pipe_slow );
7010 %}
7011
7012 // Store XMM register to memory (single-precision floating point)
7013 // MOVSS instruction
7014 instruct storeF(memory mem, regF src) %{
7015 predicate(UseSSE>=1);
7016 match(Set mem (StoreF mem src));
7017 ins_cost(95);
7018 format %{ "MOVSS $mem,$src" %}
7019 ins_encode %{
7020 __ movflt($mem$$Address, $src$$XMMRegister);
7021 %}
7022 ins_pipe( pipe_slow );
7023 %}
7024
7025 // Store Float
7026 instruct storeFPR( memory mem, regFPR1 src) %{
7027 predicate(UseSSE==0);
7028 match(Set mem (StoreF mem src));
7029
7030 ins_cost(100);
7031 format %{ "FST_S $mem,$src" %}
7032 opcode(0xD9); /* D9 /2 */
7033 ins_encode( enc_FPR_store(mem,src) );
7034 ins_pipe( fpu_mem_reg );
7035 %}
7036
7037 // Store Float does rounding on x86
7038 instruct storeFPR_rounded( memory mem, regFPR1 src) %{
7039 predicate(UseSSE==0);
7040 match(Set mem (StoreF mem (RoundFloat src)));
7041
7042 ins_cost(100);
7043 format %{ "FST_S $mem,$src\t# round" %}
7044 opcode(0xD9); /* D9 /2 */
7066 ins_cost(50);
7067 format %{ "MOV $mem,$src\t# store float" %}
7068 opcode(0xC7); /* C7 /0 */
7069 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32FPR_as_bits( src ));
7070 ins_pipe( ialu_mem_imm );
7071 %}
7072
7073 // Store immediate Float value (it is faster than store from XMM register)
7074 // The instruction usage is guarded by predicate in operand immF().
7075 instruct storeF_imm( memory mem, immF src) %{
7076 match(Set mem (StoreF mem src));
7077
7078 ins_cost(50);
7079 format %{ "MOV $mem,$src\t# store float" %}
7080 opcode(0xC7); /* C7 /0 */
7081 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32F_as_bits( src ));
7082 ins_pipe( ialu_mem_imm );
7083 %}
7084
7085 // Store Integer to stack slot
7086 instruct storeSSI(stackSlotI dst, rRegI src) %{
7087 match(Set dst src);
7088
7089 ins_cost(100);
7090 format %{ "MOV $dst,$src" %}
7091 opcode(0x89);
7092 ins_encode( OpcPRegSS( dst, src ) );
7093 ins_pipe( ialu_mem_reg );
7094 %}
7095
7096 // Store Integer to stack slot
7097 instruct storeSSP(stackSlotP dst, eRegP src) %{
7098 match(Set dst src);
7099
7100 ins_cost(100);
7101 format %{ "MOV $dst,$src" %}
7102 opcode(0x89);
7103 ins_encode( OpcPRegSS( dst, src ) );
7104 ins_pipe( ialu_mem_reg );
7105 %}
7106
7191
7192 instruct membar_storestore() %{
7193 match(MemBarStoreStore);
7194 ins_cost(0);
7195
7196 size(0);
7197 format %{ "MEMBAR-storestore (empty encoding)" %}
7198 ins_encode( );
7199 ins_pipe(empty);
7200 %}
7201
7202 //----------Move Instructions--------------------------------------------------
7203 instruct castX2P(eAXRegP dst, eAXRegI src) %{
7204 match(Set dst (CastX2P src));
7205 format %{ "# X2P $dst, $src" %}
7206 ins_encode( /*empty encoding*/ );
7207 ins_cost(0);
7208 ins_pipe(empty);
7209 %}
7210
7211 instruct castP2X(rRegI dst, eRegP src ) %{
7212 match(Set dst (CastP2X src));
7213 ins_cost(50);
7214 format %{ "MOV $dst, $src\t# CastP2X" %}
7215 ins_encode( enc_Copy( dst, src) );
7216 ins_pipe( ialu_reg_reg );
7217 %}
7218
7219 //----------Conditional Move---------------------------------------------------
7220 // Conditional move
7221 instruct jmovI_reg(cmpOp cop, eFlagsReg cr, rRegI dst, rRegI src) %{
7222 predicate(!VM_Version::supports_cmov() );
7223 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7224 ins_cost(200);
7225 format %{ "J$cop,us skip\t# signed cmove\n\t"
7226 "MOV $dst,$src\n"
7227 "skip:" %}
7228 ins_encode %{
7229 Label Lskip;
7230 // Invert sense of branch from sense of CMOV
7231 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7232 __ movl($dst$$Register, $src$$Register);
7233 __ bind(Lskip);
7234 %}
7235 ins_pipe( pipe_cmov_reg );
7236 %}
7237
7238 instruct jmovI_regU(cmpOpU cop, eFlagsRegU cr, rRegI dst, rRegI src) %{
7239 predicate(!VM_Version::supports_cmov() );
7240 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7241 ins_cost(200);
7242 format %{ "J$cop,us skip\t# unsigned cmove\n\t"
7243 "MOV $dst,$src\n"
7244 "skip:" %}
7245 ins_encode %{
7246 Label Lskip;
7247 // Invert sense of branch from sense of CMOV
7248 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip);
7249 __ movl($dst$$Register, $src$$Register);
7250 __ bind(Lskip);
7251 %}
7252 ins_pipe( pipe_cmov_reg );
7253 %}
7254
7255 instruct cmovI_reg(rRegI dst, rRegI src, eFlagsReg cr, cmpOp cop ) %{
7256 predicate(VM_Version::supports_cmov() );
7257 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7258 ins_cost(200);
7259 format %{ "CMOV$cop $dst,$src" %}
7260 opcode(0x0F,0x40);
7261 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
7262 ins_pipe( pipe_cmov_reg );
7263 %}
7264
7265 instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, rRegI dst, rRegI src ) %{
7266 predicate(VM_Version::supports_cmov() );
7267 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7268 ins_cost(200);
7269 format %{ "CMOV$cop $dst,$src" %}
7270 opcode(0x0F,0x40);
7271 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
7272 ins_pipe( pipe_cmov_reg );
7273 %}
7274
7275 instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, rRegI dst, rRegI src ) %{
7276 predicate(VM_Version::supports_cmov() );
7277 match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
7278 ins_cost(200);
7279 expand %{
7280 cmovI_regU(cop, cr, dst, src);
7281 %}
7282 %}
7283
7284 // Conditional move
7285 instruct cmovI_mem(cmpOp cop, eFlagsReg cr, rRegI dst, memory src) %{
7286 predicate(VM_Version::supports_cmov() );
7287 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7288 ins_cost(250);
7289 format %{ "CMOV$cop $dst,$src" %}
7290 opcode(0x0F,0x40);
7291 ins_encode( enc_cmov(cop), RegMem( dst, src ) );
7292 ins_pipe( pipe_cmov_mem );
7293 %}
7294
7295 // Conditional move
7296 instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, rRegI dst, memory src) %{
7297 predicate(VM_Version::supports_cmov() );
7298 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7299 ins_cost(250);
7300 format %{ "CMOV$cop $dst,$src" %}
7301 opcode(0x0F,0x40);
7302 ins_encode( enc_cmov(cop), RegMem( dst, src ) );
7303 ins_pipe( pipe_cmov_mem );
7304 %}
7305
7306 instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, rRegI dst, memory src) %{
7307 predicate(VM_Version::supports_cmov() );
7308 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
7309 ins_cost(250);
7310 expand %{
7311 cmovI_memU(cop, cr, dst, src);
7312 %}
7313 %}
7314
7315 // Conditional move
7316 instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{
7317 predicate(VM_Version::supports_cmov() );
7318 match(Set dst (CMoveP (Binary cop cr) (Binary dst src)));
7319 ins_cost(200);
7320 format %{ "CMOV$cop $dst,$src\t# ptr" %}
7321 opcode(0x0F,0x40);
7322 ins_encode( enc_cmov(cop), RegReg( dst, src ) );
7323 ins_pipe( pipe_cmov_reg );
7324 %}
7325
7326 // Conditional move (non-P6 version)
7540 ins_cost(200);
7541 format %{ "CMOV$cop $dst.lo,$src.lo\n\t"
7542 "CMOV$cop $dst.hi,$src.hi" %}
7543 opcode(0x0F,0x40);
7544 ins_encode( enc_cmov(cop), RegReg_Lo2( dst, src ), enc_cmov(cop), RegReg_Hi2( dst, src ) );
7545 ins_pipe( pipe_cmov_reg_long );
7546 %}
7547
7548 instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{
7549 predicate(VM_Version::supports_cmov() );
7550 match(Set dst (CMoveL (Binary cop cr) (Binary dst src)));
7551 ins_cost(200);
7552 expand %{
7553 cmovL_regU(cop, cr, dst, src);
7554 %}
7555 %}
7556
7557 //----------Arithmetic Instructions--------------------------------------------
7558 //----------Addition Instructions----------------------------------------------
7559 // Integer Addition Instructions
7560 instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
7561 match(Set dst (AddI dst src));
7562 effect(KILL cr);
7563
7564 size(2);
7565 format %{ "ADD $dst,$src" %}
7566 opcode(0x03);
7567 ins_encode( OpcP, RegReg( dst, src) );
7568 ins_pipe( ialu_reg_reg );
7569 %}
7570
7571 instruct addI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{
7572 match(Set dst (AddI dst src));
7573 effect(KILL cr);
7574
7575 format %{ "ADD $dst,$src" %}
7576 opcode(0x81, 0x00); /* /0 id */
7577 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
7578 ins_pipe( ialu_reg );
7579 %}
7580
7581 instruct incI_eReg(rRegI dst, immI1 src, eFlagsReg cr) %{
7582 predicate(UseIncDec);
7583 match(Set dst (AddI dst src));
7584 effect(KILL cr);
7585
7586 size(1);
7587 format %{ "INC $dst" %}
7588 opcode(0x40); /* */
7589 ins_encode( Opc_plus( primary, dst ) );
7590 ins_pipe( ialu_reg );
7591 %}
7592
7593 instruct leaI_eReg_immI(rRegI dst, rRegI src0, immI src1) %{
7594 match(Set dst (AddI src0 src1));
7595 ins_cost(110);
7596
7597 format %{ "LEA $dst,[$src0 + $src1]" %}
7598 opcode(0x8D); /* 0x8D /r */
7599 ins_encode( OpcP, RegLea( dst, src0, src1 ) );
7600 ins_pipe( ialu_reg_reg );
7601 %}
7602
7603 instruct leaP_eReg_immI(eRegP dst, eRegP src0, immI src1) %{
7604 match(Set dst (AddP src0 src1));
7605 ins_cost(110);
7606
7607 format %{ "LEA $dst,[$src0 + $src1]\t# ptr" %}
7608 opcode(0x8D); /* 0x8D /r */
7609 ins_encode( OpcP, RegLea( dst, src0, src1 ) );
7610 ins_pipe( ialu_reg_reg );
7611 %}
7612
7613 instruct decI_eReg(rRegI dst, immI_M1 src, eFlagsReg cr) %{
7614 predicate(UseIncDec);
7615 match(Set dst (AddI dst src));
7616 effect(KILL cr);
7617
7618 size(1);
7619 format %{ "DEC $dst" %}
7620 opcode(0x48); /* */
7621 ins_encode( Opc_plus( primary, dst ) );
7622 ins_pipe( ialu_reg );
7623 %}
7624
7625 instruct addP_eReg(eRegP dst, rRegI src, eFlagsReg cr) %{
7626 match(Set dst (AddP dst src));
7627 effect(KILL cr);
7628
7629 size(2);
7630 format %{ "ADD $dst,$src" %}
7631 opcode(0x03);
7632 ins_encode( OpcP, RegReg( dst, src) );
7633 ins_pipe( ialu_reg_reg );
7634 %}
7635
7636 instruct addP_eReg_imm(eRegP dst, immI src, eFlagsReg cr) %{
7637 match(Set dst (AddP dst src));
7638 effect(KILL cr);
7639
7640 format %{ "ADD $dst,$src" %}
7641 opcode(0x81,0x00); /* Opcode 81 /0 id */
7642 // ins_encode( RegImm( dst, src) );
7643 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
7644 ins_pipe( ialu_reg );
7645 %}
7646
7647 instruct addI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{
7648 match(Set dst (AddI dst (LoadI src)));
7649 effect(KILL cr);
7650
7651 ins_cost(125);
7652 format %{ "ADD $dst,$src" %}
7653 opcode(0x03);
7654 ins_encode( OpcP, RegMem( dst, src) );
7655 ins_pipe( ialu_reg_mem );
7656 %}
7657
7658 instruct addI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{
7659 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7660 effect(KILL cr);
7661
7662 ins_cost(150);
7663 format %{ "ADD $dst,$src" %}
7664 opcode(0x01); /* Opcode 01 /r */
7665 ins_encode( OpcP, RegMem( src, dst ) );
7666 ins_pipe( ialu_mem_reg );
7667 %}
7668
7669 // Add Memory with Immediate
7670 instruct addI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
7671 match(Set dst (StoreI dst (AddI (LoadI dst) src)));
7672 effect(KILL cr);
7673
7674 ins_cost(125);
7675 format %{ "ADD $dst,$src" %}
7676 opcode(0x81); /* Opcode 81 /0 id */
7677 ins_encode( OpcSE( src ), RMopc_Mem(0x00,dst), Con8or32( src ) );
7678 ins_pipe( ialu_mem_imm );
7700 ins_pipe( ialu_mem_imm );
7701 %}
7702
7703
7704 instruct checkCastPP( eRegP dst ) %{
7705 match(Set dst (CheckCastPP dst));
7706
7707 size(0);
7708 format %{ "#checkcastPP of $dst" %}
7709 ins_encode( /*empty encoding*/ );
7710 ins_pipe( empty );
7711 %}
7712
7713 instruct castPP( eRegP dst ) %{
7714 match(Set dst (CastPP dst));
7715 format %{ "#castPP of $dst" %}
7716 ins_encode( /*empty encoding*/ );
7717 ins_pipe( empty );
7718 %}
7719
7720 instruct castII( rRegI dst ) %{
7721 match(Set dst (CastII dst));
7722 format %{ "#castII of $dst" %}
7723 ins_encode( /*empty encoding*/ );
7724 ins_cost(0);
7725 ins_pipe( empty );
7726 %}
7727
7728
7729 // Load-locked - same as a regular pointer load when used with compare-swap
7730 instruct loadPLocked(eRegP dst, memory mem) %{
7731 match(Set dst (LoadPLocked mem));
7732
7733 ins_cost(125);
7734 format %{ "MOV $dst,$mem\t# Load ptr. locked" %}
7735 opcode(0x8B);
7736 ins_encode( OpcP, RegMem(dst,mem));
7737 ins_pipe( ialu_reg_mem );
7738 %}
7739
7740 // LoadLong-locked - same as a volatile long load when used with compare-swap
7778 __ psrlq($tmp$$XMMRegister, 32);
7779 __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister);
7780 %}
7781 ins_pipe( pipe_slow );
7782 %}
7783
7784 // Conditional-store of the updated heap-top.
7785 // Used during allocation of the shared heap.
7786 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel.
7787 instruct storePConditional( memory heap_top_ptr, eAXRegP oldval, eRegP newval, eFlagsReg cr ) %{
7788 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
7789 // EAX is killed if there is contention, but then it's also unused.
7790 // In the common case of no contention, EAX holds the new oop address.
7791 format %{ "CMPXCHG $heap_top_ptr,$newval\t# If EAX==$heap_top_ptr Then store $newval into $heap_top_ptr" %}
7792 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval,heap_top_ptr) );
7793 ins_pipe( pipe_cmpxchg );
7794 %}
7795
7796 // Conditional-store of an int value.
7797 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel.
7798 instruct storeIConditional( memory mem, eAXRegI oldval, rRegI newval, eFlagsReg cr ) %{
7799 match(Set cr (StoreIConditional mem (Binary oldval newval)));
7800 effect(KILL oldval);
7801 format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
7802 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) );
7803 ins_pipe( pipe_cmpxchg );
7804 %}
7805
7806 // Conditional-store of a long value.
7807 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel.
7808 instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
7809 match(Set cr (StoreLConditional mem (Binary oldval newval)));
7810 effect(KILL oldval);
7811 format %{ "XCHG EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t"
7812 "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t"
7813 "XCHG EBX,ECX"
7814 %}
7815 ins_encode %{
7816 // Note: we need to swap rbx, and rcx before and after the
7817 // cmpxchg8 instruction because the instruction uses
7818 // rcx as the high order word of the new value to store but
7819 // our register encoding uses rbx.
7820 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
7821 if( os::is_MP() )
7822 __ lock();
7823 __ cmpxchg8($mem$$Address);
7824 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
7825 %}
7826 ins_pipe( pipe_cmpxchg );
7827 %}
7828
7829 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7830
7831 instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
7832 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7833 effect(KILL cr, KILL oldval);
7834 format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
7835 "MOV $res,0\n\t"
7836 "JNE,s fail\n\t"
7837 "MOV $res,1\n"
7838 "fail:" %}
7839 ins_encode( enc_cmpxchg8(mem_ptr),
7840 enc_flags_ne_to_boolean(res) );
7841 ins_pipe( pipe_cmpxchg );
7842 %}
7843
7844 instruct compareAndSwapP( rRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{
7845 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7846 effect(KILL cr, KILL oldval);
7847 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
7848 "MOV $res,0\n\t"
7849 "JNE,s fail\n\t"
7850 "MOV $res,1\n"
7851 "fail:" %}
7852 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) );
7853 ins_pipe( pipe_cmpxchg );
7854 %}
7855
7856 instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
7857 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
7858 effect(KILL cr, KILL oldval);
7859 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
7860 "MOV $res,0\n\t"
7861 "JNE,s fail\n\t"
7862 "MOV $res,1\n"
7863 "fail:" %}
7864 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) );
7865 ins_pipe( pipe_cmpxchg );
7866 %}
7867
7868 //----------Subtraction Instructions-------------------------------------------
7869 // Integer Subtraction Instructions
7870 instruct subI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
7871 match(Set dst (SubI dst src));
7872 effect(KILL cr);
7873
7874 size(2);
7875 format %{ "SUB $dst,$src" %}
7876 opcode(0x2B);
7877 ins_encode( OpcP, RegReg( dst, src) );
7878 ins_pipe( ialu_reg_reg );
7879 %}
7880
7881 instruct subI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{
7882 match(Set dst (SubI dst src));
7883 effect(KILL cr);
7884
7885 format %{ "SUB $dst,$src" %}
7886 opcode(0x81,0x05); /* Opcode 81 /5 */
7887 // ins_encode( RegImm( dst, src) );
7888 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
7889 ins_pipe( ialu_reg );
7890 %}
7891
7892 instruct subI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{
7893 match(Set dst (SubI dst (LoadI src)));
7894 effect(KILL cr);
7895
7896 ins_cost(125);
7897 format %{ "SUB $dst,$src" %}
7898 opcode(0x2B);
7899 ins_encode( OpcP, RegMem( dst, src) );
7900 ins_pipe( ialu_reg_mem );
7901 %}
7902
7903 instruct subI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{
7904 match(Set dst (StoreI dst (SubI (LoadI dst) src)));
7905 effect(KILL cr);
7906
7907 ins_cost(150);
7908 format %{ "SUB $dst,$src" %}
7909 opcode(0x29); /* Opcode 29 /r */
7910 ins_encode( OpcP, RegMem( src, dst ) );
7911 ins_pipe( ialu_mem_reg );
7912 %}
7913
7914 // Subtract from a pointer
7915 instruct subP_eReg(eRegP dst, rRegI src, immI0 zero, eFlagsReg cr) %{
7916 match(Set dst (AddP dst (SubI zero src)));
7917 effect(KILL cr);
7918
7919 size(2);
7920 format %{ "SUB $dst,$src" %}
7921 opcode(0x2B);
7922 ins_encode( OpcP, RegReg( dst, src) );
7923 ins_pipe( ialu_reg_reg );
7924 %}
7925
7926 instruct negI_eReg(rRegI dst, immI0 zero, eFlagsReg cr) %{
7927 match(Set dst (SubI zero dst));
7928 effect(KILL cr);
7929
7930 size(2);
7931 format %{ "NEG $dst" %}
7932 opcode(0xF7,0x03); // Opcode F7 /3
7933 ins_encode( OpcP, RegOpc( dst ) );
7934 ins_pipe( ialu_reg );
7935 %}
7936
7937
7938 //----------Multiplication/Division Instructions-------------------------------
7939 // Integer Multiplication Instructions
7940 // Multiply Register
7941 instruct mulI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
7942 match(Set dst (MulI dst src));
7943 effect(KILL cr);
7944
7945 size(3);
7946 ins_cost(300);
7947 format %{ "IMUL $dst,$src" %}
7948 opcode(0xAF, 0x0F);
7949 ins_encode( OpcS, OpcP, RegReg( dst, src) );
7950 ins_pipe( ialu_reg_reg_alu0 );
7951 %}
7952
7953 // Multiply 32-bit Immediate
7954 instruct mulI_eReg_imm(rRegI dst, rRegI src, immI imm, eFlagsReg cr) %{
7955 match(Set dst (MulI src imm));
7956 effect(KILL cr);
7957
7958 ins_cost(300);
7959 format %{ "IMUL $dst,$src,$imm" %}
7960 opcode(0x69); /* 69 /r id */
7961 ins_encode( OpcSE(imm), RegReg( dst, src ), Con8or32( imm ) );
7962 ins_pipe( ialu_reg_reg_alu0 );
7963 %}
7964
7965 instruct loadConL_low_only(eADXRegL_low_only dst, immL32 src, eFlagsReg cr) %{
7966 match(Set dst src);
7967 effect(KILL cr);
7968
7969 // Note that this is artificially increased to make it more expensive than loadConL
7970 ins_cost(250);
7971 format %{ "MOV EAX,$src\t// low word only" %}
7972 opcode(0xB8);
7973 ins_encode( LdImmL_Lo(dst, src) );
7974 ins_pipe( ialu_reg_fat );
7990 ins_pipe( pipe_slow );
7991 %}
7992
7993 // Multiply by 32-bit Immediate, taking the shifted high order results
7994 instruct mulI_imm_RShift_high(eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32_63 cnt, eFlagsReg cr) %{
7995 match(Set dst (ConvL2I (RShiftL (MulL (ConvI2L src1) src2) cnt)));
7996 predicate( _kids[0]->_kids[0]->_kids[1]->_leaf->Opcode() == Op_ConL &&
7997 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() >= min_jint &&
7998 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() <= max_jint );
7999 effect(USE src1, KILL cr);
8000
8001 // Note that this is adjusted by 150 to compensate for the overcosting of loadConL_low_only
8002 ins_cost(1*100 + 1*400 - 150);
8003 format %{ "IMUL EDX:EAX,$src1\n\t"
8004 "SAR EDX,$cnt-32" %}
8005 ins_encode( multiply_con_and_shift_high( dst, src1, src2, cnt, cr ) );
8006 ins_pipe( pipe_slow );
8007 %}
8008
8009 // Multiply Memory 32-bit Immediate
8010 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, eFlagsReg cr) %{
8011 match(Set dst (MulI (LoadI src) imm));
8012 effect(KILL cr);
8013
8014 ins_cost(300);
8015 format %{ "IMUL $dst,$src,$imm" %}
8016 opcode(0x69); /* 69 /r id */
8017 ins_encode( OpcSE(imm), RegMem( dst, src ), Con8or32( imm ) );
8018 ins_pipe( ialu_reg_mem_alu0 );
8019 %}
8020
8021 // Multiply Memory
8022 instruct mulI(rRegI dst, memory src, eFlagsReg cr) %{
8023 match(Set dst (MulI dst (LoadI src)));
8024 effect(KILL cr);
8025
8026 ins_cost(350);
8027 format %{ "IMUL $dst,$src" %}
8028 opcode(0xAF, 0x0F);
8029 ins_encode( OpcS, OpcP, RegMem( dst, src) );
8030 ins_pipe( ialu_reg_mem_alu0 );
8031 %}
8032
8033 // Multiply Register Int to Long
8034 instruct mulI2L(eADXRegL dst, eAXRegI src, nadxRegI src1, eFlagsReg flags) %{
8035 // Basic Idea: long = (long)int * (long)int
8036 match(Set dst (MulL (ConvI2L src) (ConvI2L src1)));
8037 effect(DEF dst, USE src, USE src1, KILL flags);
8038
8039 ins_cost(300);
8040 format %{ "IMUL $dst,$src1" %}
8041
8042 ins_encode( long_int_multiply( dst, src1 ) );
8043 ins_pipe( ialu_reg_reg_alu0 );
8044 %}
8045
8046 instruct mulIS_eReg(eADXRegL dst, immL_32bits mask, eFlagsReg flags, eAXRegI src, nadxRegI src1) %{
8047 // Basic Idea: long = (int & 0xffffffffL) * (int & 0xffffffffL)
8048 match(Set dst (MulL (AndL (ConvI2L src) mask) (AndL (ConvI2L src1) mask)));
8049 effect(KILL flags);
8050
8051 ins_cost(300);
8052 format %{ "MUL $dst,$src1" %}
8053
8054 ins_encode( long_uint_multiply(dst, src1) );
8055 ins_pipe( ialu_reg_reg_alu0 );
8056 %}
8057
8058 // Multiply Register Long
8059 instruct mulL_eReg(eADXRegL dst, eRegL src, rRegI tmp, eFlagsReg cr) %{
8060 match(Set dst (MulL dst src));
8061 effect(KILL cr, TEMP tmp);
8062 ins_cost(4*100+3*400);
8063 // Basic idea: lo(result) = lo(x_lo * y_lo)
8064 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi)
8065 format %{ "MOV $tmp,$src.lo\n\t"
8066 "IMUL $tmp,EDX\n\t"
8067 "MOV EDX,$src.hi\n\t"
8068 "IMUL EDX,EAX\n\t"
8069 "ADD $tmp,EDX\n\t"
8070 "MUL EDX:EAX,$src.lo\n\t"
8071 "ADD EDX,$tmp" %}
8072 ins_encode( long_multiply( dst, src, tmp ) );
8073 ins_pipe( pipe_slow );
8074 %}
8075
8076 // Multiply Register Long where the left operand's high 32 bits are zero
8077 instruct mulL_eReg_lhi0(eADXRegL dst, eRegL src, rRegI tmp, eFlagsReg cr) %{
8078 predicate(is_operand_hi32_zero(n->in(1)));
8079 match(Set dst (MulL dst src));
8080 effect(KILL cr, TEMP tmp);
8081 ins_cost(2*100+2*400);
8082 // Basic idea: lo(result) = lo(x_lo * y_lo)
8083 // hi(result) = hi(x_lo * y_lo) + lo(x_lo * y_hi) where lo(x_hi * y_lo) = 0 because x_hi = 0
8084 format %{ "MOV $tmp,$src.hi\n\t"
8085 "IMUL $tmp,EAX\n\t"
8086 "MUL EDX:EAX,$src.lo\n\t"
8087 "ADD EDX,$tmp" %}
8088 ins_encode %{
8089 __ movl($tmp$$Register, HIGH_FROM_LOW($src$$Register));
8090 __ imull($tmp$$Register, rax);
8091 __ mull($src$$Register);
8092 __ addl(rdx, $tmp$$Register);
8093 %}
8094 ins_pipe( pipe_slow );
8095 %}
8096
8097 // Multiply Register Long where the right operand's high 32 bits are zero
8098 instruct mulL_eReg_rhi0(eADXRegL dst, eRegL src, rRegI tmp, eFlagsReg cr) %{
8099 predicate(is_operand_hi32_zero(n->in(2)));
8100 match(Set dst (MulL dst src));
8101 effect(KILL cr, TEMP tmp);
8102 ins_cost(2*100+2*400);
8103 // Basic idea: lo(result) = lo(x_lo * y_lo)
8104 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) where lo(x_lo * y_hi) = 0 because y_hi = 0
8105 format %{ "MOV $tmp,$src.lo\n\t"
8106 "IMUL $tmp,EDX\n\t"
8107 "MUL EDX:EAX,$src.lo\n\t"
8108 "ADD EDX,$tmp" %}
8109 ins_encode %{
8110 __ movl($tmp$$Register, $src$$Register);
8111 __ imull($tmp$$Register, rdx);
8112 __ mull($src$$Register);
8113 __ addl(rdx, $tmp$$Register);
8114 %}
8115 ins_pipe( pipe_slow );
8116 %}
8117
8118 // Multiply Register Long where the left and the right operands' high 32 bits are zero
8119 instruct mulL_eReg_hi0(eADXRegL dst, eRegL src, eFlagsReg cr) %{
8120 predicate(is_operand_hi32_zero(n->in(1)) && is_operand_hi32_zero(n->in(2)));
8121 match(Set dst (MulL dst src));
8122 effect(KILL cr);
8123 ins_cost(1*400);
8124 // Basic idea: lo(result) = lo(x_lo * y_lo)
8125 // hi(result) = hi(x_lo * y_lo) where lo(x_hi * y_lo) = 0 and lo(x_lo * y_hi) = 0 because x_hi = 0 and y_hi = 0
8126 format %{ "MUL EDX:EAX,$src.lo\n\t" %}
8127 ins_encode %{
8128 __ mull($src$$Register);
8129 %}
8130 ins_pipe( pipe_slow );
8131 %}
8132
8133 // Multiply Register Long by small constant
8134 instruct mulL_eReg_con(eADXRegL dst, immL_127 src, rRegI tmp, eFlagsReg cr) %{
8135 match(Set dst (MulL dst src));
8136 effect(KILL cr, TEMP tmp);
8137 ins_cost(2*100+2*400);
8138 size(12);
8139 // Basic idea: lo(result) = lo(src * EAX)
8140 // hi(result) = hi(src * EAX) + lo(src * EDX)
8141 format %{ "IMUL $tmp,EDX,$src\n\t"
8142 "MOV EDX,$src\n\t"
8143 "MUL EDX\t# EDX*EAX -> EDX:EAX\n\t"
8144 "ADD EDX,$tmp" %}
8145 ins_encode( long_multiply_con( dst, src, tmp ) );
8146 ins_pipe( pipe_slow );
8147 %}
8148
8149 // Integer DIV with Register
8150 instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{
8151 match(Set rax (DivI rax div));
8152 effect(KILL rdx, KILL cr);
8153 size(26);
8154 ins_cost(30*100+10*100);
8212 ins_encode( cdq_enc, OpcP, RegOpc(div) );
8213 ins_pipe( ialu_reg_reg_alu0 );
8214 %}
8215
8216 // Remainder Register Long
8217 instruct modL_eReg( eADXRegL dst, eRegL src1, eRegL src2, eFlagsReg cr, eCXRegI cx, eBXRegI bx ) %{
8218 match(Set dst (ModL src1 src2));
8219 effect( KILL cr, KILL cx, KILL bx );
8220 ins_cost(10000);
8221 format %{ "PUSH $src1.hi\n\t"
8222 "PUSH $src1.lo\n\t"
8223 "PUSH $src2.hi\n\t"
8224 "PUSH $src2.lo\n\t"
8225 "CALL SharedRuntime::lrem\n\t"
8226 "ADD ESP,16" %}
8227 ins_encode( long_mod(src1,src2) );
8228 ins_pipe( pipe_slow );
8229 %}
8230
8231 // Divide Register Long (no special case since divisor != -1)
8232 instruct divL_eReg_imm32( eADXRegL dst, immL32 imm, rRegI tmp, rRegI tmp2, eFlagsReg cr ) %{
8233 match(Set dst (DivL dst imm));
8234 effect( TEMP tmp, TEMP tmp2, KILL cr );
8235 ins_cost(1000);
8236 format %{ "MOV $tmp,abs($imm) # ldiv EDX:EAX,$imm\n\t"
8237 "XOR $tmp2,$tmp2\n\t"
8238 "CMP $tmp,EDX\n\t"
8239 "JA,s fast\n\t"
8240 "MOV $tmp2,EAX\n\t"
8241 "MOV EAX,EDX\n\t"
8242 "MOV EDX,0\n\t"
8243 "JLE,s pos\n\t"
8244 "LNEG EAX : $tmp2\n\t"
8245 "DIV $tmp # unsigned division\n\t"
8246 "XCHG EAX,$tmp2\n\t"
8247 "DIV $tmp\n\t"
8248 "LNEG $tmp2 : EAX\n\t"
8249 "JMP,s done\n"
8250 "pos:\n\t"
8251 "DIV $tmp\n\t"
8252 "XCHG EAX,$tmp2\n"
8283
8284 __ bind(Lpos);
8285 __ divl($tmp$$Register); // Use unsigned division
8286 __ xchgl($dst$$Register, $tmp2$$Register);
8287 // Fallthrow for final divide, tmp2 has 32 bit hi result
8288
8289 __ bind(Lfast);
8290 // fast path: src is positive
8291 __ divl($tmp$$Register); // Use unsigned division
8292
8293 __ bind(Ldone);
8294 __ movl(HIGH_FROM_LOW($dst$$Register),$tmp2$$Register);
8295 if (con < 0) {
8296 __ lneg(HIGH_FROM_LOW($dst$$Register), $dst$$Register);
8297 }
8298 %}
8299 ins_pipe( pipe_slow );
8300 %}
8301
8302 // Remainder Register Long (remainder fit into 32 bits)
8303 instruct modL_eReg_imm32( eADXRegL dst, immL32 imm, rRegI tmp, rRegI tmp2, eFlagsReg cr ) %{
8304 match(Set dst (ModL dst imm));
8305 effect( TEMP tmp, TEMP tmp2, KILL cr );
8306 ins_cost(1000);
8307 format %{ "MOV $tmp,abs($imm) # lrem EDX:EAX,$imm\n\t"
8308 "CMP $tmp,EDX\n\t"
8309 "JA,s fast\n\t"
8310 "MOV $tmp2,EAX\n\t"
8311 "MOV EAX,EDX\n\t"
8312 "MOV EDX,0\n\t"
8313 "JLE,s pos\n\t"
8314 "LNEG EAX : $tmp2\n\t"
8315 "DIV $tmp # unsigned division\n\t"
8316 "MOV EAX,$tmp2\n\t"
8317 "DIV $tmp\n\t"
8318 "NEG EDX\n\t"
8319 "JMP,s done\n"
8320 "pos:\n\t"
8321 "DIV $tmp\n\t"
8322 "MOV EAX,$tmp2\n"
8323 "fast:\n\t"
8351 __ jmpb(Ldone);
8352
8353 __ bind(Lpos);
8354 __ divl($tmp$$Register);
8355 __ movl($dst$$Register, $tmp2$$Register);
8356
8357 __ bind(Lfast);
8358 // fast path: src is positive
8359 __ divl($tmp$$Register);
8360
8361 __ bind(Ldone);
8362 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register));
8363 __ sarl(HIGH_FROM_LOW($dst$$Register), 31); // result sign
8364
8365 %}
8366 ins_pipe( pipe_slow );
8367 %}
8368
8369 // Integer Shift Instructions
8370 // Shift Left by one
8371 instruct shlI_eReg_1(rRegI dst, immI1 shift, eFlagsReg cr) %{
8372 match(Set dst (LShiftI dst shift));
8373 effect(KILL cr);
8374
8375 size(2);
8376 format %{ "SHL $dst,$shift" %}
8377 opcode(0xD1, 0x4); /* D1 /4 */
8378 ins_encode( OpcP, RegOpc( dst ) );
8379 ins_pipe( ialu_reg );
8380 %}
8381
8382 // Shift Left by 8-bit immediate
8383 instruct salI_eReg_imm(rRegI dst, immI8 shift, eFlagsReg cr) %{
8384 match(Set dst (LShiftI dst shift));
8385 effect(KILL cr);
8386
8387 size(3);
8388 format %{ "SHL $dst,$shift" %}
8389 opcode(0xC1, 0x4); /* C1 /4 ib */
8390 ins_encode( RegOpcImm( dst, shift) );
8391 ins_pipe( ialu_reg );
8392 %}
8393
8394 // Shift Left by variable
8395 instruct salI_eReg_CL(rRegI dst, eCXRegI shift, eFlagsReg cr) %{
8396 match(Set dst (LShiftI dst shift));
8397 effect(KILL cr);
8398
8399 size(2);
8400 format %{ "SHL $dst,$shift" %}
8401 opcode(0xD3, 0x4); /* D3 /4 */
8402 ins_encode( OpcP, RegOpc( dst ) );
8403 ins_pipe( ialu_reg_reg );
8404 %}
8405
8406 // Arithmetic shift right by one
8407 instruct sarI_eReg_1(rRegI dst, immI1 shift, eFlagsReg cr) %{
8408 match(Set dst (RShiftI dst shift));
8409 effect(KILL cr);
8410
8411 size(2);
8412 format %{ "SAR $dst,$shift" %}
8413 opcode(0xD1, 0x7); /* D1 /7 */
8414 ins_encode( OpcP, RegOpc( dst ) );
8415 ins_pipe( ialu_reg );
8416 %}
8417
8418 // Arithmetic shift right by one
8419 instruct sarI_mem_1(memory dst, immI1 shift, eFlagsReg cr) %{
8420 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8421 effect(KILL cr);
8422 format %{ "SAR $dst,$shift" %}
8423 opcode(0xD1, 0x7); /* D1 /7 */
8424 ins_encode( OpcP, RMopc_Mem(secondary,dst) );
8425 ins_pipe( ialu_mem_imm );
8426 %}
8427
8428 // Arithmetic Shift Right by 8-bit immediate
8429 instruct sarI_eReg_imm(rRegI dst, immI8 shift, eFlagsReg cr) %{
8430 match(Set dst (RShiftI dst shift));
8431 effect(KILL cr);
8432
8433 size(3);
8434 format %{ "SAR $dst,$shift" %}
8435 opcode(0xC1, 0x7); /* C1 /7 ib */
8436 ins_encode( RegOpcImm( dst, shift ) );
8437 ins_pipe( ialu_mem_imm );
8438 %}
8439
8440 // Arithmetic Shift Right by 8-bit immediate
8441 instruct sarI_mem_imm(memory dst, immI8 shift, eFlagsReg cr) %{
8442 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift)));
8443 effect(KILL cr);
8444
8445 format %{ "SAR $dst,$shift" %}
8446 opcode(0xC1, 0x7); /* C1 /7 ib */
8447 ins_encode( OpcP, RMopc_Mem(secondary, dst ), Con8or32( shift ) );
8448 ins_pipe( ialu_mem_imm );
8449 %}
8450
8451 // Arithmetic Shift Right by variable
8452 instruct sarI_eReg_CL(rRegI dst, eCXRegI shift, eFlagsReg cr) %{
8453 match(Set dst (RShiftI dst shift));
8454 effect(KILL cr);
8455
8456 size(2);
8457 format %{ "SAR $dst,$shift" %}
8458 opcode(0xD3, 0x7); /* D3 /7 */
8459 ins_encode( OpcP, RegOpc( dst ) );
8460 ins_pipe( ialu_reg_reg );
8461 %}
8462
8463 // Logical shift right by one
8464 instruct shrI_eReg_1(rRegI dst, immI1 shift, eFlagsReg cr) %{
8465 match(Set dst (URShiftI dst shift));
8466 effect(KILL cr);
8467
8468 size(2);
8469 format %{ "SHR $dst,$shift" %}
8470 opcode(0xD1, 0x5); /* D1 /5 */
8471 ins_encode( OpcP, RegOpc( dst ) );
8472 ins_pipe( ialu_reg );
8473 %}
8474
8475 // Logical Shift Right by 8-bit immediate
8476 instruct shrI_eReg_imm(rRegI dst, immI8 shift, eFlagsReg cr) %{
8477 match(Set dst (URShiftI dst shift));
8478 effect(KILL cr);
8479
8480 size(3);
8481 format %{ "SHR $dst,$shift" %}
8482 opcode(0xC1, 0x5); /* C1 /5 ib */
8483 ins_encode( RegOpcImm( dst, shift) );
8484 ins_pipe( ialu_reg );
8485 %}
8486
8487
8488 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
8489 // This idiom is used by the compiler for the i2b bytecode.
8490 instruct i2b(rRegI dst, xRegI src, immI_24 twentyfour) %{
8491 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
8492
8493 size(3);
8494 format %{ "MOVSX $dst,$src :8" %}
8495 ins_encode %{
8496 __ movsbl($dst$$Register, $src$$Register);
8497 %}
8498 ins_pipe(ialu_reg_reg);
8499 %}
8500
8501 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
8502 // This idiom is used by the compiler the i2s bytecode.
8503 instruct i2s(rRegI dst, xRegI src, immI_16 sixteen) %{
8504 match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
8505
8506 size(3);
8507 format %{ "MOVSX $dst,$src :16" %}
8508 ins_encode %{
8509 __ movswl($dst$$Register, $src$$Register);
8510 %}
8511 ins_pipe(ialu_reg_reg);
8512 %}
8513
8514
8515 // Logical Shift Right by variable
8516 instruct shrI_eReg_CL(rRegI dst, eCXRegI shift, eFlagsReg cr) %{
8517 match(Set dst (URShiftI dst shift));
8518 effect(KILL cr);
8519
8520 size(2);
8521 format %{ "SHR $dst,$shift" %}
8522 opcode(0xD3, 0x5); /* D3 /5 */
8523 ins_encode( OpcP, RegOpc( dst ) );
8524 ins_pipe( ialu_reg_reg );
8525 %}
8526
8527
8528 //----------Logical Instructions-----------------------------------------------
8529 //----------Integer Logical Instructions---------------------------------------
8530 // And Instructions
8531 // And Register with Register
8532 instruct andI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
8533 match(Set dst (AndI dst src));
8534 effect(KILL cr);
8535
8536 size(2);
8537 format %{ "AND $dst,$src" %}
8538 opcode(0x23);
8539 ins_encode( OpcP, RegReg( dst, src) );
8540 ins_pipe( ialu_reg_reg );
8541 %}
8542
8543 // And Register with Immediate
8544 instruct andI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{
8545 match(Set dst (AndI dst src));
8546 effect(KILL cr);
8547
8548 format %{ "AND $dst,$src" %}
8549 opcode(0x81,0x04); /* Opcode 81 /4 */
8550 // ins_encode( RegImm( dst, src) );
8551 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
8552 ins_pipe( ialu_reg );
8553 %}
8554
8555 // And Register with Memory
8556 instruct andI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{
8557 match(Set dst (AndI dst (LoadI src)));
8558 effect(KILL cr);
8559
8560 ins_cost(125);
8561 format %{ "AND $dst,$src" %}
8562 opcode(0x23);
8563 ins_encode( OpcP, RegMem( dst, src) );
8564 ins_pipe( ialu_reg_mem );
8565 %}
8566
8567 // And Memory with Register
8568 instruct andI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{
8569 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
8570 effect(KILL cr);
8571
8572 ins_cost(150);
8573 format %{ "AND $dst,$src" %}
8574 opcode(0x21); /* Opcode 21 /r */
8575 ins_encode( OpcP, RegMem( src, dst ) );
8576 ins_pipe( ialu_mem_reg );
8577 %}
8578
8579 // And Memory with Immediate
8580 instruct andI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
8581 match(Set dst (StoreI dst (AndI (LoadI dst) src)));
8582 effect(KILL cr);
8583
8584 ins_cost(125);
8585 format %{ "AND $dst,$src" %}
8586 opcode(0x81, 0x4); /* Opcode 81 /4 id */
8587 // ins_encode( MemImm( dst, src) );
8588 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) );
8589 ins_pipe( ialu_mem_imm );
8590 %}
8591
8592 // Or Instructions
8593 // Or Register with Register
8594 instruct orI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
8595 match(Set dst (OrI dst src));
8596 effect(KILL cr);
8597
8598 size(2);
8599 format %{ "OR $dst,$src" %}
8600 opcode(0x0B);
8601 ins_encode( OpcP, RegReg( dst, src) );
8602 ins_pipe( ialu_reg_reg );
8603 %}
8604
8605 instruct orI_eReg_castP2X(rRegI dst, eRegP src, eFlagsReg cr) %{
8606 match(Set dst (OrI dst (CastP2X src)));
8607 effect(KILL cr);
8608
8609 size(2);
8610 format %{ "OR $dst,$src" %}
8611 opcode(0x0B);
8612 ins_encode( OpcP, RegReg( dst, src) );
8613 ins_pipe( ialu_reg_reg );
8614 %}
8615
8616
8617 // Or Register with Immediate
8618 instruct orI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{
8619 match(Set dst (OrI dst src));
8620 effect(KILL cr);
8621
8622 format %{ "OR $dst,$src" %}
8623 opcode(0x81,0x01); /* Opcode 81 /1 id */
8624 // ins_encode( RegImm( dst, src) );
8625 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
8626 ins_pipe( ialu_reg );
8627 %}
8628
8629 // Or Register with Memory
8630 instruct orI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{
8631 match(Set dst (OrI dst (LoadI src)));
8632 effect(KILL cr);
8633
8634 ins_cost(125);
8635 format %{ "OR $dst,$src" %}
8636 opcode(0x0B);
8637 ins_encode( OpcP, RegMem( dst, src) );
8638 ins_pipe( ialu_reg_mem );
8639 %}
8640
8641 // Or Memory with Register
8642 instruct orI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{
8643 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
8644 effect(KILL cr);
8645
8646 ins_cost(150);
8647 format %{ "OR $dst,$src" %}
8648 opcode(0x09); /* Opcode 09 /r */
8649 ins_encode( OpcP, RegMem( src, dst ) );
8650 ins_pipe( ialu_mem_reg );
8651 %}
8652
8653 // Or Memory with Immediate
8654 instruct orI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
8655 match(Set dst (StoreI dst (OrI (LoadI dst) src)));
8656 effect(KILL cr);
8657
8658 ins_cost(125);
8659 format %{ "OR $dst,$src" %}
8660 opcode(0x81,0x1); /* Opcode 81 /1 id */
8661 // ins_encode( MemImm( dst, src) );
8662 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) );
8663 ins_pipe( ialu_mem_imm );
8664 %}
8665
8666 // ROL/ROR
8667 // ROL expand
8668 instruct rolI_eReg_imm1(rRegI dst, immI1 shift, eFlagsReg cr) %{
8669 effect(USE_DEF dst, USE shift, KILL cr);
8670
8671 format %{ "ROL $dst, $shift" %}
8672 opcode(0xD1, 0x0); /* Opcode D1 /0 */
8673 ins_encode( OpcP, RegOpc( dst ));
8674 ins_pipe( ialu_reg );
8675 %}
8676
8677 instruct rolI_eReg_imm8(rRegI dst, immI8 shift, eFlagsReg cr) %{
8678 effect(USE_DEF dst, USE shift, KILL cr);
8679
8680 format %{ "ROL $dst, $shift" %}
8681 opcode(0xC1, 0x0); /*Opcode /C1 /0 */
8682 ins_encode( RegOpcImm(dst, shift) );
8683 ins_pipe(ialu_reg);
8684 %}
8685
8686 instruct rolI_eReg_CL(ncxRegI dst, eCXRegI shift, eFlagsReg cr) %{
8687 effect(USE_DEF dst, USE shift, KILL cr);
8688
8689 format %{ "ROL $dst, $shift" %}
8690 opcode(0xD3, 0x0); /* Opcode D3 /0 */
8691 ins_encode(OpcP, RegOpc(dst));
8692 ins_pipe( ialu_reg_reg );
8693 %}
8694 // end of ROL expand
8695
8696 // ROL 32bit by one once
8697 instruct rolI_eReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, eFlagsReg cr) %{
8698 match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8699
8700 expand %{
8701 rolI_eReg_imm1(dst, lshift, cr);
8702 %}
8703 %}
8704
8705 // ROL 32bit var by imm8 once
8706 instruct rolI_eReg_i8(rRegI dst, immI8 lshift, immI8 rshift, eFlagsReg cr) %{
8707 predicate( 0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8708 match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift)));
8709
8710 expand %{
8711 rolI_eReg_imm8(dst, lshift, cr);
8712 %}
8713 %}
8714
8715 // ROL 32bit var by var once
8716 instruct rolI_eReg_Var_C0(ncxRegI dst, eCXRegI shift, immI0 zero, eFlagsReg cr) %{
8717 match(Set dst ( OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift))));
8718
8719 expand %{
8720 rolI_eReg_CL(dst, shift, cr);
8721 %}
8722 %}
8723
8724 // ROL 32bit var by var once
8725 instruct rolI_eReg_Var_C32(ncxRegI dst, eCXRegI shift, immI_32 c32, eFlagsReg cr) %{
8726 match(Set dst ( OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift))));
8727
8728 expand %{
8729 rolI_eReg_CL(dst, shift, cr);
8730 %}
8731 %}
8732
8733 // ROR expand
8734 instruct rorI_eReg_imm1(rRegI dst, immI1 shift, eFlagsReg cr) %{
8735 effect(USE_DEF dst, USE shift, KILL cr);
8736
8737 format %{ "ROR $dst, $shift" %}
8738 opcode(0xD1,0x1); /* Opcode D1 /1 */
8739 ins_encode( OpcP, RegOpc( dst ) );
8740 ins_pipe( ialu_reg );
8741 %}
8742
8743 instruct rorI_eReg_imm8(rRegI dst, immI8 shift, eFlagsReg cr) %{
8744 effect (USE_DEF dst, USE shift, KILL cr);
8745
8746 format %{ "ROR $dst, $shift" %}
8747 opcode(0xC1, 0x1); /* Opcode /C1 /1 ib */
8748 ins_encode( RegOpcImm(dst, shift) );
8749 ins_pipe( ialu_reg );
8750 %}
8751
8752 instruct rorI_eReg_CL(ncxRegI dst, eCXRegI shift, eFlagsReg cr)%{
8753 effect(USE_DEF dst, USE shift, KILL cr);
8754
8755 format %{ "ROR $dst, $shift" %}
8756 opcode(0xD3, 0x1); /* Opcode D3 /1 */
8757 ins_encode(OpcP, RegOpc(dst));
8758 ins_pipe( ialu_reg_reg );
8759 %}
8760 // end of ROR expand
8761
8762 // ROR right once
8763 instruct rorI_eReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, eFlagsReg cr) %{
8764 match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8765
8766 expand %{
8767 rorI_eReg_imm1(dst, rshift, cr);
8768 %}
8769 %}
8770
8771 // ROR 32bit by immI8 once
8772 instruct rorI_eReg_i8(rRegI dst, immI8 rshift, immI8 lshift, eFlagsReg cr) %{
8773 predicate( 0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
8774 match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift)));
8775
8776 expand %{
8777 rorI_eReg_imm8(dst, rshift, cr);
8778 %}
8779 %}
8780
8781 // ROR 32bit var by var once
8782 instruct rorI_eReg_Var_C0(ncxRegI dst, eCXRegI shift, immI0 zero, eFlagsReg cr) %{
8783 match(Set dst ( OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift))));
8784
8785 expand %{
8786 rorI_eReg_CL(dst, shift, cr);
8787 %}
8788 %}
8789
8790 // ROR 32bit var by var once
8791 instruct rorI_eReg_Var_C32(ncxRegI dst, eCXRegI shift, immI_32 c32, eFlagsReg cr) %{
8792 match(Set dst ( OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift))));
8793
8794 expand %{
8795 rorI_eReg_CL(dst, shift, cr);
8796 %}
8797 %}
8798
8799 // Xor Instructions
8800 // Xor Register with Register
8801 instruct xorI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
8802 match(Set dst (XorI dst src));
8803 effect(KILL cr);
8804
8805 size(2);
8806 format %{ "XOR $dst,$src" %}
8807 opcode(0x33);
8808 ins_encode( OpcP, RegReg( dst, src) );
8809 ins_pipe( ialu_reg_reg );
8810 %}
8811
8812 // Xor Register with Immediate -1
8813 instruct xorI_eReg_im1(rRegI dst, immI_M1 imm) %{
8814 match(Set dst (XorI dst imm));
8815
8816 size(2);
8817 format %{ "NOT $dst" %}
8818 ins_encode %{
8819 __ notl($dst$$Register);
8820 %}
8821 ins_pipe( ialu_reg );
8822 %}
8823
8824 // Xor Register with Immediate
8825 instruct xorI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{
8826 match(Set dst (XorI dst src));
8827 effect(KILL cr);
8828
8829 format %{ "XOR $dst,$src" %}
8830 opcode(0x81,0x06); /* Opcode 81 /6 id */
8831 // ins_encode( RegImm( dst, src) );
8832 ins_encode( OpcSErm( dst, src ), Con8or32( src ) );
8833 ins_pipe( ialu_reg );
8834 %}
8835
8836 // Xor Register with Memory
8837 instruct xorI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{
8838 match(Set dst (XorI dst (LoadI src)));
8839 effect(KILL cr);
8840
8841 ins_cost(125);
8842 format %{ "XOR $dst,$src" %}
8843 opcode(0x33);
8844 ins_encode( OpcP, RegMem(dst, src) );
8845 ins_pipe( ialu_reg_mem );
8846 %}
8847
8848 // Xor Memory with Register
8849 instruct xorI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{
8850 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
8851 effect(KILL cr);
8852
8853 ins_cost(150);
8854 format %{ "XOR $dst,$src" %}
8855 opcode(0x31); /* Opcode 31 /r */
8856 ins_encode( OpcP, RegMem( src, dst ) );
8857 ins_pipe( ialu_mem_reg );
8858 %}
8859
8860 // Xor Memory with Immediate
8861 instruct xorI_mem_imm(memory dst, immI src, eFlagsReg cr) %{
8862 match(Set dst (StoreI dst (XorI (LoadI dst) src)));
8863 effect(KILL cr);
8864
8865 ins_cost(125);
8866 format %{ "XOR $dst,$src" %}
8867 opcode(0x81,0x6); /* Opcode 81 /6 id */
8868 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) );
8869 ins_pipe( ialu_mem_imm );
8870 %}
8871
8872 //----------Convert Int to Boolean---------------------------------------------
8873
8874 instruct movI_nocopy(rRegI dst, rRegI src) %{
8875 effect( DEF dst, USE src );
8876 format %{ "MOV $dst,$src" %}
8877 ins_encode( enc_Copy( dst, src) );
8878 ins_pipe( ialu_reg_reg );
8879 %}
8880
8881 instruct ci2b( rRegI dst, rRegI src, eFlagsReg cr ) %{
8882 effect( USE_DEF dst, USE src, KILL cr );
8883
8884 size(4);
8885 format %{ "NEG $dst\n\t"
8886 "ADC $dst,$src" %}
8887 ins_encode( neg_reg(dst),
8888 OpcRegReg(0x13,dst,src) );
8889 ins_pipe( ialu_reg_reg_long );
8890 %}
8891
8892 instruct convI2B( rRegI dst, rRegI src, eFlagsReg cr ) %{
8893 match(Set dst (Conv2B src));
8894
8895 expand %{
8896 movI_nocopy(dst,src);
8897 ci2b(dst,src,cr);
8898 %}
8899 %}
8900
8901 instruct movP_nocopy(rRegI dst, eRegP src) %{
8902 effect( DEF dst, USE src );
8903 format %{ "MOV $dst,$src" %}
8904 ins_encode( enc_Copy( dst, src) );
8905 ins_pipe( ialu_reg_reg );
8906 %}
8907
8908 instruct cp2b( rRegI dst, eRegP src, eFlagsReg cr ) %{
8909 effect( USE_DEF dst, USE src, KILL cr );
8910 format %{ "NEG $dst\n\t"
8911 "ADC $dst,$src" %}
8912 ins_encode( neg_reg(dst),
8913 OpcRegReg(0x13,dst,src) );
8914 ins_pipe( ialu_reg_reg_long );
8915 %}
8916
8917 instruct convP2B( rRegI dst, eRegP src, eFlagsReg cr ) %{
8918 match(Set dst (Conv2B src));
8919
8920 expand %{
8921 movP_nocopy(dst,src);
8922 cp2b(dst,src,cr);
8923 %}
8924 %}
8925
8926 instruct cmpLTMask( eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr ) %{
8927 match(Set dst (CmpLTMask p q));
8928 effect( KILL cr );
8929 ins_cost(400);
8930
8931 // SETlt can only use low byte of EAX,EBX, ECX, or EDX as destination
8932 format %{ "XOR $dst,$dst\n\t"
8933 "CMP $p,$q\n\t"
8934 "SETlt $dst\n\t"
8935 "NEG $dst" %}
8936 ins_encode( OpcRegReg(0x33,dst,dst),
8937 OpcRegReg(0x3B,p,q),
8938 setLT_reg(dst), neg_reg(dst) );
8939 ins_pipe( pipe_slow );
8940 %}
8941
8942 instruct cmpLTMask0( rRegI dst, immI0 zero, eFlagsReg cr ) %{
8943 match(Set dst (CmpLTMask dst zero));
8944 effect( DEF dst, KILL cr );
8945 ins_cost(100);
8946
8947 format %{ "SAR $dst,31" %}
8948 opcode(0xC1, 0x7); /* C1 /7 ib */
8949 ins_encode( RegOpcImm( dst, 0x1F ) );
8950 ins_pipe( ialu_reg );
8951 %}
8952
8953
8954 instruct cadd_cmpLTMask( ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp, eFlagsReg cr ) %{
8955 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
8956 effect( KILL tmp, KILL cr );
8957 ins_cost(400);
8958 // annoyingly, $tmp has no edges so you cant ask for it in
8959 // any format or encoding
8960 format %{ "SUB $p,$q\n\t"
8961 "SBB ECX,ECX\n\t"
8962 "AND ECX,$y\n\t"
9394 instruct cmpDPR_cc(eFlagsRegU cr, regDPR src1, regDPR src2, eAXRegI rax) %{
9395 predicate(UseSSE<=1);
9396 match(Set cr (CmpD src1 src2));
9397 effect(KILL rax);
9398 ins_cost(200);
9399 format %{ "FLD $src1\n\t"
9400 "FCOMp $src2\n\t"
9401 "FNSTSW AX\n\t"
9402 "TEST AX,0x400\n\t"
9403 "JZ,s flags\n\t"
9404 "MOV AH,1\t# unordered treat as LT\n"
9405 "flags:\tSAHF" %}
9406 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
9407 ins_encode( Push_Reg_DPR(src1),
9408 OpcP, RegOpc(src2),
9409 fpu_flags);
9410 ins_pipe( pipe_slow );
9411 %}
9412
9413 // Compare vs zero into -1,0,1
9414 instruct cmpDPR_0(rRegI dst, regDPR src1, immDPR0 zero, eAXRegI rax, eFlagsReg cr) %{
9415 predicate(UseSSE<=1);
9416 match(Set dst (CmpD3 src1 zero));
9417 effect(KILL cr, KILL rax);
9418 ins_cost(280);
9419 format %{ "FTSTD $dst,$src1" %}
9420 opcode(0xE4, 0xD9);
9421 ins_encode( Push_Reg_DPR(src1),
9422 OpcS, OpcP, PopFPU,
9423 CmpF_Result(dst));
9424 ins_pipe( pipe_slow );
9425 %}
9426
9427 // Compare into -1,0,1
9428 instruct cmpDPR_reg(rRegI dst, regDPR src1, regDPR src2, eAXRegI rax, eFlagsReg cr) %{
9429 predicate(UseSSE<=1);
9430 match(Set dst (CmpD3 src1 src2));
9431 effect(KILL cr, KILL rax);
9432 ins_cost(300);
9433 format %{ "FCMPD $dst,$src1,$src2" %}
9434 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
9435 ins_encode( Push_Reg_DPR(src1),
9436 OpcP, RegOpc(src2),
9437 CmpF_Result(dst));
9438 ins_pipe( pipe_slow );
9439 %}
9440
9441 // float compare and set condition codes in EFLAGS by XMM regs
9442 instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2) %{
9443 predicate(UseSSE>=2);
9444 match(Set cr (CmpD src1 src2));
9445 ins_cost(145);
9446 format %{ "UCOMISD $src1,$src2\n\t"
9447 "JNP,s exit\n\t"
9448 "PUSHF\t# saw NaN, set CF\n\t"
10186 instruct cmpFPR_cc(eFlagsRegU cr, regFPR src1, regFPR src2, eAXRegI rax) %{
10187 predicate(UseSSE == 0);
10188 match(Set cr (CmpF src1 src2));
10189 effect(KILL rax);
10190 ins_cost(200);
10191 format %{ "FLD $src1\n\t"
10192 "FCOMp $src2\n\t"
10193 "FNSTSW AX\n\t"
10194 "TEST AX,0x400\n\t"
10195 "JZ,s flags\n\t"
10196 "MOV AH,1\t# unordered treat as LT\n"
10197 "flags:\tSAHF" %}
10198 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
10199 ins_encode( Push_Reg_DPR(src1),
10200 OpcP, RegOpc(src2),
10201 fpu_flags);
10202 ins_pipe( pipe_slow );
10203 %}
10204
10205 // Compare vs zero into -1,0,1
10206 instruct cmpFPR_0(rRegI dst, regFPR src1, immFPR0 zero, eAXRegI rax, eFlagsReg cr) %{
10207 predicate(UseSSE == 0);
10208 match(Set dst (CmpF3 src1 zero));
10209 effect(KILL cr, KILL rax);
10210 ins_cost(280);
10211 format %{ "FTSTF $dst,$src1" %}
10212 opcode(0xE4, 0xD9);
10213 ins_encode( Push_Reg_DPR(src1),
10214 OpcS, OpcP, PopFPU,
10215 CmpF_Result(dst));
10216 ins_pipe( pipe_slow );
10217 %}
10218
10219 // Compare into -1,0,1
10220 instruct cmpFPR_reg(rRegI dst, regFPR src1, regFPR src2, eAXRegI rax, eFlagsReg cr) %{
10221 predicate(UseSSE == 0);
10222 match(Set dst (CmpF3 src1 src2));
10223 effect(KILL cr, KILL rax);
10224 ins_cost(300);
10225 format %{ "FCMPF $dst,$src1,$src2" %}
10226 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */
10227 ins_encode( Push_Reg_DPR(src1),
10228 OpcP, RegOpc(src2),
10229 CmpF_Result(dst));
10230 ins_pipe( pipe_slow );
10231 %}
10232
10233 // float compare and set condition codes in EFLAGS by XMM regs
10234 instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2) %{
10235 predicate(UseSSE>=1);
10236 match(Set cr (CmpF src1 src2));
10237 ins_cost(145);
10238 format %{ "UCOMISS $src1,$src2\n\t"
10239 "JNP,s exit\n\t"
10240 "PUSHF\t# saw NaN, set CF\n\t"
11120 __ subptr(rsp, 4);
11121 __ movflt(Address(rsp, 0), $src$$XMMRegister);
11122 __ fld_s(Address(rsp, 0));
11123 __ addptr(rsp, 4);
11124 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::d2l_wrapper())));
11125 __ bind(fast);
11126 %}
11127 ins_pipe( pipe_slow );
11128 %}
11129
11130 instruct convI2DPR_reg(regDPR dst, stackSlotI src) %{
11131 predicate( UseSSE<=1 );
11132 match(Set dst (ConvI2D src));
11133 format %{ "FILD $src\n\t"
11134 "FSTP $dst" %}
11135 opcode(0xDB, 0x0); /* DB /0 */
11136 ins_encode(Push_Mem_I(src), Pop_Reg_DPR(dst));
11137 ins_pipe( fpu_reg_mem );
11138 %}
11139
11140 instruct convI2D_reg(regD dst, rRegI src) %{
11141 predicate( UseSSE>=2 && !UseXmmI2D );
11142 match(Set dst (ConvI2D src));
11143 format %{ "CVTSI2SD $dst,$src" %}
11144 ins_encode %{
11145 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register);
11146 %}
11147 ins_pipe( pipe_slow );
11148 %}
11149
11150 instruct convI2D_mem(regD dst, memory mem) %{
11151 predicate( UseSSE>=2 );
11152 match(Set dst (ConvI2D (LoadI mem)));
11153 format %{ "CVTSI2SD $dst,$mem" %}
11154 ins_encode %{
11155 __ cvtsi2sdl ($dst$$XMMRegister, $mem$$Address);
11156 %}
11157 ins_pipe( pipe_slow );
11158 %}
11159
11160 instruct convXI2D_reg(regD dst, rRegI src)
11161 %{
11162 predicate( UseSSE>=2 && UseXmmI2D );
11163 match(Set dst (ConvI2D src));
11164
11165 format %{ "MOVD $dst,$src\n\t"
11166 "CVTDQ2PD $dst,$dst\t# i2d" %}
11167 ins_encode %{
11168 __ movdl($dst$$XMMRegister, $src$$Register);
11169 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister);
11170 %}
11171 ins_pipe(pipe_slow); // XXX
11172 %}
11173
11174 instruct convI2DPR_mem(regDPR dst, memory mem) %{
11175 predicate( UseSSE<=1 && !Compile::current()->select_24_bit_instr());
11176 match(Set dst (ConvI2D (LoadI mem)));
11177 format %{ "FILD $mem\n\t"
11178 "FSTP $dst" %}
11179 opcode(0xDB); /* DB /0 */
11180 ins_encode( OpcP, RMopc_Mem(0x00,mem),
11228 "FSTP $dst" %}
11229 opcode(0xDB, 0x0); /* DB /0 */
11230 ins_encode( Push_Mem_I(src),
11231 Pop_Reg_FPR(dst));
11232 ins_pipe( fpu_reg_mem );
11233 %}
11234
11235 // This instruction does not round to 24-bits
11236 instruct convI2FPR_mem(regFPR dst, memory mem) %{
11237 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr());
11238 match(Set dst (ConvI2F (LoadI mem)));
11239 format %{ "FILD $mem\n\t"
11240 "FSTP $dst" %}
11241 opcode(0xDB); /* DB /0 */
11242 ins_encode( OpcP, RMopc_Mem(0x00,mem),
11243 Pop_Reg_FPR(dst));
11244 ins_pipe( fpu_reg_mem );
11245 %}
11246
11247 // Convert an int to a float in xmm; no rounding step needed.
11248 instruct convI2F_reg(regF dst, rRegI src) %{
11249 predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F );
11250 match(Set dst (ConvI2F src));
11251 format %{ "CVTSI2SS $dst, $src" %}
11252 ins_encode %{
11253 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register);
11254 %}
11255 ins_pipe( pipe_slow );
11256 %}
11257
11258 instruct convXI2F_reg(regF dst, rRegI src)
11259 %{
11260 predicate( UseSSE>=2 && UseXmmI2F );
11261 match(Set dst (ConvI2F src));
11262
11263 format %{ "MOVD $dst,$src\n\t"
11264 "CVTDQ2PS $dst,$dst\t# i2f" %}
11265 ins_encode %{
11266 __ movdl($dst$$XMMRegister, $src$$Register);
11267 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister);
11268 %}
11269 ins_pipe(pipe_slow); // XXX
11270 %}
11271
11272 instruct convI2L_reg( eRegL dst, rRegI src, eFlagsReg cr) %{
11273 match(Set dst (ConvI2L src));
11274 effect(KILL cr);
11275 ins_cost(375);
11276 format %{ "MOV $dst.lo,$src\n\t"
11277 "MOV $dst.hi,$src\n\t"
11278 "SAR $dst.hi,31" %}
11279 ins_encode(convert_int_long(dst,src));
11280 ins_pipe( ialu_reg_reg_long );
11281 %}
11282
11283 // Zero-extend convert int to long
11284 instruct convI2L_reg_zex(eRegL dst, rRegI src, immL_32bits mask, eFlagsReg flags ) %{
11285 match(Set dst (AndL (ConvI2L src) mask) );
11286 effect( KILL flags );
11287 ins_cost(250);
11288 format %{ "MOV $dst.lo,$src\n\t"
11289 "XOR $dst.hi,$dst.hi" %}
11290 opcode(0x33); // XOR
11291 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) );
11292 ins_pipe( ialu_reg_reg_long );
11293 %}
11294
11295 // Zero-extend long
11296 instruct zerox_long(eRegL dst, eRegL src, immL_32bits mask, eFlagsReg flags ) %{
11297 match(Set dst (AndL src mask) );
11298 effect( KILL flags );
11299 ins_cost(250);
11300 format %{ "MOV $dst.lo,$src.lo\n\t"
11301 "XOR $dst.hi,$dst.hi\n\t" %}
11302 opcode(0x33); // XOR
11303 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) );
11304 ins_pipe( ialu_reg_reg_long );
11344 "MOVSS $dst,[ESP]\n\t"
11345 "ADD ESP,8" %}
11346 opcode(0xDF, 0x5); /* DF /5 */
11347 ins_encode(convert_long_double2(src), Push_ResultF(dst,0x8));
11348 ins_pipe( pipe_slow );
11349 %}
11350
11351 instruct convL2FPR_reg( stackSlotF dst, eRegL src, eFlagsReg cr) %{
11352 match(Set dst (ConvL2F src));
11353 effect( KILL cr );
11354 format %{ "PUSH $src.hi\t# Convert long to single float\n\t"
11355 "PUSH $src.lo\n\t"
11356 "FILD ST,[ESP + #0]\n\t"
11357 "ADD ESP,8\n\t"
11358 "FSTP_S $dst\t# F-round" %}
11359 opcode(0xDF, 0x5); /* DF /5 */
11360 ins_encode(convert_long_double(src), Pop_Mem_FPR(dst));
11361 ins_pipe( pipe_slow );
11362 %}
11363
11364 instruct convL2I_reg( rRegI dst, eRegL src ) %{
11365 match(Set dst (ConvL2I src));
11366 effect( DEF dst, USE src );
11367 format %{ "MOV $dst,$src.lo" %}
11368 ins_encode(enc_CopyL_Lo(dst,src));
11369 ins_pipe( ialu_reg_reg );
11370 %}
11371
11372
11373 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
11374 match(Set dst (MoveF2I src));
11375 effect( DEF dst, USE src );
11376 ins_cost(100);
11377 format %{ "MOV $dst,$src\t# MoveF2I_stack_reg" %}
11378 ins_encode %{
11379 __ movl($dst$$Register, Address(rsp, $src$$disp));
11380 %}
11381 ins_pipe( ialu_reg_mem );
11382 %}
11383
11384 instruct MoveFPR2I_reg_stack(stackSlotI dst, regFPR src) %{
11385 predicate(UseSSE==0);
11386 match(Set dst (MoveF2I src));
11387 effect( DEF dst, USE src );
11388
11389 ins_cost(125);
11390 format %{ "FST_S $dst,$src\t# MoveF2I_reg_stack" %}
11391 ins_encode( Pop_Mem_Reg_FPR(dst, src) );
11392 ins_pipe( fpu_mem_reg );
11393 %}
11394
11395 instruct MoveF2I_reg_stack_sse(stackSlotI dst, regF src) %{
11396 predicate(UseSSE>=1);
11397 match(Set dst (MoveF2I src));
11398 effect( DEF dst, USE src );
11399
11400 ins_cost(95);
11401 format %{ "MOVSS $dst,$src\t# MoveF2I_reg_stack_sse" %}
11402 ins_encode %{
11403 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister);
11404 %}
11405 ins_pipe( pipe_slow );
11406 %}
11407
11408 instruct MoveF2I_reg_reg_sse(rRegI dst, regF src) %{
11409 predicate(UseSSE>=2);
11410 match(Set dst (MoveF2I src));
11411 effect( DEF dst, USE src );
11412 ins_cost(85);
11413 format %{ "MOVD $dst,$src\t# MoveF2I_reg_reg_sse" %}
11414 ins_encode %{
11415 __ movdl($dst$$Register, $src$$XMMRegister);
11416 %}
11417 ins_pipe( pipe_slow );
11418 %}
11419
11420 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
11421 match(Set dst (MoveI2F src));
11422 effect( DEF dst, USE src );
11423
11424 ins_cost(100);
11425 format %{ "MOV $dst,$src\t# MoveI2F_reg_stack" %}
11426 ins_encode %{
11427 __ movl(Address(rsp, $dst$$disp), $src$$Register);
11428 %}
11429 ins_pipe( ialu_mem_reg );
11430 %}
11431
11432
11433 instruct MoveI2FPR_stack_reg(regFPR dst, stackSlotI src) %{
11434 predicate(UseSSE==0);
11435 match(Set dst (MoveI2F src));
11436 effect(DEF dst, USE src);
11437
11438 ins_cost(125);
11439 format %{ "FLD_S $src\n\t"
11440 "FSTP $dst\t# MoveI2F_stack_reg" %}
11441 opcode(0xD9); /* D9 /0, FLD m32real */
11442 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src),
11443 Pop_Reg_FPR(dst) );
11444 ins_pipe( fpu_reg_mem );
11445 %}
11446
11447 instruct MoveI2F_stack_reg_sse(regF dst, stackSlotI src) %{
11448 predicate(UseSSE>=1);
11449 match(Set dst (MoveI2F src));
11450 effect( DEF dst, USE src );
11451
11452 ins_cost(95);
11453 format %{ "MOVSS $dst,$src\t# MoveI2F_stack_reg_sse" %}
11454 ins_encode %{
11455 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp));
11456 %}
11457 ins_pipe( pipe_slow );
11458 %}
11459
11460 instruct MoveI2F_reg_reg_sse(regF dst, rRegI src) %{
11461 predicate(UseSSE>=2);
11462 match(Set dst (MoveI2F src));
11463 effect( DEF dst, USE src );
11464
11465 ins_cost(85);
11466 format %{ "MOVD $dst,$src\t# MoveI2F_reg_reg_sse" %}
11467 ins_encode %{
11468 __ movdl($dst$$XMMRegister, $src$$Register);
11469 %}
11470 ins_pipe( pipe_slow );
11471 %}
11472
11473 instruct MoveD2L_stack_reg(eRegL dst, stackSlotD src) %{
11474 match(Set dst (MoveD2L src));
11475 effect(DEF dst, USE src);
11476
11477 ins_cost(250);
11478 format %{ "MOV $dst.lo,$src\n\t"
11479 "MOV $dst.hi,$src+4\t# MoveD2L_stack_reg" %}
11480 opcode(0x8B, 0x8B);
11574 %}
11575 ins_pipe( pipe_slow );
11576 %}
11577
11578 instruct MoveL2D_reg_reg_sse(regD dst, eRegL src, regD tmp) %{
11579 predicate(UseSSE>=2);
11580 match(Set dst (MoveL2D src));
11581 effect(TEMP dst, USE src, TEMP tmp);
11582 ins_cost(85);
11583 format %{ "MOVD $dst,$src.lo\n\t"
11584 "MOVD $tmp,$src.hi\n\t"
11585 "PUNPCKLDQ $dst,$tmp\t# MoveL2D_reg_reg_sse" %}
11586 ins_encode %{
11587 __ movdl($dst$$XMMRegister, $src$$Register);
11588 __ movdl($tmp$$XMMRegister, HIGH_FROM_LOW($src$$Register));
11589 __ punpckldq($dst$$XMMRegister, $tmp$$XMMRegister);
11590 %}
11591 ins_pipe( pipe_slow );
11592 %}
11593
11594
11595 // =======================================================================
11596 // fast clearing of an array
11597 instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{
11598 match(Set dummy (ClearArray cnt base));
11599 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr);
11600 format %{ "SHL ECX,1\t# Convert doublewords to words\n\t"
11601 "XOR EAX,EAX\n\t"
11602 "REP STOS\t# store EAX into [EDI++] while ECX--" %}
11603 opcode(0,0x4);
11604 ins_encode( Opcode(0xD1), RegOpc(ECX),
11605 OpcRegReg(0x33,EAX,EAX),
11606 Opcode(0xF3), Opcode(0xAB) );
11607 ins_pipe( pipe_slow );
11608 %}
11609
11610 instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2,
11611 eAXRegI result, regD tmp1, eFlagsReg cr) %{
11612 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
11613 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
11614
11682
11683 // fast array equals
11684 instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result,
11685 regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr)
11686 %{
11687 match(Set result (AryEq ary1 ary2));
11688 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr);
11689 //ins_cost(300);
11690
11691 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %}
11692 ins_encode %{
11693 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register,
11694 $tmp3$$Register, $result$$Register, $tmp4$$Register,
11695 $tmp1$$XMMRegister, $tmp2$$XMMRegister);
11696 %}
11697 ins_pipe( pipe_slow );
11698 %}
11699
11700 //----------Control Flow Instructions------------------------------------------
11701 // Signed compare Instructions
11702 instruct compI_eReg(eFlagsReg cr, rRegI op1, rRegI op2) %{
11703 match(Set cr (CmpI op1 op2));
11704 effect( DEF cr, USE op1, USE op2 );
11705 format %{ "CMP $op1,$op2" %}
11706 opcode(0x3B); /* Opcode 3B /r */
11707 ins_encode( OpcP, RegReg( op1, op2) );
11708 ins_pipe( ialu_cr_reg_reg );
11709 %}
11710
11711 instruct compI_eReg_imm(eFlagsReg cr, rRegI op1, immI op2) %{
11712 match(Set cr (CmpI op1 op2));
11713 effect( DEF cr, USE op1 );
11714 format %{ "CMP $op1,$op2" %}
11715 opcode(0x81,0x07); /* Opcode 81 /7 */
11716 // ins_encode( RegImm( op1, op2) ); /* Was CmpImm */
11717 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) );
11718 ins_pipe( ialu_cr_reg_imm );
11719 %}
11720
11721 // Cisc-spilled version of cmpI_eReg
11722 instruct compI_eReg_mem(eFlagsReg cr, rRegI op1, memory op2) %{
11723 match(Set cr (CmpI op1 (LoadI op2)));
11724
11725 format %{ "CMP $op1,$op2" %}
11726 ins_cost(500);
11727 opcode(0x3B); /* Opcode 3B /r */
11728 ins_encode( OpcP, RegMem( op1, op2) );
11729 ins_pipe( ialu_cr_reg_mem );
11730 %}
11731
11732 instruct testI_reg( eFlagsReg cr, rRegI src, immI0 zero ) %{
11733 match(Set cr (CmpI src zero));
11734 effect( DEF cr, USE src );
11735
11736 format %{ "TEST $src,$src" %}
11737 opcode(0x85);
11738 ins_encode( OpcP, RegReg( src, src ) );
11739 ins_pipe( ialu_cr_reg_imm );
11740 %}
11741
11742 instruct testI_reg_imm( eFlagsReg cr, rRegI src, immI con, immI0 zero ) %{
11743 match(Set cr (CmpI (AndI src con) zero));
11744
11745 format %{ "TEST $src,$con" %}
11746 opcode(0xF7,0x00);
11747 ins_encode( OpcP, RegOpc(src), Con32(con) );
11748 ins_pipe( ialu_cr_reg_imm );
11749 %}
11750
11751 instruct testI_reg_mem( eFlagsReg cr, rRegI src, memory mem, immI0 zero ) %{
11752 match(Set cr (CmpI (AndI src mem) zero));
11753
11754 format %{ "TEST $src,$mem" %}
11755 opcode(0x85);
11756 ins_encode( OpcP, RegMem( src, mem ) );
11757 ins_pipe( ialu_cr_reg_mem );
11758 %}
11759
11760 // Unsigned compare Instructions; really, same as signed except they
11761 // produce an eFlagsRegU instead of eFlagsReg.
11762 instruct compU_eReg(eFlagsRegU cr, rRegI op1, rRegI op2) %{
11763 match(Set cr (CmpU op1 op2));
11764
11765 format %{ "CMPu $op1,$op2" %}
11766 opcode(0x3B); /* Opcode 3B /r */
11767 ins_encode( OpcP, RegReg( op1, op2) );
11768 ins_pipe( ialu_cr_reg_reg );
11769 %}
11770
11771 instruct compU_eReg_imm(eFlagsRegU cr, rRegI op1, immI op2) %{
11772 match(Set cr (CmpU op1 op2));
11773
11774 format %{ "CMPu $op1,$op2" %}
11775 opcode(0x81,0x07); /* Opcode 81 /7 */
11776 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) );
11777 ins_pipe( ialu_cr_reg_imm );
11778 %}
11779
11780 // // Cisc-spilled version of cmpU_eReg
11781 instruct compU_eReg_mem(eFlagsRegU cr, rRegI op1, memory op2) %{
11782 match(Set cr (CmpU op1 (LoadI op2)));
11783
11784 format %{ "CMPu $op1,$op2" %}
11785 ins_cost(500);
11786 opcode(0x3B); /* Opcode 3B /r */
11787 ins_encode( OpcP, RegMem( op1, op2) );
11788 ins_pipe( ialu_cr_reg_mem );
11789 %}
11790
11791 // // Cisc-spilled version of cmpU_eReg
11792 //instruct compU_mem_eReg(eFlagsRegU cr, memory op1, rRegI op2) %{
11793 // match(Set cr (CmpU (LoadI op1) op2));
11794 //
11795 // format %{ "CMPu $op1,$op2" %}
11796 // ins_cost(500);
11797 // opcode(0x39); /* Opcode 39 /r */
11798 // ins_encode( OpcP, RegMem( op1, op2) );
11799 //%}
11800
11801 instruct testU_reg( eFlagsRegU cr, rRegI src, immI0 zero ) %{
11802 match(Set cr (CmpU src zero));
11803
11804 format %{ "TESTu $src,$src" %}
11805 opcode(0x85);
11806 ins_encode( OpcP, RegReg( src, src ) );
11807 ins_pipe( ialu_cr_reg_imm );
11808 %}
11809
11810 // Unsigned pointer compare Instructions
11811 instruct compP_eReg(eFlagsRegU cr, eRegP op1, eRegP op2) %{
11812 match(Set cr (CmpP op1 op2));
11813
11814 format %{ "CMPu $op1,$op2" %}
11815 opcode(0x3B); /* Opcode 3B /r */
11816 ins_encode( OpcP, RegReg( op1, op2) );
11817 ins_pipe( ialu_cr_reg_reg );
11818 %}
11819
11820 instruct compP_eReg_imm(eFlagsRegU cr, eRegP op1, immP op2) %{
11821 match(Set cr (CmpP op1 op2));
11877 // since any compare to a zero should be eq/neq.
11878 instruct testP_Reg_mem( eFlagsReg cr, memory op, immI0 zero ) %{
11879 match(Set cr (CmpP (LoadP op) zero));
11880
11881 format %{ "TEST $op,0xFFFFFFFF" %}
11882 ins_cost(500);
11883 opcode(0xF7); /* Opcode F7 /0 */
11884 ins_encode( OpcP, RMopc_Mem(0x00,op), Con_d32(0xFFFFFFFF) );
11885 ins_pipe( ialu_cr_reg_imm );
11886 %}
11887
11888 // Yanked all unsigned pointer compare operations.
11889 // Pointer compares are done with CmpP which is already unsigned.
11890
11891 //----------Max and Min--------------------------------------------------------
11892 // Min Instructions
11893 ////
11894 // *** Min and Max using the conditional move are slower than the
11895 // *** branch version on a Pentium III.
11896 // // Conditional move for min
11897 //instruct cmovI_reg_lt( rRegI op2, rRegI op1, eFlagsReg cr ) %{
11898 // effect( USE_DEF op2, USE op1, USE cr );
11899 // format %{ "CMOVlt $op2,$op1\t! min" %}
11900 // opcode(0x4C,0x0F);
11901 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
11902 // ins_pipe( pipe_cmov_reg );
11903 //%}
11904 //
11905 //// Min Register with Register (P6 version)
11906 //instruct minI_eReg_p6( rRegI op1, rRegI op2 ) %{
11907 // predicate(VM_Version::supports_cmov() );
11908 // match(Set op2 (MinI op1 op2));
11909 // ins_cost(200);
11910 // expand %{
11911 // eFlagsReg cr;
11912 // compI_eReg(cr,op1,op2);
11913 // cmovI_reg_lt(op2,op1,cr);
11914 // %}
11915 //%}
11916
11917 // Min Register with Register (generic version)
11918 instruct minI_eReg(rRegI dst, rRegI src, eFlagsReg flags) %{
11919 match(Set dst (MinI dst src));
11920 effect(KILL flags);
11921 ins_cost(300);
11922
11923 format %{ "MIN $dst,$src" %}
11924 opcode(0xCC);
11925 ins_encode( min_enc(dst,src) );
11926 ins_pipe( pipe_slow );
11927 %}
11928
11929 // Max Register with Register
11930 // *** Min and Max using the conditional move are slower than the
11931 // *** branch version on a Pentium III.
11932 // // Conditional move for max
11933 //instruct cmovI_reg_gt( rRegI op2, rRegI op1, eFlagsReg cr ) %{
11934 // effect( USE_DEF op2, USE op1, USE cr );
11935 // format %{ "CMOVgt $op2,$op1\t! max" %}
11936 // opcode(0x4F,0x0F);
11937 // ins_encode( OpcS, OpcP, RegReg( op2, op1 ) );
11938 // ins_pipe( pipe_cmov_reg );
11939 //%}
11940 //
11941 // // Max Register with Register (P6 version)
11942 //instruct maxI_eReg_p6( rRegI op1, rRegI op2 ) %{
11943 // predicate(VM_Version::supports_cmov() );
11944 // match(Set op2 (MaxI op1 op2));
11945 // ins_cost(200);
11946 // expand %{
11947 // eFlagsReg cr;
11948 // compI_eReg(cr,op1,op2);
11949 // cmovI_reg_gt(op2,op1,cr);
11950 // %}
11951 //%}
11952
11953 // Max Register with Register (generic version)
11954 instruct maxI_eReg(rRegI dst, rRegI src, eFlagsReg flags) %{
11955 match(Set dst (MaxI dst src));
11956 effect(KILL flags);
11957 ins_cost(300);
11958
11959 format %{ "MAX $dst,$src" %}
11960 opcode(0xCC);
11961 ins_encode( max_enc(dst,src) );
11962 ins_pipe( pipe_slow );
11963 %}
11964
11965 // ============================================================================
11966 // Counted Loop limit node which represents exact final iterator value.
11967 // Note: the resulting value should fit into integer range since
11968 // counted loops have limit check on overflow.
11969 instruct loopLimit_eReg(eAXRegI limit, nadxRegI init, immI stride, eDXRegI limit_hi, nadxRegI tmp, eFlagsReg flags) %{
11970 match(Set limit (LoopLimit (Binary init limit) stride));
11971 effect(TEMP limit_hi, TEMP tmp, KILL flags);
11972 ins_cost(300);
11973
11974 format %{ "loopLimit $init,$limit,$stride # $limit = $init + $stride *( $limit - $init + $stride -1)/ $stride, kills $limit_hi" %}
11995 __ lneg($limit_hi$$Register, $limit$$Register);
11996 __ movl($tmp$$Register, -strd);
11997 }
11998 // signed devision: (EAX:EDX) / pos_stride
11999 __ idivl($tmp$$Register);
12000 if (strd < 0) {
12001 // restore sign
12002 __ negl($tmp$$Register);
12003 }
12004 // (EAX) * stride
12005 __ mull($tmp$$Register);
12006 // + init (ignore upper bits)
12007 __ addl($limit$$Register, $init$$Register);
12008 %}
12009 ins_pipe( pipe_slow );
12010 %}
12011
12012 // ============================================================================
12013 // Branch Instructions
12014 // Jump Table
12015 instruct jumpXtnd(rRegI switch_val) %{
12016 match(Jump switch_val);
12017 ins_cost(350);
12018 format %{ "JMP [$constantaddress](,$switch_val,1)\n\t" %}
12019 ins_encode %{
12020 // Jump to Address(table_base + switch_reg)
12021 Address index(noreg, $switch_val$$Register, Address::times_1);
12022 __ jump(ArrayAddress($constantaddress, index));
12023 %}
12024 ins_pipe(pipe_jmp);
12025 %}
12026
12027 // Jump Direct - Label defines a relative address from JMP+1
12028 instruct jmpDir(label labl) %{
12029 match(Goto);
12030 effect(USE labl);
12031
12032 ins_cost(300);
12033 format %{ "JMP $labl" %}
12034 size(5);
12035 ins_encode %{
12413 %}
12414 ins_pipe( pipe_slow );
12415 %}
12416
12417 //======
12418 // Manifest a CmpL result in the normal flags. Only good for LT or GE
12419 // compares. Can be used for LE or GT compares by reversing arguments.
12420 // NOT GOOD FOR EQ/NE tests.
12421 instruct cmpL_zero_flags_LTGE( flagsReg_long_LTGE flags, eRegL src, immL0 zero ) %{
12422 match( Set flags (CmpL src zero ));
12423 ins_cost(100);
12424 format %{ "TEST $src.hi,$src.hi" %}
12425 opcode(0x85);
12426 ins_encode( OpcP, RegReg_Hi2( src, src ) );
12427 ins_pipe( ialu_cr_reg_reg );
12428 %}
12429
12430 // Manifest a CmpL result in the normal flags. Only good for LT or GE
12431 // compares. Can be used for LE or GT compares by reversing arguments.
12432 // NOT GOOD FOR EQ/NE tests.
12433 instruct cmpL_reg_flags_LTGE( flagsReg_long_LTGE flags, eRegL src1, eRegL src2, rRegI tmp ) %{
12434 match( Set flags (CmpL src1 src2 ));
12435 effect( TEMP tmp );
12436 ins_cost(300);
12437 format %{ "CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t"
12438 "MOV $tmp,$src1.hi\n\t"
12439 "SBB $tmp,$src2.hi\t! Compute flags for long compare" %}
12440 ins_encode( long_cmp_flags2( src1, src2, tmp ) );
12441 ins_pipe( ialu_cr_reg_reg );
12442 %}
12443
12444 // Long compares reg < zero/req OR reg >= zero/req.
12445 // Just a wrapper for a normal branch, plus the predicate test.
12446 instruct cmpL_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, label labl) %{
12447 match(If cmp flags);
12448 effect(USE labl);
12449 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
12450 expand %{
12451 jmpCon(cmp,flags,labl); // JLT or JGE...
12452 %}
12453 %}
12459 ins_cost(400);
12460 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12461 "CMOV$cmp $dst.hi,$src.hi" %}
12462 opcode(0x0F,0x40);
12463 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12464 ins_pipe( pipe_cmov_reg_long );
12465 %}
12466
12467 instruct cmovLL_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, load_long_memory src) %{
12468 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12469 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
12470 ins_cost(500);
12471 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12472 "CMOV$cmp $dst.hi,$src.hi" %}
12473 opcode(0x0F,0x40);
12474 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );
12475 ins_pipe( pipe_cmov_reg_long );
12476 %}
12477
12478 // Compare 2 longs and CMOVE ints.
12479 instruct cmovII_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, rRegI dst, rRegI src) %{
12480 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
12481 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
12482 ins_cost(200);
12483 format %{ "CMOV$cmp $dst,$src" %}
12484 opcode(0x0F,0x40);
12485 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12486 ins_pipe( pipe_cmov_reg );
12487 %}
12488
12489 instruct cmovII_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, rRegI dst, memory src) %{
12490 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
12491 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
12492 ins_cost(250);
12493 format %{ "CMOV$cmp $dst,$src" %}
12494 opcode(0x0F,0x40);
12495 ins_encode( enc_cmov(cmp), RegMem( dst, src ) );
12496 ins_pipe( pipe_cmov_mem );
12497 %}
12498
12499 // Compare 2 longs and CMOVE ints.
12500 instruct cmovPP_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegP dst, eRegP src) %{
12501 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
12502 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src)));
12503 ins_cost(200);
12504 format %{ "CMOV$cmp $dst,$src" %}
12505 opcode(0x0F,0x40);
12506 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12507 ins_pipe( pipe_cmov_reg );
12508 %}
12509
12530 instruct cmovFFPR_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regFPR dst, regFPR src) %{
12531 predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
12532 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
12533 ins_cost(200);
12534 expand %{
12535 fcmovFPR_regS(cmp,flags,dst,src);
12536 %}
12537 %}
12538
12539 instruct cmovFF_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regF dst, regF src) %{
12540 predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge );
12541 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
12542 ins_cost(200);
12543 expand %{
12544 fcmovF_regS(cmp,flags,dst,src);
12545 %}
12546 %}
12547
12548 //======
12549 // Manifest a CmpL result in the normal flags. Only good for EQ/NE compares.
12550 instruct cmpL_zero_flags_EQNE( flagsReg_long_EQNE flags, eRegL src, immL0 zero, rRegI tmp ) %{
12551 match( Set flags (CmpL src zero ));
12552 effect(TEMP tmp);
12553 ins_cost(200);
12554 format %{ "MOV $tmp,$src.lo\n\t"
12555 "OR $tmp,$src.hi\t! Long is EQ/NE 0?" %}
12556 ins_encode( long_cmp_flags0( src, tmp ) );
12557 ins_pipe( ialu_reg_reg_long );
12558 %}
12559
12560 // Manifest a CmpL result in the normal flags. Only good for EQ/NE compares.
12561 instruct cmpL_reg_flags_EQNE( flagsReg_long_EQNE flags, eRegL src1, eRegL src2 ) %{
12562 match( Set flags (CmpL src1 src2 ));
12563 ins_cost(200+300);
12564 format %{ "CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t"
12565 "JNE,s skip\n\t"
12566 "CMP $src1.hi,$src2.hi\n\t"
12567 "skip:\t" %}
12568 ins_encode( long_cmp_flags1( src1, src2 ) );
12569 ins_pipe( ialu_cr_reg_reg );
12570 %}
12587 ins_cost(400);
12588 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12589 "CMOV$cmp $dst.hi,$src.hi" %}
12590 opcode(0x0F,0x40);
12591 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12592 ins_pipe( pipe_cmov_reg_long );
12593 %}
12594
12595 instruct cmovLL_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, load_long_memory src) %{
12596 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12597 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
12598 ins_cost(500);
12599 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12600 "CMOV$cmp $dst.hi,$src.hi" %}
12601 opcode(0x0F,0x40);
12602 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );
12603 ins_pipe( pipe_cmov_reg_long );
12604 %}
12605
12606 // Compare 2 longs and CMOVE ints.
12607 instruct cmovII_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, rRegI dst, rRegI src) %{
12608 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
12609 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
12610 ins_cost(200);
12611 format %{ "CMOV$cmp $dst,$src" %}
12612 opcode(0x0F,0x40);
12613 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12614 ins_pipe( pipe_cmov_reg );
12615 %}
12616
12617 instruct cmovII_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, rRegI dst, memory src) %{
12618 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
12619 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
12620 ins_cost(250);
12621 format %{ "CMOV$cmp $dst,$src" %}
12622 opcode(0x0F,0x40);
12623 ins_encode( enc_cmov(cmp), RegMem( dst, src ) );
12624 ins_pipe( pipe_cmov_mem );
12625 %}
12626
12627 // Compare 2 longs and CMOVE ints.
12628 instruct cmovPP_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegP dst, eRegP src) %{
12629 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
12630 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src)));
12631 ins_cost(200);
12632 format %{ "CMOV$cmp $dst,$src" %}
12633 opcode(0x0F,0x40);
12634 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12635 ins_pipe( pipe_cmov_reg );
12636 %}
12637
12659 predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
12660 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
12661 ins_cost(200);
12662 expand %{
12663 fcmovFPR_regS(cmp,flags,dst,src);
12664 %}
12665 %}
12666
12667 instruct cmovFF_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regF dst, regF src) %{
12668 predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne );
12669 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src)));
12670 ins_cost(200);
12671 expand %{
12672 fcmovF_regS(cmp,flags,dst,src);
12673 %}
12674 %}
12675
12676 //======
12677 // Manifest a CmpL result in the normal flags. Only good for LE or GT compares.
12678 // Same as cmpL_reg_flags_LEGT except must negate src
12679 instruct cmpL_zero_flags_LEGT( flagsReg_long_LEGT flags, eRegL src, immL0 zero, rRegI tmp ) %{
12680 match( Set flags (CmpL src zero ));
12681 effect( TEMP tmp );
12682 ins_cost(300);
12683 format %{ "XOR $tmp,$tmp\t# Long compare for -$src < 0, use commuted test\n\t"
12684 "CMP $tmp,$src.lo\n\t"
12685 "SBB $tmp,$src.hi\n\t" %}
12686 ins_encode( long_cmp_flags3(src, tmp) );
12687 ins_pipe( ialu_reg_reg_long );
12688 %}
12689
12690 // Manifest a CmpL result in the normal flags. Only good for LE or GT compares.
12691 // Same as cmpL_reg_flags_LTGE except operands swapped. Swapping operands
12692 // requires a commuted test to get the same result.
12693 instruct cmpL_reg_flags_LEGT( flagsReg_long_LEGT flags, eRegL src1, eRegL src2, rRegI tmp ) %{
12694 match( Set flags (CmpL src1 src2 ));
12695 effect( TEMP tmp );
12696 ins_cost(300);
12697 format %{ "CMP $src2.lo,$src1.lo\t! Long compare, swapped operands, use with commuted test\n\t"
12698 "MOV $tmp,$src2.hi\n\t"
12699 "SBB $tmp,$src1.hi\t! Compute flags for long compare" %}
12700 ins_encode( long_cmp_flags2( src2, src1, tmp ) );
12701 ins_pipe( ialu_cr_reg_reg );
12702 %}
12703
12704 // Long compares reg < zero/req OR reg >= zero/req.
12705 // Just a wrapper for a normal branch, plus the predicate test
12706 instruct cmpL_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, label labl) %{
12707 match(If cmp flags);
12708 effect(USE labl);
12709 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le );
12710 ins_cost(300);
12711 expand %{
12712 jmpCon(cmp,flags,labl); // JGT or JLE...
12713 %}
12720 ins_cost(400);
12721 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12722 "CMOV$cmp $dst.hi,$src.hi" %}
12723 opcode(0x0F,0x40);
12724 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) );
12725 ins_pipe( pipe_cmov_reg_long );
12726 %}
12727
12728 instruct cmovLL_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, load_long_memory src) %{
12729 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src))));
12730 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
12731 ins_cost(500);
12732 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t"
12733 "CMOV$cmp $dst.hi,$src.hi+4" %}
12734 opcode(0x0F,0x40);
12735 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) );
12736 ins_pipe( pipe_cmov_reg_long );
12737 %}
12738
12739 // Compare 2 longs and CMOVE ints.
12740 instruct cmovII_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, rRegI dst, rRegI src) %{
12741 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
12742 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
12743 ins_cost(200);
12744 format %{ "CMOV$cmp $dst,$src" %}
12745 opcode(0x0F,0x40);
12746 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12747 ins_pipe( pipe_cmov_reg );
12748 %}
12749
12750 instruct cmovII_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, rRegI dst, memory src) %{
12751 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
12752 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
12753 ins_cost(250);
12754 format %{ "CMOV$cmp $dst,$src" %}
12755 opcode(0x0F,0x40);
12756 ins_encode( enc_cmov(cmp), RegMem( dst, src ) );
12757 ins_pipe( pipe_cmov_mem );
12758 %}
12759
12760 // Compare 2 longs and CMOVE ptrs.
12761 instruct cmovPP_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegP dst, eRegP src) %{
12762 predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
12763 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src)));
12764 ins_cost(200);
12765 format %{ "CMOV$cmp $dst,$src" %}
12766 opcode(0x0F,0x40);
12767 ins_encode( enc_cmov(cmp), RegReg( dst, src ) );
12768 ins_pipe( pipe_cmov_reg );
12769 %}
12770
13059 //
13060 // ---------VM FLAGS---------------------------------------------------------
13061 //
13062 // All peephole optimizations can be turned off using -XX:-OptoPeephole
13063 //
13064 // Each peephole rule is given an identifying number starting with zero and
13065 // increasing by one in the order seen by the parser. An individual peephole
13066 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=#
13067 // on the command-line.
13068 //
13069 // ---------CURRENT LIMITATIONS----------------------------------------------
13070 //
13071 // Only match adjacent instructions in same basic block
13072 // Only equality constraints
13073 // Only constraints between operands, not (0.dest_reg == EAX_enc)
13074 // Only one replacement instruction
13075 //
13076 // ---------EXAMPLE----------------------------------------------------------
13077 //
13078 // // pertinent parts of existing instructions in architecture description
13079 // instruct movI(rRegI dst, rRegI src) %{
13080 // match(Set dst (CopyI src));
13081 // %}
13082 //
13083 // instruct incI_eReg(rRegI dst, immI1 src, eFlagsReg cr) %{
13084 // match(Set dst (AddI dst src));
13085 // effect(KILL cr);
13086 // %}
13087 //
13088 // // Change (inc mov) to lea
13089 // peephole %{
13090 // // increment preceeded by register-register move
13091 // peepmatch ( incI_eReg movI );
13092 // // require that the destination register of the increment
13093 // // match the destination register of the move
13094 // peepconstraint ( 0.dst == 1.dst );
13095 // // construct a replacement instruction that sets
13096 // // the destination to ( move's source register + one )
13097 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13098 // %}
13099 //
13100 // Implementation no longer uses movX instructions since
13101 // machine-independent system no longer uses CopyX nodes.
13102 //
13103 // peephole %{
13108 //
13109 // peephole %{
13110 // peepmatch ( decI_eReg movI );
13111 // peepconstraint ( 0.dst == 1.dst );
13112 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13113 // %}
13114 //
13115 // peephole %{
13116 // peepmatch ( addI_eReg_imm movI );
13117 // peepconstraint ( 0.dst == 1.dst );
13118 // peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) );
13119 // %}
13120 //
13121 // peephole %{
13122 // peepmatch ( addP_eReg_imm movP );
13123 // peepconstraint ( 0.dst == 1.dst );
13124 // peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) );
13125 // %}
13126
13127 // // Change load of spilled value to only a spill
13128 // instruct storeI(memory mem, rRegI src) %{
13129 // match(Set mem (StoreI mem src));
13130 // %}
13131 //
13132 // instruct loadI(rRegI dst, memory mem) %{
13133 // match(Set dst (LoadI mem));
13134 // %}
13135 //
13136 peephole %{
13137 peepmatch ( loadI storeI );
13138 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem );
13139 peepreplace ( storeI( 1.mem 1.mem 1.src ) );
13140 %}
13141
13142 //----------SMARTSPILL RULES---------------------------------------------------
13143 // These must follow all instruction definitions as they use the names
13144 // defined in the instructions definitions.
|