x86_32.ad revision 2614:95134e034042
1// 2// Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 3// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4// 5// This code is free software; you can redistribute it and/or modify it 6// under the terms of the GNU General Public License version 2 only, as 7// published by the Free Software Foundation. 8// 9// This code is distributed in the hope that it will be useful, but WITHOUT 10// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12// version 2 for more details (a copy is included in the LICENSE file that 13// accompanied this code). 14// 15// You should have received a copy of the GNU General Public License version 16// 2 along with this work; if not, write to the Free Software Foundation, 17// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18// 19// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20// or visit www.oracle.com if you need additional information or have any 21// questions. 22// 23// 24 25// X86 Architecture Description File 26 27//----------REGISTER DEFINITION BLOCK------------------------------------------ 28// This information is used by the matcher and the register allocator to 29// describe individual registers and classes of registers within the target 30// archtecture. 31 32register %{ 33//----------Architecture Description Register Definitions---------------------- 34// General Registers 35// "reg_def" name ( register save type, C convention save type, 36// ideal register type, encoding ); 37// Register Save Types: 38// 39// NS = No-Save: The register allocator assumes that these registers 40// can be used without saving upon entry to the method, & 41// that they do not need to be saved at call sites. 42// 43// SOC = Save-On-Call: The register allocator assumes that these registers 44// can be used without saving upon entry to the method, 45// but that they must be saved at call sites. 46// 47// SOE = Save-On-Entry: The register allocator assumes that these registers 48// must be saved before using them upon entry to the 49// method, but they do not need to be saved at call 50// sites. 51// 52// AS = Always-Save: The register allocator assumes that these registers 53// must be saved before using them upon entry to the 54// method, & that they must be saved at call sites. 55// 56// Ideal Register Type is used to determine how to save & restore a 57// register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58// spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59// 60// The encoding number is the actual bit-pattern placed into the opcodes. 61 62// General Registers 63// 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 67reg_def EBX(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 68reg_def ECX(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 69reg_def ESI(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 70reg_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 72reg_def EBP(NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 73reg_def EDX(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 74reg_def EAX(SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 75reg_def ESP( NS, NS, Op_RegI, 4, rsp->as_VMReg()); 76 77// Special Registers 78reg_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. 82reg_def FPR0L( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad()); 83reg_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// 93reg_def FPR1L( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg()); 94reg_def FPR1H( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg()->next()); 95reg_def FPR2L( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg()); 96reg_def FPR2H( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg()->next()); 97reg_def FPR3L( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg()); 98reg_def FPR3H( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg()->next()); 99reg_def FPR4L( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg()); 100reg_def FPR4H( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg()->next()); 101reg_def FPR5L( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg()); 102reg_def FPR5H( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg()->next()); 103reg_def FPR6L( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg()); 104reg_def FPR6H( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg()->next()); 105reg_def FPR7L( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()); 106reg_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. 112reg_def XMM0a( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()); 113reg_def XMM0b( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next()); 114reg_def XMM1a( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()); 115reg_def XMM1b( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next()); 116reg_def XMM2a( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()); 117reg_def XMM2b( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next()); 118reg_def XMM3a( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()); 119reg_def XMM3b( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next()); 120reg_def XMM4a( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()); 121reg_def XMM4b( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next()); 122reg_def XMM5a( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()); 123reg_def XMM5b( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next()); 124reg_def XMM6a( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()); 125reg_def XMM6b( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next()); 126reg_def XMM7a( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()); 127reg_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. 136alloc_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 141alloc_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 160reg_class any_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX, ESP); 161// Class for general registers 162reg_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, 165reg_class e_reg_no_rbp(EAX, EDX, EDI, ESI, ECX, EBX); 166// Class of "X" registers 167reg_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 171reg_class p_reg(EDX, EDI, ESI, EBX); 172// Class for general registers not including ECX 173reg_class ncx_reg(EAX, EDX, EBP, EDI, ESI, EBX); 174// Class for general registers not including EAX 175reg_class nax_reg(EDX, EDI, ESI, ECX, EBX); 176// Class for general registers not including EAX or EBX. 177reg_class nabx_reg(EDX, EDI, ESI, ECX, EBP); 178// Class of EAX (for multiply and divide operations) 179reg_class eax_reg(EAX); 180// Class of EBX (for atomic add) 181reg_class ebx_reg(EBX); 182// Class of ECX (for shift and JCXZ operations and cmpLTMask) 183reg_class ecx_reg(ECX); 184// Class of EDX (for multiply and divide operations) 185reg_class edx_reg(EDX); 186// Class of EDI (for synchronization) 187reg_class edi_reg(EDI); 188// Class of ESI (for synchronization) 189reg_class esi_reg(ESI); 190// Singleton class for interpreter's stack pointer 191reg_class ebp_reg(EBP); 192// Singleton class for stack pointer 193reg_class sp_reg(ESP); 194// Singleton class for instruction pointer 195// reg_class ip_reg(EIP); 196// Singleton class for condition codes 197reg_class int_flags(EFLAGS); 198// Class of integer register pairs 199reg_class long_reg( EAX,EDX, ECX,EBX, EBP,EDI ); 200// Class of integer register pairs that aligns with calling convention 201reg_class eadx_reg( EAX,EDX ); 202reg_class ebcx_reg( ECX,EBX ); 203// Not AX or DX, used in divides 204reg_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. 209reg_class flt_reg( FPR1L,FPR2L,FPR3L,FPR4L,FPR5L,FPR6L,FPR7L ); 210 211// make a register class for SSE registers 212reg_class xmm_reg(XMM0a, XMM1a, XMM2a, XMM3a, XMM4a, XMM5a, XMM6a, XMM7a); 213 214// make a double register class for SSE2 registers 215reg_class xdb_reg(XMM0a,XMM0b, XMM1a,XMM1b, XMM2a,XMM2b, XMM3a,XMM3b, 216 XMM4a,XMM4b, XMM5a,XMM5b, XMM6a,XMM6b, XMM7a,XMM7b ); 217 218reg_class dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H, 219 FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H, 220 FPR7L,FPR7H ); 221 222reg_class flt_reg0( FPR1L ); 223reg_class dbl_reg0( FPR1L,FPR1H ); 224reg_class dbl_reg1( FPR2L,FPR2H ); 225reg_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. 230reg_class xdb_reg6( XMM6a,XMM6b ); 231reg_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 238source_hpp %{ 239// Must be visible to the DFA in dfa_x86_32.cpp 240extern bool is_operand_hi32_zero(Node* n); 241%} 242 243source %{ 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 252// These masks are used to provide 128-bit aligned bitmasks to the XMM 253// instructions, to allow sign-masking or sign-bit flipping. They allow 254// fast versions of NegF/NegD and AbsF/AbsD. 255 256// Note: 'double' and 'long long' have 32-bits alignment on x86. 257static jlong* double_quadword(jlong *adr, jlong lo, jlong hi) { 258 // Use the expression (adr)&(~0xF) to provide 128-bits aligned address 259 // of 128-bits operands for SSE instructions. 260 jlong *operand = (jlong*)(((uintptr_t)adr)&((uintptr_t)(~0xF))); 261 // Store the value to a 128-bits operand. 262 operand[0] = lo; 263 operand[1] = hi; 264 return operand; 265} 266 267// Buffer for 128-bits masks used by SSE instructions. 268static jlong fp_signmask_pool[(4+1)*2]; // 4*128bits(data) + 128bits(alignment) 269 270// Static initialization during VM startup. 271static jlong *float_signmask_pool = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF)); 272static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF)); 273static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000)); 274static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000)); 275 276// Offset hacking within calls. 277static int pre_call_FPU_size() { 278 if (Compile::current()->in_24_bit_fp_mode()) 279 return 6; // fldcw 280 return 0; 281} 282 283static int preserve_SP_size() { 284 return LP64_ONLY(1 +) 2; // [rex,] op, rm(reg/reg) 285} 286 287// !!!!! Special hack to get all type of calls to specify the byte offset 288// from the start of the call to the point where the return address 289// will point. 290int MachCallStaticJavaNode::ret_addr_offset() { 291 int offset = 5 + pre_call_FPU_size(); // 5 bytes from start of call to where return address points 292 if (_method_handle_invoke) 293 offset += preserve_SP_size(); 294 return offset; 295} 296 297int MachCallDynamicJavaNode::ret_addr_offset() { 298 return 10 + pre_call_FPU_size(); // 10 bytes from start of call to where return address points 299} 300 301static int sizeof_FFree_Float_Stack_All = -1; 302 303int MachCallRuntimeNode::ret_addr_offset() { 304 assert(sizeof_FFree_Float_Stack_All != -1, "must have been emitted already"); 305 return sizeof_FFree_Float_Stack_All + 5 + pre_call_FPU_size(); 306} 307 308// Indicate if the safepoint node needs the polling page as an input. 309// Since x86 does have absolute addressing, it doesn't. 310bool SafePointNode::needs_polling_address_input() { 311 return false; 312} 313 314// 315// Compute padding required for nodes which need alignment 316// 317 318// The address of the call instruction needs to be 4-byte aligned to 319// ensure that it does not span a cache line so that it can be patched. 320int CallStaticJavaDirectNode::compute_padding(int current_offset) const { 321 current_offset += pre_call_FPU_size(); // skip fldcw, if any 322 current_offset += 1; // skip call opcode byte 323 return round_to(current_offset, alignment_required()) - current_offset; 324} 325 326// The address of the call instruction needs to be 4-byte aligned to 327// ensure that it does not span a cache line so that it can be patched. 328int CallStaticJavaHandleNode::compute_padding(int current_offset) const { 329 current_offset += pre_call_FPU_size(); // skip fldcw, if any 330 current_offset += preserve_SP_size(); // skip mov rbp, rsp 331 current_offset += 1; // skip call opcode byte 332 return round_to(current_offset, alignment_required()) - current_offset; 333} 334 335// The address of the call instruction needs to be 4-byte aligned to 336// ensure that it does not span a cache line so that it can be patched. 337int CallDynamicJavaDirectNode::compute_padding(int current_offset) const { 338 current_offset += pre_call_FPU_size(); // skip fldcw, if any 339 current_offset += 5; // skip MOV instruction 340 current_offset += 1; // skip call opcode byte 341 return round_to(current_offset, alignment_required()) - current_offset; 342} 343 344#ifndef PRODUCT 345void MachBreakpointNode::format( PhaseRegAlloc *, outputStream* st ) const { 346 st->print("INT3"); 347} 348#endif 349 350// EMIT_RM() 351void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 352 unsigned char c = (unsigned char)((f1 << 6) | (f2 << 3) | f3); 353 cbuf.insts()->emit_int8(c); 354} 355 356// EMIT_CC() 357void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 358 unsigned char c = (unsigned char)( f1 | f2 ); 359 cbuf.insts()->emit_int8(c); 360} 361 362// EMIT_OPCODE() 363void emit_opcode(CodeBuffer &cbuf, int code) { 364 cbuf.insts()->emit_int8((unsigned char) code); 365} 366 367// EMIT_OPCODE() w/ relocation information 368void emit_opcode(CodeBuffer &cbuf, int code, relocInfo::relocType reloc, int offset = 0) { 369 cbuf.relocate(cbuf.insts_mark() + offset, reloc); 370 emit_opcode(cbuf, code); 371} 372 373// EMIT_D8() 374void emit_d8(CodeBuffer &cbuf, int d8) { 375 cbuf.insts()->emit_int8((unsigned char) d8); 376} 377 378// EMIT_D16() 379void emit_d16(CodeBuffer &cbuf, int d16) { 380 cbuf.insts()->emit_int16(d16); 381} 382 383// EMIT_D32() 384void emit_d32(CodeBuffer &cbuf, int d32) { 385 cbuf.insts()->emit_int32(d32); 386} 387 388// emit 32 bit value and construct relocation entry from relocInfo::relocType 389void emit_d32_reloc(CodeBuffer &cbuf, int d32, relocInfo::relocType reloc, 390 int format) { 391 cbuf.relocate(cbuf.insts_mark(), reloc, format); 392 cbuf.insts()->emit_int32(d32); 393} 394 395// emit 32 bit value and construct relocation entry from RelocationHolder 396void emit_d32_reloc(CodeBuffer &cbuf, int d32, RelocationHolder const& rspec, 397 int format) { 398#ifdef ASSERT 399 if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) { 400 assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code"); 401 } 402#endif 403 cbuf.relocate(cbuf.insts_mark(), rspec, format); 404 cbuf.insts()->emit_int32(d32); 405} 406 407// Access stack slot for load or store 408void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) { 409 emit_opcode( cbuf, opcode ); // (e.g., FILD [ESP+src]) 410 if( -128 <= disp && disp <= 127 ) { 411 emit_rm( cbuf, 0x01, rm_field, ESP_enc ); // R/M byte 412 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte 413 emit_d8 (cbuf, disp); // Displacement // R/M byte 414 } else { 415 emit_rm( cbuf, 0x02, rm_field, ESP_enc ); // R/M byte 416 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte 417 emit_d32(cbuf, disp); // Displacement // R/M byte 418 } 419} 420 421 // eRegI ereg, memory mem) %{ // emit_reg_mem 422void encode_RegMem( CodeBuffer &cbuf, int reg_encoding, int base, int index, int scale, int displace, bool displace_is_oop ) { 423 // There is no index & no scale, use form without SIB byte 424 if ((index == 0x4) && 425 (scale == 0) && (base != ESP_enc)) { 426 // If no displacement, mode is 0x0; unless base is [EBP] 427 if ( (displace == 0) && (base != EBP_enc) ) { 428 emit_rm(cbuf, 0x0, reg_encoding, base); 429 } 430 else { // If 8-bit displacement, mode 0x1 431 if ((displace >= -128) && (displace <= 127) 432 && !(displace_is_oop) ) { 433 emit_rm(cbuf, 0x1, reg_encoding, base); 434 emit_d8(cbuf, displace); 435 } 436 else { // If 32-bit displacement 437 if (base == -1) { // Special flag for absolute address 438 emit_rm(cbuf, 0x0, reg_encoding, 0x5); 439 // (manual lies; no SIB needed here) 440 if ( displace_is_oop ) { 441 emit_d32_reloc(cbuf, displace, relocInfo::oop_type, 1); 442 } else { 443 emit_d32 (cbuf, displace); 444 } 445 } 446 else { // Normal base + offset 447 emit_rm(cbuf, 0x2, reg_encoding, base); 448 if ( displace_is_oop ) { 449 emit_d32_reloc(cbuf, displace, relocInfo::oop_type, 1); 450 } else { 451 emit_d32 (cbuf, displace); 452 } 453 } 454 } 455 } 456 } 457 else { // Else, encode with the SIB byte 458 // If no displacement, mode is 0x0; unless base is [EBP] 459 if (displace == 0 && (base != EBP_enc)) { // If no displacement 460 emit_rm(cbuf, 0x0, reg_encoding, 0x4); 461 emit_rm(cbuf, scale, index, base); 462 } 463 else { // If 8-bit displacement, mode 0x1 464 if ((displace >= -128) && (displace <= 127) 465 && !(displace_is_oop) ) { 466 emit_rm(cbuf, 0x1, reg_encoding, 0x4); 467 emit_rm(cbuf, scale, index, base); 468 emit_d8(cbuf, displace); 469 } 470 else { // If 32-bit displacement 471 if (base == 0x04 ) { 472 emit_rm(cbuf, 0x2, reg_encoding, 0x4); 473 emit_rm(cbuf, scale, index, 0x04); 474 } else { 475 emit_rm(cbuf, 0x2, reg_encoding, 0x4); 476 emit_rm(cbuf, scale, index, base); 477 } 478 if ( displace_is_oop ) { 479 emit_d32_reloc(cbuf, displace, relocInfo::oop_type, 1); 480 } else { 481 emit_d32 (cbuf, displace); 482 } 483 } 484 } 485 } 486} 487 488 489void encode_Copy( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) { 490 if( dst_encoding == src_encoding ) { 491 // reg-reg copy, use an empty encoding 492 } else { 493 emit_opcode( cbuf, 0x8B ); 494 emit_rm(cbuf, 0x3, dst_encoding, src_encoding ); 495 } 496} 497 498void encode_CopyXD( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) { 499 if( dst_encoding == src_encoding ) { 500 // reg-reg copy, use an empty encoding 501 } else { 502 MacroAssembler _masm(&cbuf); 503 504 __ movdqa(as_XMMRegister(dst_encoding), as_XMMRegister(src_encoding)); 505 } 506} 507 508 509//============================================================================= 510const bool Matcher::constant_table_absolute_addressing = true; 511const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 512 513void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 514 // Empty encoding 515} 516 517uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 518 return 0; 519} 520 521#ifndef PRODUCT 522void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 523 st->print("# MachConstantBaseNode (empty encoding)"); 524} 525#endif 526 527 528//============================================================================= 529#ifndef PRODUCT 530void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 531 Compile* C = ra_->C; 532 if( C->in_24_bit_fp_mode() ) { 533 st->print("FLDCW 24 bit fpu control word"); 534 st->print_cr(""); st->print("\t"); 535 } 536 537 int framesize = C->frame_slots() << LogBytesPerInt; 538 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 539 // Remove two words for return addr and rbp, 540 framesize -= 2*wordSize; 541 542 // Calls to C2R adapters often do not accept exceptional returns. 543 // We require that their callers must bang for them. But be careful, because 544 // some VM calls (such as call site linkage) can use several kilobytes of 545 // stack. But the stack safety zone should account for that. 546 // See bugs 4446381, 4468289, 4497237. 547 if (C->need_stack_bang(framesize)) { 548 st->print_cr("# stack bang"); st->print("\t"); 549 } 550 st->print_cr("PUSHL EBP"); st->print("\t"); 551 552 if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth 553 st->print("PUSH 0xBADB100D\t# Majik cookie for stack depth check"); 554 st->print_cr(""); st->print("\t"); 555 framesize -= wordSize; 556 } 557 558 if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) { 559 if (framesize) { 560 st->print("SUB ESP,%d\t# Create frame",framesize); 561 } 562 } else { 563 st->print("SUB ESP,%d\t# Create frame",framesize); 564 } 565} 566#endif 567 568 569void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 570 Compile* C = ra_->C; 571 572 if (UseSSE >= 2 && VerifyFPU) { 573 MacroAssembler masm(&cbuf); 574 masm.verify_FPU(0, "FPU stack must be clean on entry"); 575 } 576 577 // WARNING: Initial instruction MUST be 5 bytes or longer so that 578 // NativeJump::patch_verified_entry will be able to patch out the entry 579 // code safely. The fldcw is ok at 6 bytes, the push to verify stack 580 // depth is ok at 5 bytes, the frame allocation can be either 3 or 581 // 6 bytes. So if we don't do the fldcw or the push then we must 582 // use the 6 byte frame allocation even if we have no frame. :-( 583 // If method sets FPU control word do it now 584 if( C->in_24_bit_fp_mode() ) { 585 MacroAssembler masm(&cbuf); 586 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24())); 587 } 588 589 int framesize = C->frame_slots() << LogBytesPerInt; 590 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 591 // Remove two words for return addr and rbp, 592 framesize -= 2*wordSize; 593 594 // Calls to C2R adapters often do not accept exceptional returns. 595 // We require that their callers must bang for them. But be careful, because 596 // some VM calls (such as call site linkage) can use several kilobytes of 597 // stack. But the stack safety zone should account for that. 598 // See bugs 4446381, 4468289, 4497237. 599 if (C->need_stack_bang(framesize)) { 600 MacroAssembler masm(&cbuf); 601 masm.generate_stack_overflow_check(framesize); 602 } 603 604 // We always push rbp, so that on return to interpreter rbp, will be 605 // restored correctly and we can correct the stack. 606 emit_opcode(cbuf, 0x50 | EBP_enc); 607 608 if( VerifyStackAtCalls ) { // Majik cookie to verify stack depth 609 emit_opcode(cbuf, 0x68); // push 0xbadb100d 610 emit_d32(cbuf, 0xbadb100d); 611 framesize -= wordSize; 612 } 613 614 if ((C->in_24_bit_fp_mode() || VerifyStackAtCalls ) && framesize < 128 ) { 615 if (framesize) { 616 emit_opcode(cbuf, 0x83); // sub SP,#framesize 617 emit_rm(cbuf, 0x3, 0x05, ESP_enc); 618 emit_d8(cbuf, framesize); 619 } 620 } else { 621 emit_opcode(cbuf, 0x81); // sub SP,#framesize 622 emit_rm(cbuf, 0x3, 0x05, ESP_enc); 623 emit_d32(cbuf, framesize); 624 } 625 C->set_frame_complete(cbuf.insts_size()); 626 627#ifdef ASSERT 628 if (VerifyStackAtCalls) { 629 Label L; 630 MacroAssembler masm(&cbuf); 631 masm.push(rax); 632 masm.mov(rax, rsp); 633 masm.andptr(rax, StackAlignmentInBytes-1); 634 masm.cmpptr(rax, StackAlignmentInBytes-wordSize); 635 masm.pop(rax); 636 masm.jcc(Assembler::equal, L); 637 masm.stop("Stack is not properly aligned!"); 638 masm.bind(L); 639 } 640#endif 641 642} 643 644uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 645 return MachNode::size(ra_); // too many variables; just compute it the hard way 646} 647 648int MachPrologNode::reloc() const { 649 return 0; // a large enough number 650} 651 652//============================================================================= 653#ifndef PRODUCT 654void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 655 Compile *C = ra_->C; 656 int framesize = C->frame_slots() << LogBytesPerInt; 657 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 658 // Remove two words for return addr and rbp, 659 framesize -= 2*wordSize; 660 661 if( C->in_24_bit_fp_mode() ) { 662 st->print("FLDCW standard control word"); 663 st->cr(); st->print("\t"); 664 } 665 if( framesize ) { 666 st->print("ADD ESP,%d\t# Destroy frame",framesize); 667 st->cr(); st->print("\t"); 668 } 669 st->print_cr("POPL EBP"); st->print("\t"); 670 if( do_polling() && C->is_method_compilation() ) { 671 st->print("TEST PollPage,EAX\t! Poll Safepoint"); 672 st->cr(); st->print("\t"); 673 } 674} 675#endif 676 677void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 678 Compile *C = ra_->C; 679 680 // If method set FPU control word, restore to standard control word 681 if( C->in_24_bit_fp_mode() ) { 682 MacroAssembler masm(&cbuf); 683 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); 684 } 685 686 int framesize = C->frame_slots() << LogBytesPerInt; 687 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 688 // Remove two words for return addr and rbp, 689 framesize -= 2*wordSize; 690 691 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 692 693 if( framesize >= 128 ) { 694 emit_opcode(cbuf, 0x81); // add SP, #framesize 695 emit_rm(cbuf, 0x3, 0x00, ESP_enc); 696 emit_d32(cbuf, framesize); 697 } 698 else if( framesize ) { 699 emit_opcode(cbuf, 0x83); // add SP, #framesize 700 emit_rm(cbuf, 0x3, 0x00, ESP_enc); 701 emit_d8(cbuf, framesize); 702 } 703 704 emit_opcode(cbuf, 0x58 | EBP_enc); 705 706 if( do_polling() && C->is_method_compilation() ) { 707 cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0); 708 emit_opcode(cbuf,0x85); 709 emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX 710 emit_d32(cbuf, (intptr_t)os::get_polling_page()); 711 } 712} 713 714uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 715 Compile *C = ra_->C; 716 // If method set FPU control word, restore to standard control word 717 int size = C->in_24_bit_fp_mode() ? 6 : 0; 718 if( do_polling() && C->is_method_compilation() ) size += 6; 719 720 int framesize = C->frame_slots() << LogBytesPerInt; 721 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 722 // Remove two words for return addr and rbp, 723 framesize -= 2*wordSize; 724 725 size++; // popl rbp, 726 727 if( framesize >= 128 ) { 728 size += 6; 729 } else { 730 size += framesize ? 3 : 0; 731 } 732 return size; 733} 734 735int MachEpilogNode::reloc() const { 736 return 0; // a large enough number 737} 738 739const Pipeline * MachEpilogNode::pipeline() const { 740 return MachNode::pipeline_class(); 741} 742 743int MachEpilogNode::safepoint_offset() const { return 0; } 744 745//============================================================================= 746 747enum RC { rc_bad, rc_int, rc_float, rc_xmm, rc_stack }; 748static enum RC rc_class( OptoReg::Name reg ) { 749 750 if( !OptoReg::is_valid(reg) ) return rc_bad; 751 if (OptoReg::is_stack(reg)) return rc_stack; 752 753 VMReg r = OptoReg::as_VMReg(reg); 754 if (r->is_Register()) return rc_int; 755 if (r->is_FloatRegister()) { 756 assert(UseSSE < 2, "shouldn't be used in SSE2+ mode"); 757 return rc_float; 758 } 759 assert(r->is_XMMRegister(), "must be"); 760 return rc_xmm; 761} 762 763static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg, 764 int opcode, const char *op_str, int size, outputStream* st ) { 765 if( cbuf ) { 766 emit_opcode (*cbuf, opcode ); 767 encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, false); 768#ifndef PRODUCT 769 } else if( !do_size ) { 770 if( size != 0 ) st->print("\n\t"); 771 if( opcode == 0x8B || opcode == 0x89 ) { // MOV 772 if( is_load ) st->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset); 773 else st->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]); 774 } else { // FLD, FST, PUSH, POP 775 st->print("%s [ESP + #%d]",op_str,offset); 776 } 777#endif 778 } 779 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4); 780 return size+3+offset_size; 781} 782 783// Helper for XMM registers. Extra opcode bits, limited syntax. 784static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load, 785 int offset, int reg_lo, int reg_hi, int size, outputStream* st ) { 786 if( cbuf ) { 787 if( reg_lo+1 == reg_hi ) { // double move? 788 if( is_load && !UseXmmLoadAndClearUpper ) 789 emit_opcode(*cbuf, 0x66 ); // use 'movlpd' for load 790 else 791 emit_opcode(*cbuf, 0xF2 ); // use 'movsd' otherwise 792 } else { 793 emit_opcode(*cbuf, 0xF3 ); 794 } 795 emit_opcode(*cbuf, 0x0F ); 796 if( reg_lo+1 == reg_hi && is_load && !UseXmmLoadAndClearUpper ) 797 emit_opcode(*cbuf, 0x12 ); // use 'movlpd' for load 798 else 799 emit_opcode(*cbuf, is_load ? 0x10 : 0x11 ); 800 encode_RegMem(*cbuf, Matcher::_regEncode[reg_lo], ESP_enc, 0x4, 0, offset, false); 801#ifndef PRODUCT 802 } else if( !do_size ) { 803 if( size != 0 ) st->print("\n\t"); 804 if( reg_lo+1 == reg_hi ) { // double move? 805 if( is_load ) st->print("%s %s,[ESP + #%d]", 806 UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD", 807 Matcher::regName[reg_lo], offset); 808 else st->print("MOVSD [ESP + #%d],%s", 809 offset, Matcher::regName[reg_lo]); 810 } else { 811 if( is_load ) st->print("MOVSS %s,[ESP + #%d]", 812 Matcher::regName[reg_lo], offset); 813 else st->print("MOVSS [ESP + #%d],%s", 814 offset, Matcher::regName[reg_lo]); 815 } 816#endif 817 } 818 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4); 819 return size+5+offset_size; 820} 821 822 823static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 824 int src_hi, int dst_hi, int size, outputStream* st ) { 825 if( UseXmmRegToRegMoveAll ) {//Use movaps,movapd to move between xmm registers 826 if( cbuf ) { 827 if( (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ) { 828 emit_opcode(*cbuf, 0x66 ); 829 } 830 emit_opcode(*cbuf, 0x0F ); 831 emit_opcode(*cbuf, 0x28 ); 832 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] ); 833#ifndef PRODUCT 834 } else if( !do_size ) { 835 if( size != 0 ) st->print("\n\t"); 836 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move? 837 st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 838 } else { 839 st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 840 } 841#endif 842 } 843 return size + ((src_lo+1 == src_hi && dst_lo+1 == dst_hi) ? 4 : 3); 844 } else { 845 if( cbuf ) { 846 emit_opcode(*cbuf, (src_lo+1 == src_hi && dst_lo+1 == dst_hi) ? 0xF2 : 0xF3 ); 847 emit_opcode(*cbuf, 0x0F ); 848 emit_opcode(*cbuf, 0x10 ); 849 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst_lo], Matcher::_regEncode[src_lo] ); 850#ifndef PRODUCT 851 } else if( !do_size ) { 852 if( size != 0 ) st->print("\n\t"); 853 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move? 854 st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 855 } else { 856 st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 857 } 858#endif 859 } 860 return size+4; 861 } 862} 863 864static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 865 int src_hi, int dst_hi, int size, outputStream* st ) { 866 // 32-bit 867 if (cbuf) { 868 emit_opcode(*cbuf, 0x66); 869 emit_opcode(*cbuf, 0x0F); 870 emit_opcode(*cbuf, 0x6E); 871 emit_rm(*cbuf, 0x3, Matcher::_regEncode[dst_lo] & 7, Matcher::_regEncode[src_lo] & 7); 872#ifndef PRODUCT 873 } else if (!do_size) { 874 st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 875#endif 876 } 877 return 4; 878} 879 880 881static int impl_movx2gpr_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 882 int src_hi, int dst_hi, int size, outputStream* st ) { 883 // 32-bit 884 if (cbuf) { 885 emit_opcode(*cbuf, 0x66); 886 emit_opcode(*cbuf, 0x0F); 887 emit_opcode(*cbuf, 0x7E); 888 emit_rm(*cbuf, 0x3, Matcher::_regEncode[src_lo] & 7, Matcher::_regEncode[dst_lo] & 7); 889#ifndef PRODUCT 890 } else if (!do_size) { 891 st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 892#endif 893 } 894 return 4; 895} 896 897static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) { 898 if( cbuf ) { 899 emit_opcode(*cbuf, 0x8B ); 900 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] ); 901#ifndef PRODUCT 902 } else if( !do_size ) { 903 if( size != 0 ) st->print("\n\t"); 904 st->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]); 905#endif 906 } 907 return size+2; 908} 909 910static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi, 911 int offset, int size, outputStream* st ) { 912 if( src_lo != FPR1L_num ) { // Move value to top of FP stack, if not already there 913 if( cbuf ) { 914 emit_opcode( *cbuf, 0xD9 ); // FLD (i.e., push it) 915 emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] ); 916#ifndef PRODUCT 917 } else if( !do_size ) { 918 if( size != 0 ) st->print("\n\t"); 919 st->print("FLD %s",Matcher::regName[src_lo]); 920#endif 921 } 922 size += 2; 923 } 924 925 int st_op = (src_lo != FPR1L_num) ? EBX_num /*store & pop*/ : EDX_num /*store no pop*/; 926 const char *op_str; 927 int op; 928 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double store? 929 op_str = (src_lo != FPR1L_num) ? "FSTP_D" : "FST_D "; 930 op = 0xDD; 931 } else { // 32-bit store 932 op_str = (src_lo != FPR1L_num) ? "FSTP_S" : "FST_S "; 933 op = 0xD9; 934 assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" ); 935 } 936 937 return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st); 938} 939 940uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const { 941 // Get registers to move 942 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 943 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 944 OptoReg::Name dst_second = ra_->get_reg_second(this ); 945 OptoReg::Name dst_first = ra_->get_reg_first(this ); 946 947 enum RC src_second_rc = rc_class(src_second); 948 enum RC src_first_rc = rc_class(src_first); 949 enum RC dst_second_rc = rc_class(dst_second); 950 enum RC dst_first_rc = rc_class(dst_first); 951 952 assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" ); 953 954 // Generate spill code! 955 int size = 0; 956 957 if( src_first == dst_first && src_second == dst_second ) 958 return size; // Self copy, no move 959 960 // -------------------------------------- 961 // Check for mem-mem move. push/pop to move. 962 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 963 if( src_second == dst_first ) { // overlapping stack copy ranges 964 assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" ); 965 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st); 966 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st); 967 src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits 968 } 969 // move low bits 970 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size, st); 971 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size, st); 972 if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits 973 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st); 974 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st); 975 } 976 return size; 977 } 978 979 // -------------------------------------- 980 // Check for integer reg-reg copy 981 if( src_first_rc == rc_int && dst_first_rc == rc_int ) 982 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size, st); 983 984 // Check for integer store 985 if( src_first_rc == rc_int && dst_first_rc == rc_stack ) 986 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size, st); 987 988 // Check for integer load 989 if( dst_first_rc == rc_int && src_first_rc == rc_stack ) 990 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st); 991 992 // Check for integer reg-xmm reg copy 993 if( src_first_rc == rc_int && dst_first_rc == rc_xmm ) { 994 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad), 995 "no 64 bit integer-float reg moves" ); 996 return impl_movgpr2x_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st); 997 } 998 // -------------------------------------- 999 // Check for float reg-reg copy 1000 if( src_first_rc == rc_float && dst_first_rc == rc_float ) { 1001 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) || 1002 (src_first+1 == src_second && dst_first+1 == dst_second), "no non-adjacent float-moves" ); 1003 if( cbuf ) { 1004 1005 // Note the mucking with the register encode to compensate for the 0/1 1006 // indexing issue mentioned in a comment in the reg_def sections 1007 // for FPR registers many lines above here. 1008 1009 if( src_first != FPR1L_num ) { 1010 emit_opcode (*cbuf, 0xD9 ); // FLD ST(i) 1011 emit_d8 (*cbuf, 0xC0+Matcher::_regEncode[src_first]-1 ); 1012 emit_opcode (*cbuf, 0xDD ); // FSTP ST(i) 1013 emit_d8 (*cbuf, 0xD8+Matcher::_regEncode[dst_first] ); 1014 } else { 1015 emit_opcode (*cbuf, 0xDD ); // FST ST(i) 1016 emit_d8 (*cbuf, 0xD0+Matcher::_regEncode[dst_first]-1 ); 1017 } 1018#ifndef PRODUCT 1019 } else if( !do_size ) { 1020 if( size != 0 ) st->print("\n\t"); 1021 if( src_first != FPR1L_num ) st->print("FLD %s\n\tFSTP %s",Matcher::regName[src_first],Matcher::regName[dst_first]); 1022 else st->print( "FST %s", Matcher::regName[dst_first]); 1023#endif 1024 } 1025 return size + ((src_first != FPR1L_num) ? 2+2 : 2); 1026 } 1027 1028 // Check for float store 1029 if( src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1030 return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size, st); 1031 } 1032 1033 // Check for float load 1034 if( dst_first_rc == rc_float && src_first_rc == rc_stack ) { 1035 int offset = ra_->reg2offset(src_first); 1036 const char *op_str; 1037 int op; 1038 if( src_first+1 == src_second && dst_first+1 == dst_second ) { // double load? 1039 op_str = "FLD_D"; 1040 op = 0xDD; 1041 } else { // 32-bit load 1042 op_str = "FLD_S"; 1043 op = 0xD9; 1044 assert( src_second_rc == rc_bad && dst_second_rc == rc_bad, "no non-adjacent float-loads" ); 1045 } 1046 if( cbuf ) { 1047 emit_opcode (*cbuf, op ); 1048 encode_RegMem(*cbuf, 0x0, ESP_enc, 0x4, 0, offset, false); 1049 emit_opcode (*cbuf, 0xDD ); // FSTP ST(i) 1050 emit_d8 (*cbuf, 0xD8+Matcher::_regEncode[dst_first] ); 1051#ifndef PRODUCT 1052 } else if( !do_size ) { 1053 if( size != 0 ) st->print("\n\t"); 1054 st->print("%s ST,[ESP + #%d]\n\tFSTP %s",op_str, offset,Matcher::regName[dst_first]); 1055#endif 1056 } 1057 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4); 1058 return size + 3+offset_size+2; 1059 } 1060 1061 // Check for xmm reg-reg copy 1062 if( src_first_rc == rc_xmm && dst_first_rc == rc_xmm ) { 1063 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) || 1064 (src_first+1 == src_second && dst_first+1 == dst_second), 1065 "no non-adjacent float-moves" ); 1066 return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st); 1067 } 1068 1069 // Check for xmm reg-integer reg copy 1070 if( src_first_rc == rc_xmm && dst_first_rc == rc_int ) { 1071 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad), 1072 "no 64 bit float-integer reg moves" ); 1073 return impl_movx2gpr_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st); 1074 } 1075 1076 // Check for xmm store 1077 if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) { 1078 return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size, st); 1079 } 1080 1081 // Check for float xmm load 1082 if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) { 1083 return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size, st); 1084 } 1085 1086 // Copy from float reg to xmm reg 1087 if( dst_first_rc == rc_xmm && src_first_rc == rc_float ) { 1088 // copy to the top of stack from floating point reg 1089 // and use LEA to preserve flags 1090 if( cbuf ) { 1091 emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP-8] 1092 emit_rm(*cbuf, 0x1, ESP_enc, 0x04); 1093 emit_rm(*cbuf, 0x0, 0x04, ESP_enc); 1094 emit_d8(*cbuf,0xF8); 1095#ifndef PRODUCT 1096 } else if( !do_size ) { 1097 if( size != 0 ) st->print("\n\t"); 1098 st->print("LEA ESP,[ESP-8]"); 1099#endif 1100 } 1101 size += 4; 1102 1103 size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size, st); 1104 1105 // Copy from the temp memory to the xmm reg. 1106 size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size, st); 1107 1108 if( cbuf ) { 1109 emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP+8] 1110 emit_rm(*cbuf, 0x1, ESP_enc, 0x04); 1111 emit_rm(*cbuf, 0x0, 0x04, ESP_enc); 1112 emit_d8(*cbuf,0x08); 1113#ifndef PRODUCT 1114 } else if( !do_size ) { 1115 if( size != 0 ) st->print("\n\t"); 1116 st->print("LEA ESP,[ESP+8]"); 1117#endif 1118 } 1119 size += 4; 1120 return size; 1121 } 1122 1123 assert( size > 0, "missed a case" ); 1124 1125 // -------------------------------------------------------------------- 1126 // Check for second bits still needing moving. 1127 if( src_second == dst_second ) 1128 return size; // Self copy; no move 1129 assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" ); 1130 1131 // Check for second word int-int move 1132 if( src_second_rc == rc_int && dst_second_rc == rc_int ) 1133 return impl_mov_helper(cbuf,do_size,src_second,dst_second,size, st); 1134 1135 // Check for second word integer store 1136 if( src_second_rc == rc_int && dst_second_rc == rc_stack ) 1137 return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size, st); 1138 1139 // Check for second word integer load 1140 if( dst_second_rc == rc_int && src_second_rc == rc_stack ) 1141 return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size, st); 1142 1143 1144 Unimplemented(); 1145} 1146 1147#ifndef PRODUCT 1148void MachSpillCopyNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 1149 implementation( NULL, ra_, false, st ); 1150} 1151#endif 1152 1153void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1154 implementation( &cbuf, ra_, false, NULL ); 1155} 1156 1157uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1158 return implementation( NULL, ra_, true, NULL ); 1159} 1160 1161//============================================================================= 1162#ifndef PRODUCT 1163void MachNopNode::format( PhaseRegAlloc *, outputStream* st ) const { 1164 st->print("NOP \t# %d bytes pad for loops and calls", _count); 1165} 1166#endif 1167 1168void MachNopNode::emit(CodeBuffer &cbuf, PhaseRegAlloc * ) const { 1169 MacroAssembler _masm(&cbuf); 1170 __ nop(_count); 1171} 1172 1173uint MachNopNode::size(PhaseRegAlloc *) const { 1174 return _count; 1175} 1176 1177 1178//============================================================================= 1179#ifndef PRODUCT 1180void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 1181 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1182 int reg = ra_->get_reg_first(this); 1183 st->print("LEA %s,[ESP + #%d]",Matcher::regName[reg],offset); 1184} 1185#endif 1186 1187void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1188 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1189 int reg = ra_->get_encode(this); 1190 if( offset >= 128 ) { 1191 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1192 emit_rm(cbuf, 0x2, reg, 0x04); 1193 emit_rm(cbuf, 0x0, 0x04, ESP_enc); 1194 emit_d32(cbuf, offset); 1195 } 1196 else { 1197 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1198 emit_rm(cbuf, 0x1, reg, 0x04); 1199 emit_rm(cbuf, 0x0, 0x04, ESP_enc); 1200 emit_d8(cbuf, offset); 1201 } 1202} 1203 1204uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1205 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1206 if( offset >= 128 ) { 1207 return 7; 1208 } 1209 else { 1210 return 4; 1211 } 1212} 1213 1214//============================================================================= 1215 1216// emit call stub, compiled java to interpreter 1217void emit_java_to_interp(CodeBuffer &cbuf ) { 1218 // Stub is fixed up when the corresponding call is converted from calling 1219 // compiled code to calling interpreted code. 1220 // mov rbx,0 1221 // jmp -1 1222 1223 address mark = cbuf.insts_mark(); // get mark within main instrs section 1224 1225 // Note that the code buffer's insts_mark is always relative to insts. 1226 // That's why we must use the macroassembler to generate a stub. 1227 MacroAssembler _masm(&cbuf); 1228 1229 address base = 1230 __ start_a_stub(Compile::MAX_stubs_size); 1231 if (base == NULL) return; // CodeBuffer::expand failed 1232 // static stub relocation stores the instruction address of the call 1233 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM32); 1234 // static stub relocation also tags the methodOop in the code-stream. 1235 __ movoop(rbx, (jobject)NULL); // method is zapped till fixup time 1236 // This is recognized as unresolved by relocs/nativeInst/ic code 1237 __ jump(RuntimeAddress(__ pc())); 1238 1239 __ end_a_stub(); 1240 // Update current stubs pointer and restore insts_end. 1241} 1242// size of call stub, compiled java to interpretor 1243uint size_java_to_interp() { 1244 return 10; // movl; jmp 1245} 1246// relocation entries for call stub, compiled java to interpretor 1247uint reloc_java_to_interp() { 1248 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call 1249} 1250 1251//============================================================================= 1252#ifndef PRODUCT 1253void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 1254 st->print_cr( "CMP EAX,[ECX+4]\t# Inline cache check"); 1255 st->print_cr("\tJNE SharedRuntime::handle_ic_miss_stub"); 1256 st->print_cr("\tNOP"); 1257 st->print_cr("\tNOP"); 1258 if( !OptoBreakpoint ) 1259 st->print_cr("\tNOP"); 1260} 1261#endif 1262 1263void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1264 MacroAssembler masm(&cbuf); 1265#ifdef ASSERT 1266 uint insts_size = cbuf.insts_size(); 1267#endif 1268 masm.cmpptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); 1269 masm.jump_cc(Assembler::notEqual, 1270 RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1271 /* WARNING these NOPs are critical so that verified entry point is properly 1272 aligned for patching by NativeJump::patch_verified_entry() */ 1273 int nops_cnt = 2; 1274 if( !OptoBreakpoint ) // Leave space for int3 1275 nops_cnt += 1; 1276 masm.nop(nops_cnt); 1277 1278 assert(cbuf.insts_size() - insts_size == size(ra_), "checking code size of inline cache node"); 1279} 1280 1281uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 1282 return OptoBreakpoint ? 11 : 12; 1283} 1284 1285 1286//============================================================================= 1287uint size_exception_handler() { 1288 // NativeCall instruction size is the same as NativeJump. 1289 // exception handler starts out as jump and can be patched to 1290 // a call be deoptimization. (4932387) 1291 // Note that this value is also credited (in output.cpp) to 1292 // the size of the code section. 1293 return NativeJump::instruction_size; 1294} 1295 1296// Emit exception handler code. Stuff framesize into a register 1297// and call a VM stub routine. 1298int emit_exception_handler(CodeBuffer& cbuf) { 1299 1300 // Note that the code buffer's insts_mark is always relative to insts. 1301 // That's why we must use the macroassembler to generate a handler. 1302 MacroAssembler _masm(&cbuf); 1303 address base = 1304 __ start_a_stub(size_exception_handler()); 1305 if (base == NULL) return 0; // CodeBuffer::expand failed 1306 int offset = __ offset(); 1307 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1308 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1309 __ end_a_stub(); 1310 return offset; 1311} 1312 1313uint size_deopt_handler() { 1314 // NativeCall instruction size is the same as NativeJump. 1315 // exception handler starts out as jump and can be patched to 1316 // a call be deoptimization. (4932387) 1317 // Note that this value is also credited (in output.cpp) to 1318 // the size of the code section. 1319 return 5 + NativeJump::instruction_size; // pushl(); jmp; 1320} 1321 1322// Emit deopt handler code. 1323int emit_deopt_handler(CodeBuffer& cbuf) { 1324 1325 // Note that the code buffer's insts_mark is always relative to insts. 1326 // That's why we must use the macroassembler to generate a handler. 1327 MacroAssembler _masm(&cbuf); 1328 address base = 1329 __ start_a_stub(size_exception_handler()); 1330 if (base == NULL) return 0; // CodeBuffer::expand failed 1331 int offset = __ offset(); 1332 InternalAddress here(__ pc()); 1333 __ pushptr(here.addr()); 1334 1335 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1336 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1337 __ end_a_stub(); 1338 return offset; 1339} 1340 1341 1342const bool Matcher::match_rule_supported(int opcode) { 1343 if (!has_match_rule(opcode)) 1344 return false; 1345 1346 return true; // Per default match rules are supported. 1347} 1348 1349int Matcher::regnum_to_fpu_offset(int regnum) { 1350 return regnum - 32; // The FP registers are in the second chunk 1351} 1352 1353// This is UltraSparc specific, true just means we have fast l2f conversion 1354const bool Matcher::convL2FSupported(void) { 1355 return true; 1356} 1357 1358// Vector width in bytes 1359const uint Matcher::vector_width_in_bytes(void) { 1360 return UseSSE >= 2 ? 8 : 0; 1361} 1362 1363// Vector ideal reg 1364const uint Matcher::vector_ideal_reg(void) { 1365 return Op_RegD; 1366} 1367 1368// Is this branch offset short enough that a short branch can be used? 1369// 1370// NOTE: If the platform does not provide any short branch variants, then 1371// this method should return false for offset 0. 1372bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1373 // The passed offset is relative to address of the branch. 1374 // On 86 a branch displacement is calculated relative to address 1375 // of a next instruction. 1376 offset -= br_size; 1377 1378 // the short version of jmpConUCF2 contains multiple branches, 1379 // making the reach slightly less 1380 if (rule == jmpConUCF2_rule) 1381 return (-126 <= offset && offset <= 125); 1382 return (-128 <= offset && offset <= 127); 1383} 1384 1385const bool Matcher::isSimpleConstant64(jlong value) { 1386 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1387 return false; 1388} 1389 1390// The ecx parameter to rep stos for the ClearArray node is in dwords. 1391const bool Matcher::init_array_count_is_in_bytes = false; 1392 1393// Threshold size for cleararray. 1394const int Matcher::init_array_short_size = 8 * BytesPerLong; 1395 1396// Should the Matcher clone shifts on addressing modes, expecting them to 1397// be subsumed into complex addressing expressions or compute them into 1398// registers? True for Intel but false for most RISCs 1399const bool Matcher::clone_shift_expressions = true; 1400 1401// Do we need to mask the count passed to shift instructions or does 1402// the cpu only look at the lower 5/6 bits anyway? 1403const bool Matcher::need_masked_shift_count = false; 1404 1405bool Matcher::narrow_oop_use_complex_address() { 1406 ShouldNotCallThis(); 1407 return true; 1408} 1409 1410 1411// Is it better to copy float constants, or load them directly from memory? 1412// Intel can load a float constant from a direct address, requiring no 1413// extra registers. Most RISCs will have to materialize an address into a 1414// register first, so they would do better to copy the constant from stack. 1415const bool Matcher::rematerialize_float_constants = true; 1416 1417// If CPU can load and store mis-aligned doubles directly then no fixup is 1418// needed. Else we split the double into 2 integer pieces and move it 1419// piece-by-piece. Only happens when passing doubles into C code as the 1420// Java calling convention forces doubles to be aligned. 1421const bool Matcher::misaligned_doubles_ok = true; 1422 1423 1424void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 1425 // Get the memory operand from the node 1426 uint numopnds = node->num_opnds(); // Virtual call for number of operands 1427 uint skipped = node->oper_input_base(); // Sum of leaves skipped so far 1428 assert( idx >= skipped, "idx too low in pd_implicit_null_fixup" ); 1429 uint opcnt = 1; // First operand 1430 uint num_edges = node->_opnds[1]->num_edges(); // leaves for first operand 1431 while( idx >= skipped+num_edges ) { 1432 skipped += num_edges; 1433 opcnt++; // Bump operand count 1434 assert( opcnt < numopnds, "Accessing non-existent operand" ); 1435 num_edges = node->_opnds[opcnt]->num_edges(); // leaves for next operand 1436 } 1437 1438 MachOper *memory = node->_opnds[opcnt]; 1439 MachOper *new_memory = NULL; 1440 switch (memory->opcode()) { 1441 case DIRECT: 1442 case INDOFFSET32X: 1443 // No transformation necessary. 1444 return; 1445 case INDIRECT: 1446 new_memory = new (C) indirect_win95_safeOper( ); 1447 break; 1448 case INDOFFSET8: 1449 new_memory = new (C) indOffset8_win95_safeOper(memory->disp(NULL, NULL, 0)); 1450 break; 1451 case INDOFFSET32: 1452 new_memory = new (C) indOffset32_win95_safeOper(memory->disp(NULL, NULL, 0)); 1453 break; 1454 case INDINDEXOFFSET: 1455 new_memory = new (C) indIndexOffset_win95_safeOper(memory->disp(NULL, NULL, 0)); 1456 break; 1457 case INDINDEXSCALE: 1458 new_memory = new (C) indIndexScale_win95_safeOper(memory->scale()); 1459 break; 1460 case INDINDEXSCALEOFFSET: 1461 new_memory = new (C) indIndexScaleOffset_win95_safeOper(memory->scale(), memory->disp(NULL, NULL, 0)); 1462 break; 1463 case LOAD_LONG_INDIRECT: 1464 case LOAD_LONG_INDOFFSET32: 1465 // Does not use EBP as address register, use { EDX, EBX, EDI, ESI} 1466 return; 1467 default: 1468 assert(false, "unexpected memory operand in pd_implicit_null_fixup()"); 1469 return; 1470 } 1471 node->_opnds[opcnt] = new_memory; 1472} 1473 1474// Advertise here if the CPU requires explicit rounding operations 1475// to implement the UseStrictFP mode. 1476const bool Matcher::strict_fp_requires_explicit_rounding = true; 1477 1478// Are floats conerted to double when stored to stack during deoptimization? 1479// On x32 it is stored with convertion only when FPU is used for floats. 1480bool Matcher::float_in_double() { return (UseSSE == 0); } 1481 1482// Do ints take an entire long register or just half? 1483const bool Matcher::int_in_long = false; 1484 1485// Return whether or not this register is ever used as an argument. This 1486// function is used on startup to build the trampoline stubs in generateOptoStub. 1487// Registers not mentioned will be killed by the VM call in the trampoline, and 1488// arguments in those registers not be available to the callee. 1489bool Matcher::can_be_java_arg( int reg ) { 1490 if( reg == ECX_num || reg == EDX_num ) return true; 1491 if( (reg == XMM0a_num || reg == XMM1a_num) && UseSSE>=1 ) return true; 1492 if( (reg == XMM0b_num || reg == XMM1b_num) && UseSSE>=2 ) return true; 1493 return false; 1494} 1495 1496bool Matcher::is_spillable_arg( int reg ) { 1497 return can_be_java_arg(reg); 1498} 1499 1500bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1501 // Use hardware integer DIV instruction when 1502 // it is faster than a code which use multiply. 1503 // Only when constant divisor fits into 32 bit 1504 // (min_jint is excluded to get only correct 1505 // positive 32 bit values from negative). 1506 return VM_Version::has_fast_idiv() && 1507 (divisor == (int)divisor && divisor != min_jint); 1508} 1509 1510// Register for DIVI projection of divmodI 1511RegMask Matcher::divI_proj_mask() { 1512 return EAX_REG_mask; 1513} 1514 1515// Register for MODI projection of divmodI 1516RegMask Matcher::modI_proj_mask() { 1517 return EDX_REG_mask; 1518} 1519 1520// Register for DIVL projection of divmodL 1521RegMask Matcher::divL_proj_mask() { 1522 ShouldNotReachHere(); 1523 return RegMask(); 1524} 1525 1526// Register for MODL projection of divmodL 1527RegMask Matcher::modL_proj_mask() { 1528 ShouldNotReachHere(); 1529 return RegMask(); 1530} 1531 1532const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1533 return EBP_REG_mask; 1534} 1535 1536// Returns true if the high 32 bits of the value is known to be zero. 1537bool is_operand_hi32_zero(Node* n) { 1538 int opc = n->Opcode(); 1539 if (opc == Op_LoadUI2L) { 1540 return true; 1541 } 1542 if (opc == Op_AndL) { 1543 Node* o2 = n->in(2); 1544 if (o2->is_Con() && (o2->get_long() & 0xFFFFFFFF00000000LL) == 0LL) { 1545 return true; 1546 } 1547 } 1548 if (opc == Op_ConL && (n->get_long() & 0xFFFFFFFF00000000LL) == 0LL) { 1549 return true; 1550 } 1551 return false; 1552} 1553 1554%} 1555 1556//----------ENCODING BLOCK----------------------------------------------------- 1557// This block specifies the encoding classes used by the compiler to output 1558// byte streams. Encoding classes generate functions which are called by 1559// Machine Instruction Nodes in order to generate the bit encoding of the 1560// instruction. Operands specify their base encoding interface with the 1561// interface keyword. There are currently supported four interfaces, 1562// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 1563// operand to generate a function which returns its register number when 1564// queried. CONST_INTER causes an operand to generate a function which 1565// returns the value of the constant when queried. MEMORY_INTER causes an 1566// operand to generate four functions which return the Base Register, the 1567// Index Register, the Scale Value, and the Offset Value of the operand when 1568// queried. COND_INTER causes an operand to generate six functions which 1569// return the encoding code (ie - encoding bits for the instruction) 1570// associated with each basic boolean condition for a conditional instruction. 1571// Instructions specify two basic values for encoding. They use the 1572// ins_encode keyword to specify their encoding class (which must be one of 1573// the class names specified in the encoding block), and they use the 1574// opcode keyword to specify, in order, their primary, secondary, and 1575// tertiary opcode. Only the opcode sections which a particular instruction 1576// needs for encoding need to be specified. 1577encode %{ 1578 // Build emit functions for each basic byte or larger field in the intel 1579 // encoding scheme (opcode, rm, sib, immediate), and call them from C++ 1580 // code in the enc_class source block. Emit functions will live in the 1581 // main source block for now. In future, we can generalize this by 1582 // adding a syntax that specifies the sizes of fields in an order, 1583 // so that the adlc can build the emit functions automagically 1584 1585 // Emit primary opcode 1586 enc_class OpcP %{ 1587 emit_opcode(cbuf, $primary); 1588 %} 1589 1590 // Emit secondary opcode 1591 enc_class OpcS %{ 1592 emit_opcode(cbuf, $secondary); 1593 %} 1594 1595 // Emit opcode directly 1596 enc_class Opcode(immI d8) %{ 1597 emit_opcode(cbuf, $d8$$constant); 1598 %} 1599 1600 enc_class SizePrefix %{ 1601 emit_opcode(cbuf,0x66); 1602 %} 1603 1604 enc_class RegReg (eRegI dst, eRegI src) %{ // RegReg(Many) 1605 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 1606 %} 1607 1608 enc_class OpcRegReg (immI opcode, eRegI dst, eRegI src) %{ // OpcRegReg(Many) 1609 emit_opcode(cbuf,$opcode$$constant); 1610 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 1611 %} 1612 1613 enc_class mov_r32_imm0( eRegI dst ) %{ 1614 emit_opcode( cbuf, 0xB8 + $dst$$reg ); // 0xB8+ rd -- MOV r32 ,imm32 1615 emit_d32 ( cbuf, 0x0 ); // imm32==0x0 1616 %} 1617 1618 enc_class cdq_enc %{ 1619 // Full implementation of Java idiv and irem; checks for 1620 // special case as described in JVM spec., p.243 & p.271. 1621 // 1622 // normal case special case 1623 // 1624 // input : rax,: dividend min_int 1625 // reg: divisor -1 1626 // 1627 // output: rax,: quotient (= rax, idiv reg) min_int 1628 // rdx: remainder (= rax, irem reg) 0 1629 // 1630 // Code sequnce: 1631 // 1632 // 81 F8 00 00 00 80 cmp rax,80000000h 1633 // 0F 85 0B 00 00 00 jne normal_case 1634 // 33 D2 xor rdx,edx 1635 // 83 F9 FF cmp rcx,0FFh 1636 // 0F 84 03 00 00 00 je done 1637 // normal_case: 1638 // 99 cdq 1639 // F7 F9 idiv rax,ecx 1640 // done: 1641 // 1642 emit_opcode(cbuf,0x81); emit_d8(cbuf,0xF8); 1643 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); 1644 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x80); // cmp rax,80000000h 1645 emit_opcode(cbuf,0x0F); emit_d8(cbuf,0x85); 1646 emit_opcode(cbuf,0x0B); emit_d8(cbuf,0x00); 1647 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); // jne normal_case 1648 emit_opcode(cbuf,0x33); emit_d8(cbuf,0xD2); // xor rdx,edx 1649 emit_opcode(cbuf,0x83); emit_d8(cbuf,0xF9); emit_d8(cbuf,0xFF); // cmp rcx,0FFh 1650 emit_opcode(cbuf,0x0F); emit_d8(cbuf,0x84); 1651 emit_opcode(cbuf,0x03); emit_d8(cbuf,0x00); 1652 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); // je done 1653 // normal_case: 1654 emit_opcode(cbuf,0x99); // cdq 1655 // idiv (note: must be emitted by the user of this rule) 1656 // normal: 1657 %} 1658 1659 // Dense encoding for older common ops 1660 enc_class Opc_plus(immI opcode, eRegI reg) %{ 1661 emit_opcode(cbuf, $opcode$$constant + $reg$$reg); 1662 %} 1663 1664 1665 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1666 enc_class OpcSE (immI imm) %{ // Emit primary opcode and set sign-extend bit 1667 // Check for 8-bit immediate, and set sign extend bit in opcode 1668 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) { 1669 emit_opcode(cbuf, $primary | 0x02); 1670 } 1671 else { // If 32-bit immediate 1672 emit_opcode(cbuf, $primary); 1673 } 1674 %} 1675 1676 enc_class OpcSErm (eRegI dst, immI imm) %{ // OpcSEr/m 1677 // Emit primary opcode and set sign-extend bit 1678 // Check for 8-bit immediate, and set sign extend bit in opcode 1679 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) { 1680 emit_opcode(cbuf, $primary | 0x02); } 1681 else { // If 32-bit immediate 1682 emit_opcode(cbuf, $primary); 1683 } 1684 // Emit r/m byte with secondary opcode, after primary opcode. 1685 emit_rm(cbuf, 0x3, $secondary, $dst$$reg); 1686 %} 1687 1688 enc_class Con8or32 (immI imm) %{ // Con8or32(storeImmI), 8 or 32 bits 1689 // Check for 8-bit immediate, and set sign extend bit in opcode 1690 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) { 1691 $$$emit8$imm$$constant; 1692 } 1693 else { // If 32-bit immediate 1694 // Output immediate 1695 $$$emit32$imm$$constant; 1696 } 1697 %} 1698 1699 enc_class Long_OpcSErm_Lo(eRegL dst, immL imm) %{ 1700 // Emit primary opcode and set sign-extend bit 1701 // Check for 8-bit immediate, and set sign extend bit in opcode 1702 int con = (int)$imm$$constant; // Throw away top bits 1703 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary); 1704 // Emit r/m byte with secondary opcode, after primary opcode. 1705 emit_rm(cbuf, 0x3, $secondary, $dst$$reg); 1706 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con); 1707 else emit_d32(cbuf,con); 1708 %} 1709 1710 enc_class Long_OpcSErm_Hi(eRegL dst, immL imm) %{ 1711 // Emit primary opcode and set sign-extend bit 1712 // Check for 8-bit immediate, and set sign extend bit in opcode 1713 int con = (int)($imm$$constant >> 32); // Throw away bottom bits 1714 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary); 1715 // Emit r/m byte with tertiary opcode, after primary opcode. 1716 emit_rm(cbuf, 0x3, $tertiary, HIGH_FROM_LOW($dst$$reg)); 1717 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con); 1718 else emit_d32(cbuf,con); 1719 %} 1720 1721 enc_class OpcSReg (eRegI dst) %{ // BSWAP 1722 emit_cc(cbuf, $secondary, $dst$$reg ); 1723 %} 1724 1725 enc_class bswap_long_bytes(eRegL dst) %{ // BSWAP 1726 int destlo = $dst$$reg; 1727 int desthi = HIGH_FROM_LOW(destlo); 1728 // bswap lo 1729 emit_opcode(cbuf, 0x0F); 1730 emit_cc(cbuf, 0xC8, destlo); 1731 // bswap hi 1732 emit_opcode(cbuf, 0x0F); 1733 emit_cc(cbuf, 0xC8, desthi); 1734 // xchg lo and hi 1735 emit_opcode(cbuf, 0x87); 1736 emit_rm(cbuf, 0x3, destlo, desthi); 1737 %} 1738 1739 enc_class RegOpc (eRegI div) %{ // IDIV, IMOD, JMP indirect, ... 1740 emit_rm(cbuf, 0x3, $secondary, $div$$reg ); 1741 %} 1742 1743 enc_class enc_cmov(cmpOp cop ) %{ // CMOV 1744 $$$emit8$primary; 1745 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1746 %} 1747 1748 enc_class enc_cmov_d(cmpOp cop, regD src ) %{ // CMOV 1749 int op = 0xDA00 + $cop$$cmpcode + ($src$$reg-1); 1750 emit_d8(cbuf, op >> 8 ); 1751 emit_d8(cbuf, op & 255); 1752 %} 1753 1754 // emulate a CMOV with a conditional branch around a MOV 1755 enc_class enc_cmov_branch( cmpOp cop, immI brOffs ) %{ // CMOV 1756 // Invert sense of branch from sense of CMOV 1757 emit_cc( cbuf, 0x70, ($cop$$cmpcode^1) ); 1758 emit_d8( cbuf, $brOffs$$constant ); 1759 %} 1760 1761 enc_class enc_PartialSubtypeCheck( ) %{ 1762 Register Redi = as_Register(EDI_enc); // result register 1763 Register Reax = as_Register(EAX_enc); // super class 1764 Register Recx = as_Register(ECX_enc); // killed 1765 Register Resi = as_Register(ESI_enc); // sub class 1766 Label miss; 1767 1768 MacroAssembler _masm(&cbuf); 1769 __ check_klass_subtype_slow_path(Resi, Reax, Recx, Redi, 1770 NULL, &miss, 1771 /*set_cond_codes:*/ true); 1772 if ($primary) { 1773 __ xorptr(Redi, Redi); 1774 } 1775 __ bind(miss); 1776 %} 1777 1778 enc_class FFree_Float_Stack_All %{ // Free_Float_Stack_All 1779 MacroAssembler masm(&cbuf); 1780 int start = masm.offset(); 1781 if (UseSSE >= 2) { 1782 if (VerifyFPU) { 1783 masm.verify_FPU(0, "must be empty in SSE2+ mode"); 1784 } 1785 } else { 1786 // External c_calling_convention expects the FPU stack to be 'clean'. 1787 // Compiled code leaves it dirty. Do cleanup now. 1788 masm.empty_FPU_stack(); 1789 } 1790 if (sizeof_FFree_Float_Stack_All == -1) { 1791 sizeof_FFree_Float_Stack_All = masm.offset() - start; 1792 } else { 1793 assert(masm.offset() - start == sizeof_FFree_Float_Stack_All, "wrong size"); 1794 } 1795 %} 1796 1797 enc_class Verify_FPU_For_Leaf %{ 1798 if( VerifyFPU ) { 1799 MacroAssembler masm(&cbuf); 1800 masm.verify_FPU( -3, "Returning from Runtime Leaf call"); 1801 } 1802 %} 1803 1804 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf 1805 // This is the instruction starting address for relocation info. 1806 cbuf.set_insts_mark(); 1807 $$$emit8$primary; 1808 // CALL directly to the runtime 1809 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4), 1810 runtime_call_Relocation::spec(), RELOC_IMM32 ); 1811 1812 if (UseSSE >= 2) { 1813 MacroAssembler _masm(&cbuf); 1814 BasicType rt = tf()->return_type(); 1815 1816 if ((rt == T_FLOAT || rt == T_DOUBLE) && !return_value_is_used()) { 1817 // A C runtime call where the return value is unused. In SSE2+ 1818 // mode the result needs to be removed from the FPU stack. It's 1819 // likely that this function call could be removed by the 1820 // optimizer if the C function is a pure function. 1821 __ ffree(0); 1822 } else if (rt == T_FLOAT) { 1823 __ lea(rsp, Address(rsp, -4)); 1824 __ fstp_s(Address(rsp, 0)); 1825 __ movflt(xmm0, Address(rsp, 0)); 1826 __ lea(rsp, Address(rsp, 4)); 1827 } else if (rt == T_DOUBLE) { 1828 __ lea(rsp, Address(rsp, -8)); 1829 __ fstp_d(Address(rsp, 0)); 1830 __ movdbl(xmm0, Address(rsp, 0)); 1831 __ lea(rsp, Address(rsp, 8)); 1832 } 1833 } 1834 %} 1835 1836 1837 enc_class pre_call_FPU %{ 1838 // If method sets FPU control word restore it here 1839 debug_only(int off0 = cbuf.insts_size()); 1840 if( Compile::current()->in_24_bit_fp_mode() ) { 1841 MacroAssembler masm(&cbuf); 1842 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); 1843 } 1844 debug_only(int off1 = cbuf.insts_size()); 1845 assert(off1 - off0 == pre_call_FPU_size(), "correct size prediction"); 1846 %} 1847 1848 enc_class post_call_FPU %{ 1849 // If method sets FPU control word do it here also 1850 if( Compile::current()->in_24_bit_fp_mode() ) { 1851 MacroAssembler masm(&cbuf); 1852 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24())); 1853 } 1854 %} 1855 1856 enc_class preserve_SP %{ 1857 debug_only(int off0 = cbuf.insts_size()); 1858 MacroAssembler _masm(&cbuf); 1859 // RBP is preserved across all calls, even compiled calls. 1860 // Use it to preserve RSP in places where the callee might change the SP. 1861 __ movptr(rbp_mh_SP_save, rsp); 1862 debug_only(int off1 = cbuf.insts_size()); 1863 assert(off1 - off0 == preserve_SP_size(), "correct size prediction"); 1864 %} 1865 1866 enc_class restore_SP %{ 1867 MacroAssembler _masm(&cbuf); 1868 __ movptr(rsp, rbp_mh_SP_save); 1869 %} 1870 1871 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL 1872 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 1873 // who we intended to call. 1874 cbuf.set_insts_mark(); 1875 $$$emit8$primary; 1876 if ( !_method ) { 1877 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4), 1878 runtime_call_Relocation::spec(), RELOC_IMM32 ); 1879 } else if(_optimized_virtual) { 1880 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4), 1881 opt_virtual_call_Relocation::spec(), RELOC_IMM32 ); 1882 } else { 1883 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4), 1884 static_call_Relocation::spec(), RELOC_IMM32 ); 1885 } 1886 if( _method ) { // Emit stub for static call 1887 emit_java_to_interp(cbuf); 1888 } 1889 %} 1890 1891 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL 1892 // !!!!! 1893 // Generate "Mov EAX,0x00", placeholder instruction to load oop-info 1894 // emit_call_dynamic_prologue( cbuf ); 1895 cbuf.set_insts_mark(); 1896 emit_opcode(cbuf, 0xB8 + EAX_enc); // mov EAX,-1 1897 emit_d32_reloc(cbuf, (int)Universe::non_oop_word(), oop_Relocation::spec_for_immediate(), RELOC_IMM32); 1898 address virtual_call_oop_addr = cbuf.insts_mark(); 1899 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 1900 // who we intended to call. 1901 cbuf.set_insts_mark(); 1902 $$$emit8$primary; 1903 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4), 1904 virtual_call_Relocation::spec(virtual_call_oop_addr), RELOC_IMM32 ); 1905 %} 1906 1907 enc_class Java_Compiled_Call (method meth) %{ // JAVA COMPILED CALL 1908 int disp = in_bytes(methodOopDesc::from_compiled_offset()); 1909 assert( -128 <= disp && disp <= 127, "compiled_code_offset isn't small"); 1910 1911 // CALL *[EAX+in_bytes(methodOopDesc::from_compiled_code_entry_point_offset())] 1912 cbuf.set_insts_mark(); 1913 $$$emit8$primary; 1914 emit_rm(cbuf, 0x01, $secondary, EAX_enc ); // R/M byte 1915 emit_d8(cbuf, disp); // Displacement 1916 1917 %} 1918 1919 enc_class Xor_Reg (eRegI dst) %{ 1920 emit_opcode(cbuf, 0x33); 1921 emit_rm(cbuf, 0x3, $dst$$reg, $dst$$reg); 1922 %} 1923 1924// Following encoding is no longer used, but may be restored if calling 1925// convention changes significantly. 1926// Became: Xor_Reg(EBP), Java_To_Runtime( labl ) 1927// 1928// enc_class Java_Interpreter_Call (label labl) %{ // JAVA INTERPRETER CALL 1929// // int ic_reg = Matcher::inline_cache_reg(); 1930// // int ic_encode = Matcher::_regEncode[ic_reg]; 1931// // int imo_reg = Matcher::interpreter_method_oop_reg(); 1932// // int imo_encode = Matcher::_regEncode[imo_reg]; 1933// 1934// // // Interpreter expects method_oop in EBX, currently a callee-saved register, 1935// // // so we load it immediately before the call 1936// // emit_opcode(cbuf, 0x8B); // MOV imo_reg,ic_reg # method_oop 1937// // emit_rm(cbuf, 0x03, imo_encode, ic_encode ); // R/M byte 1938// 1939// // xor rbp,ebp 1940// emit_opcode(cbuf, 0x33); 1941// emit_rm(cbuf, 0x3, EBP_enc, EBP_enc); 1942// 1943// // CALL to interpreter. 1944// cbuf.set_insts_mark(); 1945// $$$emit8$primary; 1946// emit_d32_reloc(cbuf, ($labl$$label - (int)(cbuf.insts_end()) - 4), 1947// runtime_call_Relocation::spec(), RELOC_IMM32 ); 1948// %} 1949 1950 enc_class RegOpcImm (eRegI dst, immI8 shift) %{ // SHL, SAR, SHR 1951 $$$emit8$primary; 1952 emit_rm(cbuf, 0x3, $secondary, $dst$$reg); 1953 $$$emit8$shift$$constant; 1954 %} 1955 1956 enc_class LdImmI (eRegI dst, immI src) %{ // Load Immediate 1957 // Load immediate does not have a zero or sign extended version 1958 // for 8-bit immediates 1959 emit_opcode(cbuf, 0xB8 + $dst$$reg); 1960 $$$emit32$src$$constant; 1961 %} 1962 1963 enc_class LdImmP (eRegI dst, immI src) %{ // Load Immediate 1964 // Load immediate does not have a zero or sign extended version 1965 // for 8-bit immediates 1966 emit_opcode(cbuf, $primary + $dst$$reg); 1967 $$$emit32$src$$constant; 1968 %} 1969 1970 enc_class LdImmL_Lo( eRegL dst, immL src) %{ // Load Immediate 1971 // Load immediate does not have a zero or sign extended version 1972 // for 8-bit immediates 1973 int dst_enc = $dst$$reg; 1974 int src_con = $src$$constant & 0x0FFFFFFFFL; 1975 if (src_con == 0) { 1976 // xor dst, dst 1977 emit_opcode(cbuf, 0x33); 1978 emit_rm(cbuf, 0x3, dst_enc, dst_enc); 1979 } else { 1980 emit_opcode(cbuf, $primary + dst_enc); 1981 emit_d32(cbuf, src_con); 1982 } 1983 %} 1984 1985 enc_class LdImmL_Hi( eRegL dst, immL src) %{ // Load Immediate 1986 // Load immediate does not have a zero or sign extended version 1987 // for 8-bit immediates 1988 int dst_enc = $dst$$reg + 2; 1989 int src_con = ((julong)($src$$constant)) >> 32; 1990 if (src_con == 0) { 1991 // xor dst, dst 1992 emit_opcode(cbuf, 0x33); 1993 emit_rm(cbuf, 0x3, dst_enc, dst_enc); 1994 } else { 1995 emit_opcode(cbuf, $primary + dst_enc); 1996 emit_d32(cbuf, src_con); 1997 } 1998 %} 1999 2000 2001 enc_class MovI2X_reg(regX dst, eRegI src) %{ 2002 emit_opcode(cbuf, 0x66 ); // MOVD dst,src 2003 emit_opcode(cbuf, 0x0F ); 2004 emit_opcode(cbuf, 0x6E ); 2005 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2006 %} 2007 2008 enc_class MovX2I_reg(eRegI dst, regX src) %{ 2009 emit_opcode(cbuf, 0x66 ); // MOVD dst,src 2010 emit_opcode(cbuf, 0x0F ); 2011 emit_opcode(cbuf, 0x7E ); 2012 emit_rm(cbuf, 0x3, $src$$reg, $dst$$reg); 2013 %} 2014 2015 enc_class MovL2XD_reg(regXD dst, eRegL src, regXD tmp) %{ 2016 { // MOVD $dst,$src.lo 2017 emit_opcode(cbuf,0x66); 2018 emit_opcode(cbuf,0x0F); 2019 emit_opcode(cbuf,0x6E); 2020 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2021 } 2022 { // MOVD $tmp,$src.hi 2023 emit_opcode(cbuf,0x66); 2024 emit_opcode(cbuf,0x0F); 2025 emit_opcode(cbuf,0x6E); 2026 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg)); 2027 } 2028 { // PUNPCKLDQ $dst,$tmp 2029 emit_opcode(cbuf,0x66); 2030 emit_opcode(cbuf,0x0F); 2031 emit_opcode(cbuf,0x62); 2032 emit_rm(cbuf, 0x3, $dst$$reg, $tmp$$reg); 2033 } 2034 %} 2035 2036 enc_class MovXD2L_reg(eRegL dst, regXD src, regXD tmp) %{ 2037 { // MOVD $dst.lo,$src 2038 emit_opcode(cbuf,0x66); 2039 emit_opcode(cbuf,0x0F); 2040 emit_opcode(cbuf,0x7E); 2041 emit_rm(cbuf, 0x3, $src$$reg, $dst$$reg); 2042 } 2043 { // PSHUFLW $tmp,$src,0x4E (01001110b) 2044 emit_opcode(cbuf,0xF2); 2045 emit_opcode(cbuf,0x0F); 2046 emit_opcode(cbuf,0x70); 2047 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg); 2048 emit_d8(cbuf, 0x4E); 2049 } 2050 { // MOVD $dst.hi,$tmp 2051 emit_opcode(cbuf,0x66); 2052 emit_opcode(cbuf,0x0F); 2053 emit_opcode(cbuf,0x7E); 2054 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg)); 2055 } 2056 %} 2057 2058 2059 // Encode a reg-reg copy. If it is useless, then empty encoding. 2060 enc_class enc_Copy( eRegI dst, eRegI src ) %{ 2061 encode_Copy( cbuf, $dst$$reg, $src$$reg ); 2062 %} 2063 2064 enc_class enc_CopyL_Lo( eRegI dst, eRegL src ) %{ 2065 encode_Copy( cbuf, $dst$$reg, $src$$reg ); 2066 %} 2067 2068 // Encode xmm reg-reg copy. If it is useless, then empty encoding. 2069 enc_class enc_CopyXD( RegXD dst, RegXD src ) %{ 2070 encode_CopyXD( cbuf, $dst$$reg, $src$$reg ); 2071 %} 2072 2073 enc_class RegReg (eRegI dst, eRegI src) %{ // RegReg(Many) 2074 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2075 %} 2076 2077 enc_class RegReg_Lo(eRegL dst, eRegL src) %{ // RegReg(Many) 2078 $$$emit8$primary; 2079 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2080 %} 2081 2082 enc_class RegReg_Hi(eRegL dst, eRegL src) %{ // RegReg(Many) 2083 $$$emit8$secondary; 2084 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg)); 2085 %} 2086 2087 enc_class RegReg_Lo2(eRegL dst, eRegL src) %{ // RegReg(Many) 2088 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2089 %} 2090 2091 enc_class RegReg_Hi2(eRegL dst, eRegL src) %{ // RegReg(Many) 2092 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg)); 2093 %} 2094 2095 enc_class RegReg_HiLo( eRegL src, eRegI dst ) %{ 2096 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($src$$reg)); 2097 %} 2098 2099 enc_class Con32 (immI src) %{ // Con32(storeImmI) 2100 // Output immediate 2101 $$$emit32$src$$constant; 2102 %} 2103 2104 enc_class Con32F_as_bits(immF src) %{ // storeF_imm 2105 // Output Float immediate bits 2106 jfloat jf = $src$$constant; 2107 int jf_as_bits = jint_cast( jf ); 2108 emit_d32(cbuf, jf_as_bits); 2109 %} 2110 2111 enc_class Con32XF_as_bits(immXF src) %{ // storeX_imm 2112 // Output Float immediate bits 2113 jfloat jf = $src$$constant; 2114 int jf_as_bits = jint_cast( jf ); 2115 emit_d32(cbuf, jf_as_bits); 2116 %} 2117 2118 enc_class Con16 (immI src) %{ // Con16(storeImmI) 2119 // Output immediate 2120 $$$emit16$src$$constant; 2121 %} 2122 2123 enc_class Con_d32(immI src) %{ 2124 emit_d32(cbuf,$src$$constant); 2125 %} 2126 2127 enc_class conmemref (eRegP t1) %{ // Con32(storeImmI) 2128 // Output immediate memory reference 2129 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2130 emit_d32(cbuf, 0x00); 2131 %} 2132 2133 enc_class lock_prefix( ) %{ 2134 if( os::is_MP() ) 2135 emit_opcode(cbuf,0xF0); // [Lock] 2136 %} 2137 2138 // Cmp-xchg long value. 2139 // Note: we need to swap rbx, and rcx before and after the 2140 // cmpxchg8 instruction because the instruction uses 2141 // rcx as the high order word of the new value to store but 2142 // our register encoding uses rbx,. 2143 enc_class enc_cmpxchg8(eSIRegP mem_ptr) %{ 2144 2145 // XCHG rbx,ecx 2146 emit_opcode(cbuf,0x87); 2147 emit_opcode(cbuf,0xD9); 2148 // [Lock] 2149 if( os::is_MP() ) 2150 emit_opcode(cbuf,0xF0); 2151 // CMPXCHG8 [Eptr] 2152 emit_opcode(cbuf,0x0F); 2153 emit_opcode(cbuf,0xC7); 2154 emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg ); 2155 // XCHG rbx,ecx 2156 emit_opcode(cbuf,0x87); 2157 emit_opcode(cbuf,0xD9); 2158 %} 2159 2160 enc_class enc_cmpxchg(eSIRegP mem_ptr) %{ 2161 // [Lock] 2162 if( os::is_MP() ) 2163 emit_opcode(cbuf,0xF0); 2164 2165 // CMPXCHG [Eptr] 2166 emit_opcode(cbuf,0x0F); 2167 emit_opcode(cbuf,0xB1); 2168 emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg ); 2169 %} 2170 2171 enc_class enc_flags_ne_to_boolean( iRegI res ) %{ 2172 int res_encoding = $res$$reg; 2173 2174 // MOV res,0 2175 emit_opcode( cbuf, 0xB8 + res_encoding); 2176 emit_d32( cbuf, 0 ); 2177 // JNE,s fail 2178 emit_opcode(cbuf,0x75); 2179 emit_d8(cbuf, 5 ); 2180 // MOV res,1 2181 emit_opcode( cbuf, 0xB8 + res_encoding); 2182 emit_d32( cbuf, 1 ); 2183 // fail: 2184 %} 2185 2186 enc_class set_instruction_start( ) %{ 2187 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand 2188 %} 2189 2190 enc_class RegMem (eRegI ereg, memory mem) %{ // emit_reg_mem 2191 int reg_encoding = $ereg$$reg; 2192 int base = $mem$$base; 2193 int index = $mem$$index; 2194 int scale = $mem$$scale; 2195 int displace = $mem$$disp; 2196 bool disp_is_oop = $mem->disp_is_oop(); 2197 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop); 2198 %} 2199 2200 enc_class RegMem_Hi(eRegL ereg, memory mem) %{ // emit_reg_mem 2201 int reg_encoding = HIGH_FROM_LOW($ereg$$reg); // Hi register of pair, computed from lo 2202 int base = $mem$$base; 2203 int index = $mem$$index; 2204 int scale = $mem$$scale; 2205 int displace = $mem$$disp + 4; // Offset is 4 further in memory 2206 assert( !$mem->disp_is_oop(), "Cannot add 4 to oop" ); 2207 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, false/*disp_is_oop*/); 2208 %} 2209 2210 enc_class move_long_small_shift( eRegL dst, immI_1_31 cnt ) %{ 2211 int r1, r2; 2212 if( $tertiary == 0xA4 ) { r1 = $dst$$reg; r2 = HIGH_FROM_LOW($dst$$reg); } 2213 else { r2 = $dst$$reg; r1 = HIGH_FROM_LOW($dst$$reg); } 2214 emit_opcode(cbuf,0x0F); 2215 emit_opcode(cbuf,$tertiary); 2216 emit_rm(cbuf, 0x3, r1, r2); 2217 emit_d8(cbuf,$cnt$$constant); 2218 emit_d8(cbuf,$primary); 2219 emit_rm(cbuf, 0x3, $secondary, r1); 2220 emit_d8(cbuf,$cnt$$constant); 2221 %} 2222 2223 enc_class move_long_big_shift_sign( eRegL dst, immI_32_63 cnt ) %{ 2224 emit_opcode( cbuf, 0x8B ); // Move 2225 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg)); 2226 if( $cnt$$constant > 32 ) { // Shift, if not by zero 2227 emit_d8(cbuf,$primary); 2228 emit_rm(cbuf, 0x3, $secondary, $dst$$reg); 2229 emit_d8(cbuf,$cnt$$constant-32); 2230 } 2231 emit_d8(cbuf,$primary); 2232 emit_rm(cbuf, 0x3, $secondary, HIGH_FROM_LOW($dst$$reg)); 2233 emit_d8(cbuf,31); 2234 %} 2235 2236 enc_class move_long_big_shift_clr( eRegL dst, immI_32_63 cnt ) %{ 2237 int r1, r2; 2238 if( $secondary == 0x5 ) { r1 = $dst$$reg; r2 = HIGH_FROM_LOW($dst$$reg); } 2239 else { r2 = $dst$$reg; r1 = HIGH_FROM_LOW($dst$$reg); } 2240 2241 emit_opcode( cbuf, 0x8B ); // Move r1,r2 2242 emit_rm(cbuf, 0x3, r1, r2); 2243 if( $cnt$$constant > 32 ) { // Shift, if not by zero 2244 emit_opcode(cbuf,$primary); 2245 emit_rm(cbuf, 0x3, $secondary, r1); 2246 emit_d8(cbuf,$cnt$$constant-32); 2247 } 2248 emit_opcode(cbuf,0x33); // XOR r2,r2 2249 emit_rm(cbuf, 0x3, r2, r2); 2250 %} 2251 2252 // Clone of RegMem but accepts an extra parameter to access each 2253 // half of a double in memory; it never needs relocation info. 2254 enc_class Mov_MemD_half_to_Reg (immI opcode, memory mem, immI disp_for_half, eRegI rm_reg) %{ 2255 emit_opcode(cbuf,$opcode$$constant); 2256 int reg_encoding = $rm_reg$$reg; 2257 int base = $mem$$base; 2258 int index = $mem$$index; 2259 int scale = $mem$$scale; 2260 int displace = $mem$$disp + $disp_for_half$$constant; 2261 bool disp_is_oop = false; 2262 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop); 2263 %} 2264 2265 // !!!!! Special Custom Code used by MemMove, and stack access instructions !!!!! 2266 // 2267 // Clone of RegMem except the RM-byte's reg/opcode field is an ADLC-time constant 2268 // and it never needs relocation information. 2269 // Frequently used to move data between FPU's Stack Top and memory. 2270 enc_class RMopc_Mem_no_oop (immI rm_opcode, memory mem) %{ 2271 int rm_byte_opcode = $rm_opcode$$constant; 2272 int base = $mem$$base; 2273 int index = $mem$$index; 2274 int scale = $mem$$scale; 2275 int displace = $mem$$disp; 2276 assert( !$mem->disp_is_oop(), "No oops here because no relo info allowed" ); 2277 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, false); 2278 %} 2279 2280 enc_class RMopc_Mem (immI rm_opcode, memory mem) %{ 2281 int rm_byte_opcode = $rm_opcode$$constant; 2282 int base = $mem$$base; 2283 int index = $mem$$index; 2284 int scale = $mem$$scale; 2285 int displace = $mem$$disp; 2286 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals 2287 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop); 2288 %} 2289 2290 enc_class RegLea (eRegI dst, eRegI src0, immI src1 ) %{ // emit_reg_lea 2291 int reg_encoding = $dst$$reg; 2292 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2293 int index = 0x04; // 0x04 indicates no index 2294 int scale = 0x00; // 0x00 indicates no scale 2295 int displace = $src1$$constant; // 0x00 indicates no displacement 2296 bool disp_is_oop = false; 2297 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop); 2298 %} 2299 2300 enc_class min_enc (eRegI dst, eRegI src) %{ // MIN 2301 // Compare dst,src 2302 emit_opcode(cbuf,0x3B); 2303 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2304 // jmp dst < src around move 2305 emit_opcode(cbuf,0x7C); 2306 emit_d8(cbuf,2); 2307 // move dst,src 2308 emit_opcode(cbuf,0x8B); 2309 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2310 %} 2311 2312 enc_class max_enc (eRegI dst, eRegI src) %{ // MAX 2313 // Compare dst,src 2314 emit_opcode(cbuf,0x3B); 2315 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2316 // jmp dst > src around move 2317 emit_opcode(cbuf,0x7F); 2318 emit_d8(cbuf,2); 2319 // move dst,src 2320 emit_opcode(cbuf,0x8B); 2321 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2322 %} 2323 2324 enc_class enc_FP_store(memory mem, regD src) %{ 2325 // If src is FPR1, we can just FST to store it. 2326 // Else we need to FLD it to FPR1, then FSTP to store/pop it. 2327 int reg_encoding = 0x2; // Just store 2328 int base = $mem$$base; 2329 int index = $mem$$index; 2330 int scale = $mem$$scale; 2331 int displace = $mem$$disp; 2332 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals 2333 if( $src$$reg != FPR1L_enc ) { 2334 reg_encoding = 0x3; // Store & pop 2335 emit_opcode( cbuf, 0xD9 ); // FLD (i.e., push it) 2336 emit_d8( cbuf, 0xC0-1+$src$$reg ); 2337 } 2338 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand 2339 emit_opcode(cbuf,$primary); 2340 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop); 2341 %} 2342 2343 enc_class neg_reg(eRegI dst) %{ 2344 // NEG $dst 2345 emit_opcode(cbuf,0xF7); 2346 emit_rm(cbuf, 0x3, 0x03, $dst$$reg ); 2347 %} 2348 2349 enc_class setLT_reg(eCXRegI dst) %{ 2350 // SETLT $dst 2351 emit_opcode(cbuf,0x0F); 2352 emit_opcode(cbuf,0x9C); 2353 emit_rm( cbuf, 0x3, 0x4, $dst$$reg ); 2354 %} 2355 2356 enc_class enc_cmpLTP(ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp) %{ // cadd_cmpLT 2357 int tmpReg = $tmp$$reg; 2358 2359 // SUB $p,$q 2360 emit_opcode(cbuf,0x2B); 2361 emit_rm(cbuf, 0x3, $p$$reg, $q$$reg); 2362 // SBB $tmp,$tmp 2363 emit_opcode(cbuf,0x1B); 2364 emit_rm(cbuf, 0x3, tmpReg, tmpReg); 2365 // AND $tmp,$y 2366 emit_opcode(cbuf,0x23); 2367 emit_rm(cbuf, 0x3, tmpReg, $y$$reg); 2368 // ADD $p,$tmp 2369 emit_opcode(cbuf,0x03); 2370 emit_rm(cbuf, 0x3, $p$$reg, tmpReg); 2371 %} 2372 2373 enc_class enc_cmpLTP_mem(eRegI p, eRegI q, memory mem, eCXRegI tmp) %{ // cadd_cmpLT 2374 int tmpReg = $tmp$$reg; 2375 2376 // SUB $p,$q 2377 emit_opcode(cbuf,0x2B); 2378 emit_rm(cbuf, 0x3, $p$$reg, $q$$reg); 2379 // SBB $tmp,$tmp 2380 emit_opcode(cbuf,0x1B); 2381 emit_rm(cbuf, 0x3, tmpReg, tmpReg); 2382 // AND $tmp,$y 2383 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand 2384 emit_opcode(cbuf,0x23); 2385 int reg_encoding = tmpReg; 2386 int base = $mem$$base; 2387 int index = $mem$$index; 2388 int scale = $mem$$scale; 2389 int displace = $mem$$disp; 2390 bool disp_is_oop = $mem->disp_is_oop(); 2391 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop); 2392 // ADD $p,$tmp 2393 emit_opcode(cbuf,0x03); 2394 emit_rm(cbuf, 0x3, $p$$reg, tmpReg); 2395 %} 2396 2397 enc_class shift_left_long( eRegL dst, eCXRegI shift ) %{ 2398 // TEST shift,32 2399 emit_opcode(cbuf,0xF7); 2400 emit_rm(cbuf, 0x3, 0, ECX_enc); 2401 emit_d32(cbuf,0x20); 2402 // JEQ,s small 2403 emit_opcode(cbuf, 0x74); 2404 emit_d8(cbuf, 0x04); 2405 // MOV $dst.hi,$dst.lo 2406 emit_opcode( cbuf, 0x8B ); 2407 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg ); 2408 // CLR $dst.lo 2409 emit_opcode(cbuf, 0x33); 2410 emit_rm(cbuf, 0x3, $dst$$reg, $dst$$reg); 2411// small: 2412 // SHLD $dst.hi,$dst.lo,$shift 2413 emit_opcode(cbuf,0x0F); 2414 emit_opcode(cbuf,0xA5); 2415 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg)); 2416 // SHL $dst.lo,$shift" 2417 emit_opcode(cbuf,0xD3); 2418 emit_rm(cbuf, 0x3, 0x4, $dst$$reg ); 2419 %} 2420 2421 enc_class shift_right_long( eRegL dst, eCXRegI shift ) %{ 2422 // TEST shift,32 2423 emit_opcode(cbuf,0xF7); 2424 emit_rm(cbuf, 0x3, 0, ECX_enc); 2425 emit_d32(cbuf,0x20); 2426 // JEQ,s small 2427 emit_opcode(cbuf, 0x74); 2428 emit_d8(cbuf, 0x04); 2429 // MOV $dst.lo,$dst.hi 2430 emit_opcode( cbuf, 0x8B ); 2431 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg) ); 2432 // CLR $dst.hi 2433 emit_opcode(cbuf, 0x33); 2434 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($dst$$reg)); 2435// small: 2436 // SHRD $dst.lo,$dst.hi,$shift 2437 emit_opcode(cbuf,0x0F); 2438 emit_opcode(cbuf,0xAD); 2439 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg); 2440 // SHR $dst.hi,$shift" 2441 emit_opcode(cbuf,0xD3); 2442 emit_rm(cbuf, 0x3, 0x5, HIGH_FROM_LOW($dst$$reg) ); 2443 %} 2444 2445 enc_class shift_right_arith_long( eRegL dst, eCXRegI shift ) %{ 2446 // TEST shift,32 2447 emit_opcode(cbuf,0xF7); 2448 emit_rm(cbuf, 0x3, 0, ECX_enc); 2449 emit_d32(cbuf,0x20); 2450 // JEQ,s small 2451 emit_opcode(cbuf, 0x74); 2452 emit_d8(cbuf, 0x05); 2453 // MOV $dst.lo,$dst.hi 2454 emit_opcode( cbuf, 0x8B ); 2455 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg) ); 2456 // SAR $dst.hi,31 2457 emit_opcode(cbuf, 0xC1); 2458 emit_rm(cbuf, 0x3, 7, HIGH_FROM_LOW($dst$$reg) ); 2459 emit_d8(cbuf, 0x1F ); 2460// small: 2461 // SHRD $dst.lo,$dst.hi,$shift 2462 emit_opcode(cbuf,0x0F); 2463 emit_opcode(cbuf,0xAD); 2464 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg); 2465 // SAR $dst.hi,$shift" 2466 emit_opcode(cbuf,0xD3); 2467 emit_rm(cbuf, 0x3, 0x7, HIGH_FROM_LOW($dst$$reg) ); 2468 %} 2469 2470 2471 // ----------------- Encodings for floating point unit ----------------- 2472 // May leave result in FPU-TOS or FPU reg depending on opcodes 2473 enc_class OpcReg_F (regF src) %{ // FMUL, FDIV 2474 $$$emit8$primary; 2475 emit_rm(cbuf, 0x3, $secondary, $src$$reg ); 2476 %} 2477 2478 // Pop argument in FPR0 with FSTP ST(0) 2479 enc_class PopFPU() %{ 2480 emit_opcode( cbuf, 0xDD ); 2481 emit_d8( cbuf, 0xD8 ); 2482 %} 2483 2484 // !!!!! equivalent to Pop_Reg_F 2485 enc_class Pop_Reg_D( regD dst ) %{ 2486 emit_opcode( cbuf, 0xDD ); // FSTP ST(i) 2487 emit_d8( cbuf, 0xD8+$dst$$reg ); 2488 %} 2489 2490 enc_class Push_Reg_D( regD dst ) %{ 2491 emit_opcode( cbuf, 0xD9 ); 2492 emit_d8( cbuf, 0xC0-1+$dst$$reg ); // FLD ST(i-1) 2493 %} 2494 2495 enc_class strictfp_bias1( regD dst ) %{ 2496 emit_opcode( cbuf, 0xDB ); // FLD m80real 2497 emit_opcode( cbuf, 0x2D ); 2498 emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias1() ); 2499 emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0 2500 emit_opcode( cbuf, 0xC8+$dst$$reg ); 2501 %} 2502 2503 enc_class strictfp_bias2( regD dst ) %{ 2504 emit_opcode( cbuf, 0xDB ); // FLD m80real 2505 emit_opcode( cbuf, 0x2D ); 2506 emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias2() ); 2507 emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0 2508 emit_opcode( cbuf, 0xC8+$dst$$reg ); 2509 %} 2510 2511 // Special case for moving an integer register to a stack slot. 2512 enc_class OpcPRegSS( stackSlotI dst, eRegI src ) %{ // RegSS 2513 store_to_stackslot( cbuf, $primary, $src$$reg, $dst$$disp ); 2514 %} 2515 2516 // Special case for moving a register to a stack slot. 2517 enc_class RegSS( stackSlotI dst, eRegI src ) %{ // RegSS 2518 // Opcode already emitted 2519 emit_rm( cbuf, 0x02, $src$$reg, ESP_enc ); // R/M byte 2520 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte 2521 emit_d32(cbuf, $dst$$disp); // Displacement 2522 %} 2523 2524 // Push the integer in stackSlot 'src' onto FP-stack 2525 enc_class Push_Mem_I( memory src ) %{ // FILD [ESP+src] 2526 store_to_stackslot( cbuf, $primary, $secondary, $src$$disp ); 2527 %} 2528 2529 // Push the float in stackSlot 'src' onto FP-stack 2530 enc_class Push_Mem_F( memory src ) %{ // FLD_S [ESP+src] 2531 store_to_stackslot( cbuf, 0xD9, 0x00, $src$$disp ); 2532 %} 2533 2534 // Push the double in stackSlot 'src' onto FP-stack 2535 enc_class Push_Mem_D( memory src ) %{ // FLD_D [ESP+src] 2536 store_to_stackslot( cbuf, 0xDD, 0x00, $src$$disp ); 2537 %} 2538 2539 // Push FPU's TOS float to a stack-slot, and pop FPU-stack 2540 enc_class Pop_Mem_F( stackSlotF dst ) %{ // FSTP_S [ESP+dst] 2541 store_to_stackslot( cbuf, 0xD9, 0x03, $dst$$disp ); 2542 %} 2543 2544 // Same as Pop_Mem_F except for opcode 2545 // Push FPU's TOS double to a stack-slot, and pop FPU-stack 2546 enc_class Pop_Mem_D( stackSlotD dst ) %{ // FSTP_D [ESP+dst] 2547 store_to_stackslot( cbuf, 0xDD, 0x03, $dst$$disp ); 2548 %} 2549 2550 enc_class Pop_Reg_F( regF dst ) %{ 2551 emit_opcode( cbuf, 0xDD ); // FSTP ST(i) 2552 emit_d8( cbuf, 0xD8+$dst$$reg ); 2553 %} 2554 2555 enc_class Push_Reg_F( regF dst ) %{ 2556 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1) 2557 emit_d8( cbuf, 0xC0-1+$dst$$reg ); 2558 %} 2559 2560 // Push FPU's float to a stack-slot, and pop FPU-stack 2561 enc_class Pop_Mem_Reg_F( stackSlotF dst, regF src ) %{ 2562 int pop = 0x02; 2563 if ($src$$reg != FPR1L_enc) { 2564 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1) 2565 emit_d8( cbuf, 0xC0-1+$src$$reg ); 2566 pop = 0x03; 2567 } 2568 store_to_stackslot( cbuf, 0xD9, pop, $dst$$disp ); // FST<P>_S [ESP+dst] 2569 %} 2570 2571 // Push FPU's double to a stack-slot, and pop FPU-stack 2572 enc_class Pop_Mem_Reg_D( stackSlotD dst, regD src ) %{ 2573 int pop = 0x02; 2574 if ($src$$reg != FPR1L_enc) { 2575 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1) 2576 emit_d8( cbuf, 0xC0-1+$src$$reg ); 2577 pop = 0x03; 2578 } 2579 store_to_stackslot( cbuf, 0xDD, pop, $dst$$disp ); // FST<P>_D [ESP+dst] 2580 %} 2581 2582 // Push FPU's double to a FPU-stack-slot, and pop FPU-stack 2583 enc_class Pop_Reg_Reg_D( regD dst, regF src ) %{ 2584 int pop = 0xD0 - 1; // -1 since we skip FLD 2585 if ($src$$reg != FPR1L_enc) { 2586 emit_opcode( cbuf, 0xD9 ); // FLD ST(src-1) 2587 emit_d8( cbuf, 0xC0-1+$src$$reg ); 2588 pop = 0xD8; 2589 } 2590 emit_opcode( cbuf, 0xDD ); 2591 emit_d8( cbuf, pop+$dst$$reg ); // FST<P> ST(i) 2592 %} 2593 2594 2595 enc_class Mul_Add_F( regF dst, regF src, regF src1, regF src2 ) %{ 2596 MacroAssembler masm(&cbuf); 2597 masm.fld_s( $src1$$reg-1); // nothing at TOS, load TOS from src1.reg 2598 masm.fmul( $src2$$reg+0); // value at TOS 2599 masm.fadd( $src$$reg+0); // value at TOS 2600 masm.fstp_d( $dst$$reg+0); // value at TOS, popped off after store 2601 %} 2602 2603 2604 enc_class Push_Reg_Mod_D( regD dst, regD src) %{ 2605 // load dst in FPR0 2606 emit_opcode( cbuf, 0xD9 ); 2607 emit_d8( cbuf, 0xC0-1+$dst$$reg ); 2608 if ($src$$reg != FPR1L_enc) { 2609 // fincstp 2610 emit_opcode (cbuf, 0xD9); 2611 emit_opcode (cbuf, 0xF7); 2612 // swap src with FPR1: 2613 // FXCH FPR1 with src 2614 emit_opcode(cbuf, 0xD9); 2615 emit_d8(cbuf, 0xC8-1+$src$$reg ); 2616 // fdecstp 2617 emit_opcode (cbuf, 0xD9); 2618 emit_opcode (cbuf, 0xF6); 2619 } 2620 %} 2621 2622 enc_class Push_ModD_encoding( regXD src0, regXD src1) %{ 2623 // Allocate a word 2624 emit_opcode(cbuf,0x83); // SUB ESP,8 2625 emit_opcode(cbuf,0xEC); 2626 emit_d8(cbuf,0x08); 2627 2628 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src1 2629 emit_opcode (cbuf, 0x0F ); 2630 emit_opcode (cbuf, 0x11 ); 2631 encode_RegMem(cbuf, $src1$$reg, ESP_enc, 0x4, 0, 0, false); 2632 2633 emit_opcode(cbuf,0xDD ); // FLD_D [ESP] 2634 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 2635 2636 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src0 2637 emit_opcode (cbuf, 0x0F ); 2638 emit_opcode (cbuf, 0x11 ); 2639 encode_RegMem(cbuf, $src0$$reg, ESP_enc, 0x4, 0, 0, false); 2640 2641 emit_opcode(cbuf,0xDD ); // FLD_D [ESP] 2642 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 2643 2644 %} 2645 2646 enc_class Push_ModX_encoding( regX src0, regX src1) %{ 2647 // Allocate a word 2648 emit_opcode(cbuf,0x83); // SUB ESP,4 2649 emit_opcode(cbuf,0xEC); 2650 emit_d8(cbuf,0x04); 2651 2652 emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src1 2653 emit_opcode (cbuf, 0x0F ); 2654 emit_opcode (cbuf, 0x11 ); 2655 encode_RegMem(cbuf, $src1$$reg, ESP_enc, 0x4, 0, 0, false); 2656 2657 emit_opcode(cbuf,0xD9 ); // FLD [ESP] 2658 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 2659 2660 emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src0 2661 emit_opcode (cbuf, 0x0F ); 2662 emit_opcode (cbuf, 0x11 ); 2663 encode_RegMem(cbuf, $src0$$reg, ESP_enc, 0x4, 0, 0, false); 2664 2665 emit_opcode(cbuf,0xD9 ); // FLD [ESP] 2666 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 2667 2668 %} 2669 2670 enc_class Push_ResultXD(regXD dst) %{ 2671 store_to_stackslot( cbuf, 0xDD, 0x03, 0 ); //FSTP [ESP] 2672 2673 // UseXmmLoadAndClearUpper ? movsd dst,[esp] : movlpd dst,[esp] 2674 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 2675 emit_opcode (cbuf, 0x0F ); 2676 emit_opcode (cbuf, UseXmmLoadAndClearUpper ? 0x10 : 0x12); 2677 encode_RegMem(cbuf, $dst$$reg, ESP_enc, 0x4, 0, 0, false); 2678 2679 emit_opcode(cbuf,0x83); // ADD ESP,8 2680 emit_opcode(cbuf,0xC4); 2681 emit_d8(cbuf,0x08); 2682 %} 2683 2684 enc_class Push_ResultX(regX dst, immI d8) %{ 2685 store_to_stackslot( cbuf, 0xD9, 0x03, 0 ); //FSTP_S [ESP] 2686 2687 emit_opcode (cbuf, 0xF3 ); // MOVSS dst(xmm), [ESP] 2688 emit_opcode (cbuf, 0x0F ); 2689 emit_opcode (cbuf, 0x10 ); 2690 encode_RegMem(cbuf, $dst$$reg, ESP_enc, 0x4, 0, 0, false); 2691 2692 emit_opcode(cbuf,0x83); // ADD ESP,d8 (4 or 8) 2693 emit_opcode(cbuf,0xC4); 2694 emit_d8(cbuf,$d8$$constant); 2695 %} 2696 2697 enc_class Push_SrcXD(regXD src) %{ 2698 // Allocate a word 2699 emit_opcode(cbuf,0x83); // SUB ESP,8 2700 emit_opcode(cbuf,0xEC); 2701 emit_d8(cbuf,0x08); 2702 2703 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src 2704 emit_opcode (cbuf, 0x0F ); 2705 emit_opcode (cbuf, 0x11 ); 2706 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false); 2707 2708 emit_opcode(cbuf,0xDD ); // FLD_D [ESP] 2709 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 2710 %} 2711 2712 enc_class push_stack_temp_qword() %{ 2713 emit_opcode(cbuf,0x83); // SUB ESP,8 2714 emit_opcode(cbuf,0xEC); 2715 emit_d8 (cbuf,0x08); 2716 %} 2717 2718 enc_class pop_stack_temp_qword() %{ 2719 emit_opcode(cbuf,0x83); // ADD ESP,8 2720 emit_opcode(cbuf,0xC4); 2721 emit_d8 (cbuf,0x08); 2722 %} 2723 2724 enc_class push_xmm_to_fpr1( regXD xmm_src ) %{ 2725 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], xmm_src 2726 emit_opcode (cbuf, 0x0F ); 2727 emit_opcode (cbuf, 0x11 ); 2728 encode_RegMem(cbuf, $xmm_src$$reg, ESP_enc, 0x4, 0, 0, false); 2729 2730 emit_opcode(cbuf,0xDD ); // FLD_D [ESP] 2731 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 2732 %} 2733 2734 // Compute X^Y using Intel's fast hardware instructions, if possible. 2735 // Otherwise return a NaN. 2736 enc_class pow_exp_core_encoding %{ 2737 // FPR1 holds Y*ln2(X). Compute FPR1 = 2^(Y*ln2(X)) 2738 emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xC0); // fdup = fld st(0) Q Q 2739 emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xFC); // frndint int(Q) Q 2740 emit_opcode(cbuf,0xDC); emit_opcode(cbuf,0xE9); // fsub st(1) -= st(0); int(Q) frac(Q) 2741 emit_opcode(cbuf,0xDB); // FISTP [ESP] frac(Q) 2742 emit_opcode(cbuf,0x1C); 2743 emit_d8(cbuf,0x24); 2744 emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xF0); // f2xm1 2^frac(Q)-1 2745 emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xE8); // fld1 1 2^frac(Q)-1 2746 emit_opcode(cbuf,0xDE); emit_opcode(cbuf,0xC1); // faddp 2^frac(Q) 2747 emit_opcode(cbuf,0x8B); // mov rax,[esp+0]=int(Q) 2748 encode_RegMem(cbuf, EAX_enc, ESP_enc, 0x4, 0, 0, false); 2749 emit_opcode(cbuf,0xC7); // mov rcx,0xFFFFF800 - overflow mask 2750 emit_rm(cbuf, 0x3, 0x0, ECX_enc); 2751 emit_d32(cbuf,0xFFFFF800); 2752 emit_opcode(cbuf,0x81); // add rax,1023 - the double exponent bias 2753 emit_rm(cbuf, 0x3, 0x0, EAX_enc); 2754 emit_d32(cbuf,1023); 2755 emit_opcode(cbuf,0x8B); // mov rbx,eax 2756 emit_rm(cbuf, 0x3, EBX_enc, EAX_enc); 2757 emit_opcode(cbuf,0xC1); // shl rax,20 - Slide to exponent position 2758 emit_rm(cbuf,0x3,0x4,EAX_enc); 2759 emit_d8(cbuf,20); 2760 emit_opcode(cbuf,0x85); // test rbx,ecx - check for overflow 2761 emit_rm(cbuf, 0x3, EBX_enc, ECX_enc); 2762 emit_opcode(cbuf,0x0F); emit_opcode(cbuf,0x45); // CMOVne rax,ecx - overflow; stuff NAN into EAX 2763 emit_rm(cbuf, 0x3, EAX_enc, ECX_enc); 2764 emit_opcode(cbuf,0x89); // mov [esp+4],eax - Store as part of double word 2765 encode_RegMem(cbuf, EAX_enc, ESP_enc, 0x4, 0, 4, false); 2766 emit_opcode(cbuf,0xC7); // mov [esp+0],0 - [ESP] = (double)(1<<int(Q)) = 2^int(Q) 2767 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 2768 emit_d32(cbuf,0); 2769 emit_opcode(cbuf,0xDC); // fmul dword st(0),[esp+0]; FPR1 = 2^int(Q)*2^frac(Q) = 2^Q 2770 encode_RegMem(cbuf, 0x1, ESP_enc, 0x4, 0, 0, false); 2771 %} 2772 2773// enc_class Pop_Reg_Mod_D( regD dst, regD src) 2774// was replaced by Push_Result_Mod_D followed by Pop_Reg_X() or Pop_Mem_X() 2775 2776 enc_class Push_Result_Mod_D( regD src) %{ 2777 if ($src$$reg != FPR1L_enc) { 2778 // fincstp 2779 emit_opcode (cbuf, 0xD9); 2780 emit_opcode (cbuf, 0xF7); 2781 // FXCH FPR1 with src 2782 emit_opcode(cbuf, 0xD9); 2783 emit_d8(cbuf, 0xC8-1+$src$$reg ); 2784 // fdecstp 2785 emit_opcode (cbuf, 0xD9); 2786 emit_opcode (cbuf, 0xF6); 2787 } 2788 // // following asm replaced with Pop_Reg_F or Pop_Mem_F 2789 // // FSTP FPR$dst$$reg 2790 // emit_opcode( cbuf, 0xDD ); 2791 // emit_d8( cbuf, 0xD8+$dst$$reg ); 2792 %} 2793 2794 enc_class fnstsw_sahf_skip_parity() %{ 2795 // fnstsw ax 2796 emit_opcode( cbuf, 0xDF ); 2797 emit_opcode( cbuf, 0xE0 ); 2798 // sahf 2799 emit_opcode( cbuf, 0x9E ); 2800 // jnp ::skip 2801 emit_opcode( cbuf, 0x7B ); 2802 emit_opcode( cbuf, 0x05 ); 2803 %} 2804 2805 enc_class emitModD() %{ 2806 // fprem must be iterative 2807 // :: loop 2808 // fprem 2809 emit_opcode( cbuf, 0xD9 ); 2810 emit_opcode( cbuf, 0xF8 ); 2811 // wait 2812 emit_opcode( cbuf, 0x9b ); 2813 // fnstsw ax 2814 emit_opcode( cbuf, 0xDF ); 2815 emit_opcode( cbuf, 0xE0 ); 2816 // sahf 2817 emit_opcode( cbuf, 0x9E ); 2818 // jp ::loop 2819 emit_opcode( cbuf, 0x0F ); 2820 emit_opcode( cbuf, 0x8A ); 2821 emit_opcode( cbuf, 0xF4 ); 2822 emit_opcode( cbuf, 0xFF ); 2823 emit_opcode( cbuf, 0xFF ); 2824 emit_opcode( cbuf, 0xFF ); 2825 %} 2826 2827 enc_class fpu_flags() %{ 2828 // fnstsw_ax 2829 emit_opcode( cbuf, 0xDF); 2830 emit_opcode( cbuf, 0xE0); 2831 // test ax,0x0400 2832 emit_opcode( cbuf, 0x66 ); // operand-size prefix for 16-bit immediate 2833 emit_opcode( cbuf, 0xA9 ); 2834 emit_d16 ( cbuf, 0x0400 ); 2835 // // // This sequence works, but stalls for 12-16 cycles on PPro 2836 // // test rax,0x0400 2837 // emit_opcode( cbuf, 0xA9 ); 2838 // emit_d32 ( cbuf, 0x00000400 ); 2839 // 2840 // jz exit (no unordered comparison) 2841 emit_opcode( cbuf, 0x74 ); 2842 emit_d8 ( cbuf, 0x02 ); 2843 // mov ah,1 - treat as LT case (set carry flag) 2844 emit_opcode( cbuf, 0xB4 ); 2845 emit_d8 ( cbuf, 0x01 ); 2846 // sahf 2847 emit_opcode( cbuf, 0x9E); 2848 %} 2849 2850 enc_class cmpF_P6_fixup() %{ 2851 // Fixup the integer flags in case comparison involved a NaN 2852 // 2853 // JNP exit (no unordered comparison, P-flag is set by NaN) 2854 emit_opcode( cbuf, 0x7B ); 2855 emit_d8 ( cbuf, 0x03 ); 2856 // MOV AH,1 - treat as LT case (set carry flag) 2857 emit_opcode( cbuf, 0xB4 ); 2858 emit_d8 ( cbuf, 0x01 ); 2859 // SAHF 2860 emit_opcode( cbuf, 0x9E); 2861 // NOP // target for branch to avoid branch to branch 2862 emit_opcode( cbuf, 0x90); 2863 %} 2864 2865// fnstsw_ax(); 2866// sahf(); 2867// movl(dst, nan_result); 2868// jcc(Assembler::parity, exit); 2869// movl(dst, less_result); 2870// jcc(Assembler::below, exit); 2871// movl(dst, equal_result); 2872// jcc(Assembler::equal, exit); 2873// movl(dst, greater_result); 2874 2875// less_result = 1; 2876// greater_result = -1; 2877// equal_result = 0; 2878// nan_result = -1; 2879 2880 enc_class CmpF_Result(eRegI dst) %{ 2881 // fnstsw_ax(); 2882 emit_opcode( cbuf, 0xDF); 2883 emit_opcode( cbuf, 0xE0); 2884 // sahf 2885 emit_opcode( cbuf, 0x9E); 2886 // movl(dst, nan_result); 2887 emit_opcode( cbuf, 0xB8 + $dst$$reg); 2888 emit_d32( cbuf, -1 ); 2889 // jcc(Assembler::parity, exit); 2890 emit_opcode( cbuf, 0x7A ); 2891 emit_d8 ( cbuf, 0x13 ); 2892 // movl(dst, less_result); 2893 emit_opcode( cbuf, 0xB8 + $dst$$reg); 2894 emit_d32( cbuf, -1 ); 2895 // jcc(Assembler::below, exit); 2896 emit_opcode( cbuf, 0x72 ); 2897 emit_d8 ( cbuf, 0x0C ); 2898 // movl(dst, equal_result); 2899 emit_opcode( cbuf, 0xB8 + $dst$$reg); 2900 emit_d32( cbuf, 0 ); 2901 // jcc(Assembler::equal, exit); 2902 emit_opcode( cbuf, 0x74 ); 2903 emit_d8 ( cbuf, 0x05 ); 2904 // movl(dst, greater_result); 2905 emit_opcode( cbuf, 0xB8 + $dst$$reg); 2906 emit_d32( cbuf, 1 ); 2907 %} 2908 2909 2910 // XMM version of CmpF_Result. Because the XMM compare 2911 // instructions set the EFLAGS directly. It becomes simpler than 2912 // the float version above. 2913 enc_class CmpX_Result(eRegI dst) %{ 2914 MacroAssembler _masm(&cbuf); 2915 Label nan, inc, done; 2916 2917 __ jccb(Assembler::parity, nan); 2918 __ jccb(Assembler::equal, done); 2919 __ jccb(Assembler::above, inc); 2920 __ bind(nan); 2921 __ decrement(as_Register($dst$$reg)); // NO L qqq 2922 __ jmpb(done); 2923 __ bind(inc); 2924 __ increment(as_Register($dst$$reg)); // NO L qqq 2925 __ bind(done); 2926 %} 2927 2928 // Compare the longs and set flags 2929 // BROKEN! Do Not use as-is 2930 enc_class cmpl_test( eRegL src1, eRegL src2 ) %{ 2931 // CMP $src1.hi,$src2.hi 2932 emit_opcode( cbuf, 0x3B ); 2933 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) ); 2934 // JNE,s done 2935 emit_opcode(cbuf,0x75); 2936 emit_d8(cbuf, 2 ); 2937 // CMP $src1.lo,$src2.lo 2938 emit_opcode( cbuf, 0x3B ); 2939 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg ); 2940// done: 2941 %} 2942 2943 enc_class convert_int_long( regL dst, eRegI src ) %{ 2944 // mov $dst.lo,$src 2945 int dst_encoding = $dst$$reg; 2946 int src_encoding = $src$$reg; 2947 encode_Copy( cbuf, dst_encoding , src_encoding ); 2948 // mov $dst.hi,$src 2949 encode_Copy( cbuf, HIGH_FROM_LOW(dst_encoding), src_encoding ); 2950 // sar $dst.hi,31 2951 emit_opcode( cbuf, 0xC1 ); 2952 emit_rm(cbuf, 0x3, 7, HIGH_FROM_LOW(dst_encoding) ); 2953 emit_d8(cbuf, 0x1F ); 2954 %} 2955 2956 enc_class convert_long_double( eRegL src ) %{ 2957 // push $src.hi 2958 emit_opcode(cbuf, 0x50+HIGH_FROM_LOW($src$$reg)); 2959 // push $src.lo 2960 emit_opcode(cbuf, 0x50+$src$$reg ); 2961 // fild 64-bits at [SP] 2962 emit_opcode(cbuf,0xdf); 2963 emit_d8(cbuf, 0x6C); 2964 emit_d8(cbuf, 0x24); 2965 emit_d8(cbuf, 0x00); 2966 // pop stack 2967 emit_opcode(cbuf, 0x83); // add SP, #8 2968 emit_rm(cbuf, 0x3, 0x00, ESP_enc); 2969 emit_d8(cbuf, 0x8); 2970 %} 2971 2972 enc_class multiply_con_and_shift_high( eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32_63 cnt, eFlagsReg cr ) %{ 2973 // IMUL EDX:EAX,$src1 2974 emit_opcode( cbuf, 0xF7 ); 2975 emit_rm( cbuf, 0x3, 0x5, $src1$$reg ); 2976 // SAR EDX,$cnt-32 2977 int shift_count = ((int)$cnt$$constant) - 32; 2978 if (shift_count > 0) { 2979 emit_opcode(cbuf, 0xC1); 2980 emit_rm(cbuf, 0x3, 7, $dst$$reg ); 2981 emit_d8(cbuf, shift_count); 2982 } 2983 %} 2984 2985 // this version doesn't have add sp, 8 2986 enc_class convert_long_double2( eRegL src ) %{ 2987 // push $src.hi 2988 emit_opcode(cbuf, 0x50+HIGH_FROM_LOW($src$$reg)); 2989 // push $src.lo 2990 emit_opcode(cbuf, 0x50+$src$$reg ); 2991 // fild 64-bits at [SP] 2992 emit_opcode(cbuf,0xdf); 2993 emit_d8(cbuf, 0x6C); 2994 emit_d8(cbuf, 0x24); 2995 emit_d8(cbuf, 0x00); 2996 %} 2997 2998 enc_class long_int_multiply( eADXRegL dst, nadxRegI src) %{ 2999 // Basic idea: long = (long)int * (long)int 3000 // IMUL EDX:EAX, src 3001 emit_opcode( cbuf, 0xF7 ); 3002 emit_rm( cbuf, 0x3, 0x5, $src$$reg); 3003 %} 3004 3005 enc_class long_uint_multiply( eADXRegL dst, nadxRegI src) %{ 3006 // Basic Idea: long = (int & 0xffffffffL) * (int & 0xffffffffL) 3007 // MUL EDX:EAX, src 3008 emit_opcode( cbuf, 0xF7 ); 3009 emit_rm( cbuf, 0x3, 0x4, $src$$reg); 3010 %} 3011 3012 enc_class long_multiply( eADXRegL dst, eRegL src, eRegI tmp ) %{ 3013 // Basic idea: lo(result) = lo(x_lo * y_lo) 3014 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi) 3015 // MOV $tmp,$src.lo 3016 encode_Copy( cbuf, $tmp$$reg, $src$$reg ); 3017 // IMUL $tmp,EDX 3018 emit_opcode( cbuf, 0x0F ); 3019 emit_opcode( cbuf, 0xAF ); 3020 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) ); 3021 // MOV EDX,$src.hi 3022 encode_Copy( cbuf, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg) ); 3023 // IMUL EDX,EAX 3024 emit_opcode( cbuf, 0x0F ); 3025 emit_opcode( cbuf, 0xAF ); 3026 emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg ); 3027 // ADD $tmp,EDX 3028 emit_opcode( cbuf, 0x03 ); 3029 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) ); 3030 // MUL EDX:EAX,$src.lo 3031 emit_opcode( cbuf, 0xF7 ); 3032 emit_rm( cbuf, 0x3, 0x4, $src$$reg ); 3033 // ADD EDX,ESI 3034 emit_opcode( cbuf, 0x03 ); 3035 emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $tmp$$reg ); 3036 %} 3037 3038 enc_class long_multiply_con( eADXRegL dst, immL_127 src, eRegI tmp ) %{ 3039 // Basic idea: lo(result) = lo(src * y_lo) 3040 // hi(result) = hi(src * y_lo) + lo(src * y_hi) 3041 // IMUL $tmp,EDX,$src 3042 emit_opcode( cbuf, 0x6B ); 3043 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) ); 3044 emit_d8( cbuf, (int)$src$$constant ); 3045 // MOV EDX,$src 3046 emit_opcode(cbuf, 0xB8 + EDX_enc); 3047 emit_d32( cbuf, (int)$src$$constant ); 3048 // MUL EDX:EAX,EDX 3049 emit_opcode( cbuf, 0xF7 ); 3050 emit_rm( cbuf, 0x3, 0x4, EDX_enc ); 3051 // ADD EDX,ESI 3052 emit_opcode( cbuf, 0x03 ); 3053 emit_rm( cbuf, 0x3, EDX_enc, $tmp$$reg ); 3054 %} 3055 3056 enc_class long_div( eRegL src1, eRegL src2 ) %{ 3057 // PUSH src1.hi 3058 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src1$$reg) ); 3059 // PUSH src1.lo 3060 emit_opcode(cbuf, 0x50+$src1$$reg ); 3061 // PUSH src2.hi 3062 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src2$$reg) ); 3063 // PUSH src2.lo 3064 emit_opcode(cbuf, 0x50+$src2$$reg ); 3065 // CALL directly to the runtime 3066 cbuf.set_insts_mark(); 3067 emit_opcode(cbuf,0xE8); // Call into runtime 3068 emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::ldiv) - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 3069 // Restore stack 3070 emit_opcode(cbuf, 0x83); // add SP, #framesize 3071 emit_rm(cbuf, 0x3, 0x00, ESP_enc); 3072 emit_d8(cbuf, 4*4); 3073 %} 3074 3075 enc_class long_mod( eRegL src1, eRegL src2 ) %{ 3076 // PUSH src1.hi 3077 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src1$$reg) ); 3078 // PUSH src1.lo 3079 emit_opcode(cbuf, 0x50+$src1$$reg ); 3080 // PUSH src2.hi 3081 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src2$$reg) ); 3082 // PUSH src2.lo 3083 emit_opcode(cbuf, 0x50+$src2$$reg ); 3084 // CALL directly to the runtime 3085 cbuf.set_insts_mark(); 3086 emit_opcode(cbuf,0xE8); // Call into runtime 3087 emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::lrem ) - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 3088 // Restore stack 3089 emit_opcode(cbuf, 0x83); // add SP, #framesize 3090 emit_rm(cbuf, 0x3, 0x00, ESP_enc); 3091 emit_d8(cbuf, 4*4); 3092 %} 3093 3094 enc_class long_cmp_flags0( eRegL src, eRegI tmp ) %{ 3095 // MOV $tmp,$src.lo 3096 emit_opcode(cbuf, 0x8B); 3097 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg); 3098 // OR $tmp,$src.hi 3099 emit_opcode(cbuf, 0x0B); 3100 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg)); 3101 %} 3102 3103 enc_class long_cmp_flags1( eRegL src1, eRegL src2 ) %{ 3104 // CMP $src1.lo,$src2.lo 3105 emit_opcode( cbuf, 0x3B ); 3106 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg ); 3107 // JNE,s skip 3108 emit_cc(cbuf, 0x70, 0x5); 3109 emit_d8(cbuf,2); 3110 // CMP $src1.hi,$src2.hi 3111 emit_opcode( cbuf, 0x3B ); 3112 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) ); 3113 %} 3114 3115 enc_class long_cmp_flags2( eRegL src1, eRegL src2, eRegI tmp ) %{ 3116 // CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits 3117 emit_opcode( cbuf, 0x3B ); 3118 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg ); 3119 // MOV $tmp,$src1.hi 3120 emit_opcode( cbuf, 0x8B ); 3121 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src1$$reg) ); 3122 // SBB $tmp,$src2.hi\t! Compute flags for long compare 3123 emit_opcode( cbuf, 0x1B ); 3124 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src2$$reg) ); 3125 %} 3126 3127 enc_class long_cmp_flags3( eRegL src, eRegI tmp ) %{ 3128 // XOR $tmp,$tmp 3129 emit_opcode(cbuf,0x33); // XOR 3130 emit_rm(cbuf,0x3, $tmp$$reg, $tmp$$reg); 3131 // CMP $tmp,$src.lo 3132 emit_opcode( cbuf, 0x3B ); 3133 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg ); 3134 // SBB $tmp,$src.hi 3135 emit_opcode( cbuf, 0x1B ); 3136 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg) ); 3137 %} 3138 3139 // Sniff, sniff... smells like Gnu Superoptimizer 3140 enc_class neg_long( eRegL dst ) %{ 3141 emit_opcode(cbuf,0xF7); // NEG hi 3142 emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg)); 3143 emit_opcode(cbuf,0xF7); // NEG lo 3144 emit_rm (cbuf,0x3, 0x3, $dst$$reg ); 3145 emit_opcode(cbuf,0x83); // SBB hi,0 3146 emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg)); 3147 emit_d8 (cbuf,0 ); 3148 %} 3149 3150 enc_class movq_ld(regXD dst, memory mem) %{ 3151 MacroAssembler _masm(&cbuf); 3152 __ movq($dst$$XMMRegister, $mem$$Address); 3153 %} 3154 3155 enc_class movq_st(memory mem, regXD src) %{ 3156 MacroAssembler _masm(&cbuf); 3157 __ movq($mem$$Address, $src$$XMMRegister); 3158 %} 3159 3160 enc_class pshufd_8x8(regX dst, regX src) %{ 3161 MacroAssembler _masm(&cbuf); 3162 3163 encode_CopyXD(cbuf, $dst$$reg, $src$$reg); 3164 __ punpcklbw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg)); 3165 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($dst$$reg), 0x00); 3166 %} 3167 3168 enc_class pshufd_4x16(regX dst, regX src) %{ 3169 MacroAssembler _masm(&cbuf); 3170 3171 __ pshuflw(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), 0x00); 3172 %} 3173 3174 enc_class pshufd(regXD dst, regXD src, int mode) %{ 3175 MacroAssembler _masm(&cbuf); 3176 3177 __ pshufd(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg), $mode); 3178 %} 3179 3180 enc_class pxor(regXD dst, regXD src) %{ 3181 MacroAssembler _masm(&cbuf); 3182 3183 __ pxor(as_XMMRegister($dst$$reg), as_XMMRegister($src$$reg)); 3184 %} 3185 3186 enc_class mov_i2x(regXD dst, eRegI src) %{ 3187 MacroAssembler _masm(&cbuf); 3188 3189 __ movdl(as_XMMRegister($dst$$reg), as_Register($src$$reg)); 3190 %} 3191 3192 3193 // Because the transitions from emitted code to the runtime 3194 // monitorenter/exit helper stubs are so slow it's critical that 3195 // we inline both the stack-locking fast-path and the inflated fast path. 3196 // 3197 // See also: cmpFastLock and cmpFastUnlock. 3198 // 3199 // What follows is a specialized inline transliteration of the code 3200 // in slow_enter() and slow_exit(). If we're concerned about I$ bloat 3201 // another option would be to emit TrySlowEnter and TrySlowExit methods 3202 // at startup-time. These methods would accept arguments as 3203 // (rax,=Obj, rbx=Self, rcx=box, rdx=Scratch) and return success-failure 3204 // indications in the icc.ZFlag. Fast_Lock and Fast_Unlock would simply 3205 // marshal the arguments and emit calls to TrySlowEnter and TrySlowExit. 3206 // In practice, however, the # of lock sites is bounded and is usually small. 3207 // Besides the call overhead, TrySlowEnter and TrySlowExit might suffer 3208 // if the processor uses simple bimodal branch predictors keyed by EIP 3209 // Since the helper routines would be called from multiple synchronization 3210 // sites. 3211 // 3212 // An even better approach would be write "MonitorEnter()" and "MonitorExit()" 3213 // in java - using j.u.c and unsafe - and just bind the lock and unlock sites 3214 // to those specialized methods. That'd give us a mostly platform-independent 3215 // implementation that the JITs could optimize and inline at their pleasure. 3216 // Done correctly, the only time we'd need to cross to native could would be 3217 // to park() or unpark() threads. We'd also need a few more unsafe operators 3218 // to (a) prevent compiler-JIT reordering of non-volatile accesses, and 3219 // (b) explicit barriers or fence operations. 3220 // 3221 // TODO: 3222 // 3223 // * Arrange for C2 to pass "Self" into Fast_Lock and Fast_Unlock in one of the registers (scr). 3224 // This avoids manifesting the Self pointer in the Fast_Lock and Fast_Unlock terminals. 3225 // Given TLAB allocation, Self is usually manifested in a register, so passing it into 3226 // the lock operators would typically be faster than reifying Self. 3227 // 3228 // * Ideally I'd define the primitives as: 3229 // fast_lock (nax Obj, nax box, EAX tmp, nax scr) where box, tmp and scr are KILLED. 3230 // fast_unlock (nax Obj, EAX box, nax tmp) where box and tmp are KILLED 3231 // Unfortunately ADLC bugs prevent us from expressing the ideal form. 3232 // Instead, we're stuck with a rather awkward and brittle register assignments below. 3233 // Furthermore the register assignments are overconstrained, possibly resulting in 3234 // sub-optimal code near the synchronization site. 3235 // 3236 // * Eliminate the sp-proximity tests and just use "== Self" tests instead. 3237 // Alternately, use a better sp-proximity test. 3238 // 3239 // * Currently ObjectMonitor._Owner can hold either an sp value or a (THREAD *) value. 3240 // Either one is sufficient to uniquely identify a thread. 3241 // TODO: eliminate use of sp in _owner and use get_thread(tr) instead. 3242 // 3243 // * Intrinsify notify() and notifyAll() for the common cases where the 3244 // object is locked by the calling thread but the waitlist is empty. 3245 // avoid the expensive JNI call to JVM_Notify() and JVM_NotifyAll(). 3246 // 3247 // * use jccb and jmpb instead of jcc and jmp to improve code density. 3248 // But beware of excessive branch density on AMD Opterons. 3249 // 3250 // * Both Fast_Lock and Fast_Unlock set the ICC.ZF to indicate success 3251 // or failure of the fast-path. If the fast-path fails then we pass 3252 // control to the slow-path, typically in C. In Fast_Lock and 3253 // Fast_Unlock we often branch to DONE_LABEL, just to find that C2 3254 // will emit a conditional branch immediately after the node. 3255 // So we have branches to branches and lots of ICC.ZF games. 3256 // Instead, it might be better to have C2 pass a "FailureLabel" 3257 // into Fast_Lock and Fast_Unlock. In the case of success, control 3258 // will drop through the node. ICC.ZF is undefined at exit. 3259 // In the case of failure, the node will branch directly to the 3260 // FailureLabel 3261 3262 3263 // obj: object to lock 3264 // box: on-stack box address (displaced header location) - KILLED 3265 // rax,: tmp -- KILLED 3266 // scr: tmp -- KILLED 3267 enc_class Fast_Lock( eRegP obj, eRegP box, eAXRegI tmp, eRegP scr ) %{ 3268 3269 Register objReg = as_Register($obj$$reg); 3270 Register boxReg = as_Register($box$$reg); 3271 Register tmpReg = as_Register($tmp$$reg); 3272 Register scrReg = as_Register($scr$$reg); 3273 3274 // Ensure the register assignents are disjoint 3275 guarantee (objReg != boxReg, "") ; 3276 guarantee (objReg != tmpReg, "") ; 3277 guarantee (objReg != scrReg, "") ; 3278 guarantee (boxReg != tmpReg, "") ; 3279 guarantee (boxReg != scrReg, "") ; 3280 guarantee (tmpReg == as_Register(EAX_enc), "") ; 3281 3282 MacroAssembler masm(&cbuf); 3283 3284 if (_counters != NULL) { 3285 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 3286 } 3287 if (EmitSync & 1) { 3288 // set box->dhw = unused_mark (3) 3289 // Force all sync thru slow-path: slow_enter() and slow_exit() 3290 masm.movptr (Address(boxReg, 0), int32_t(markOopDesc::unused_mark())) ; 3291 masm.cmpptr (rsp, (int32_t)0) ; 3292 } else 3293 if (EmitSync & 2) { 3294 Label DONE_LABEL ; 3295 if (UseBiasedLocking) { 3296 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 3297 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 3298 } 3299 3300 masm.movptr(tmpReg, Address(objReg, 0)) ; // fetch markword 3301 masm.orptr (tmpReg, 0x1); 3302 masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS 3303 if (os::is_MP()) { masm.lock(); } 3304 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3305 masm.jcc(Assembler::equal, DONE_LABEL); 3306 // Recursive locking 3307 masm.subptr(tmpReg, rsp); 3308 masm.andptr(tmpReg, (int32_t) 0xFFFFF003 ); 3309 masm.movptr(Address(boxReg, 0), tmpReg); 3310 masm.bind(DONE_LABEL) ; 3311 } else { 3312 // Possible cases that we'll encounter in fast_lock 3313 // ------------------------------------------------ 3314 // * Inflated 3315 // -- unlocked 3316 // -- Locked 3317 // = by self 3318 // = by other 3319 // * biased 3320 // -- by Self 3321 // -- by other 3322 // * neutral 3323 // * stack-locked 3324 // -- by self 3325 // = sp-proximity test hits 3326 // = sp-proximity test generates false-negative 3327 // -- by other 3328 // 3329 3330 Label IsInflated, DONE_LABEL, PopDone ; 3331 3332 // TODO: optimize away redundant LDs of obj->mark and improve the markword triage 3333 // order to reduce the number of conditional branches in the most common cases. 3334 // Beware -- there's a subtle invariant that fetch of the markword 3335 // at [FETCH], below, will never observe a biased encoding (*101b). 3336 // If this invariant is not held we risk exclusion (safety) failure. 3337 if (UseBiasedLocking && !UseOptoBiasInlining) { 3338 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 3339 } 3340 3341 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 3342 masm.testptr(tmpReg, 0x02) ; // Inflated v (Stack-locked or neutral) 3343 masm.jccb (Assembler::notZero, IsInflated) ; 3344 3345 // Attempt stack-locking ... 3346 masm.orptr (tmpReg, 0x1); 3347 masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS 3348 if (os::is_MP()) { masm.lock(); } 3349 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3350 if (_counters != NULL) { 3351 masm.cond_inc32(Assembler::equal, 3352 ExternalAddress((address)_counters->fast_path_entry_count_addr())); 3353 } 3354 masm.jccb (Assembler::equal, DONE_LABEL); 3355 3356 // Recursive locking 3357 masm.subptr(tmpReg, rsp); 3358 masm.andptr(tmpReg, 0xFFFFF003 ); 3359 masm.movptr(Address(boxReg, 0), tmpReg); 3360 if (_counters != NULL) { 3361 masm.cond_inc32(Assembler::equal, 3362 ExternalAddress((address)_counters->fast_path_entry_count_addr())); 3363 } 3364 masm.jmp (DONE_LABEL) ; 3365 3366 masm.bind (IsInflated) ; 3367 3368 // The object is inflated. 3369 // 3370 // TODO-FIXME: eliminate the ugly use of manifest constants: 3371 // Use markOopDesc::monitor_value instead of "2". 3372 // use markOop::unused_mark() instead of "3". 3373 // The tmpReg value is an objectMonitor reference ORed with 3374 // markOopDesc::monitor_value (2). We can either convert tmpReg to an 3375 // objectmonitor pointer by masking off the "2" bit or we can just 3376 // use tmpReg as an objectmonitor pointer but bias the objectmonitor 3377 // field offsets with "-2" to compensate for and annul the low-order tag bit. 3378 // 3379 // I use the latter as it avoids AGI stalls. 3380 // As such, we write "mov r, [tmpReg+OFFSETOF(Owner)-2]" 3381 // instead of "mov r, [tmpReg+OFFSETOF(Owner)]". 3382 // 3383 #define OFFSET_SKEWED(f) ((ObjectMonitor::f ## _offset_in_bytes())-2) 3384 3385 // boxReg refers to the on-stack BasicLock in the current frame. 3386 // We'd like to write: 3387 // set box->_displaced_header = markOop::unused_mark(). Any non-0 value suffices. 3388 // This is convenient but results a ST-before-CAS penalty. The following CAS suffers 3389 // additional latency as we have another ST in the store buffer that must drain. 3390 3391 if (EmitSync & 8192) { 3392 masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty 3393 masm.get_thread (scrReg) ; 3394 masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] 3395 masm.movptr(tmpReg, NULL_WORD); // consider: xor vs mov 3396 if (os::is_MP()) { masm.lock(); } 3397 masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3398 } else 3399 if ((EmitSync & 128) == 0) { // avoid ST-before-CAS 3400 masm.movptr(scrReg, boxReg) ; 3401 masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] 3402 3403 // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes 3404 if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 3405 // prefetchw [eax + Offset(_owner)-2] 3406 masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); 3407 } 3408 3409 if ((EmitSync & 64) == 0) { 3410 // Optimistic form: consider XORL tmpReg,tmpReg 3411 masm.movptr(tmpReg, NULL_WORD) ; 3412 } else { 3413 // Can suffer RTS->RTO upgrades on shared or cold $ lines 3414 // Test-And-CAS instead of CAS 3415 masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner 3416 masm.testptr(tmpReg, tmpReg) ; // Locked ? 3417 masm.jccb (Assembler::notZero, DONE_LABEL) ; 3418 } 3419 3420 // Appears unlocked - try to swing _owner from null to non-null. 3421 // Ideally, I'd manifest "Self" with get_thread and then attempt 3422 // to CAS the register containing Self into m->Owner. 3423 // But we don't have enough registers, so instead we can either try to CAS 3424 // rsp or the address of the box (in scr) into &m->owner. If the CAS succeeds 3425 // we later store "Self" into m->Owner. Transiently storing a stack address 3426 // (rsp or the address of the box) into m->owner is harmless. 3427 // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. 3428 if (os::is_MP()) { masm.lock(); } 3429 masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3430 masm.movptr(Address(scrReg, 0), 3) ; // box->_displaced_header = 3 3431 masm.jccb (Assembler::notZero, DONE_LABEL) ; 3432 masm.get_thread (scrReg) ; // beware: clobbers ICCs 3433 masm.movptr(Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2), scrReg) ; 3434 masm.xorptr(boxReg, boxReg) ; // set icc.ZFlag = 1 to indicate success 3435 3436 // If the CAS fails we can either retry or pass control to the slow-path. 3437 // We use the latter tactic. 3438 // Pass the CAS result in the icc.ZFlag into DONE_LABEL 3439 // If the CAS was successful ... 3440 // Self has acquired the lock 3441 // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. 3442 // Intentional fall-through into DONE_LABEL ... 3443 } else { 3444 masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty 3445 masm.movptr(boxReg, tmpReg) ; 3446 3447 // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes 3448 if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 3449 // prefetchw [eax + Offset(_owner)-2] 3450 masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); 3451 } 3452 3453 if ((EmitSync & 64) == 0) { 3454 // Optimistic form 3455 masm.xorptr (tmpReg, tmpReg) ; 3456 } else { 3457 // Can suffer RTS->RTO upgrades on shared or cold $ lines 3458 masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner 3459 masm.testptr(tmpReg, tmpReg) ; // Locked ? 3460 masm.jccb (Assembler::notZero, DONE_LABEL) ; 3461 } 3462 3463 // Appears unlocked - try to swing _owner from null to non-null. 3464 // Use either "Self" (in scr) or rsp as thread identity in _owner. 3465 // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. 3466 masm.get_thread (scrReg) ; 3467 if (os::is_MP()) { masm.lock(); } 3468 masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3469 3470 // If the CAS fails we can either retry or pass control to the slow-path. 3471 // We use the latter tactic. 3472 // Pass the CAS result in the icc.ZFlag into DONE_LABEL 3473 // If the CAS was successful ... 3474 // Self has acquired the lock 3475 // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. 3476 // Intentional fall-through into DONE_LABEL ... 3477 } 3478 3479 // DONE_LABEL is a hot target - we'd really like to place it at the 3480 // start of cache line by padding with NOPs. 3481 // See the AMD and Intel software optimization manuals for the 3482 // most efficient "long" NOP encodings. 3483 // Unfortunately none of our alignment mechanisms suffice. 3484 masm.bind(DONE_LABEL); 3485 3486 // Avoid branch-to-branch on AMD processors 3487 // This appears to be superstition. 3488 if (EmitSync & 32) masm.nop() ; 3489 3490 3491 // At DONE_LABEL the icc ZFlag is set as follows ... 3492 // Fast_Unlock uses the same protocol. 3493 // ZFlag == 1 -> Success 3494 // ZFlag == 0 -> Failure - force control through the slow-path 3495 } 3496 %} 3497 3498 // obj: object to unlock 3499 // box: box address (displaced header location), killed. Must be EAX. 3500 // rbx,: killed tmp; cannot be obj nor box. 3501 // 3502 // Some commentary on balanced locking: 3503 // 3504 // Fast_Lock and Fast_Unlock are emitted only for provably balanced lock sites. 3505 // Methods that don't have provably balanced locking are forced to run in the 3506 // interpreter - such methods won't be compiled to use fast_lock and fast_unlock. 3507 // The interpreter provides two properties: 3508 // I1: At return-time the interpreter automatically and quietly unlocks any 3509 // objects acquired the current activation (frame). Recall that the 3510 // interpreter maintains an on-stack list of locks currently held by 3511 // a frame. 3512 // I2: If a method attempts to unlock an object that is not held by the 3513 // the frame the interpreter throws IMSX. 3514 // 3515 // Lets say A(), which has provably balanced locking, acquires O and then calls B(). 3516 // B() doesn't have provably balanced locking so it runs in the interpreter. 3517 // Control returns to A() and A() unlocks O. By I1 and I2, above, we know that O 3518 // is still locked by A(). 3519 // 3520 // The only other source of unbalanced locking would be JNI. The "Java Native Interface: 3521 // Programmer's Guide and Specification" claims that an object locked by jni_monitorenter 3522 // should not be unlocked by "normal" java-level locking and vice-versa. The specification 3523 // doesn't specify what will occur if a program engages in such mixed-mode locking, however. 3524 3525 enc_class Fast_Unlock( nabxRegP obj, eAXRegP box, eRegP tmp) %{ 3526 3527 Register objReg = as_Register($obj$$reg); 3528 Register boxReg = as_Register($box$$reg); 3529 Register tmpReg = as_Register($tmp$$reg); 3530 3531 guarantee (objReg != boxReg, "") ; 3532 guarantee (objReg != tmpReg, "") ; 3533 guarantee (boxReg != tmpReg, "") ; 3534 guarantee (boxReg == as_Register(EAX_enc), "") ; 3535 MacroAssembler masm(&cbuf); 3536 3537 if (EmitSync & 4) { 3538 // Disable - inhibit all inlining. Force control through the slow-path 3539 masm.cmpptr (rsp, 0) ; 3540 } else 3541 if (EmitSync & 8) { 3542 Label DONE_LABEL ; 3543 if (UseBiasedLocking) { 3544 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3545 } 3546 // classic stack-locking code ... 3547 masm.movptr(tmpReg, Address(boxReg, 0)) ; 3548 masm.testptr(tmpReg, tmpReg) ; 3549 masm.jcc (Assembler::zero, DONE_LABEL) ; 3550 if (os::is_MP()) { masm.lock(); } 3551 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box 3552 masm.bind(DONE_LABEL); 3553 } else { 3554 Label DONE_LABEL, Stacked, CheckSucc, Inflated ; 3555 3556 // Critically, the biased locking test must have precedence over 3557 // and appear before the (box->dhw == 0) recursive stack-lock test. 3558 if (UseBiasedLocking && !UseOptoBiasInlining) { 3559 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3560 } 3561 3562 masm.cmpptr(Address(boxReg, 0), 0) ; // Examine the displaced header 3563 masm.movptr(tmpReg, Address(objReg, 0)) ; // Examine the object's markword 3564 masm.jccb (Assembler::zero, DONE_LABEL) ; // 0 indicates recursive stack-lock 3565 3566 masm.testptr(tmpReg, 0x02) ; // Inflated? 3567 masm.jccb (Assembler::zero, Stacked) ; 3568 3569 masm.bind (Inflated) ; 3570 // It's inflated. 3571 // Despite our balanced locking property we still check that m->_owner == Self 3572 // as java routines or native JNI code called by this thread might 3573 // have released the lock. 3574 // Refer to the comments in synchronizer.cpp for how we might encode extra 3575 // state in _succ so we can avoid fetching EntryList|cxq. 3576 // 3577 // I'd like to add more cases in fast_lock() and fast_unlock() -- 3578 // such as recursive enter and exit -- but we have to be wary of 3579 // I$ bloat, T$ effects and BP$ effects. 3580 // 3581 // If there's no contention try a 1-0 exit. That is, exit without 3582 // a costly MEMBAR or CAS. See synchronizer.cpp for details on how 3583 // we detect and recover from the race that the 1-0 exit admits. 3584 // 3585 // Conceptually Fast_Unlock() must execute a STST|LDST "release" barrier 3586 // before it STs null into _owner, releasing the lock. Updates 3587 // to data protected by the critical section must be visible before 3588 // we drop the lock (and thus before any other thread could acquire 3589 // the lock and observe the fields protected by the lock). 3590 // IA32's memory-model is SPO, so STs are ordered with respect to 3591 // each other and there's no need for an explicit barrier (fence). 3592 // See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html. 3593 3594 masm.get_thread (boxReg) ; 3595 if ((EmitSync & 4096) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 3596 // prefetchw [ebx + Offset(_owner)-2] 3597 masm.prefetchw(Address(rbx, ObjectMonitor::owner_offset_in_bytes()-2)); 3598 } 3599 3600 // Note that we could employ various encoding schemes to reduce 3601 // the number of loads below (currently 4) to just 2 or 3. 3602 // Refer to the comments in synchronizer.cpp. 3603 // In practice the chain of fetches doesn't seem to impact performance, however. 3604 if ((EmitSync & 65536) == 0 && (EmitSync & 256)) { 3605 // Attempt to reduce branch density - AMD's branch predictor. 3606 masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3607 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 3608 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 3609 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 3610 masm.jccb (Assembler::notZero, DONE_LABEL) ; 3611 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 3612 masm.jmpb (DONE_LABEL) ; 3613 } else { 3614 masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3615 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 3616 masm.jccb (Assembler::notZero, DONE_LABEL) ; 3617 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 3618 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 3619 masm.jccb (Assembler::notZero, CheckSucc) ; 3620 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 3621 masm.jmpb (DONE_LABEL) ; 3622 } 3623 3624 // The Following code fragment (EmitSync & 65536) improves the performance of 3625 // contended applications and contended synchronization microbenchmarks. 3626 // Unfortunately the emission of the code - even though not executed - causes regressions 3627 // in scimark and jetstream, evidently because of $ effects. Replacing the code 3628 // with an equal number of never-executed NOPs results in the same regression. 3629 // We leave it off by default. 3630 3631 if ((EmitSync & 65536) != 0) { 3632 Label LSuccess, LGoSlowPath ; 3633 3634 masm.bind (CheckSucc) ; 3635 3636 // Optional pre-test ... it's safe to elide this 3637 if ((EmitSync & 16) == 0) { 3638 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; 3639 masm.jccb (Assembler::zero, LGoSlowPath) ; 3640 } 3641 3642 // We have a classic Dekker-style idiom: 3643 // ST m->_owner = 0 ; MEMBAR; LD m->_succ 3644 // There are a number of ways to implement the barrier: 3645 // (1) lock:andl &m->_owner, 0 3646 // is fast, but mask doesn't currently support the "ANDL M,IMM32" form. 3647 // LOCK: ANDL [ebx+Offset(_Owner)-2], 0 3648 // Encodes as 81 31 OFF32 IMM32 or 83 63 OFF8 IMM8 3649 // (2) If supported, an explicit MFENCE is appealing. 3650 // In older IA32 processors MFENCE is slower than lock:add or xchg 3651 // particularly if the write-buffer is full as might be the case if 3652 // if stores closely precede the fence or fence-equivalent instruction. 3653 // In more modern implementations MFENCE appears faster, however. 3654 // (3) In lieu of an explicit fence, use lock:addl to the top-of-stack 3655 // The $lines underlying the top-of-stack should be in M-state. 3656 // The locked add instruction is serializing, of course. 3657 // (4) Use xchg, which is serializing 3658 // mov boxReg, 0; xchgl boxReg, [tmpReg + Offset(_owner)-2] also works 3659 // (5) ST m->_owner = 0 and then execute lock:orl &m->_succ, 0. 3660 // The integer condition codes will tell us if succ was 0. 3661 // Since _succ and _owner should reside in the same $line and 3662 // we just stored into _owner, it's likely that the $line 3663 // remains in M-state for the lock:orl. 3664 // 3665 // We currently use (3), although it's likely that switching to (2) 3666 // is correct for the future. 3667 3668 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 3669 if (os::is_MP()) { 3670 if (VM_Version::supports_sse2() && 1 == FenceInstruction) { 3671 masm.mfence(); 3672 } else { 3673 masm.lock () ; masm.addptr(Address(rsp, 0), 0) ; 3674 } 3675 } 3676 // Ratify _succ remains non-null 3677 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; 3678 masm.jccb (Assembler::notZero, LSuccess) ; 3679 3680 masm.xorptr(boxReg, boxReg) ; // box is really EAX 3681 if (os::is_MP()) { masm.lock(); } 3682 masm.cmpxchgptr(rsp, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3683 masm.jccb (Assembler::notEqual, LSuccess) ; 3684 // Since we're low on registers we installed rsp as a placeholding in _owner. 3685 // Now install Self over rsp. This is safe as we're transitioning from 3686 // non-null to non=null 3687 masm.get_thread (boxReg) ; 3688 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), boxReg) ; 3689 // Intentional fall-through into LGoSlowPath ... 3690 3691 masm.bind (LGoSlowPath) ; 3692 masm.orptr(boxReg, 1) ; // set ICC.ZF=0 to indicate failure 3693 masm.jmpb (DONE_LABEL) ; 3694 3695 masm.bind (LSuccess) ; 3696 masm.xorptr(boxReg, boxReg) ; // set ICC.ZF=1 to indicate success 3697 masm.jmpb (DONE_LABEL) ; 3698 } 3699 3700 masm.bind (Stacked) ; 3701 // It's not inflated and it's not recursively stack-locked and it's not biased. 3702 // It must be stack-locked. 3703 // Try to reset the header to displaced header. 3704 // The "box" value on the stack is stable, so we can reload 3705 // and be assured we observe the same value as above. 3706 masm.movptr(tmpReg, Address(boxReg, 0)) ; 3707 if (os::is_MP()) { masm.lock(); } 3708 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box 3709 // Intention fall-thru into DONE_LABEL 3710 3711 3712 // DONE_LABEL is a hot target - we'd really like to place it at the 3713 // start of cache line by padding with NOPs. 3714 // See the AMD and Intel software optimization manuals for the 3715 // most efficient "long" NOP encodings. 3716 // Unfortunately none of our alignment mechanisms suffice. 3717 if ((EmitSync & 65536) == 0) { 3718 masm.bind (CheckSucc) ; 3719 } 3720 masm.bind(DONE_LABEL); 3721 3722 // Avoid branch to branch on AMD processors 3723 if (EmitSync & 32768) { masm.nop() ; } 3724 } 3725 %} 3726 3727 3728 enc_class enc_pop_rdx() %{ 3729 emit_opcode(cbuf,0x5A); 3730 %} 3731 3732 enc_class enc_rethrow() %{ 3733 cbuf.set_insts_mark(); 3734 emit_opcode(cbuf, 0xE9); // jmp entry 3735 emit_d32_reloc(cbuf, (int)OptoRuntime::rethrow_stub() - ((int)cbuf.insts_end())-4, 3736 runtime_call_Relocation::spec(), RELOC_IMM32 ); 3737 %} 3738 3739 3740 // Convert a double to an int. Java semantics require we do complex 3741 // manglelations in the corner cases. So we set the rounding mode to 3742 // 'zero', store the darned double down as an int, and reset the 3743 // rounding mode to 'nearest'. The hardware throws an exception which 3744 // patches up the correct value directly to the stack. 3745 enc_class D2I_encoding( regD src ) %{ 3746 // Flip to round-to-zero mode. We attempted to allow invalid-op 3747 // exceptions here, so that a NAN or other corner-case value will 3748 // thrown an exception (but normal values get converted at full speed). 3749 // However, I2C adapters and other float-stack manglers leave pending 3750 // invalid-op exceptions hanging. We would have to clear them before 3751 // enabling them and that is more expensive than just testing for the 3752 // invalid value Intel stores down in the corner cases. 3753 emit_opcode(cbuf,0xD9); // FLDCW trunc 3754 emit_opcode(cbuf,0x2D); 3755 emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc()); 3756 // Allocate a word 3757 emit_opcode(cbuf,0x83); // SUB ESP,4 3758 emit_opcode(cbuf,0xEC); 3759 emit_d8(cbuf,0x04); 3760 // Encoding assumes a double has been pushed into FPR0. 3761 // Store down the double as an int, popping the FPU stack 3762 emit_opcode(cbuf,0xDB); // FISTP [ESP] 3763 emit_opcode(cbuf,0x1C); 3764 emit_d8(cbuf,0x24); 3765 // Restore the rounding mode; mask the exception 3766 emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode 3767 emit_opcode(cbuf,0x2D); 3768 emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode() 3769 ? (int)StubRoutines::addr_fpu_cntrl_wrd_24() 3770 : (int)StubRoutines::addr_fpu_cntrl_wrd_std()); 3771 3772 // Load the converted int; adjust CPU stack 3773 emit_opcode(cbuf,0x58); // POP EAX 3774 emit_opcode(cbuf,0x3D); // CMP EAX,imm 3775 emit_d32 (cbuf,0x80000000); // 0x80000000 3776 emit_opcode(cbuf,0x75); // JNE around_slow_call 3777 emit_d8 (cbuf,0x07); // Size of slow_call 3778 // Push src onto stack slow-path 3779 emit_opcode(cbuf,0xD9 ); // FLD ST(i) 3780 emit_d8 (cbuf,0xC0-1+$src$$reg ); 3781 // CALL directly to the runtime 3782 cbuf.set_insts_mark(); 3783 emit_opcode(cbuf,0xE8); // Call into runtime 3784 emit_d32_reloc(cbuf, (StubRoutines::d2i_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 3785 // Carry on here... 3786 %} 3787 3788 enc_class D2L_encoding( regD src ) %{ 3789 emit_opcode(cbuf,0xD9); // FLDCW trunc 3790 emit_opcode(cbuf,0x2D); 3791 emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc()); 3792 // Allocate a word 3793 emit_opcode(cbuf,0x83); // SUB ESP,8 3794 emit_opcode(cbuf,0xEC); 3795 emit_d8(cbuf,0x08); 3796 // Encoding assumes a double has been pushed into FPR0. 3797 // Store down the double as a long, popping the FPU stack 3798 emit_opcode(cbuf,0xDF); // FISTP [ESP] 3799 emit_opcode(cbuf,0x3C); 3800 emit_d8(cbuf,0x24); 3801 // Restore the rounding mode; mask the exception 3802 emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode 3803 emit_opcode(cbuf,0x2D); 3804 emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode() 3805 ? (int)StubRoutines::addr_fpu_cntrl_wrd_24() 3806 : (int)StubRoutines::addr_fpu_cntrl_wrd_std()); 3807 3808 // Load the converted int; adjust CPU stack 3809 emit_opcode(cbuf,0x58); // POP EAX 3810 emit_opcode(cbuf,0x5A); // POP EDX 3811 emit_opcode(cbuf,0x81); // CMP EDX,imm 3812 emit_d8 (cbuf,0xFA); // rdx 3813 emit_d32 (cbuf,0x80000000); // 0x80000000 3814 emit_opcode(cbuf,0x75); // JNE around_slow_call 3815 emit_d8 (cbuf,0x07+4); // Size of slow_call 3816 emit_opcode(cbuf,0x85); // TEST EAX,EAX 3817 emit_opcode(cbuf,0xC0); // 2/rax,/rax, 3818 emit_opcode(cbuf,0x75); // JNE around_slow_call 3819 emit_d8 (cbuf,0x07); // Size of slow_call 3820 // Push src onto stack slow-path 3821 emit_opcode(cbuf,0xD9 ); // FLD ST(i) 3822 emit_d8 (cbuf,0xC0-1+$src$$reg ); 3823 // CALL directly to the runtime 3824 cbuf.set_insts_mark(); 3825 emit_opcode(cbuf,0xE8); // Call into runtime 3826 emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 3827 // Carry on here... 3828 %} 3829 3830 enc_class X2L_encoding( regX src ) %{ 3831 // Allocate a word 3832 emit_opcode(cbuf,0x83); // SUB ESP,8 3833 emit_opcode(cbuf,0xEC); 3834 emit_d8(cbuf,0x08); 3835 3836 emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src 3837 emit_opcode (cbuf, 0x0F ); 3838 emit_opcode (cbuf, 0x11 ); 3839 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false); 3840 3841 emit_opcode(cbuf,0xD9 ); // FLD_S [ESP] 3842 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 3843 3844 emit_opcode(cbuf,0xD9); // FLDCW trunc 3845 emit_opcode(cbuf,0x2D); 3846 emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc()); 3847 3848 // Encoding assumes a double has been pushed into FPR0. 3849 // Store down the double as a long, popping the FPU stack 3850 emit_opcode(cbuf,0xDF); // FISTP [ESP] 3851 emit_opcode(cbuf,0x3C); 3852 emit_d8(cbuf,0x24); 3853 3854 // Restore the rounding mode; mask the exception 3855 emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode 3856 emit_opcode(cbuf,0x2D); 3857 emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode() 3858 ? (int)StubRoutines::addr_fpu_cntrl_wrd_24() 3859 : (int)StubRoutines::addr_fpu_cntrl_wrd_std()); 3860 3861 // Load the converted int; adjust CPU stack 3862 emit_opcode(cbuf,0x58); // POP EAX 3863 3864 emit_opcode(cbuf,0x5A); // POP EDX 3865 3866 emit_opcode(cbuf,0x81); // CMP EDX,imm 3867 emit_d8 (cbuf,0xFA); // rdx 3868 emit_d32 (cbuf,0x80000000);// 0x80000000 3869 3870 emit_opcode(cbuf,0x75); // JNE around_slow_call 3871 emit_d8 (cbuf,0x13+4); // Size of slow_call 3872 3873 emit_opcode(cbuf,0x85); // TEST EAX,EAX 3874 emit_opcode(cbuf,0xC0); // 2/rax,/rax, 3875 3876 emit_opcode(cbuf,0x75); // JNE around_slow_call 3877 emit_d8 (cbuf,0x13); // Size of slow_call 3878 3879 // Allocate a word 3880 emit_opcode(cbuf,0x83); // SUB ESP,4 3881 emit_opcode(cbuf,0xEC); 3882 emit_d8(cbuf,0x04); 3883 3884 emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], src 3885 emit_opcode (cbuf, 0x0F ); 3886 emit_opcode (cbuf, 0x11 ); 3887 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false); 3888 3889 emit_opcode(cbuf,0xD9 ); // FLD_S [ESP] 3890 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 3891 3892 emit_opcode(cbuf,0x83); // ADD ESP,4 3893 emit_opcode(cbuf,0xC4); 3894 emit_d8(cbuf,0x04); 3895 3896 // CALL directly to the runtime 3897 cbuf.set_insts_mark(); 3898 emit_opcode(cbuf,0xE8); // Call into runtime 3899 emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 3900 // Carry on here... 3901 %} 3902 3903 enc_class XD2L_encoding( regXD src ) %{ 3904 // Allocate a word 3905 emit_opcode(cbuf,0x83); // SUB ESP,8 3906 emit_opcode(cbuf,0xEC); 3907 emit_d8(cbuf,0x08); 3908 3909 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src 3910 emit_opcode (cbuf, 0x0F ); 3911 emit_opcode (cbuf, 0x11 ); 3912 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false); 3913 3914 emit_opcode(cbuf,0xDD ); // FLD_D [ESP] 3915 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 3916 3917 emit_opcode(cbuf,0xD9); // FLDCW trunc 3918 emit_opcode(cbuf,0x2D); 3919 emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc()); 3920 3921 // Encoding assumes a double has been pushed into FPR0. 3922 // Store down the double as a long, popping the FPU stack 3923 emit_opcode(cbuf,0xDF); // FISTP [ESP] 3924 emit_opcode(cbuf,0x3C); 3925 emit_d8(cbuf,0x24); 3926 3927 // Restore the rounding mode; mask the exception 3928 emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode 3929 emit_opcode(cbuf,0x2D); 3930 emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode() 3931 ? (int)StubRoutines::addr_fpu_cntrl_wrd_24() 3932 : (int)StubRoutines::addr_fpu_cntrl_wrd_std()); 3933 3934 // Load the converted int; adjust CPU stack 3935 emit_opcode(cbuf,0x58); // POP EAX 3936 3937 emit_opcode(cbuf,0x5A); // POP EDX 3938 3939 emit_opcode(cbuf,0x81); // CMP EDX,imm 3940 emit_d8 (cbuf,0xFA); // rdx 3941 emit_d32 (cbuf,0x80000000); // 0x80000000 3942 3943 emit_opcode(cbuf,0x75); // JNE around_slow_call 3944 emit_d8 (cbuf,0x13+4); // Size of slow_call 3945 3946 emit_opcode(cbuf,0x85); // TEST EAX,EAX 3947 emit_opcode(cbuf,0xC0); // 2/rax,/rax, 3948 3949 emit_opcode(cbuf,0x75); // JNE around_slow_call 3950 emit_d8 (cbuf,0x13); // Size of slow_call 3951 3952 // Push src onto stack slow-path 3953 // Allocate a word 3954 emit_opcode(cbuf,0x83); // SUB ESP,8 3955 emit_opcode(cbuf,0xEC); 3956 emit_d8(cbuf,0x08); 3957 3958 emit_opcode (cbuf, 0xF2 ); // MOVSD [ESP], src 3959 emit_opcode (cbuf, 0x0F ); 3960 emit_opcode (cbuf, 0x11 ); 3961 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false); 3962 3963 emit_opcode(cbuf,0xDD ); // FLD_D [ESP] 3964 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 3965 3966 emit_opcode(cbuf,0x83); // ADD ESP,8 3967 emit_opcode(cbuf,0xC4); 3968 emit_d8(cbuf,0x08); 3969 3970 // CALL directly to the runtime 3971 cbuf.set_insts_mark(); 3972 emit_opcode(cbuf,0xE8); // Call into runtime 3973 emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 3974 // Carry on here... 3975 %} 3976 3977 enc_class D2X_encoding( regX dst, regD src ) %{ 3978 // Allocate a word 3979 emit_opcode(cbuf,0x83); // SUB ESP,4 3980 emit_opcode(cbuf,0xEC); 3981 emit_d8(cbuf,0x04); 3982 int pop = 0x02; 3983 if ($src$$reg != FPR1L_enc) { 3984 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1) 3985 emit_d8( cbuf, 0xC0-1+$src$$reg ); 3986 pop = 0x03; 3987 } 3988 store_to_stackslot( cbuf, 0xD9, pop, 0 ); // FST<P>_S [ESP] 3989 3990 emit_opcode (cbuf, 0xF3 ); // MOVSS dst(xmm), [ESP] 3991 emit_opcode (cbuf, 0x0F ); 3992 emit_opcode (cbuf, 0x10 ); 3993 encode_RegMem(cbuf, $dst$$reg, ESP_enc, 0x4, 0, 0, false); 3994 3995 emit_opcode(cbuf,0x83); // ADD ESP,4 3996 emit_opcode(cbuf,0xC4); 3997 emit_d8(cbuf,0x04); 3998 // Carry on here... 3999 %} 4000 4001 enc_class FX2I_encoding( regX src, eRegI dst ) %{ 4002 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 4003 4004 // Compare the result to see if we need to go to the slow path 4005 emit_opcode(cbuf,0x81); // CMP dst,imm 4006 emit_rm (cbuf,0x3,0x7,$dst$$reg); 4007 emit_d32 (cbuf,0x80000000); // 0x80000000 4008 4009 emit_opcode(cbuf,0x75); // JNE around_slow_call 4010 emit_d8 (cbuf,0x13); // Size of slow_call 4011 // Store xmm to a temp memory 4012 // location and push it onto stack. 4013 4014 emit_opcode(cbuf,0x83); // SUB ESP,4 4015 emit_opcode(cbuf,0xEC); 4016 emit_d8(cbuf, $primary ? 0x8 : 0x4); 4017 4018 emit_opcode (cbuf, $primary ? 0xF2 : 0xF3 ); // MOVSS [ESP], xmm 4019 emit_opcode (cbuf, 0x0F ); 4020 emit_opcode (cbuf, 0x11 ); 4021 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false); 4022 4023 emit_opcode(cbuf, $primary ? 0xDD : 0xD9 ); // FLD [ESP] 4024 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 4025 4026 emit_opcode(cbuf,0x83); // ADD ESP,4 4027 emit_opcode(cbuf,0xC4); 4028 emit_d8(cbuf, $primary ? 0x8 : 0x4); 4029 4030 // CALL directly to the runtime 4031 cbuf.set_insts_mark(); 4032 emit_opcode(cbuf,0xE8); // Call into runtime 4033 emit_d32_reloc(cbuf, (StubRoutines::d2i_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 4034 4035 // Carry on here... 4036 %} 4037 4038 enc_class X2D_encoding( regD dst, regX src ) %{ 4039 // Allocate a word 4040 emit_opcode(cbuf,0x83); // SUB ESP,4 4041 emit_opcode(cbuf,0xEC); 4042 emit_d8(cbuf,0x04); 4043 4044 emit_opcode (cbuf, 0xF3 ); // MOVSS [ESP], xmm 4045 emit_opcode (cbuf, 0x0F ); 4046 emit_opcode (cbuf, 0x11 ); 4047 encode_RegMem(cbuf, $src$$reg, ESP_enc, 0x4, 0, 0, false); 4048 4049 emit_opcode(cbuf,0xD9 ); // FLD_S [ESP] 4050 encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false); 4051 4052 emit_opcode(cbuf,0x83); // ADD ESP,4 4053 emit_opcode(cbuf,0xC4); 4054 emit_d8(cbuf,0x04); 4055 4056 // Carry on here... 4057 %} 4058 4059 enc_class AbsXF_encoding(regX dst) %{ 4060 address signmask_address=(address)float_signmask_pool; 4061 // andpd:\tANDPS $dst,[signconst] 4062 emit_opcode(cbuf, 0x0F); 4063 emit_opcode(cbuf, 0x54); 4064 emit_rm(cbuf, 0x0, $dst$$reg, 0x5); 4065 emit_d32(cbuf, (int)signmask_address); 4066 %} 4067 4068 enc_class AbsXD_encoding(regXD dst) %{ 4069 address signmask_address=(address)double_signmask_pool; 4070 // andpd:\tANDPD $dst,[signconst] 4071 emit_opcode(cbuf, 0x66); 4072 emit_opcode(cbuf, 0x0F); 4073 emit_opcode(cbuf, 0x54); 4074 emit_rm(cbuf, 0x0, $dst$$reg, 0x5); 4075 emit_d32(cbuf, (int)signmask_address); 4076 %} 4077 4078 enc_class NegXF_encoding(regX dst) %{ 4079 address signmask_address=(address)float_signflip_pool; 4080 // andpd:\tXORPS $dst,[signconst] 4081 emit_opcode(cbuf, 0x0F); 4082 emit_opcode(cbuf, 0x57); 4083 emit_rm(cbuf, 0x0, $dst$$reg, 0x5); 4084 emit_d32(cbuf, (int)signmask_address); 4085 %} 4086 4087 enc_class NegXD_encoding(regXD dst) %{ 4088 address signmask_address=(address)double_signflip_pool; 4089 // andpd:\tXORPD $dst,[signconst] 4090 emit_opcode(cbuf, 0x66); 4091 emit_opcode(cbuf, 0x0F); 4092 emit_opcode(cbuf, 0x57); 4093 emit_rm(cbuf, 0x0, $dst$$reg, 0x5); 4094 emit_d32(cbuf, (int)signmask_address); 4095 %} 4096 4097 enc_class FMul_ST_reg( eRegF src1 ) %{ 4098 // Operand was loaded from memory into fp ST (stack top) 4099 // FMUL ST,$src /* D8 C8+i */ 4100 emit_opcode(cbuf, 0xD8); 4101 emit_opcode(cbuf, 0xC8 + $src1$$reg); 4102 %} 4103 4104 enc_class FAdd_ST_reg( eRegF src2 ) %{ 4105 // FADDP ST,src2 /* D8 C0+i */ 4106 emit_opcode(cbuf, 0xD8); 4107 emit_opcode(cbuf, 0xC0 + $src2$$reg); 4108 //could use FADDP src2,fpST /* DE C0+i */ 4109 %} 4110 4111 enc_class FAddP_reg_ST( eRegF src2 ) %{ 4112 // FADDP src2,ST /* DE C0+i */ 4113 emit_opcode(cbuf, 0xDE); 4114 emit_opcode(cbuf, 0xC0 + $src2$$reg); 4115 %} 4116 4117 enc_class subF_divF_encode( eRegF src1, eRegF src2) %{ 4118 // Operand has been loaded into fp ST (stack top) 4119 // FSUB ST,$src1 4120 emit_opcode(cbuf, 0xD8); 4121 emit_opcode(cbuf, 0xE0 + $src1$$reg); 4122 4123 // FDIV 4124 emit_opcode(cbuf, 0xD8); 4125 emit_opcode(cbuf, 0xF0 + $src2$$reg); 4126 %} 4127 4128 enc_class MulFAddF (eRegF src1, eRegF src2) %{ 4129 // Operand was loaded from memory into fp ST (stack top) 4130 // FADD ST,$src /* D8 C0+i */ 4131 emit_opcode(cbuf, 0xD8); 4132 emit_opcode(cbuf, 0xC0 + $src1$$reg); 4133 4134 // FMUL ST,src2 /* D8 C*+i */ 4135 emit_opcode(cbuf, 0xD8); 4136 emit_opcode(cbuf, 0xC8 + $src2$$reg); 4137 %} 4138 4139 4140 enc_class MulFAddFreverse (eRegF src1, eRegF src2) %{ 4141 // Operand was loaded from memory into fp ST (stack top) 4142 // FADD ST,$src /* D8 C0+i */ 4143 emit_opcode(cbuf, 0xD8); 4144 emit_opcode(cbuf, 0xC0 + $src1$$reg); 4145 4146 // FMULP src2,ST /* DE C8+i */ 4147 emit_opcode(cbuf, 0xDE); 4148 emit_opcode(cbuf, 0xC8 + $src2$$reg); 4149 %} 4150 4151 // Atomically load the volatile long 4152 enc_class enc_loadL_volatile( memory mem, stackSlotL dst ) %{ 4153 emit_opcode(cbuf,0xDF); 4154 int rm_byte_opcode = 0x05; 4155 int base = $mem$$base; 4156 int index = $mem$$index; 4157 int scale = $mem$$scale; 4158 int displace = $mem$$disp; 4159 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals 4160 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop); 4161 store_to_stackslot( cbuf, 0x0DF, 0x07, $dst$$disp ); 4162 %} 4163 4164 enc_class enc_loadLX_volatile( memory mem, stackSlotL dst, regXD tmp ) %{ 4165 { // Atomic long load 4166 // UseXmmLoadAndClearUpper ? movsd $tmp,$mem : movlpd $tmp,$mem 4167 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 4168 emit_opcode(cbuf,0x0F); 4169 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0x10 : 0x12); 4170 int base = $mem$$base; 4171 int index = $mem$$index; 4172 int scale = $mem$$scale; 4173 int displace = $mem$$disp; 4174 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals 4175 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop); 4176 } 4177 { // MOVSD $dst,$tmp ! atomic long store 4178 emit_opcode(cbuf,0xF2); 4179 emit_opcode(cbuf,0x0F); 4180 emit_opcode(cbuf,0x11); 4181 int base = $dst$$base; 4182 int index = $dst$$index; 4183 int scale = $dst$$scale; 4184 int displace = $dst$$disp; 4185 bool disp_is_oop = $dst->disp_is_oop(); // disp-as-oop when working with static globals 4186 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop); 4187 } 4188 %} 4189 4190 enc_class enc_loadLX_reg_volatile( memory mem, eRegL dst, regXD tmp ) %{ 4191 { // Atomic long load 4192 // UseXmmLoadAndClearUpper ? movsd $tmp,$mem : movlpd $tmp,$mem 4193 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 4194 emit_opcode(cbuf,0x0F); 4195 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0x10 : 0x12); 4196 int base = $mem$$base; 4197 int index = $mem$$index; 4198 int scale = $mem$$scale; 4199 int displace = $mem$$disp; 4200 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals 4201 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop); 4202 } 4203 { // MOVD $dst.lo,$tmp 4204 emit_opcode(cbuf,0x66); 4205 emit_opcode(cbuf,0x0F); 4206 emit_opcode(cbuf,0x7E); 4207 emit_rm(cbuf, 0x3, $tmp$$reg, $dst$$reg); 4208 } 4209 { // PSRLQ $tmp,32 4210 emit_opcode(cbuf,0x66); 4211 emit_opcode(cbuf,0x0F); 4212 emit_opcode(cbuf,0x73); 4213 emit_rm(cbuf, 0x3, 0x02, $tmp$$reg); 4214 emit_d8(cbuf, 0x20); 4215 } 4216 { // MOVD $dst.hi,$tmp 4217 emit_opcode(cbuf,0x66); 4218 emit_opcode(cbuf,0x0F); 4219 emit_opcode(cbuf,0x7E); 4220 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg)); 4221 } 4222 %} 4223 4224 // Volatile Store Long. Must be atomic, so move it into 4225 // the FP TOS and then do a 64-bit FIST. Has to probe the 4226 // target address before the store (for null-ptr checks) 4227 // so the memory operand is used twice in the encoding. 4228 enc_class enc_storeL_volatile( memory mem, stackSlotL src ) %{ 4229 store_to_stackslot( cbuf, 0x0DF, 0x05, $src$$disp ); 4230 cbuf.set_insts_mark(); // Mark start of FIST in case $mem has an oop 4231 emit_opcode(cbuf,0xDF); 4232 int rm_byte_opcode = 0x07; 4233 int base = $mem$$base; 4234 int index = $mem$$index; 4235 int scale = $mem$$scale; 4236 int displace = $mem$$disp; 4237 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals 4238 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop); 4239 %} 4240 4241 enc_class enc_storeLX_volatile( memory mem, stackSlotL src, regXD tmp) %{ 4242 { // Atomic long load 4243 // UseXmmLoadAndClearUpper ? movsd $tmp,[$src] : movlpd $tmp,[$src] 4244 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0xF2 : 0x66); 4245 emit_opcode(cbuf,0x0F); 4246 emit_opcode(cbuf,UseXmmLoadAndClearUpper ? 0x10 : 0x12); 4247 int base = $src$$base; 4248 int index = $src$$index; 4249 int scale = $src$$scale; 4250 int displace = $src$$disp; 4251 bool disp_is_oop = $src->disp_is_oop(); // disp-as-oop when working with static globals 4252 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop); 4253 } 4254 cbuf.set_insts_mark(); // Mark start of MOVSD in case $mem has an oop 4255 { // MOVSD $mem,$tmp ! atomic long store 4256 emit_opcode(cbuf,0xF2); 4257 emit_opcode(cbuf,0x0F); 4258 emit_opcode(cbuf,0x11); 4259 int base = $mem$$base; 4260 int index = $mem$$index; 4261 int scale = $mem$$scale; 4262 int displace = $mem$$disp; 4263 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals 4264 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop); 4265 } 4266 %} 4267 4268 enc_class enc_storeLX_reg_volatile( memory mem, eRegL src, regXD tmp, regXD tmp2) %{ 4269 { // MOVD $tmp,$src.lo 4270 emit_opcode(cbuf,0x66); 4271 emit_opcode(cbuf,0x0F); 4272 emit_opcode(cbuf,0x6E); 4273 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg); 4274 } 4275 { // MOVD $tmp2,$src.hi 4276 emit_opcode(cbuf,0x66); 4277 emit_opcode(cbuf,0x0F); 4278 emit_opcode(cbuf,0x6E); 4279 emit_rm(cbuf, 0x3, $tmp2$$reg, HIGH_FROM_LOW($src$$reg)); 4280 } 4281 { // PUNPCKLDQ $tmp,$tmp2 4282 emit_opcode(cbuf,0x66); 4283 emit_opcode(cbuf,0x0F); 4284 emit_opcode(cbuf,0x62); 4285 emit_rm(cbuf, 0x3, $tmp$$reg, $tmp2$$reg); 4286 } 4287 cbuf.set_insts_mark(); // Mark start of MOVSD in case $mem has an oop 4288 { // MOVSD $mem,$tmp ! atomic long store 4289 emit_opcode(cbuf,0xF2); 4290 emit_opcode(cbuf,0x0F); 4291 emit_opcode(cbuf,0x11); 4292 int base = $mem$$base; 4293 int index = $mem$$index; 4294 int scale = $mem$$scale; 4295 int displace = $mem$$disp; 4296 bool disp_is_oop = $mem->disp_is_oop(); // disp-as-oop when working with static globals 4297 encode_RegMem(cbuf, $tmp$$reg, base, index, scale, displace, disp_is_oop); 4298 } 4299 %} 4300 4301 // Safepoint Poll. This polls the safepoint page, and causes an 4302 // exception if it is not readable. Unfortunately, it kills the condition code 4303 // in the process 4304 // We current use TESTL [spp],EDI 4305 // A better choice might be TESTB [spp + pagesize() - CacheLineSize()],0 4306 4307 enc_class Safepoint_Poll() %{ 4308 cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0); 4309 emit_opcode(cbuf,0x85); 4310 emit_rm (cbuf, 0x0, 0x7, 0x5); 4311 emit_d32(cbuf, (intptr_t)os::get_polling_page()); 4312 %} 4313%} 4314 4315 4316//----------FRAME-------------------------------------------------------------- 4317// Definition of frame structure and management information. 4318// 4319// S T A C K L A Y O U T Allocators stack-slot number 4320// | (to get allocators register number 4321// G Owned by | | v add OptoReg::stack0()) 4322// r CALLER | | 4323// o | +--------+ pad to even-align allocators stack-slot 4324// w V | pad0 | numbers; owned by CALLER 4325// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 4326// h ^ | in | 5 4327// | | args | 4 Holes in incoming args owned by SELF 4328// | | | | 3 4329// | | +--------+ 4330// V | | old out| Empty on Intel, window on Sparc 4331// | old |preserve| Must be even aligned. 4332// | SP-+--------+----> Matcher::_old_SP, even aligned 4333// | | in | 3 area for Intel ret address 4334// Owned by |preserve| Empty on Sparc. 4335// SELF +--------+ 4336// | | pad2 | 2 pad to align old SP 4337// | +--------+ 1 4338// | | locks | 0 4339// | +--------+----> OptoReg::stack0(), even aligned 4340// | | pad1 | 11 pad to align new SP 4341// | +--------+ 4342// | | | 10 4343// | | spills | 9 spills 4344// V | | 8 (pad0 slot for callee) 4345// -----------+--------+----> Matcher::_out_arg_limit, unaligned 4346// ^ | out | 7 4347// | | args | 6 Holes in outgoing args owned by CALLEE 4348// Owned by +--------+ 4349// CALLEE | new out| 6 Empty on Intel, window on Sparc 4350// | new |preserve| Must be even-aligned. 4351// | SP-+--------+----> Matcher::_new_SP, even aligned 4352// | | | 4353// 4354// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 4355// known from SELF's arguments and the Java calling convention. 4356// Region 6-7 is determined per call site. 4357// Note 2: If the calling convention leaves holes in the incoming argument 4358// area, those holes are owned by SELF. Holes in the outgoing area 4359// are owned by the CALLEE. Holes should not be nessecary in the 4360// incoming area, as the Java calling convention is completely under 4361// the control of the AD file. Doubles can be sorted and packed to 4362// avoid holes. Holes in the outgoing arguments may be nessecary for 4363// varargs C calling conventions. 4364// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 4365// even aligned with pad0 as needed. 4366// Region 6 is even aligned. Region 6-7 is NOT even aligned; 4367// region 6-11 is even aligned; it may be padded out more so that 4368// the region from SP to FP meets the minimum stack alignment. 4369 4370frame %{ 4371 // What direction does stack grow in (assumed to be same for C & Java) 4372 stack_direction(TOWARDS_LOW); 4373 4374 // These three registers define part of the calling convention 4375 // between compiled code and the interpreter. 4376 inline_cache_reg(EAX); // Inline Cache Register 4377 interpreter_method_oop_reg(EBX); // Method Oop Register when calling interpreter 4378 4379 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset] 4380 cisc_spilling_operand_name(indOffset32); 4381 4382 // Number of stack slots consumed by locking an object 4383 sync_stack_slots(1); 4384 4385 // Compiled code's Frame Pointer 4386 frame_pointer(ESP); 4387 // Interpreter stores its frame pointer in a register which is 4388 // stored to the stack by I2CAdaptors. 4389 // I2CAdaptors convert from interpreted java to compiled java. 4390 interpreter_frame_pointer(EBP); 4391 4392 // Stack alignment requirement 4393 // Alignment size in bytes (128-bit -> 16 bytes) 4394 stack_alignment(StackAlignmentInBytes); 4395 4396 // Number of stack slots between incoming argument block and the start of 4397 // a new frame. The PROLOG must add this many slots to the stack. The 4398 // EPILOG must remove this many slots. Intel needs one slot for 4399 // return address and one for rbp, (must save rbp) 4400 in_preserve_stack_slots(2+VerifyStackAtCalls); 4401 4402 // Number of outgoing stack slots killed above the out_preserve_stack_slots 4403 // for calls to C. Supports the var-args backing area for register parms. 4404 varargs_C_out_slots_killed(0); 4405 4406 // The after-PROLOG location of the return address. Location of 4407 // return address specifies a type (REG or STACK) and a number 4408 // representing the register number (i.e. - use a register name) or 4409 // stack slot. 4410 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 4411 // Otherwise, it is above the locks and verification slot and alignment word 4412 return_addr(STACK - 1 + 4413 round_to(1+VerifyStackAtCalls+ 4414 Compile::current()->fixed_slots(), 4415 (StackAlignmentInBytes/wordSize))); 4416 4417 // Body of function which returns an integer array locating 4418 // arguments either in registers or in stack slots. Passed an array 4419 // of ideal registers called "sig" and a "length" count. Stack-slot 4420 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4421 // arguments for a CALLEE. Incoming stack arguments are 4422 // automatically biased by the preserve_stack_slots field above. 4423 calling_convention %{ 4424 // No difference between ingoing/outgoing just pass false 4425 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 4426 %} 4427 4428 4429 // Body of function which returns an integer array locating 4430 // arguments either in registers or in stack slots. Passed an array 4431 // of ideal registers called "sig" and a "length" count. Stack-slot 4432 // offsets are based on outgoing arguments, i.e. a CALLER setting up 4433 // arguments for a CALLEE. Incoming stack arguments are 4434 // automatically biased by the preserve_stack_slots field above. 4435 c_calling_convention %{ 4436 // This is obviously always outgoing 4437 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); 4438 %} 4439 4440 // Location of C & interpreter return values 4441 c_return_value %{ 4442 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); 4443 static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num, EAX_num, FPR1L_num, FPR1L_num, EAX_num }; 4444 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num }; 4445 4446 // in SSE2+ mode we want to keep the FPU stack clean so pretend 4447 // that C functions return float and double results in XMM0. 4448 if( ideal_reg == Op_RegD && UseSSE>=2 ) 4449 return OptoRegPair(XMM0b_num,XMM0a_num); 4450 if( ideal_reg == Op_RegF && UseSSE>=2 ) 4451 return OptoRegPair(OptoReg::Bad,XMM0a_num); 4452 4453 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]); 4454 %} 4455 4456 // Location of return values 4457 return_value %{ 4458 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); 4459 static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num, EAX_num, FPR1L_num, FPR1L_num, EAX_num }; 4460 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num }; 4461 if( ideal_reg == Op_RegD && UseSSE>=2 ) 4462 return OptoRegPair(XMM0b_num,XMM0a_num); 4463 if( ideal_reg == Op_RegF && UseSSE>=1 ) 4464 return OptoRegPair(OptoReg::Bad,XMM0a_num); 4465 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]); 4466 %} 4467 4468%} 4469 4470//----------ATTRIBUTES--------------------------------------------------------- 4471//----------Operand Attributes------------------------------------------------- 4472op_attrib op_cost(0); // Required cost attribute 4473 4474//----------Instruction Attributes--------------------------------------------- 4475ins_attrib ins_cost(100); // Required cost attribute 4476ins_attrib ins_size(8); // Required size attribute (in bits) 4477ins_attrib ins_short_branch(0); // Required flag: is this instruction a 4478 // non-matching short branch variant of some 4479 // long branch? 4480ins_attrib ins_alignment(1); // Required alignment attribute (must be a power of 2) 4481 // specifies the alignment that some part of the instruction (not 4482 // necessarily the start) requires. If > 1, a compute_padding() 4483 // function must be provided for the instruction 4484 4485//----------OPERANDS----------------------------------------------------------- 4486// Operand definitions must precede instruction definitions for correct parsing 4487// in the ADLC because operands constitute user defined types which are used in 4488// instruction definitions. 4489 4490//----------Simple Operands---------------------------------------------------- 4491// Immediate Operands 4492// Integer Immediate 4493operand immI() %{ 4494 match(ConI); 4495 4496 op_cost(10); 4497 format %{ %} 4498 interface(CONST_INTER); 4499%} 4500 4501// Constant for test vs zero 4502operand immI0() %{ 4503 predicate(n->get_int() == 0); 4504 match(ConI); 4505 4506 op_cost(0); 4507 format %{ %} 4508 interface(CONST_INTER); 4509%} 4510 4511// Constant for increment 4512operand immI1() %{ 4513 predicate(n->get_int() == 1); 4514 match(ConI); 4515 4516 op_cost(0); 4517 format %{ %} 4518 interface(CONST_INTER); 4519%} 4520 4521// Constant for decrement 4522operand immI_M1() %{ 4523 predicate(n->get_int() == -1); 4524 match(ConI); 4525 4526 op_cost(0); 4527 format %{ %} 4528 interface(CONST_INTER); 4529%} 4530 4531// Valid scale values for addressing modes 4532operand immI2() %{ 4533 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 4534 match(ConI); 4535 4536 format %{ %} 4537 interface(CONST_INTER); 4538%} 4539 4540operand immI8() %{ 4541 predicate((-128 <= n->get_int()) && (n->get_int() <= 127)); 4542 match(ConI); 4543 4544 op_cost(5); 4545 format %{ %} 4546 interface(CONST_INTER); 4547%} 4548 4549operand immI16() %{ 4550 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 4551 match(ConI); 4552 4553 op_cost(10); 4554 format %{ %} 4555 interface(CONST_INTER); 4556%} 4557 4558// Constant for long shifts 4559operand immI_32() %{ 4560 predicate( n->get_int() == 32 ); 4561 match(ConI); 4562 4563 op_cost(0); 4564 format %{ %} 4565 interface(CONST_INTER); 4566%} 4567 4568operand immI_1_31() %{ 4569 predicate( n->get_int() >= 1 && n->get_int() <= 31 ); 4570 match(ConI); 4571 4572 op_cost(0); 4573 format %{ %} 4574 interface(CONST_INTER); 4575%} 4576 4577operand immI_32_63() %{ 4578 predicate( n->get_int() >= 32 && n->get_int() <= 63 ); 4579 match(ConI); 4580 op_cost(0); 4581 4582 format %{ %} 4583 interface(CONST_INTER); 4584%} 4585 4586operand immI_1() %{ 4587 predicate( n->get_int() == 1 ); 4588 match(ConI); 4589 4590 op_cost(0); 4591 format %{ %} 4592 interface(CONST_INTER); 4593%} 4594 4595operand immI_2() %{ 4596 predicate( n->get_int() == 2 ); 4597 match(ConI); 4598 4599 op_cost(0); 4600 format %{ %} 4601 interface(CONST_INTER); 4602%} 4603 4604operand immI_3() %{ 4605 predicate( n->get_int() == 3 ); 4606 match(ConI); 4607 4608 op_cost(0); 4609 format %{ %} 4610 interface(CONST_INTER); 4611%} 4612 4613// Pointer Immediate 4614operand immP() %{ 4615 match(ConP); 4616 4617 op_cost(10); 4618 format %{ %} 4619 interface(CONST_INTER); 4620%} 4621 4622// NULL Pointer Immediate 4623operand immP0() %{ 4624 predicate( n->get_ptr() == 0 ); 4625 match(ConP); 4626 op_cost(0); 4627 4628 format %{ %} 4629 interface(CONST_INTER); 4630%} 4631 4632// Long Immediate 4633operand immL() %{ 4634 match(ConL); 4635 4636 op_cost(20); 4637 format %{ %} 4638 interface(CONST_INTER); 4639%} 4640 4641// Long Immediate zero 4642operand immL0() %{ 4643 predicate( n->get_long() == 0L ); 4644 match(ConL); 4645 op_cost(0); 4646 4647 format %{ %} 4648 interface(CONST_INTER); 4649%} 4650 4651// Long Immediate zero 4652operand immL_M1() %{ 4653 predicate( n->get_long() == -1L ); 4654 match(ConL); 4655 op_cost(0); 4656 4657 format %{ %} 4658 interface(CONST_INTER); 4659%} 4660 4661// Long immediate from 0 to 127. 4662// Used for a shorter form of long mul by 10. 4663operand immL_127() %{ 4664 predicate((0 <= n->get_long()) && (n->get_long() <= 127)); 4665 match(ConL); 4666 op_cost(0); 4667 4668 format %{ %} 4669 interface(CONST_INTER); 4670%} 4671 4672// Long Immediate: low 32-bit mask 4673operand immL_32bits() %{ 4674 predicate(n->get_long() == 0xFFFFFFFFL); 4675 match(ConL); 4676 op_cost(0); 4677 4678 format %{ %} 4679 interface(CONST_INTER); 4680%} 4681 4682// Long Immediate: low 32-bit mask 4683operand immL32() %{ 4684 predicate(n->get_long() == (int)(n->get_long())); 4685 match(ConL); 4686 op_cost(20); 4687 4688 format %{ %} 4689 interface(CONST_INTER); 4690%} 4691 4692//Double Immediate zero 4693operand immD0() %{ 4694 // Do additional (and counter-intuitive) test against NaN to work around VC++ 4695 // bug that generates code such that NaNs compare equal to 0.0 4696 predicate( UseSSE<=1 && n->getd() == 0.0 && !g_isnan(n->getd()) ); 4697 match(ConD); 4698 4699 op_cost(5); 4700 format %{ %} 4701 interface(CONST_INTER); 4702%} 4703 4704// Double Immediate one 4705operand immD1() %{ 4706 predicate( UseSSE<=1 && n->getd() == 1.0 ); 4707 match(ConD); 4708 4709 op_cost(5); 4710 format %{ %} 4711 interface(CONST_INTER); 4712%} 4713 4714// Double Immediate 4715operand immD() %{ 4716 predicate(UseSSE<=1); 4717 match(ConD); 4718 4719 op_cost(5); 4720 format %{ %} 4721 interface(CONST_INTER); 4722%} 4723 4724operand immXD() %{ 4725 predicate(UseSSE>=2); 4726 match(ConD); 4727 4728 op_cost(5); 4729 format %{ %} 4730 interface(CONST_INTER); 4731%} 4732 4733// Double Immediate zero 4734operand immXD0() %{ 4735 // Do additional (and counter-intuitive) test against NaN to work around VC++ 4736 // bug that generates code such that NaNs compare equal to 0.0 AND do not 4737 // compare equal to -0.0. 4738 predicate( UseSSE>=2 && jlong_cast(n->getd()) == 0 ); 4739 match(ConD); 4740 4741 format %{ %} 4742 interface(CONST_INTER); 4743%} 4744 4745// Float Immediate zero 4746operand immF0() %{ 4747 predicate(UseSSE == 0 && n->getf() == 0.0F); 4748 match(ConF); 4749 4750 op_cost(5); 4751 format %{ %} 4752 interface(CONST_INTER); 4753%} 4754 4755// Float Immediate one 4756operand immF1() %{ 4757 predicate(UseSSE == 0 && n->getf() == 1.0F); 4758 match(ConF); 4759 4760 op_cost(5); 4761 format %{ %} 4762 interface(CONST_INTER); 4763%} 4764 4765// Float Immediate 4766operand immF() %{ 4767 predicate( UseSSE == 0 ); 4768 match(ConF); 4769 4770 op_cost(5); 4771 format %{ %} 4772 interface(CONST_INTER); 4773%} 4774 4775// Float Immediate 4776operand immXF() %{ 4777 predicate(UseSSE >= 1); 4778 match(ConF); 4779 4780 op_cost(5); 4781 format %{ %} 4782 interface(CONST_INTER); 4783%} 4784 4785// Float Immediate zero. Zero and not -0.0 4786operand immXF0() %{ 4787 predicate( UseSSE >= 1 && jint_cast(n->getf()) == 0 ); 4788 match(ConF); 4789 4790 op_cost(5); 4791 format %{ %} 4792 interface(CONST_INTER); 4793%} 4794 4795// Immediates for special shifts (sign extend) 4796 4797// Constants for increment 4798operand immI_16() %{ 4799 predicate( n->get_int() == 16 ); 4800 match(ConI); 4801 4802 format %{ %} 4803 interface(CONST_INTER); 4804%} 4805 4806operand immI_24() %{ 4807 predicate( n->get_int() == 24 ); 4808 match(ConI); 4809 4810 format %{ %} 4811 interface(CONST_INTER); 4812%} 4813 4814// Constant for byte-wide masking 4815operand immI_255() %{ 4816 predicate( n->get_int() == 255 ); 4817 match(ConI); 4818 4819 format %{ %} 4820 interface(CONST_INTER); 4821%} 4822 4823// Constant for short-wide masking 4824operand immI_65535() %{ 4825 predicate(n->get_int() == 65535); 4826 match(ConI); 4827 4828 format %{ %} 4829 interface(CONST_INTER); 4830%} 4831 4832// Register Operands 4833// Integer Register 4834operand eRegI() %{ 4835 constraint(ALLOC_IN_RC(e_reg)); 4836 match(RegI); 4837 match(xRegI); 4838 match(eAXRegI); 4839 match(eBXRegI); 4840 match(eCXRegI); 4841 match(eDXRegI); 4842 match(eDIRegI); 4843 match(eSIRegI); 4844 4845 format %{ %} 4846 interface(REG_INTER); 4847%} 4848 4849// Subset of Integer Register 4850operand xRegI(eRegI reg) %{ 4851 constraint(ALLOC_IN_RC(x_reg)); 4852 match(reg); 4853 match(eAXRegI); 4854 match(eBXRegI); 4855 match(eCXRegI); 4856 match(eDXRegI); 4857 4858 format %{ %} 4859 interface(REG_INTER); 4860%} 4861 4862// Special Registers 4863operand eAXRegI(xRegI reg) %{ 4864 constraint(ALLOC_IN_RC(eax_reg)); 4865 match(reg); 4866 match(eRegI); 4867 4868 format %{ "EAX" %} 4869 interface(REG_INTER); 4870%} 4871 4872// Special Registers 4873operand eBXRegI(xRegI reg) %{ 4874 constraint(ALLOC_IN_RC(ebx_reg)); 4875 match(reg); 4876 match(eRegI); 4877 4878 format %{ "EBX" %} 4879 interface(REG_INTER); 4880%} 4881 4882operand eCXRegI(xRegI reg) %{ 4883 constraint(ALLOC_IN_RC(ecx_reg)); 4884 match(reg); 4885 match(eRegI); 4886 4887 format %{ "ECX" %} 4888 interface(REG_INTER); 4889%} 4890 4891operand eDXRegI(xRegI reg) %{ 4892 constraint(ALLOC_IN_RC(edx_reg)); 4893 match(reg); 4894 match(eRegI); 4895 4896 format %{ "EDX" %} 4897 interface(REG_INTER); 4898%} 4899 4900operand eDIRegI(xRegI reg) %{ 4901 constraint(ALLOC_IN_RC(edi_reg)); 4902 match(reg); 4903 match(eRegI); 4904 4905 format %{ "EDI" %} 4906 interface(REG_INTER); 4907%} 4908 4909operand naxRegI() %{ 4910 constraint(ALLOC_IN_RC(nax_reg)); 4911 match(RegI); 4912 match(eCXRegI); 4913 match(eDXRegI); 4914 match(eSIRegI); 4915 match(eDIRegI); 4916 4917 format %{ %} 4918 interface(REG_INTER); 4919%} 4920 4921operand nadxRegI() %{ 4922 constraint(ALLOC_IN_RC(nadx_reg)); 4923 match(RegI); 4924 match(eBXRegI); 4925 match(eCXRegI); 4926 match(eSIRegI); 4927 match(eDIRegI); 4928 4929 format %{ %} 4930 interface(REG_INTER); 4931%} 4932 4933operand ncxRegI() %{ 4934 constraint(ALLOC_IN_RC(ncx_reg)); 4935 match(RegI); 4936 match(eAXRegI); 4937 match(eDXRegI); 4938 match(eSIRegI); 4939 match(eDIRegI); 4940 4941 format %{ %} 4942 interface(REG_INTER); 4943%} 4944 4945// // This operand was used by cmpFastUnlock, but conflicted with 'object' reg 4946// // 4947operand eSIRegI(xRegI reg) %{ 4948 constraint(ALLOC_IN_RC(esi_reg)); 4949 match(reg); 4950 match(eRegI); 4951 4952 format %{ "ESI" %} 4953 interface(REG_INTER); 4954%} 4955 4956// Pointer Register 4957operand anyRegP() %{ 4958 constraint(ALLOC_IN_RC(any_reg)); 4959 match(RegP); 4960 match(eAXRegP); 4961 match(eBXRegP); 4962 match(eCXRegP); 4963 match(eDIRegP); 4964 match(eRegP); 4965 4966 format %{ %} 4967 interface(REG_INTER); 4968%} 4969 4970operand eRegP() %{ 4971 constraint(ALLOC_IN_RC(e_reg)); 4972 match(RegP); 4973 match(eAXRegP); 4974 match(eBXRegP); 4975 match(eCXRegP); 4976 match(eDIRegP); 4977 4978 format %{ %} 4979 interface(REG_INTER); 4980%} 4981 4982// On windows95, EBP is not safe to use for implicit null tests. 4983operand eRegP_no_EBP() %{ 4984 constraint(ALLOC_IN_RC(e_reg_no_rbp)); 4985 match(RegP); 4986 match(eAXRegP); 4987 match(eBXRegP); 4988 match(eCXRegP); 4989 match(eDIRegP); 4990 4991 op_cost(100); 4992 format %{ %} 4993 interface(REG_INTER); 4994%} 4995 4996operand naxRegP() %{ 4997 constraint(ALLOC_IN_RC(nax_reg)); 4998 match(RegP); 4999 match(eBXRegP); 5000 match(eDXRegP); 5001 match(eCXRegP); 5002 match(eSIRegP); 5003 match(eDIRegP); 5004 5005 format %{ %} 5006 interface(REG_INTER); 5007%} 5008 5009operand nabxRegP() %{ 5010 constraint(ALLOC_IN_RC(nabx_reg)); 5011 match(RegP); 5012 match(eCXRegP); 5013 match(eDXRegP); 5014 match(eSIRegP); 5015 match(eDIRegP); 5016 5017 format %{ %} 5018 interface(REG_INTER); 5019%} 5020 5021operand pRegP() %{ 5022 constraint(ALLOC_IN_RC(p_reg)); 5023 match(RegP); 5024 match(eBXRegP); 5025 match(eDXRegP); 5026 match(eSIRegP); 5027 match(eDIRegP); 5028 5029 format %{ %} 5030 interface(REG_INTER); 5031%} 5032 5033// Special Registers 5034// Return a pointer value 5035operand eAXRegP(eRegP reg) %{ 5036 constraint(ALLOC_IN_RC(eax_reg)); 5037 match(reg); 5038 format %{ "EAX" %} 5039 interface(REG_INTER); 5040%} 5041 5042// Used in AtomicAdd 5043operand eBXRegP(eRegP reg) %{ 5044 constraint(ALLOC_IN_RC(ebx_reg)); 5045 match(reg); 5046 format %{ "EBX" %} 5047 interface(REG_INTER); 5048%} 5049 5050// Tail-call (interprocedural jump) to interpreter 5051operand eCXRegP(eRegP reg) %{ 5052 constraint(ALLOC_IN_RC(ecx_reg)); 5053 match(reg); 5054 format %{ "ECX" %} 5055 interface(REG_INTER); 5056%} 5057 5058operand eSIRegP(eRegP reg) %{ 5059 constraint(ALLOC_IN_RC(esi_reg)); 5060 match(reg); 5061 format %{ "ESI" %} 5062 interface(REG_INTER); 5063%} 5064 5065// Used in rep stosw 5066operand eDIRegP(eRegP reg) %{ 5067 constraint(ALLOC_IN_RC(edi_reg)); 5068 match(reg); 5069 format %{ "EDI" %} 5070 interface(REG_INTER); 5071%} 5072 5073operand eBPRegP() %{ 5074 constraint(ALLOC_IN_RC(ebp_reg)); 5075 match(RegP); 5076 format %{ "EBP" %} 5077 interface(REG_INTER); 5078%} 5079 5080operand eRegL() %{ 5081 constraint(ALLOC_IN_RC(long_reg)); 5082 match(RegL); 5083 match(eADXRegL); 5084 5085 format %{ %} 5086 interface(REG_INTER); 5087%} 5088 5089operand eADXRegL( eRegL reg ) %{ 5090 constraint(ALLOC_IN_RC(eadx_reg)); 5091 match(reg); 5092 5093 format %{ "EDX:EAX" %} 5094 interface(REG_INTER); 5095%} 5096 5097operand eBCXRegL( eRegL reg ) %{ 5098 constraint(ALLOC_IN_RC(ebcx_reg)); 5099 match(reg); 5100 5101 format %{ "EBX:ECX" %} 5102 interface(REG_INTER); 5103%} 5104 5105// Special case for integer high multiply 5106operand eADXRegL_low_only() %{ 5107 constraint(ALLOC_IN_RC(eadx_reg)); 5108 match(RegL); 5109 5110 format %{ "EAX" %} 5111 interface(REG_INTER); 5112%} 5113 5114// Flags register, used as output of compare instructions 5115operand eFlagsReg() %{ 5116 constraint(ALLOC_IN_RC(int_flags)); 5117 match(RegFlags); 5118 5119 format %{ "EFLAGS" %} 5120 interface(REG_INTER); 5121%} 5122 5123// Flags register, used as output of FLOATING POINT compare instructions 5124operand eFlagsRegU() %{ 5125 constraint(ALLOC_IN_RC(int_flags)); 5126 match(RegFlags); 5127 5128 format %{ "EFLAGS_U" %} 5129 interface(REG_INTER); 5130%} 5131 5132operand eFlagsRegUCF() %{ 5133 constraint(ALLOC_IN_RC(int_flags)); 5134 match(RegFlags); 5135 predicate(false); 5136 5137 format %{ "EFLAGS_U_CF" %} 5138 interface(REG_INTER); 5139%} 5140 5141// Condition Code Register used by long compare 5142operand flagsReg_long_LTGE() %{ 5143 constraint(ALLOC_IN_RC(int_flags)); 5144 match(RegFlags); 5145 format %{ "FLAGS_LTGE" %} 5146 interface(REG_INTER); 5147%} 5148operand flagsReg_long_EQNE() %{ 5149 constraint(ALLOC_IN_RC(int_flags)); 5150 match(RegFlags); 5151 format %{ "FLAGS_EQNE" %} 5152 interface(REG_INTER); 5153%} 5154operand flagsReg_long_LEGT() %{ 5155 constraint(ALLOC_IN_RC(int_flags)); 5156 match(RegFlags); 5157 format %{ "FLAGS_LEGT" %} 5158 interface(REG_INTER); 5159%} 5160 5161// Float register operands 5162operand regD() %{ 5163 predicate( UseSSE < 2 ); 5164 constraint(ALLOC_IN_RC(dbl_reg)); 5165 match(RegD); 5166 match(regDPR1); 5167 match(regDPR2); 5168 format %{ %} 5169 interface(REG_INTER); 5170%} 5171 5172operand regDPR1(regD reg) %{ 5173 predicate( UseSSE < 2 ); 5174 constraint(ALLOC_IN_RC(dbl_reg0)); 5175 match(reg); 5176 format %{ "FPR1" %} 5177 interface(REG_INTER); 5178%} 5179 5180operand regDPR2(regD reg) %{ 5181 predicate( UseSSE < 2 ); 5182 constraint(ALLOC_IN_RC(dbl_reg1)); 5183 match(reg); 5184 format %{ "FPR2" %} 5185 interface(REG_INTER); 5186%} 5187 5188operand regnotDPR1(regD reg) %{ 5189 predicate( UseSSE < 2 ); 5190 constraint(ALLOC_IN_RC(dbl_notreg0)); 5191 match(reg); 5192 format %{ %} 5193 interface(REG_INTER); 5194%} 5195 5196// XMM Double register operands 5197operand regXD() %{ 5198 predicate( UseSSE>=2 ); 5199 constraint(ALLOC_IN_RC(xdb_reg)); 5200 match(RegD); 5201 match(regXD6); 5202 match(regXD7); 5203 format %{ %} 5204 interface(REG_INTER); 5205%} 5206 5207// XMM6 double register operands 5208operand regXD6(regXD reg) %{ 5209 predicate( UseSSE>=2 ); 5210 constraint(ALLOC_IN_RC(xdb_reg6)); 5211 match(reg); 5212 format %{ "XMM6" %} 5213 interface(REG_INTER); 5214%} 5215 5216// XMM7 double register operands 5217operand regXD7(regXD reg) %{ 5218 predicate( UseSSE>=2 ); 5219 constraint(ALLOC_IN_RC(xdb_reg7)); 5220 match(reg); 5221 format %{ "XMM7" %} 5222 interface(REG_INTER); 5223%} 5224 5225// Float register operands 5226operand regF() %{ 5227 predicate( UseSSE < 2 ); 5228 constraint(ALLOC_IN_RC(flt_reg)); 5229 match(RegF); 5230 match(regFPR1); 5231 format %{ %} 5232 interface(REG_INTER); 5233%} 5234 5235// Float register operands 5236operand regFPR1(regF reg) %{ 5237 predicate( UseSSE < 2 ); 5238 constraint(ALLOC_IN_RC(flt_reg0)); 5239 match(reg); 5240 format %{ "FPR1" %} 5241 interface(REG_INTER); 5242%} 5243 5244// XMM register operands 5245operand regX() %{ 5246 predicate( UseSSE>=1 ); 5247 constraint(ALLOC_IN_RC(xmm_reg)); 5248 match(RegF); 5249 format %{ %} 5250 interface(REG_INTER); 5251%} 5252 5253 5254//----------Memory Operands---------------------------------------------------- 5255// Direct Memory Operand 5256operand direct(immP addr) %{ 5257 match(addr); 5258 5259 format %{ "[$addr]" %} 5260 interface(MEMORY_INTER) %{ 5261 base(0xFFFFFFFF); 5262 index(0x4); 5263 scale(0x0); 5264 disp($addr); 5265 %} 5266%} 5267 5268// Indirect Memory Operand 5269operand indirect(eRegP reg) %{ 5270 constraint(ALLOC_IN_RC(e_reg)); 5271 match(reg); 5272 5273 format %{ "[$reg]" %} 5274 interface(MEMORY_INTER) %{ 5275 base($reg); 5276 index(0x4); 5277 scale(0x0); 5278 disp(0x0); 5279 %} 5280%} 5281 5282// Indirect Memory Plus Short Offset Operand 5283operand indOffset8(eRegP reg, immI8 off) %{ 5284 match(AddP reg off); 5285 5286 format %{ "[$reg + $off]" %} 5287 interface(MEMORY_INTER) %{ 5288 base($reg); 5289 index(0x4); 5290 scale(0x0); 5291 disp($off); 5292 %} 5293%} 5294 5295// Indirect Memory Plus Long Offset Operand 5296operand indOffset32(eRegP reg, immI off) %{ 5297 match(AddP reg off); 5298 5299 format %{ "[$reg + $off]" %} 5300 interface(MEMORY_INTER) %{ 5301 base($reg); 5302 index(0x4); 5303 scale(0x0); 5304 disp($off); 5305 %} 5306%} 5307 5308// Indirect Memory Plus Long Offset Operand 5309operand indOffset32X(eRegI reg, immP off) %{ 5310 match(AddP off reg); 5311 5312 format %{ "[$reg + $off]" %} 5313 interface(MEMORY_INTER) %{ 5314 base($reg); 5315 index(0x4); 5316 scale(0x0); 5317 disp($off); 5318 %} 5319%} 5320 5321// Indirect Memory Plus Index Register Plus Offset Operand 5322operand indIndexOffset(eRegP reg, eRegI ireg, immI off) %{ 5323 match(AddP (AddP reg ireg) off); 5324 5325 op_cost(10); 5326 format %{"[$reg + $off + $ireg]" %} 5327 interface(MEMORY_INTER) %{ 5328 base($reg); 5329 index($ireg); 5330 scale(0x0); 5331 disp($off); 5332 %} 5333%} 5334 5335// Indirect Memory Plus Index Register Plus Offset Operand 5336operand indIndex(eRegP reg, eRegI ireg) %{ 5337 match(AddP reg ireg); 5338 5339 op_cost(10); 5340 format %{"[$reg + $ireg]" %} 5341 interface(MEMORY_INTER) %{ 5342 base($reg); 5343 index($ireg); 5344 scale(0x0); 5345 disp(0x0); 5346 %} 5347%} 5348 5349// // ------------------------------------------------------------------------- 5350// // 486 architecture doesn't support "scale * index + offset" with out a base 5351// // ------------------------------------------------------------------------- 5352// // Scaled Memory Operands 5353// // Indirect Memory Times Scale Plus Offset Operand 5354// operand indScaleOffset(immP off, eRegI ireg, immI2 scale) %{ 5355// match(AddP off (LShiftI ireg scale)); 5356// 5357// op_cost(10); 5358// format %{"[$off + $ireg << $scale]" %} 5359// interface(MEMORY_INTER) %{ 5360// base(0x4); 5361// index($ireg); 5362// scale($scale); 5363// disp($off); 5364// %} 5365// %} 5366 5367// Indirect Memory Times Scale Plus Index Register 5368operand indIndexScale(eRegP reg, eRegI ireg, immI2 scale) %{ 5369 match(AddP reg (LShiftI ireg scale)); 5370 5371 op_cost(10); 5372 format %{"[$reg + $ireg << $scale]" %} 5373 interface(MEMORY_INTER) %{ 5374 base($reg); 5375 index($ireg); 5376 scale($scale); 5377 disp(0x0); 5378 %} 5379%} 5380 5381// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 5382operand indIndexScaleOffset(eRegP reg, immI off, eRegI ireg, immI2 scale) %{ 5383 match(AddP (AddP reg (LShiftI ireg scale)) off); 5384 5385 op_cost(10); 5386 format %{"[$reg + $off + $ireg << $scale]" %} 5387 interface(MEMORY_INTER) %{ 5388 base($reg); 5389 index($ireg); 5390 scale($scale); 5391 disp($off); 5392 %} 5393%} 5394 5395//----------Load Long Memory Operands------------------------------------------ 5396// The load-long idiom will use it's address expression again after loading 5397// the first word of the long. If the load-long destination overlaps with 5398// registers used in the addressing expression, the 2nd half will be loaded 5399// from a clobbered address. Fix this by requiring that load-long use 5400// address registers that do not overlap with the load-long target. 5401 5402// load-long support 5403operand load_long_RegP() %{ 5404 constraint(ALLOC_IN_RC(esi_reg)); 5405 match(RegP); 5406 match(eSIRegP); 5407 op_cost(100); 5408 format %{ %} 5409 interface(REG_INTER); 5410%} 5411 5412// Indirect Memory Operand Long 5413operand load_long_indirect(load_long_RegP reg) %{ 5414 constraint(ALLOC_IN_RC(esi_reg)); 5415 match(reg); 5416 5417 format %{ "[$reg]" %} 5418 interface(MEMORY_INTER) %{ 5419 base($reg); 5420 index(0x4); 5421 scale(0x0); 5422 disp(0x0); 5423 %} 5424%} 5425 5426// Indirect Memory Plus Long Offset Operand 5427operand load_long_indOffset32(load_long_RegP reg, immI off) %{ 5428 match(AddP reg off); 5429 5430 format %{ "[$reg + $off]" %} 5431 interface(MEMORY_INTER) %{ 5432 base($reg); 5433 index(0x4); 5434 scale(0x0); 5435 disp($off); 5436 %} 5437%} 5438 5439opclass load_long_memory(load_long_indirect, load_long_indOffset32); 5440 5441 5442//----------Special Memory Operands-------------------------------------------- 5443// Stack Slot Operand - This operand is used for loading and storing temporary 5444// values on the stack where a match requires a value to 5445// flow through memory. 5446operand stackSlotP(sRegP reg) %{ 5447 constraint(ALLOC_IN_RC(stack_slots)); 5448 // No match rule because this operand is only generated in matching 5449 format %{ "[$reg]" %} 5450 interface(MEMORY_INTER) %{ 5451 base(0x4); // ESP 5452 index(0x4); // No Index 5453 scale(0x0); // No Scale 5454 disp($reg); // Stack Offset 5455 %} 5456%} 5457 5458operand stackSlotI(sRegI reg) %{ 5459 constraint(ALLOC_IN_RC(stack_slots)); 5460 // No match rule because this operand is only generated in matching 5461 format %{ "[$reg]" %} 5462 interface(MEMORY_INTER) %{ 5463 base(0x4); // ESP 5464 index(0x4); // No Index 5465 scale(0x0); // No Scale 5466 disp($reg); // Stack Offset 5467 %} 5468%} 5469 5470operand stackSlotF(sRegF reg) %{ 5471 constraint(ALLOC_IN_RC(stack_slots)); 5472 // No match rule because this operand is only generated in matching 5473 format %{ "[$reg]" %} 5474 interface(MEMORY_INTER) %{ 5475 base(0x4); // ESP 5476 index(0x4); // No Index 5477 scale(0x0); // No Scale 5478 disp($reg); // Stack Offset 5479 %} 5480%} 5481 5482operand stackSlotD(sRegD reg) %{ 5483 constraint(ALLOC_IN_RC(stack_slots)); 5484 // No match rule because this operand is only generated in matching 5485 format %{ "[$reg]" %} 5486 interface(MEMORY_INTER) %{ 5487 base(0x4); // ESP 5488 index(0x4); // No Index 5489 scale(0x0); // No Scale 5490 disp($reg); // Stack Offset 5491 %} 5492%} 5493 5494operand stackSlotL(sRegL reg) %{ 5495 constraint(ALLOC_IN_RC(stack_slots)); 5496 // No match rule because this operand is only generated in matching 5497 format %{ "[$reg]" %} 5498 interface(MEMORY_INTER) %{ 5499 base(0x4); // ESP 5500 index(0x4); // No Index 5501 scale(0x0); // No Scale 5502 disp($reg); // Stack Offset 5503 %} 5504%} 5505 5506//----------Memory Operands - Win95 Implicit Null Variants---------------- 5507// Indirect Memory Operand 5508operand indirect_win95_safe(eRegP_no_EBP reg) 5509%{ 5510 constraint(ALLOC_IN_RC(e_reg)); 5511 match(reg); 5512 5513 op_cost(100); 5514 format %{ "[$reg]" %} 5515 interface(MEMORY_INTER) %{ 5516 base($reg); 5517 index(0x4); 5518 scale(0x0); 5519 disp(0x0); 5520 %} 5521%} 5522 5523// Indirect Memory Plus Short Offset Operand 5524operand indOffset8_win95_safe(eRegP_no_EBP reg, immI8 off) 5525%{ 5526 match(AddP reg off); 5527 5528 op_cost(100); 5529 format %{ "[$reg + $off]" %} 5530 interface(MEMORY_INTER) %{ 5531 base($reg); 5532 index(0x4); 5533 scale(0x0); 5534 disp($off); 5535 %} 5536%} 5537 5538// Indirect Memory Plus Long Offset Operand 5539operand indOffset32_win95_safe(eRegP_no_EBP reg, immI off) 5540%{ 5541 match(AddP reg off); 5542 5543 op_cost(100); 5544 format %{ "[$reg + $off]" %} 5545 interface(MEMORY_INTER) %{ 5546 base($reg); 5547 index(0x4); 5548 scale(0x0); 5549 disp($off); 5550 %} 5551%} 5552 5553// Indirect Memory Plus Index Register Plus Offset Operand 5554operand indIndexOffset_win95_safe(eRegP_no_EBP reg, eRegI ireg, immI off) 5555%{ 5556 match(AddP (AddP reg ireg) off); 5557 5558 op_cost(100); 5559 format %{"[$reg + $off + $ireg]" %} 5560 interface(MEMORY_INTER) %{ 5561 base($reg); 5562 index($ireg); 5563 scale(0x0); 5564 disp($off); 5565 %} 5566%} 5567 5568// Indirect Memory Times Scale Plus Index Register 5569operand indIndexScale_win95_safe(eRegP_no_EBP reg, eRegI ireg, immI2 scale) 5570%{ 5571 match(AddP reg (LShiftI ireg scale)); 5572 5573 op_cost(100); 5574 format %{"[$reg + $ireg << $scale]" %} 5575 interface(MEMORY_INTER) %{ 5576 base($reg); 5577 index($ireg); 5578 scale($scale); 5579 disp(0x0); 5580 %} 5581%} 5582 5583// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 5584operand indIndexScaleOffset_win95_safe(eRegP_no_EBP reg, immI off, eRegI ireg, immI2 scale) 5585%{ 5586 match(AddP (AddP reg (LShiftI ireg scale)) off); 5587 5588 op_cost(100); 5589 format %{"[$reg + $off + $ireg << $scale]" %} 5590 interface(MEMORY_INTER) %{ 5591 base($reg); 5592 index($ireg); 5593 scale($scale); 5594 disp($off); 5595 %} 5596%} 5597 5598//----------Conditional Branch Operands---------------------------------------- 5599// Comparison Op - This is the operation of the comparison, and is limited to 5600// the following set of codes: 5601// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 5602// 5603// Other attributes of the comparison, such as unsignedness, are specified 5604// by the comparison instruction that sets a condition code flags register. 5605// That result is represented by a flags operand whose subtype is appropriate 5606// to the unsignedness (etc.) of the comparison. 5607// 5608// Later, the instruction which matches both the Comparison Op (a Bool) and 5609// the flags (produced by the Cmp) specifies the coding of the comparison op 5610// by matching a specific subtype of Bool operand below, such as cmpOpU. 5611 5612// Comparision Code 5613operand cmpOp() %{ 5614 match(Bool); 5615 5616 format %{ "" %} 5617 interface(COND_INTER) %{ 5618 equal(0x4, "e"); 5619 not_equal(0x5, "ne"); 5620 less(0xC, "l"); 5621 greater_equal(0xD, "ge"); 5622 less_equal(0xE, "le"); 5623 greater(0xF, "g"); 5624 %} 5625%} 5626 5627// Comparison Code, unsigned compare. Used by FP also, with 5628// C2 (unordered) turned into GT or LT already. The other bits 5629// C0 and C3 are turned into Carry & Zero flags. 5630operand cmpOpU() %{ 5631 match(Bool); 5632 5633 format %{ "" %} 5634 interface(COND_INTER) %{ 5635 equal(0x4, "e"); 5636 not_equal(0x5, "ne"); 5637 less(0x2, "b"); 5638 greater_equal(0x3, "nb"); 5639 less_equal(0x6, "be"); 5640 greater(0x7, "nbe"); 5641 %} 5642%} 5643 5644// Floating comparisons that don't require any fixup for the unordered case 5645operand cmpOpUCF() %{ 5646 match(Bool); 5647 predicate(n->as_Bool()->_test._test == BoolTest::lt || 5648 n->as_Bool()->_test._test == BoolTest::ge || 5649 n->as_Bool()->_test._test == BoolTest::le || 5650 n->as_Bool()->_test._test == BoolTest::gt); 5651 format %{ "" %} 5652 interface(COND_INTER) %{ 5653 equal(0x4, "e"); 5654 not_equal(0x5, "ne"); 5655 less(0x2, "b"); 5656 greater_equal(0x3, "nb"); 5657 less_equal(0x6, "be"); 5658 greater(0x7, "nbe"); 5659 %} 5660%} 5661 5662 5663// Floating comparisons that can be fixed up with extra conditional jumps 5664operand cmpOpUCF2() %{ 5665 match(Bool); 5666 predicate(n->as_Bool()->_test._test == BoolTest::ne || 5667 n->as_Bool()->_test._test == BoolTest::eq); 5668 format %{ "" %} 5669 interface(COND_INTER) %{ 5670 equal(0x4, "e"); 5671 not_equal(0x5, "ne"); 5672 less(0x2, "b"); 5673 greater_equal(0x3, "nb"); 5674 less_equal(0x6, "be"); 5675 greater(0x7, "nbe"); 5676 %} 5677%} 5678 5679// Comparison Code for FP conditional move 5680operand cmpOp_fcmov() %{ 5681 match(Bool); 5682 5683 format %{ "" %} 5684 interface(COND_INTER) %{ 5685 equal (0x0C8); 5686 not_equal (0x1C8); 5687 less (0x0C0); 5688 greater_equal(0x1C0); 5689 less_equal (0x0D0); 5690 greater (0x1D0); 5691 %} 5692%} 5693 5694// Comparision Code used in long compares 5695operand cmpOp_commute() %{ 5696 match(Bool); 5697 5698 format %{ "" %} 5699 interface(COND_INTER) %{ 5700 equal(0x4, "e"); 5701 not_equal(0x5, "ne"); 5702 less(0xF, "g"); 5703 greater_equal(0xE, "le"); 5704 less_equal(0xD, "ge"); 5705 greater(0xC, "l"); 5706 %} 5707%} 5708 5709//----------OPERAND CLASSES---------------------------------------------------- 5710// Operand Classes are groups of operands that are used as to simplify 5711// instruction definitions by not requiring the AD writer to specify separate 5712// instructions for every form of operand when the instruction accepts 5713// multiple operand types with the same basic encoding and format. The classic 5714// case of this is memory operands. 5715 5716opclass memory(direct, indirect, indOffset8, indOffset32, indOffset32X, indIndexOffset, 5717 indIndex, indIndexScale, indIndexScaleOffset); 5718 5719// Long memory operations are encoded in 2 instructions and a +4 offset. 5720// This means some kind of offset is always required and you cannot use 5721// an oop as the offset (done when working on static globals). 5722opclass long_memory(direct, indirect, indOffset8, indOffset32, indIndexOffset, 5723 indIndex, indIndexScale, indIndexScaleOffset); 5724 5725 5726//----------PIPELINE----------------------------------------------------------- 5727// Rules which define the behavior of the target architectures pipeline. 5728pipeline %{ 5729 5730//----------ATTRIBUTES--------------------------------------------------------- 5731attributes %{ 5732 variable_size_instructions; // Fixed size instructions 5733 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 5734 instruction_unit_size = 1; // An instruction is 1 bytes long 5735 instruction_fetch_unit_size = 16; // The processor fetches one line 5736 instruction_fetch_units = 1; // of 16 bytes 5737 5738 // List of nop instructions 5739 nops( MachNop ); 5740%} 5741 5742//----------RESOURCES---------------------------------------------------------- 5743// Resources are the functional units available to the machine 5744 5745// Generic P2/P3 pipeline 5746// 3 decoders, only D0 handles big operands; a "bundle" is the limit of 5747// 3 instructions decoded per cycle. 5748// 2 load/store ops per cycle, 1 branch, 1 FPU, 5749// 2 ALU op, only ALU0 handles mul/div instructions. 5750resources( D0, D1, D2, DECODE = D0 | D1 | D2, 5751 MS0, MS1, MEM = MS0 | MS1, 5752 BR, FPU, 5753 ALU0, ALU1, ALU = ALU0 | ALU1 ); 5754 5755//----------PIPELINE DESCRIPTION----------------------------------------------- 5756// Pipeline Description specifies the stages in the machine's pipeline 5757 5758// Generic P2/P3 pipeline 5759pipe_desc(S0, S1, S2, S3, S4, S5); 5760 5761//----------PIPELINE CLASSES--------------------------------------------------- 5762// Pipeline Classes describe the stages in which input and output are 5763// referenced by the hardware pipeline. 5764 5765// Naming convention: ialu or fpu 5766// Then: _reg 5767// Then: _reg if there is a 2nd register 5768// Then: _long if it's a pair of instructions implementing a long 5769// Then: _fat if it requires the big decoder 5770// Or: _mem if it requires the big decoder and a memory unit. 5771 5772// Integer ALU reg operation 5773pipe_class ialu_reg(eRegI dst) %{ 5774 single_instruction; 5775 dst : S4(write); 5776 dst : S3(read); 5777 DECODE : S0; // any decoder 5778 ALU : S3; // any alu 5779%} 5780 5781// Long ALU reg operation 5782pipe_class ialu_reg_long(eRegL dst) %{ 5783 instruction_count(2); 5784 dst : S4(write); 5785 dst : S3(read); 5786 DECODE : S0(2); // any 2 decoders 5787 ALU : S3(2); // both alus 5788%} 5789 5790// Integer ALU reg operation using big decoder 5791pipe_class ialu_reg_fat(eRegI dst) %{ 5792 single_instruction; 5793 dst : S4(write); 5794 dst : S3(read); 5795 D0 : S0; // big decoder only 5796 ALU : S3; // any alu 5797%} 5798 5799// Long ALU reg operation using big decoder 5800pipe_class ialu_reg_long_fat(eRegL dst) %{ 5801 instruction_count(2); 5802 dst : S4(write); 5803 dst : S3(read); 5804 D0 : S0(2); // big decoder only; twice 5805 ALU : S3(2); // any 2 alus 5806%} 5807 5808// Integer ALU reg-reg operation 5809pipe_class ialu_reg_reg(eRegI dst, eRegI src) %{ 5810 single_instruction; 5811 dst : S4(write); 5812 src : S3(read); 5813 DECODE : S0; // any decoder 5814 ALU : S3; // any alu 5815%} 5816 5817// Long ALU reg-reg operation 5818pipe_class ialu_reg_reg_long(eRegL dst, eRegL src) %{ 5819 instruction_count(2); 5820 dst : S4(write); 5821 src : S3(read); 5822 DECODE : S0(2); // any 2 decoders 5823 ALU : S3(2); // both alus 5824%} 5825 5826// Integer ALU reg-reg operation 5827pipe_class ialu_reg_reg_fat(eRegI dst, memory src) %{ 5828 single_instruction; 5829 dst : S4(write); 5830 src : S3(read); 5831 D0 : S0; // big decoder only 5832 ALU : S3; // any alu 5833%} 5834 5835// Long ALU reg-reg operation 5836pipe_class ialu_reg_reg_long_fat(eRegL dst, eRegL src) %{ 5837 instruction_count(2); 5838 dst : S4(write); 5839 src : S3(read); 5840 D0 : S0(2); // big decoder only; twice 5841 ALU : S3(2); // both alus 5842%} 5843 5844// Integer ALU reg-mem operation 5845pipe_class ialu_reg_mem(eRegI dst, memory mem) %{ 5846 single_instruction; 5847 dst : S5(write); 5848 mem : S3(read); 5849 D0 : S0; // big decoder only 5850 ALU : S4; // any alu 5851 MEM : S3; // any mem 5852%} 5853 5854// Long ALU reg-mem operation 5855pipe_class ialu_reg_long_mem(eRegL dst, load_long_memory mem) %{ 5856 instruction_count(2); 5857 dst : S5(write); 5858 mem : S3(read); 5859 D0 : S0(2); // big decoder only; twice 5860 ALU : S4(2); // any 2 alus 5861 MEM : S3(2); // both mems 5862%} 5863 5864// Integer mem operation (prefetch) 5865pipe_class ialu_mem(memory mem) 5866%{ 5867 single_instruction; 5868 mem : S3(read); 5869 D0 : S0; // big decoder only 5870 MEM : S3; // any mem 5871%} 5872 5873// Integer Store to Memory 5874pipe_class ialu_mem_reg(memory mem, eRegI src) %{ 5875 single_instruction; 5876 mem : S3(read); 5877 src : S5(read); 5878 D0 : S0; // big decoder only 5879 ALU : S4; // any alu 5880 MEM : S3; 5881%} 5882 5883// Long Store to Memory 5884pipe_class ialu_mem_long_reg(memory mem, eRegL src) %{ 5885 instruction_count(2); 5886 mem : S3(read); 5887 src : S5(read); 5888 D0 : S0(2); // big decoder only; twice 5889 ALU : S4(2); // any 2 alus 5890 MEM : S3(2); // Both mems 5891%} 5892 5893// Integer Store to Memory 5894pipe_class ialu_mem_imm(memory mem) %{ 5895 single_instruction; 5896 mem : S3(read); 5897 D0 : S0; // big decoder only 5898 ALU : S4; // any alu 5899 MEM : S3; 5900%} 5901 5902// Integer ALU0 reg-reg operation 5903pipe_class ialu_reg_reg_alu0(eRegI dst, eRegI src) %{ 5904 single_instruction; 5905 dst : S4(write); 5906 src : S3(read); 5907 D0 : S0; // Big decoder only 5908 ALU0 : S3; // only alu0 5909%} 5910 5911// Integer ALU0 reg-mem operation 5912pipe_class ialu_reg_mem_alu0(eRegI dst, memory mem) %{ 5913 single_instruction; 5914 dst : S5(write); 5915 mem : S3(read); 5916 D0 : S0; // big decoder only 5917 ALU0 : S4; // ALU0 only 5918 MEM : S3; // any mem 5919%} 5920 5921// Integer ALU reg-reg operation 5922pipe_class ialu_cr_reg_reg(eFlagsReg cr, eRegI src1, eRegI src2) %{ 5923 single_instruction; 5924 cr : S4(write); 5925 src1 : S3(read); 5926 src2 : S3(read); 5927 DECODE : S0; // any decoder 5928 ALU : S3; // any alu 5929%} 5930 5931// Integer ALU reg-imm operation 5932pipe_class ialu_cr_reg_imm(eFlagsReg cr, eRegI src1) %{ 5933 single_instruction; 5934 cr : S4(write); 5935 src1 : S3(read); 5936 DECODE : S0; // any decoder 5937 ALU : S3; // any alu 5938%} 5939 5940// Integer ALU reg-mem operation 5941pipe_class ialu_cr_reg_mem(eFlagsReg cr, eRegI src1, memory src2) %{ 5942 single_instruction; 5943 cr : S4(write); 5944 src1 : S3(read); 5945 src2 : S3(read); 5946 D0 : S0; // big decoder only 5947 ALU : S4; // any alu 5948 MEM : S3; 5949%} 5950 5951// Conditional move reg-reg 5952pipe_class pipe_cmplt( eRegI p, eRegI q, eRegI y ) %{ 5953 instruction_count(4); 5954 y : S4(read); 5955 q : S3(read); 5956 p : S3(read); 5957 DECODE : S0(4); // any decoder 5958%} 5959 5960// Conditional move reg-reg 5961pipe_class pipe_cmov_reg( eRegI dst, eRegI src, eFlagsReg cr ) %{ 5962 single_instruction; 5963 dst : S4(write); 5964 src : S3(read); 5965 cr : S3(read); 5966 DECODE : S0; // any decoder 5967%} 5968 5969// Conditional move reg-mem 5970pipe_class pipe_cmov_mem( eFlagsReg cr, eRegI dst, memory src) %{ 5971 single_instruction; 5972 dst : S4(write); 5973 src : S3(read); 5974 cr : S3(read); 5975 DECODE : S0; // any decoder 5976 MEM : S3; 5977%} 5978 5979// Conditional move reg-reg long 5980pipe_class pipe_cmov_reg_long( eFlagsReg cr, eRegL dst, eRegL src) %{ 5981 single_instruction; 5982 dst : S4(write); 5983 src : S3(read); 5984 cr : S3(read); 5985 DECODE : S0(2); // any 2 decoders 5986%} 5987 5988// Conditional move double reg-reg 5989pipe_class pipe_cmovD_reg( eFlagsReg cr, regDPR1 dst, regD src) %{ 5990 single_instruction; 5991 dst : S4(write); 5992 src : S3(read); 5993 cr : S3(read); 5994 DECODE : S0; // any decoder 5995%} 5996 5997// Float reg-reg operation 5998pipe_class fpu_reg(regD dst) %{ 5999 instruction_count(2); 6000 dst : S3(read); 6001 DECODE : S0(2); // any 2 decoders 6002 FPU : S3; 6003%} 6004 6005// Float reg-reg operation 6006pipe_class fpu_reg_reg(regD dst, regD src) %{ 6007 instruction_count(2); 6008 dst : S4(write); 6009 src : S3(read); 6010 DECODE : S0(2); // any 2 decoders 6011 FPU : S3; 6012%} 6013 6014// Float reg-reg operation 6015pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) %{ 6016 instruction_count(3); 6017 dst : S4(write); 6018 src1 : S3(read); 6019 src2 : S3(read); 6020 DECODE : S0(3); // any 3 decoders 6021 FPU : S3(2); 6022%} 6023 6024// Float reg-reg operation 6025pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) %{ 6026 instruction_count(4); 6027 dst : S4(write); 6028 src1 : S3(read); 6029 src2 : S3(read); 6030 src3 : S3(read); 6031 DECODE : S0(4); // any 3 decoders 6032 FPU : S3(2); 6033%} 6034 6035// Float reg-reg operation 6036pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) %{ 6037 instruction_count(4); 6038 dst : S4(write); 6039 src1 : S3(read); 6040 src2 : S3(read); 6041 src3 : S3(read); 6042 DECODE : S1(3); // any 3 decoders 6043 D0 : S0; // Big decoder only 6044 FPU : S3(2); 6045 MEM : S3; 6046%} 6047 6048// Float reg-mem operation 6049pipe_class fpu_reg_mem(regD dst, memory mem) %{ 6050 instruction_count(2); 6051 dst : S5(write); 6052 mem : S3(read); 6053 D0 : S0; // big decoder only 6054 DECODE : S1; // any decoder for FPU POP 6055 FPU : S4; 6056 MEM : S3; // any mem 6057%} 6058 6059// Float reg-mem operation 6060pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) %{ 6061 instruction_count(3); 6062 dst : S5(write); 6063 src1 : S3(read); 6064 mem : S3(read); 6065 D0 : S0; // big decoder only 6066 DECODE : S1(2); // any decoder for FPU POP 6067 FPU : S4; 6068 MEM : S3; // any mem 6069%} 6070 6071// Float mem-reg operation 6072pipe_class fpu_mem_reg(memory mem, regD src) %{ 6073 instruction_count(2); 6074 src : S5(read); 6075 mem : S3(read); 6076 DECODE : S0; // any decoder for FPU PUSH 6077 D0 : S1; // big decoder only 6078 FPU : S4; 6079 MEM : S3; // any mem 6080%} 6081 6082pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) %{ 6083 instruction_count(3); 6084 src1 : S3(read); 6085 src2 : S3(read); 6086 mem : S3(read); 6087 DECODE : S0(2); // any decoder for FPU PUSH 6088 D0 : S1; // big decoder only 6089 FPU : S4; 6090 MEM : S3; // any mem 6091%} 6092 6093pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) %{ 6094 instruction_count(3); 6095 src1 : S3(read); 6096 src2 : S3(read); 6097 mem : S4(read); 6098 DECODE : S0; // any decoder for FPU PUSH 6099 D0 : S0(2); // big decoder only 6100 FPU : S4; 6101 MEM : S3(2); // any mem 6102%} 6103 6104pipe_class fpu_mem_mem(memory dst, memory src1) %{ 6105 instruction_count(2); 6106 src1 : S3(read); 6107 dst : S4(read); 6108 D0 : S0(2); // big decoder only 6109 MEM : S3(2); // any mem 6110%} 6111 6112pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) %{ 6113 instruction_count(3); 6114 src1 : S3(read); 6115 src2 : S3(read); 6116 dst : S4(read); 6117 D0 : S0(3); // big decoder only 6118 FPU : S4; 6119 MEM : S3(3); // any mem 6120%} 6121 6122pipe_class fpu_mem_reg_con(memory mem, regD src1) %{ 6123 instruction_count(3); 6124 src1 : S4(read); 6125 mem : S4(read); 6126 DECODE : S0; // any decoder for FPU PUSH 6127 D0 : S0(2); // big decoder only 6128 FPU : S4; 6129 MEM : S3(2); // any mem 6130%} 6131 6132// Float load constant 6133pipe_class fpu_reg_con(regD dst) %{ 6134 instruction_count(2); 6135 dst : S5(write); 6136 D0 : S0; // big decoder only for the load 6137 DECODE : S1; // any decoder for FPU POP 6138 FPU : S4; 6139 MEM : S3; // any mem 6140%} 6141 6142// Float load constant 6143pipe_class fpu_reg_reg_con(regD dst, regD src) %{ 6144 instruction_count(3); 6145 dst : S5(write); 6146 src : S3(read); 6147 D0 : S0; // big decoder only for the load 6148 DECODE : S1(2); // any decoder for FPU POP 6149 FPU : S4; 6150 MEM : S3; // any mem 6151%} 6152 6153// UnConditional branch 6154pipe_class pipe_jmp( label labl ) %{ 6155 single_instruction; 6156 BR : S3; 6157%} 6158 6159// Conditional branch 6160pipe_class pipe_jcc( cmpOp cmp, eFlagsReg cr, label labl ) %{ 6161 single_instruction; 6162 cr : S1(read); 6163 BR : S3; 6164%} 6165 6166// Allocation idiom 6167pipe_class pipe_cmpxchg( eRegP dst, eRegP heap_ptr ) %{ 6168 instruction_count(1); force_serialization; 6169 fixed_latency(6); 6170 heap_ptr : S3(read); 6171 DECODE : S0(3); 6172 D0 : S2; 6173 MEM : S3; 6174 ALU : S3(2); 6175 dst : S5(write); 6176 BR : S5; 6177%} 6178 6179// Generic big/slow expanded idiom 6180pipe_class pipe_slow( ) %{ 6181 instruction_count(10); multiple_bundles; force_serialization; 6182 fixed_latency(100); 6183 D0 : S0(2); 6184 MEM : S3(2); 6185%} 6186 6187// The real do-nothing guy 6188pipe_class empty( ) %{ 6189 instruction_count(0); 6190%} 6191 6192// Define the class for the Nop node 6193define %{ 6194 MachNop = empty; 6195%} 6196 6197%} 6198 6199//----------INSTRUCTIONS------------------------------------------------------- 6200// 6201// match -- States which machine-independent subtree may be replaced 6202// by this instruction. 6203// ins_cost -- The estimated cost of this instruction is used by instruction 6204// selection to identify a minimum cost tree of machine 6205// instructions that matches a tree of machine-independent 6206// instructions. 6207// format -- A string providing the disassembly for this instruction. 6208// The value of an instruction's operand may be inserted 6209// by referring to it with a '$' prefix. 6210// opcode -- Three instruction opcodes may be provided. These are referred 6211// to within an encode class as $primary, $secondary, and $tertiary 6212// respectively. The primary opcode is commonly used to 6213// indicate the type of machine instruction, while secondary 6214// and tertiary are often used for prefix options or addressing 6215// modes. 6216// ins_encode -- A list of encode classes with parameters. The encode class 6217// name must have been defined in an 'enc_class' specification 6218// in the encode section of the architecture description. 6219 6220//----------BSWAP-Instruction-------------------------------------------------- 6221instruct bytes_reverse_int(eRegI dst) %{ 6222 match(Set dst (ReverseBytesI dst)); 6223 6224 format %{ "BSWAP $dst" %} 6225 opcode(0x0F, 0xC8); 6226 ins_encode( OpcP, OpcSReg(dst) ); 6227 ins_pipe( ialu_reg ); 6228%} 6229 6230instruct bytes_reverse_long(eRegL dst) %{ 6231 match(Set dst (ReverseBytesL dst)); 6232 6233 format %{ "BSWAP $dst.lo\n\t" 6234 "BSWAP $dst.hi\n\t" 6235 "XCHG $dst.lo $dst.hi" %} 6236 6237 ins_cost(125); 6238 ins_encode( bswap_long_bytes(dst) ); 6239 ins_pipe( ialu_reg_reg); 6240%} 6241 6242instruct bytes_reverse_unsigned_short(eRegI dst) %{ 6243 match(Set dst (ReverseBytesUS dst)); 6244 6245 format %{ "BSWAP $dst\n\t" 6246 "SHR $dst,16\n\t" %} 6247 ins_encode %{ 6248 __ bswapl($dst$$Register); 6249 __ shrl($dst$$Register, 16); 6250 %} 6251 ins_pipe( ialu_reg ); 6252%} 6253 6254instruct bytes_reverse_short(eRegI dst) %{ 6255 match(Set dst (ReverseBytesS dst)); 6256 6257 format %{ "BSWAP $dst\n\t" 6258 "SAR $dst,16\n\t" %} 6259 ins_encode %{ 6260 __ bswapl($dst$$Register); 6261 __ sarl($dst$$Register, 16); 6262 %} 6263 ins_pipe( ialu_reg ); 6264%} 6265 6266 6267//---------- Zeros Count Instructions ------------------------------------------ 6268 6269instruct countLeadingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{ 6270 predicate(UseCountLeadingZerosInstruction); 6271 match(Set dst (CountLeadingZerosI src)); 6272 effect(KILL cr); 6273 6274 format %{ "LZCNT $dst, $src\t# count leading zeros (int)" %} 6275 ins_encode %{ 6276 __ lzcntl($dst$$Register, $src$$Register); 6277 %} 6278 ins_pipe(ialu_reg); 6279%} 6280 6281instruct countLeadingZerosI_bsr(eRegI dst, eRegI src, eFlagsReg cr) %{ 6282 predicate(!UseCountLeadingZerosInstruction); 6283 match(Set dst (CountLeadingZerosI src)); 6284 effect(KILL cr); 6285 6286 format %{ "BSR $dst, $src\t# count leading zeros (int)\n\t" 6287 "JNZ skip\n\t" 6288 "MOV $dst, -1\n" 6289 "skip:\n\t" 6290 "NEG $dst\n\t" 6291 "ADD $dst, 31" %} 6292 ins_encode %{ 6293 Register Rdst = $dst$$Register; 6294 Register Rsrc = $src$$Register; 6295 Label skip; 6296 __ bsrl(Rdst, Rsrc); 6297 __ jccb(Assembler::notZero, skip); 6298 __ movl(Rdst, -1); 6299 __ bind(skip); 6300 __ negl(Rdst); 6301 __ addl(Rdst, BitsPerInt - 1); 6302 %} 6303 ins_pipe(ialu_reg); 6304%} 6305 6306instruct countLeadingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{ 6307 predicate(UseCountLeadingZerosInstruction); 6308 match(Set dst (CountLeadingZerosL src)); 6309 effect(TEMP dst, KILL cr); 6310 6311 format %{ "LZCNT $dst, $src.hi\t# count leading zeros (long)\n\t" 6312 "JNC done\n\t" 6313 "LZCNT $dst, $src.lo\n\t" 6314 "ADD $dst, 32\n" 6315 "done:" %} 6316 ins_encode %{ 6317 Register Rdst = $dst$$Register; 6318 Register Rsrc = $src$$Register; 6319 Label done; 6320 __ lzcntl(Rdst, HIGH_FROM_LOW(Rsrc)); 6321 __ jccb(Assembler::carryClear, done); 6322 __ lzcntl(Rdst, Rsrc); 6323 __ addl(Rdst, BitsPerInt); 6324 __ bind(done); 6325 %} 6326 ins_pipe(ialu_reg); 6327%} 6328 6329instruct countLeadingZerosL_bsr(eRegI dst, eRegL src, eFlagsReg cr) %{ 6330 predicate(!UseCountLeadingZerosInstruction); 6331 match(Set dst (CountLeadingZerosL src)); 6332 effect(TEMP dst, KILL cr); 6333 6334 format %{ "BSR $dst, $src.hi\t# count leading zeros (long)\n\t" 6335 "JZ msw_is_zero\n\t" 6336 "ADD $dst, 32\n\t" 6337 "JMP not_zero\n" 6338 "msw_is_zero:\n\t" 6339 "BSR $dst, $src.lo\n\t" 6340 "JNZ not_zero\n\t" 6341 "MOV $dst, -1\n" 6342 "not_zero:\n\t" 6343 "NEG $dst\n\t" 6344 "ADD $dst, 63\n" %} 6345 ins_encode %{ 6346 Register Rdst = $dst$$Register; 6347 Register Rsrc = $src$$Register; 6348 Label msw_is_zero; 6349 Label not_zero; 6350 __ bsrl(Rdst, HIGH_FROM_LOW(Rsrc)); 6351 __ jccb(Assembler::zero, msw_is_zero); 6352 __ addl(Rdst, BitsPerInt); 6353 __ jmpb(not_zero); 6354 __ bind(msw_is_zero); 6355 __ bsrl(Rdst, Rsrc); 6356 __ jccb(Assembler::notZero, not_zero); 6357 __ movl(Rdst, -1); 6358 __ bind(not_zero); 6359 __ negl(Rdst); 6360 __ addl(Rdst, BitsPerLong - 1); 6361 %} 6362 ins_pipe(ialu_reg); 6363%} 6364 6365instruct countTrailingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{ 6366 match(Set dst (CountTrailingZerosI src)); 6367 effect(KILL cr); 6368 6369 format %{ "BSF $dst, $src\t# count trailing zeros (int)\n\t" 6370 "JNZ done\n\t" 6371 "MOV $dst, 32\n" 6372 "done:" %} 6373 ins_encode %{ 6374 Register Rdst = $dst$$Register; 6375 Label done; 6376 __ bsfl(Rdst, $src$$Register); 6377 __ jccb(Assembler::notZero, done); 6378 __ movl(Rdst, BitsPerInt); 6379 __ bind(done); 6380 %} 6381 ins_pipe(ialu_reg); 6382%} 6383 6384instruct countTrailingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{ 6385 match(Set dst (CountTrailingZerosL src)); 6386 effect(TEMP dst, KILL cr); 6387 6388 format %{ "BSF $dst, $src.lo\t# count trailing zeros (long)\n\t" 6389 "JNZ done\n\t" 6390 "BSF $dst, $src.hi\n\t" 6391 "JNZ msw_not_zero\n\t" 6392 "MOV $dst, 32\n" 6393 "msw_not_zero:\n\t" 6394 "ADD $dst, 32\n" 6395 "done:" %} 6396 ins_encode %{ 6397 Register Rdst = $dst$$Register; 6398 Register Rsrc = $src$$Register; 6399 Label msw_not_zero; 6400 Label done; 6401 __ bsfl(Rdst, Rsrc); 6402 __ jccb(Assembler::notZero, done); 6403 __ bsfl(Rdst, HIGH_FROM_LOW(Rsrc)); 6404 __ jccb(Assembler::notZero, msw_not_zero); 6405 __ movl(Rdst, BitsPerInt); 6406 __ bind(msw_not_zero); 6407 __ addl(Rdst, BitsPerInt); 6408 __ bind(done); 6409 %} 6410 ins_pipe(ialu_reg); 6411%} 6412 6413 6414//---------- Population Count Instructions ------------------------------------- 6415 6416instruct popCountI(eRegI dst, eRegI src) %{ 6417 predicate(UsePopCountInstruction); 6418 match(Set dst (PopCountI src)); 6419 6420 format %{ "POPCNT $dst, $src" %} 6421 ins_encode %{ 6422 __ popcntl($dst$$Register, $src$$Register); 6423 %} 6424 ins_pipe(ialu_reg); 6425%} 6426 6427instruct popCountI_mem(eRegI dst, memory mem) %{ 6428 predicate(UsePopCountInstruction); 6429 match(Set dst (PopCountI (LoadI mem))); 6430 6431 format %{ "POPCNT $dst, $mem" %} 6432 ins_encode %{ 6433 __ popcntl($dst$$Register, $mem$$Address); 6434 %} 6435 ins_pipe(ialu_reg); 6436%} 6437 6438// Note: Long.bitCount(long) returns an int. 6439instruct popCountL(eRegI dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ 6440 predicate(UsePopCountInstruction); 6441 match(Set dst (PopCountL src)); 6442 effect(KILL cr, TEMP tmp, TEMP dst); 6443 6444 format %{ "POPCNT $dst, $src.lo\n\t" 6445 "POPCNT $tmp, $src.hi\n\t" 6446 "ADD $dst, $tmp" %} 6447 ins_encode %{ 6448 __ popcntl($dst$$Register, $src$$Register); 6449 __ popcntl($tmp$$Register, HIGH_FROM_LOW($src$$Register)); 6450 __ addl($dst$$Register, $tmp$$Register); 6451 %} 6452 ins_pipe(ialu_reg); 6453%} 6454 6455// Note: Long.bitCount(long) returns an int. 6456instruct popCountL_mem(eRegI dst, memory mem, eRegI tmp, eFlagsReg cr) %{ 6457 predicate(UsePopCountInstruction); 6458 match(Set dst (PopCountL (LoadL mem))); 6459 effect(KILL cr, TEMP tmp, TEMP dst); 6460 6461 format %{ "POPCNT $dst, $mem\n\t" 6462 "POPCNT $tmp, $mem+4\n\t" 6463 "ADD $dst, $tmp" %} 6464 ins_encode %{ 6465 //__ popcntl($dst$$Register, $mem$$Address$$first); 6466 //__ popcntl($tmp$$Register, $mem$$Address$$second); 6467 __ popcntl($dst$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false)); 6468 __ popcntl($tmp$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false)); 6469 __ addl($dst$$Register, $tmp$$Register); 6470 %} 6471 ins_pipe(ialu_reg); 6472%} 6473 6474 6475//----------Load/Store/Move Instructions--------------------------------------- 6476//----------Load Instructions-------------------------------------------------- 6477// Load Byte (8bit signed) 6478instruct loadB(xRegI dst, memory mem) %{ 6479 match(Set dst (LoadB mem)); 6480 6481 ins_cost(125); 6482 format %{ "MOVSX8 $dst,$mem\t# byte" %} 6483 6484 ins_encode %{ 6485 __ movsbl($dst$$Register, $mem$$Address); 6486 %} 6487 6488 ins_pipe(ialu_reg_mem); 6489%} 6490 6491// Load Byte (8bit signed) into Long Register 6492instruct loadB2L(eRegL dst, memory mem, eFlagsReg cr) %{ 6493 match(Set dst (ConvI2L (LoadB mem))); 6494 effect(KILL cr); 6495 6496 ins_cost(375); 6497 format %{ "MOVSX8 $dst.lo,$mem\t# byte -> long\n\t" 6498 "MOV $dst.hi,$dst.lo\n\t" 6499 "SAR $dst.hi,7" %} 6500 6501 ins_encode %{ 6502 __ movsbl($dst$$Register, $mem$$Address); 6503 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register. 6504 __ sarl(HIGH_FROM_LOW($dst$$Register), 7); // 24+1 MSB are already signed extended. 6505 %} 6506 6507 ins_pipe(ialu_reg_mem); 6508%} 6509 6510// Load Unsigned Byte (8bit UNsigned) 6511instruct loadUB(xRegI dst, memory mem) %{ 6512 match(Set dst (LoadUB mem)); 6513 6514 ins_cost(125); 6515 format %{ "MOVZX8 $dst,$mem\t# ubyte -> int" %} 6516 6517 ins_encode %{ 6518 __ movzbl($dst$$Register, $mem$$Address); 6519 %} 6520 6521 ins_pipe(ialu_reg_mem); 6522%} 6523 6524// Load Unsigned Byte (8 bit UNsigned) into Long Register 6525instruct loadUB2L(eRegL dst, memory mem, eFlagsReg cr) %{ 6526 match(Set dst (ConvI2L (LoadUB mem))); 6527 effect(KILL cr); 6528 6529 ins_cost(250); 6530 format %{ "MOVZX8 $dst.lo,$mem\t# ubyte -> long\n\t" 6531 "XOR $dst.hi,$dst.hi" %} 6532 6533 ins_encode %{ 6534 Register Rdst = $dst$$Register; 6535 __ movzbl(Rdst, $mem$$Address); 6536 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6537 %} 6538 6539 ins_pipe(ialu_reg_mem); 6540%} 6541 6542// Load Unsigned Byte (8 bit UNsigned) with mask into Long Register 6543instruct loadUB2L_immI8(eRegL dst, memory mem, immI8 mask, eFlagsReg cr) %{ 6544 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 6545 effect(KILL cr); 6546 6547 format %{ "MOVZX8 $dst.lo,$mem\t# ubyte & 8-bit mask -> long\n\t" 6548 "XOR $dst.hi,$dst.hi\n\t" 6549 "AND $dst.lo,$mask" %} 6550 ins_encode %{ 6551 Register Rdst = $dst$$Register; 6552 __ movzbl(Rdst, $mem$$Address); 6553 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6554 __ andl(Rdst, $mask$$constant); 6555 %} 6556 ins_pipe(ialu_reg_mem); 6557%} 6558 6559// Load Short (16bit signed) 6560instruct loadS(eRegI dst, memory mem) %{ 6561 match(Set dst (LoadS mem)); 6562 6563 ins_cost(125); 6564 format %{ "MOVSX $dst,$mem\t# short" %} 6565 6566 ins_encode %{ 6567 __ movswl($dst$$Register, $mem$$Address); 6568 %} 6569 6570 ins_pipe(ialu_reg_mem); 6571%} 6572 6573// Load Short (16 bit signed) to Byte (8 bit signed) 6574instruct loadS2B(eRegI dst, memory mem, immI_24 twentyfour) %{ 6575 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 6576 6577 ins_cost(125); 6578 format %{ "MOVSX $dst, $mem\t# short -> byte" %} 6579 ins_encode %{ 6580 __ movsbl($dst$$Register, $mem$$Address); 6581 %} 6582 ins_pipe(ialu_reg_mem); 6583%} 6584 6585// Load Short (16bit signed) into Long Register 6586instruct loadS2L(eRegL dst, memory mem, eFlagsReg cr) %{ 6587 match(Set dst (ConvI2L (LoadS mem))); 6588 effect(KILL cr); 6589 6590 ins_cost(375); 6591 format %{ "MOVSX $dst.lo,$mem\t# short -> long\n\t" 6592 "MOV $dst.hi,$dst.lo\n\t" 6593 "SAR $dst.hi,15" %} 6594 6595 ins_encode %{ 6596 __ movswl($dst$$Register, $mem$$Address); 6597 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register. 6598 __ sarl(HIGH_FROM_LOW($dst$$Register), 15); // 16+1 MSB are already signed extended. 6599 %} 6600 6601 ins_pipe(ialu_reg_mem); 6602%} 6603 6604// Load Unsigned Short/Char (16bit unsigned) 6605instruct loadUS(eRegI dst, memory mem) %{ 6606 match(Set dst (LoadUS mem)); 6607 6608 ins_cost(125); 6609 format %{ "MOVZX $dst,$mem\t# ushort/char -> int" %} 6610 6611 ins_encode %{ 6612 __ movzwl($dst$$Register, $mem$$Address); 6613 %} 6614 6615 ins_pipe(ialu_reg_mem); 6616%} 6617 6618// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 6619instruct loadUS2B(eRegI dst, memory mem, immI_24 twentyfour) %{ 6620 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 6621 6622 ins_cost(125); 6623 format %{ "MOVSX $dst, $mem\t# ushort -> byte" %} 6624 ins_encode %{ 6625 __ movsbl($dst$$Register, $mem$$Address); 6626 %} 6627 ins_pipe(ialu_reg_mem); 6628%} 6629 6630// Load Unsigned Short/Char (16 bit UNsigned) into Long Register 6631instruct loadUS2L(eRegL dst, memory mem, eFlagsReg cr) %{ 6632 match(Set dst (ConvI2L (LoadUS mem))); 6633 effect(KILL cr); 6634 6635 ins_cost(250); 6636 format %{ "MOVZX $dst.lo,$mem\t# ushort/char -> long\n\t" 6637 "XOR $dst.hi,$dst.hi" %} 6638 6639 ins_encode %{ 6640 __ movzwl($dst$$Register, $mem$$Address); 6641 __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register)); 6642 %} 6643 6644 ins_pipe(ialu_reg_mem); 6645%} 6646 6647// Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 6648instruct loadUS2L_immI_255(eRegL dst, memory mem, immI_255 mask, eFlagsReg cr) %{ 6649 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 6650 effect(KILL cr); 6651 6652 format %{ "MOVZX8 $dst.lo,$mem\t# ushort/char & 0xFF -> long\n\t" 6653 "XOR $dst.hi,$dst.hi" %} 6654 ins_encode %{ 6655 Register Rdst = $dst$$Register; 6656 __ movzbl(Rdst, $mem$$Address); 6657 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6658 %} 6659 ins_pipe(ialu_reg_mem); 6660%} 6661 6662// Load Unsigned Short/Char (16 bit UNsigned) with a 16-bit mask into Long Register 6663instruct loadUS2L_immI16(eRegL dst, memory mem, immI16 mask, eFlagsReg cr) %{ 6664 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 6665 effect(KILL cr); 6666 6667 format %{ "MOVZX $dst.lo, $mem\t# ushort/char & 16-bit mask -> long\n\t" 6668 "XOR $dst.hi,$dst.hi\n\t" 6669 "AND $dst.lo,$mask" %} 6670 ins_encode %{ 6671 Register Rdst = $dst$$Register; 6672 __ movzwl(Rdst, $mem$$Address); 6673 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6674 __ andl(Rdst, $mask$$constant); 6675 %} 6676 ins_pipe(ialu_reg_mem); 6677%} 6678 6679// Load Integer 6680instruct loadI(eRegI dst, memory mem) %{ 6681 match(Set dst (LoadI mem)); 6682 6683 ins_cost(125); 6684 format %{ "MOV $dst,$mem\t# int" %} 6685 6686 ins_encode %{ 6687 __ movl($dst$$Register, $mem$$Address); 6688 %} 6689 6690 ins_pipe(ialu_reg_mem); 6691%} 6692 6693// Load Integer (32 bit signed) to Byte (8 bit signed) 6694instruct loadI2B(eRegI dst, memory mem, immI_24 twentyfour) %{ 6695 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 6696 6697 ins_cost(125); 6698 format %{ "MOVSX $dst, $mem\t# int -> byte" %} 6699 ins_encode %{ 6700 __ movsbl($dst$$Register, $mem$$Address); 6701 %} 6702 ins_pipe(ialu_reg_mem); 6703%} 6704 6705// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 6706instruct loadI2UB(eRegI dst, memory mem, immI_255 mask) %{ 6707 match(Set dst (AndI (LoadI mem) mask)); 6708 6709 ins_cost(125); 6710 format %{ "MOVZX $dst, $mem\t# int -> ubyte" %} 6711 ins_encode %{ 6712 __ movzbl($dst$$Register, $mem$$Address); 6713 %} 6714 ins_pipe(ialu_reg_mem); 6715%} 6716 6717// Load Integer (32 bit signed) to Short (16 bit signed) 6718instruct loadI2S(eRegI dst, memory mem, immI_16 sixteen) %{ 6719 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 6720 6721 ins_cost(125); 6722 format %{ "MOVSX $dst, $mem\t# int -> short" %} 6723 ins_encode %{ 6724 __ movswl($dst$$Register, $mem$$Address); 6725 %} 6726 ins_pipe(ialu_reg_mem); 6727%} 6728 6729// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 6730instruct loadI2US(eRegI dst, memory mem, immI_65535 mask) %{ 6731 match(Set dst (AndI (LoadI mem) mask)); 6732 6733 ins_cost(125); 6734 format %{ "MOVZX $dst, $mem\t# int -> ushort/char" %} 6735 ins_encode %{ 6736 __ movzwl($dst$$Register, $mem$$Address); 6737 %} 6738 ins_pipe(ialu_reg_mem); 6739%} 6740 6741// Load Integer into Long Register 6742instruct loadI2L(eRegL dst, memory mem, eFlagsReg cr) %{ 6743 match(Set dst (ConvI2L (LoadI mem))); 6744 effect(KILL cr); 6745 6746 ins_cost(375); 6747 format %{ "MOV $dst.lo,$mem\t# int -> long\n\t" 6748 "MOV $dst.hi,$dst.lo\n\t" 6749 "SAR $dst.hi,31" %} 6750 6751 ins_encode %{ 6752 __ movl($dst$$Register, $mem$$Address); 6753 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register. 6754 __ sarl(HIGH_FROM_LOW($dst$$Register), 31); 6755 %} 6756 6757 ins_pipe(ialu_reg_mem); 6758%} 6759 6760// Load Integer with mask 0xFF into Long Register 6761instruct loadI2L_immI_255(eRegL dst, memory mem, immI_255 mask, eFlagsReg cr) %{ 6762 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6763 effect(KILL cr); 6764 6765 format %{ "MOVZX8 $dst.lo,$mem\t# int & 0xFF -> long\n\t" 6766 "XOR $dst.hi,$dst.hi" %} 6767 ins_encode %{ 6768 Register Rdst = $dst$$Register; 6769 __ movzbl(Rdst, $mem$$Address); 6770 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6771 %} 6772 ins_pipe(ialu_reg_mem); 6773%} 6774 6775// Load Integer with mask 0xFFFF into Long Register 6776instruct loadI2L_immI_65535(eRegL dst, memory mem, immI_65535 mask, eFlagsReg cr) %{ 6777 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6778 effect(KILL cr); 6779 6780 format %{ "MOVZX $dst.lo,$mem\t# int & 0xFFFF -> long\n\t" 6781 "XOR $dst.hi,$dst.hi" %} 6782 ins_encode %{ 6783 Register Rdst = $dst$$Register; 6784 __ movzwl(Rdst, $mem$$Address); 6785 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6786 %} 6787 ins_pipe(ialu_reg_mem); 6788%} 6789 6790// Load Integer with 32-bit mask into Long Register 6791instruct loadI2L_immI(eRegL dst, memory mem, immI mask, eFlagsReg cr) %{ 6792 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6793 effect(KILL cr); 6794 6795 format %{ "MOV $dst.lo,$mem\t# int & 32-bit mask -> long\n\t" 6796 "XOR $dst.hi,$dst.hi\n\t" 6797 "AND $dst.lo,$mask" %} 6798 ins_encode %{ 6799 Register Rdst = $dst$$Register; 6800 __ movl(Rdst, $mem$$Address); 6801 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6802 __ andl(Rdst, $mask$$constant); 6803 %} 6804 ins_pipe(ialu_reg_mem); 6805%} 6806 6807// Load Unsigned Integer into Long Register 6808instruct loadUI2L(eRegL dst, memory mem, eFlagsReg cr) %{ 6809 match(Set dst (LoadUI2L mem)); 6810 effect(KILL cr); 6811 6812 ins_cost(250); 6813 format %{ "MOV $dst.lo,$mem\t# uint -> long\n\t" 6814 "XOR $dst.hi,$dst.hi" %} 6815 6816 ins_encode %{ 6817 __ movl($dst$$Register, $mem$$Address); 6818 __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register)); 6819 %} 6820 6821 ins_pipe(ialu_reg_mem); 6822%} 6823 6824// Load Long. Cannot clobber address while loading, so restrict address 6825// register to ESI 6826instruct loadL(eRegL dst, load_long_memory mem) %{ 6827 predicate(!((LoadLNode*)n)->require_atomic_access()); 6828 match(Set dst (LoadL mem)); 6829 6830 ins_cost(250); 6831 format %{ "MOV $dst.lo,$mem\t# long\n\t" 6832 "MOV $dst.hi,$mem+4" %} 6833 6834 ins_encode %{ 6835 Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, false); 6836 Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, false); 6837 __ movl($dst$$Register, Amemlo); 6838 __ movl(HIGH_FROM_LOW($dst$$Register), Amemhi); 6839 %} 6840 6841 ins_pipe(ialu_reg_long_mem); 6842%} 6843 6844// Volatile Load Long. Must be atomic, so do 64-bit FILD 6845// then store it down to the stack and reload on the int 6846// side. 6847instruct loadL_volatile(stackSlotL dst, memory mem) %{ 6848 predicate(UseSSE<=1 && ((LoadLNode*)n)->require_atomic_access()); 6849 match(Set dst (LoadL mem)); 6850 6851 ins_cost(200); 6852 format %{ "FILD $mem\t# Atomic volatile long load\n\t" 6853 "FISTp $dst" %} 6854 ins_encode(enc_loadL_volatile(mem,dst)); 6855 ins_pipe( fpu_reg_mem ); 6856%} 6857 6858instruct loadLX_volatile(stackSlotL dst, memory mem, regXD tmp) %{ 6859 predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access()); 6860 match(Set dst (LoadL mem)); 6861 effect(TEMP tmp); 6862 ins_cost(180); 6863 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t" 6864 "MOVSD $dst,$tmp" %} 6865 ins_encode(enc_loadLX_volatile(mem, dst, tmp)); 6866 ins_pipe( pipe_slow ); 6867%} 6868 6869instruct loadLX_reg_volatile(eRegL dst, memory mem, regXD tmp) %{ 6870 predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access()); 6871 match(Set dst (LoadL mem)); 6872 effect(TEMP tmp); 6873 ins_cost(160); 6874 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t" 6875 "MOVD $dst.lo,$tmp\n\t" 6876 "PSRLQ $tmp,32\n\t" 6877 "MOVD $dst.hi,$tmp" %} 6878 ins_encode(enc_loadLX_reg_volatile(mem, dst, tmp)); 6879 ins_pipe( pipe_slow ); 6880%} 6881 6882// Load Range 6883instruct loadRange(eRegI dst, memory mem) %{ 6884 match(Set dst (LoadRange mem)); 6885 6886 ins_cost(125); 6887 format %{ "MOV $dst,$mem" %} 6888 opcode(0x8B); 6889 ins_encode( OpcP, RegMem(dst,mem)); 6890 ins_pipe( ialu_reg_mem ); 6891%} 6892 6893 6894// Load Pointer 6895instruct loadP(eRegP dst, memory mem) %{ 6896 match(Set dst (LoadP mem)); 6897 6898 ins_cost(125); 6899 format %{ "MOV $dst,$mem" %} 6900 opcode(0x8B); 6901 ins_encode( OpcP, RegMem(dst,mem)); 6902 ins_pipe( ialu_reg_mem ); 6903%} 6904 6905// Load Klass Pointer 6906instruct loadKlass(eRegP dst, memory mem) %{ 6907 match(Set dst (LoadKlass mem)); 6908 6909 ins_cost(125); 6910 format %{ "MOV $dst,$mem" %} 6911 opcode(0x8B); 6912 ins_encode( OpcP, RegMem(dst,mem)); 6913 ins_pipe( ialu_reg_mem ); 6914%} 6915 6916// Load Double 6917instruct loadD(regD dst, memory mem) %{ 6918 predicate(UseSSE<=1); 6919 match(Set dst (LoadD mem)); 6920 6921 ins_cost(150); 6922 format %{ "FLD_D ST,$mem\n\t" 6923 "FSTP $dst" %} 6924 opcode(0xDD); /* DD /0 */ 6925 ins_encode( OpcP, RMopc_Mem(0x00,mem), 6926 Pop_Reg_D(dst) ); 6927 ins_pipe( fpu_reg_mem ); 6928%} 6929 6930// Load Double to XMM 6931instruct loadXD(regXD dst, memory mem) %{ 6932 predicate(UseSSE>=2 && UseXmmLoadAndClearUpper); 6933 match(Set dst (LoadD mem)); 6934 ins_cost(145); 6935 format %{ "MOVSD $dst,$mem" %} 6936 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x10), RegMem(dst,mem)); 6937 ins_pipe( pipe_slow ); 6938%} 6939 6940instruct loadXD_partial(regXD dst, memory mem) %{ 6941 predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper); 6942 match(Set dst (LoadD mem)); 6943 ins_cost(145); 6944 format %{ "MOVLPD $dst,$mem" %} 6945 ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x12), RegMem(dst,mem)); 6946 ins_pipe( pipe_slow ); 6947%} 6948 6949// Load to XMM register (single-precision floating point) 6950// MOVSS instruction 6951instruct loadX(regX dst, memory mem) %{ 6952 predicate(UseSSE>=1); 6953 match(Set dst (LoadF mem)); 6954 ins_cost(145); 6955 format %{ "MOVSS $dst,$mem" %} 6956 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x10), RegMem(dst,mem)); 6957 ins_pipe( pipe_slow ); 6958%} 6959 6960// Load Float 6961instruct loadF(regF dst, memory mem) %{ 6962 predicate(UseSSE==0); 6963 match(Set dst (LoadF mem)); 6964 6965 ins_cost(150); 6966 format %{ "FLD_S ST,$mem\n\t" 6967 "FSTP $dst" %} 6968 opcode(0xD9); /* D9 /0 */ 6969 ins_encode( OpcP, RMopc_Mem(0x00,mem), 6970 Pop_Reg_F(dst) ); 6971 ins_pipe( fpu_reg_mem ); 6972%} 6973 6974// Load Aligned Packed Byte to XMM register 6975instruct loadA8B(regXD dst, memory mem) %{ 6976 predicate(UseSSE>=1); 6977 match(Set dst (Load8B mem)); 6978 ins_cost(125); 6979 format %{ "MOVQ $dst,$mem\t! packed8B" %} 6980 ins_encode( movq_ld(dst, mem)); 6981 ins_pipe( pipe_slow ); 6982%} 6983 6984// Load Aligned Packed Short to XMM register 6985instruct loadA4S(regXD dst, memory mem) %{ 6986 predicate(UseSSE>=1); 6987 match(Set dst (Load4S mem)); 6988 ins_cost(125); 6989 format %{ "MOVQ $dst,$mem\t! packed4S" %} 6990 ins_encode( movq_ld(dst, mem)); 6991 ins_pipe( pipe_slow ); 6992%} 6993 6994// Load Aligned Packed Char to XMM register 6995instruct loadA4C(regXD dst, memory mem) %{ 6996 predicate(UseSSE>=1); 6997 match(Set dst (Load4C mem)); 6998 ins_cost(125); 6999 format %{ "MOVQ $dst,$mem\t! packed4C" %} 7000 ins_encode( movq_ld(dst, mem)); 7001 ins_pipe( pipe_slow ); 7002%} 7003 7004// Load Aligned Packed Integer to XMM register 7005instruct load2IU(regXD dst, memory mem) %{ 7006 predicate(UseSSE>=1); 7007 match(Set dst (Load2I mem)); 7008 ins_cost(125); 7009 format %{ "MOVQ $dst,$mem\t! packed2I" %} 7010 ins_encode( movq_ld(dst, mem)); 7011 ins_pipe( pipe_slow ); 7012%} 7013 7014// Load Aligned Packed Single to XMM 7015instruct loadA2F(regXD dst, memory mem) %{ 7016 predicate(UseSSE>=1); 7017 match(Set dst (Load2F mem)); 7018 ins_cost(145); 7019 format %{ "MOVQ $dst,$mem\t! packed2F" %} 7020 ins_encode( movq_ld(dst, mem)); 7021 ins_pipe( pipe_slow ); 7022%} 7023 7024// Load Effective Address 7025instruct leaP8(eRegP dst, indOffset8 mem) %{ 7026 match(Set dst mem); 7027 7028 ins_cost(110); 7029 format %{ "LEA $dst,$mem" %} 7030 opcode(0x8D); 7031 ins_encode( OpcP, RegMem(dst,mem)); 7032 ins_pipe( ialu_reg_reg_fat ); 7033%} 7034 7035instruct leaP32(eRegP dst, indOffset32 mem) %{ 7036 match(Set dst mem); 7037 7038 ins_cost(110); 7039 format %{ "LEA $dst,$mem" %} 7040 opcode(0x8D); 7041 ins_encode( OpcP, RegMem(dst,mem)); 7042 ins_pipe( ialu_reg_reg_fat ); 7043%} 7044 7045instruct leaPIdxOff(eRegP dst, indIndexOffset mem) %{ 7046 match(Set dst mem); 7047 7048 ins_cost(110); 7049 format %{ "LEA $dst,$mem" %} 7050 opcode(0x8D); 7051 ins_encode( OpcP, RegMem(dst,mem)); 7052 ins_pipe( ialu_reg_reg_fat ); 7053%} 7054 7055instruct leaPIdxScale(eRegP dst, indIndexScale mem) %{ 7056 match(Set dst mem); 7057 7058 ins_cost(110); 7059 format %{ "LEA $dst,$mem" %} 7060 opcode(0x8D); 7061 ins_encode( OpcP, RegMem(dst,mem)); 7062 ins_pipe( ialu_reg_reg_fat ); 7063%} 7064 7065instruct leaPIdxScaleOff(eRegP dst, indIndexScaleOffset mem) %{ 7066 match(Set dst mem); 7067 7068 ins_cost(110); 7069 format %{ "LEA $dst,$mem" %} 7070 opcode(0x8D); 7071 ins_encode( OpcP, RegMem(dst,mem)); 7072 ins_pipe( ialu_reg_reg_fat ); 7073%} 7074 7075// Load Constant 7076instruct loadConI(eRegI dst, immI src) %{ 7077 match(Set dst src); 7078 7079 format %{ "MOV $dst,$src" %} 7080 ins_encode( LdImmI(dst, src) ); 7081 ins_pipe( ialu_reg_fat ); 7082%} 7083 7084// Load Constant zero 7085instruct loadConI0(eRegI dst, immI0 src, eFlagsReg cr) %{ 7086 match(Set dst src); 7087 effect(KILL cr); 7088 7089 ins_cost(50); 7090 format %{ "XOR $dst,$dst" %} 7091 opcode(0x33); /* + rd */ 7092 ins_encode( OpcP, RegReg( dst, dst ) ); 7093 ins_pipe( ialu_reg ); 7094%} 7095 7096instruct loadConP(eRegP dst, immP src) %{ 7097 match(Set dst src); 7098 7099 format %{ "MOV $dst,$src" %} 7100 opcode(0xB8); /* + rd */ 7101 ins_encode( LdImmP(dst, src) ); 7102 ins_pipe( ialu_reg_fat ); 7103%} 7104 7105instruct loadConL(eRegL dst, immL src, eFlagsReg cr) %{ 7106 match(Set dst src); 7107 effect(KILL cr); 7108 ins_cost(200); 7109 format %{ "MOV $dst.lo,$src.lo\n\t" 7110 "MOV $dst.hi,$src.hi" %} 7111 opcode(0xB8); 7112 ins_encode( LdImmL_Lo(dst, src), LdImmL_Hi(dst, src) ); 7113 ins_pipe( ialu_reg_long_fat ); 7114%} 7115 7116instruct loadConL0(eRegL dst, immL0 src, eFlagsReg cr) %{ 7117 match(Set dst src); 7118 effect(KILL cr); 7119 ins_cost(150); 7120 format %{ "XOR $dst.lo,$dst.lo\n\t" 7121 "XOR $dst.hi,$dst.hi" %} 7122 opcode(0x33,0x33); 7123 ins_encode( RegReg_Lo(dst,dst), RegReg_Hi(dst, dst) ); 7124 ins_pipe( ialu_reg_long ); 7125%} 7126 7127// The instruction usage is guarded by predicate in operand immF(). 7128instruct loadConF(regF dst, immF con) %{ 7129 match(Set dst con); 7130 ins_cost(125); 7131 format %{ "FLD_S ST,[$constantaddress]\t# load from constant table: float=$con\n\t" 7132 "FSTP $dst" %} 7133 ins_encode %{ 7134 __ fld_s($constantaddress($con)); 7135 __ fstp_d($dst$$reg); 7136 %} 7137 ins_pipe(fpu_reg_con); 7138%} 7139 7140// The instruction usage is guarded by predicate in operand immF0(). 7141instruct loadConF0(regF dst, immF0 con) %{ 7142 match(Set dst con); 7143 ins_cost(125); 7144 format %{ "FLDZ ST\n\t" 7145 "FSTP $dst" %} 7146 ins_encode %{ 7147 __ fldz(); 7148 __ fstp_d($dst$$reg); 7149 %} 7150 ins_pipe(fpu_reg_con); 7151%} 7152 7153// The instruction usage is guarded by predicate in operand immF1(). 7154instruct loadConF1(regF dst, immF1 con) %{ 7155 match(Set dst con); 7156 ins_cost(125); 7157 format %{ "FLD1 ST\n\t" 7158 "FSTP $dst" %} 7159 ins_encode %{ 7160 __ fld1(); 7161 __ fstp_d($dst$$reg); 7162 %} 7163 ins_pipe(fpu_reg_con); 7164%} 7165 7166// The instruction usage is guarded by predicate in operand immXF(). 7167instruct loadConX(regX dst, immXF con) %{ 7168 match(Set dst con); 7169 ins_cost(125); 7170 format %{ "MOVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 7171 ins_encode %{ 7172 __ movflt($dst$$XMMRegister, $constantaddress($con)); 7173 %} 7174 ins_pipe(pipe_slow); 7175%} 7176 7177// The instruction usage is guarded by predicate in operand immXF0(). 7178instruct loadConX0(regX dst, immXF0 src) %{ 7179 match(Set dst src); 7180 ins_cost(100); 7181 format %{ "XORPS $dst,$dst\t# float 0.0" %} 7182 ins_encode %{ 7183 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 7184 %} 7185 ins_pipe(pipe_slow); 7186%} 7187 7188// The instruction usage is guarded by predicate in operand immD(). 7189instruct loadConD(regD dst, immD con) %{ 7190 match(Set dst con); 7191 ins_cost(125); 7192 7193 format %{ "FLD_D ST,[$constantaddress]\t# load from constant table: double=$con\n\t" 7194 "FSTP $dst" %} 7195 ins_encode %{ 7196 __ fld_d($constantaddress($con)); 7197 __ fstp_d($dst$$reg); 7198 %} 7199 ins_pipe(fpu_reg_con); 7200%} 7201 7202// The instruction usage is guarded by predicate in operand immD0(). 7203instruct loadConD0(regD dst, immD0 con) %{ 7204 match(Set dst con); 7205 ins_cost(125); 7206 7207 format %{ "FLDZ ST\n\t" 7208 "FSTP $dst" %} 7209 ins_encode %{ 7210 __ fldz(); 7211 __ fstp_d($dst$$reg); 7212 %} 7213 ins_pipe(fpu_reg_con); 7214%} 7215 7216// The instruction usage is guarded by predicate in operand immD1(). 7217instruct loadConD1(regD dst, immD1 con) %{ 7218 match(Set dst con); 7219 ins_cost(125); 7220 7221 format %{ "FLD1 ST\n\t" 7222 "FSTP $dst" %} 7223 ins_encode %{ 7224 __ fld1(); 7225 __ fstp_d($dst$$reg); 7226 %} 7227 ins_pipe(fpu_reg_con); 7228%} 7229 7230// The instruction usage is guarded by predicate in operand immXD(). 7231instruct loadConXD(regXD dst, immXD con) %{ 7232 match(Set dst con); 7233 ins_cost(125); 7234 format %{ "MOVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 7235 ins_encode %{ 7236 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 7237 %} 7238 ins_pipe(pipe_slow); 7239%} 7240 7241// The instruction usage is guarded by predicate in operand immXD0(). 7242instruct loadConXD0(regXD dst, immXD0 src) %{ 7243 match(Set dst src); 7244 ins_cost(100); 7245 format %{ "XORPD $dst,$dst\t# double 0.0" %} 7246 ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x57), RegReg(dst,dst)); 7247 ins_pipe( pipe_slow ); 7248%} 7249 7250// Load Stack Slot 7251instruct loadSSI(eRegI dst, stackSlotI src) %{ 7252 match(Set dst src); 7253 ins_cost(125); 7254 7255 format %{ "MOV $dst,$src" %} 7256 opcode(0x8B); 7257 ins_encode( OpcP, RegMem(dst,src)); 7258 ins_pipe( ialu_reg_mem ); 7259%} 7260 7261instruct loadSSL(eRegL dst, stackSlotL src) %{ 7262 match(Set dst src); 7263 7264 ins_cost(200); 7265 format %{ "MOV $dst,$src.lo\n\t" 7266 "MOV $dst+4,$src.hi" %} 7267 opcode(0x8B, 0x8B); 7268 ins_encode( OpcP, RegMem( dst, src ), OpcS, RegMem_Hi( dst, src ) ); 7269 ins_pipe( ialu_mem_long_reg ); 7270%} 7271 7272// Load Stack Slot 7273instruct loadSSP(eRegP dst, stackSlotP src) %{ 7274 match(Set dst src); 7275 ins_cost(125); 7276 7277 format %{ "MOV $dst,$src" %} 7278 opcode(0x8B); 7279 ins_encode( OpcP, RegMem(dst,src)); 7280 ins_pipe( ialu_reg_mem ); 7281%} 7282 7283// Load Stack Slot 7284instruct loadSSF(regF dst, stackSlotF src) %{ 7285 match(Set dst src); 7286 ins_cost(125); 7287 7288 format %{ "FLD_S $src\n\t" 7289 "FSTP $dst" %} 7290 opcode(0xD9); /* D9 /0, FLD m32real */ 7291 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src), 7292 Pop_Reg_F(dst) ); 7293 ins_pipe( fpu_reg_mem ); 7294%} 7295 7296// Load Stack Slot 7297instruct loadSSD(regD dst, stackSlotD src) %{ 7298 match(Set dst src); 7299 ins_cost(125); 7300 7301 format %{ "FLD_D $src\n\t" 7302 "FSTP $dst" %} 7303 opcode(0xDD); /* DD /0, FLD m64real */ 7304 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src), 7305 Pop_Reg_D(dst) ); 7306 ins_pipe( fpu_reg_mem ); 7307%} 7308 7309// Prefetch instructions. 7310// Must be safe to execute with invalid address (cannot fault). 7311 7312instruct prefetchr0( memory mem ) %{ 7313 predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch()); 7314 match(PrefetchRead mem); 7315 ins_cost(0); 7316 size(0); 7317 format %{ "PREFETCHR (non-SSE is empty encoding)" %} 7318 ins_encode(); 7319 ins_pipe(empty); 7320%} 7321 7322instruct prefetchr( memory mem ) %{ 7323 predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || ReadPrefetchInstr==3); 7324 match(PrefetchRead mem); 7325 ins_cost(100); 7326 7327 format %{ "PREFETCHR $mem\t! Prefetch into level 1 cache for read" %} 7328 opcode(0x0F, 0x0d); /* Opcode 0F 0d /0 */ 7329 ins_encode(OpcP, OpcS, RMopc_Mem(0x00,mem)); 7330 ins_pipe(ialu_mem); 7331%} 7332 7333instruct prefetchrNTA( memory mem ) %{ 7334 predicate(UseSSE>=1 && ReadPrefetchInstr==0); 7335 match(PrefetchRead mem); 7336 ins_cost(100); 7337 7338 format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for read" %} 7339 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */ 7340 ins_encode(OpcP, OpcS, RMopc_Mem(0x00,mem)); 7341 ins_pipe(ialu_mem); 7342%} 7343 7344instruct prefetchrT0( memory mem ) %{ 7345 predicate(UseSSE>=1 && ReadPrefetchInstr==1); 7346 match(PrefetchRead mem); 7347 ins_cost(100); 7348 7349 format %{ "PREFETCHT0 $mem\t! Prefetch into L1 and L2 caches for read" %} 7350 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */ 7351 ins_encode(OpcP, OpcS, RMopc_Mem(0x01,mem)); 7352 ins_pipe(ialu_mem); 7353%} 7354 7355instruct prefetchrT2( memory mem ) %{ 7356 predicate(UseSSE>=1 && ReadPrefetchInstr==2); 7357 match(PrefetchRead mem); 7358 ins_cost(100); 7359 7360 format %{ "PREFETCHT2 $mem\t! Prefetch into L2 cache for read" %} 7361 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */ 7362 ins_encode(OpcP, OpcS, RMopc_Mem(0x03,mem)); 7363 ins_pipe(ialu_mem); 7364%} 7365 7366instruct prefetchw0( memory mem ) %{ 7367 predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch()); 7368 match(PrefetchWrite mem); 7369 ins_cost(0); 7370 size(0); 7371 format %{ "Prefetch (non-SSE is empty encoding)" %} 7372 ins_encode(); 7373 ins_pipe(empty); 7374%} 7375 7376instruct prefetchw( memory mem ) %{ 7377 predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || AllocatePrefetchInstr==3); 7378 match( PrefetchWrite mem ); 7379 ins_cost(100); 7380 7381 format %{ "PREFETCHW $mem\t! Prefetch into L1 cache and mark modified" %} 7382 opcode(0x0F, 0x0D); /* Opcode 0F 0D /1 */ 7383 ins_encode(OpcP, OpcS, RMopc_Mem(0x01,mem)); 7384 ins_pipe(ialu_mem); 7385%} 7386 7387instruct prefetchwNTA( memory mem ) %{ 7388 predicate(UseSSE>=1 && AllocatePrefetchInstr==0); 7389 match(PrefetchWrite mem); 7390 ins_cost(100); 7391 7392 format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for write" %} 7393 opcode(0x0F, 0x18); /* Opcode 0F 18 /0 */ 7394 ins_encode(OpcP, OpcS, RMopc_Mem(0x00,mem)); 7395 ins_pipe(ialu_mem); 7396%} 7397 7398instruct prefetchwT0( memory mem ) %{ 7399 predicate(UseSSE>=1 && AllocatePrefetchInstr==1); 7400 match(PrefetchWrite mem); 7401 ins_cost(100); 7402 7403 format %{ "PREFETCHT0 $mem\t! Prefetch into L1 and L2 caches for write" %} 7404 opcode(0x0F, 0x18); /* Opcode 0F 18 /1 */ 7405 ins_encode(OpcP, OpcS, RMopc_Mem(0x01,mem)); 7406 ins_pipe(ialu_mem); 7407%} 7408 7409instruct prefetchwT2( memory mem ) %{ 7410 predicate(UseSSE>=1 && AllocatePrefetchInstr==2); 7411 match(PrefetchWrite mem); 7412 ins_cost(100); 7413 7414 format %{ "PREFETCHT2 $mem\t! Prefetch into L2 cache for write" %} 7415 opcode(0x0F, 0x18); /* Opcode 0F 18 /3 */ 7416 ins_encode(OpcP, OpcS, RMopc_Mem(0x03,mem)); 7417 ins_pipe(ialu_mem); 7418%} 7419 7420//----------Store Instructions------------------------------------------------- 7421 7422// Store Byte 7423instruct storeB(memory mem, xRegI src) %{ 7424 match(Set mem (StoreB mem src)); 7425 7426 ins_cost(125); 7427 format %{ "MOV8 $mem,$src" %} 7428 opcode(0x88); 7429 ins_encode( OpcP, RegMem( src, mem ) ); 7430 ins_pipe( ialu_mem_reg ); 7431%} 7432 7433// Store Char/Short 7434instruct storeC(memory mem, eRegI src) %{ 7435 match(Set mem (StoreC mem src)); 7436 7437 ins_cost(125); 7438 format %{ "MOV16 $mem,$src" %} 7439 opcode(0x89, 0x66); 7440 ins_encode( OpcS, OpcP, RegMem( src, mem ) ); 7441 ins_pipe( ialu_mem_reg ); 7442%} 7443 7444// Store Integer 7445instruct storeI(memory mem, eRegI src) %{ 7446 match(Set mem (StoreI mem src)); 7447 7448 ins_cost(125); 7449 format %{ "MOV $mem,$src" %} 7450 opcode(0x89); 7451 ins_encode( OpcP, RegMem( src, mem ) ); 7452 ins_pipe( ialu_mem_reg ); 7453%} 7454 7455// Store Long 7456instruct storeL(long_memory mem, eRegL src) %{ 7457 predicate(!((StoreLNode*)n)->require_atomic_access()); 7458 match(Set mem (StoreL mem src)); 7459 7460 ins_cost(200); 7461 format %{ "MOV $mem,$src.lo\n\t" 7462 "MOV $mem+4,$src.hi" %} 7463 opcode(0x89, 0x89); 7464 ins_encode( OpcP, RegMem( src, mem ), OpcS, RegMem_Hi( src, mem ) ); 7465 ins_pipe( ialu_mem_long_reg ); 7466%} 7467 7468// Store Long to Integer 7469instruct storeL2I(memory mem, eRegL src) %{ 7470 match(Set mem (StoreI mem (ConvL2I src))); 7471 7472 format %{ "MOV $mem,$src.lo\t# long -> int" %} 7473 ins_encode %{ 7474 __ movl($mem$$Address, $src$$Register); 7475 %} 7476 ins_pipe(ialu_mem_reg); 7477%} 7478 7479// Volatile Store Long. Must be atomic, so move it into 7480// the FP TOS and then do a 64-bit FIST. Has to probe the 7481// target address before the store (for null-ptr checks) 7482// so the memory operand is used twice in the encoding. 7483instruct storeL_volatile(memory mem, stackSlotL src, eFlagsReg cr ) %{ 7484 predicate(UseSSE<=1 && ((StoreLNode*)n)->require_atomic_access()); 7485 match(Set mem (StoreL mem src)); 7486 effect( KILL cr ); 7487 ins_cost(400); 7488 format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t" 7489 "FILD $src\n\t" 7490 "FISTp $mem\t # 64-bit atomic volatile long store" %} 7491 opcode(0x3B); 7492 ins_encode( OpcP, RegMem( EAX, mem ), enc_storeL_volatile(mem,src)); 7493 ins_pipe( fpu_reg_mem ); 7494%} 7495 7496instruct storeLX_volatile(memory mem, stackSlotL src, regXD tmp, eFlagsReg cr) %{ 7497 predicate(UseSSE>=2 && ((StoreLNode*)n)->require_atomic_access()); 7498 match(Set mem (StoreL mem src)); 7499 effect( TEMP tmp, KILL cr ); 7500 ins_cost(380); 7501 format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t" 7502 "MOVSD $tmp,$src\n\t" 7503 "MOVSD $mem,$tmp\t # 64-bit atomic volatile long store" %} 7504 opcode(0x3B); 7505 ins_encode( OpcP, RegMem( EAX, mem ), enc_storeLX_volatile(mem, src, tmp)); 7506 ins_pipe( pipe_slow ); 7507%} 7508 7509instruct storeLX_reg_volatile(memory mem, eRegL src, regXD tmp2, regXD tmp, eFlagsReg cr) %{ 7510 predicate(UseSSE>=2 && ((StoreLNode*)n)->require_atomic_access()); 7511 match(Set mem (StoreL mem src)); 7512 effect( TEMP tmp2 , TEMP tmp, KILL cr ); 7513 ins_cost(360); 7514 format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t" 7515 "MOVD $tmp,$src.lo\n\t" 7516 "MOVD $tmp2,$src.hi\n\t" 7517 "PUNPCKLDQ $tmp,$tmp2\n\t" 7518 "MOVSD $mem,$tmp\t # 64-bit atomic volatile long store" %} 7519 opcode(0x3B); 7520 ins_encode( OpcP, RegMem( EAX, mem ), enc_storeLX_reg_volatile(mem, src, tmp, tmp2)); 7521 ins_pipe( pipe_slow ); 7522%} 7523 7524// Store Pointer; for storing unknown oops and raw pointers 7525instruct storeP(memory mem, anyRegP src) %{ 7526 match(Set mem (StoreP mem src)); 7527 7528 ins_cost(125); 7529 format %{ "MOV $mem,$src" %} 7530 opcode(0x89); 7531 ins_encode( OpcP, RegMem( src, mem ) ); 7532 ins_pipe( ialu_mem_reg ); 7533%} 7534 7535// Store Integer Immediate 7536instruct storeImmI(memory mem, immI src) %{ 7537 match(Set mem (StoreI mem src)); 7538 7539 ins_cost(150); 7540 format %{ "MOV $mem,$src" %} 7541 opcode(0xC7); /* C7 /0 */ 7542 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32( src )); 7543 ins_pipe( ialu_mem_imm ); 7544%} 7545 7546// Store Short/Char Immediate 7547instruct storeImmI16(memory mem, immI16 src) %{ 7548 predicate(UseStoreImmI16); 7549 match(Set mem (StoreC mem src)); 7550 7551 ins_cost(150); 7552 format %{ "MOV16 $mem,$src" %} 7553 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 7554 ins_encode( SizePrefix, OpcP, RMopc_Mem(0x00,mem), Con16( src )); 7555 ins_pipe( ialu_mem_imm ); 7556%} 7557 7558// Store Pointer Immediate; null pointers or constant oops that do not 7559// need card-mark barriers. 7560instruct storeImmP(memory mem, immP src) %{ 7561 match(Set mem (StoreP mem src)); 7562 7563 ins_cost(150); 7564 format %{ "MOV $mem,$src" %} 7565 opcode(0xC7); /* C7 /0 */ 7566 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32( src )); 7567 ins_pipe( ialu_mem_imm ); 7568%} 7569 7570// Store Byte Immediate 7571instruct storeImmB(memory mem, immI8 src) %{ 7572 match(Set mem (StoreB mem src)); 7573 7574 ins_cost(150); 7575 format %{ "MOV8 $mem,$src" %} 7576 opcode(0xC6); /* C6 /0 */ 7577 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src )); 7578 ins_pipe( ialu_mem_imm ); 7579%} 7580 7581// Store Aligned Packed Byte XMM register to memory 7582instruct storeA8B(memory mem, regXD src) %{ 7583 predicate(UseSSE>=1); 7584 match(Set mem (Store8B mem src)); 7585 ins_cost(145); 7586 format %{ "MOVQ $mem,$src\t! packed8B" %} 7587 ins_encode( movq_st(mem, src)); 7588 ins_pipe( pipe_slow ); 7589%} 7590 7591// Store Aligned Packed Char/Short XMM register to memory 7592instruct storeA4C(memory mem, regXD src) %{ 7593 predicate(UseSSE>=1); 7594 match(Set mem (Store4C mem src)); 7595 ins_cost(145); 7596 format %{ "MOVQ $mem,$src\t! packed4C" %} 7597 ins_encode( movq_st(mem, src)); 7598 ins_pipe( pipe_slow ); 7599%} 7600 7601// Store Aligned Packed Integer XMM register to memory 7602instruct storeA2I(memory mem, regXD src) %{ 7603 predicate(UseSSE>=1); 7604 match(Set mem (Store2I mem src)); 7605 ins_cost(145); 7606 format %{ "MOVQ $mem,$src\t! packed2I" %} 7607 ins_encode( movq_st(mem, src)); 7608 ins_pipe( pipe_slow ); 7609%} 7610 7611// Store CMS card-mark Immediate 7612instruct storeImmCM(memory mem, immI8 src) %{ 7613 match(Set mem (StoreCM mem src)); 7614 7615 ins_cost(150); 7616 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %} 7617 opcode(0xC6); /* C6 /0 */ 7618 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src )); 7619 ins_pipe( ialu_mem_imm ); 7620%} 7621 7622// Store Double 7623instruct storeD( memory mem, regDPR1 src) %{ 7624 predicate(UseSSE<=1); 7625 match(Set mem (StoreD mem src)); 7626 7627 ins_cost(100); 7628 format %{ "FST_D $mem,$src" %} 7629 opcode(0xDD); /* DD /2 */ 7630 ins_encode( enc_FP_store(mem,src) ); 7631 ins_pipe( fpu_mem_reg ); 7632%} 7633 7634// Store double does rounding on x86 7635instruct storeD_rounded( memory mem, regDPR1 src) %{ 7636 predicate(UseSSE<=1); 7637 match(Set mem (StoreD mem (RoundDouble src))); 7638 7639 ins_cost(100); 7640 format %{ "FST_D $mem,$src\t# round" %} 7641 opcode(0xDD); /* DD /2 */ 7642 ins_encode( enc_FP_store(mem,src) ); 7643 ins_pipe( fpu_mem_reg ); 7644%} 7645 7646// Store XMM register to memory (double-precision floating points) 7647// MOVSD instruction 7648instruct storeXD(memory mem, regXD src) %{ 7649 predicate(UseSSE>=2); 7650 match(Set mem (StoreD mem src)); 7651 ins_cost(95); 7652 format %{ "MOVSD $mem,$src" %} 7653 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x11), RegMem(src, mem)); 7654 ins_pipe( pipe_slow ); 7655%} 7656 7657// Store XMM register to memory (single-precision floating point) 7658// MOVSS instruction 7659instruct storeX(memory mem, regX src) %{ 7660 predicate(UseSSE>=1); 7661 match(Set mem (StoreF mem src)); 7662 ins_cost(95); 7663 format %{ "MOVSS $mem,$src" %} 7664 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x11), RegMem(src, mem)); 7665 ins_pipe( pipe_slow ); 7666%} 7667 7668// Store Aligned Packed Single Float XMM register to memory 7669instruct storeA2F(memory mem, regXD src) %{ 7670 predicate(UseSSE>=1); 7671 match(Set mem (Store2F mem src)); 7672 ins_cost(145); 7673 format %{ "MOVQ $mem,$src\t! packed2F" %} 7674 ins_encode( movq_st(mem, src)); 7675 ins_pipe( pipe_slow ); 7676%} 7677 7678// Store Float 7679instruct storeF( memory mem, regFPR1 src) %{ 7680 predicate(UseSSE==0); 7681 match(Set mem (StoreF mem src)); 7682 7683 ins_cost(100); 7684 format %{ "FST_S $mem,$src" %} 7685 opcode(0xD9); /* D9 /2 */ 7686 ins_encode( enc_FP_store(mem,src) ); 7687 ins_pipe( fpu_mem_reg ); 7688%} 7689 7690// Store Float does rounding on x86 7691instruct storeF_rounded( memory mem, regFPR1 src) %{ 7692 predicate(UseSSE==0); 7693 match(Set mem (StoreF mem (RoundFloat src))); 7694 7695 ins_cost(100); 7696 format %{ "FST_S $mem,$src\t# round" %} 7697 opcode(0xD9); /* D9 /2 */ 7698 ins_encode( enc_FP_store(mem,src) ); 7699 ins_pipe( fpu_mem_reg ); 7700%} 7701 7702// Store Float does rounding on x86 7703instruct storeF_Drounded( memory mem, regDPR1 src) %{ 7704 predicate(UseSSE<=1); 7705 match(Set mem (StoreF mem (ConvD2F src))); 7706 7707 ins_cost(100); 7708 format %{ "FST_S $mem,$src\t# D-round" %} 7709 opcode(0xD9); /* D9 /2 */ 7710 ins_encode( enc_FP_store(mem,src) ); 7711 ins_pipe( fpu_mem_reg ); 7712%} 7713 7714// Store immediate Float value (it is faster than store from FPU register) 7715// The instruction usage is guarded by predicate in operand immF(). 7716instruct storeF_imm( memory mem, immF src) %{ 7717 match(Set mem (StoreF mem src)); 7718 7719 ins_cost(50); 7720 format %{ "MOV $mem,$src\t# store float" %} 7721 opcode(0xC7); /* C7 /0 */ 7722 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32F_as_bits( src )); 7723 ins_pipe( ialu_mem_imm ); 7724%} 7725 7726// Store immediate Float value (it is faster than store from XMM register) 7727// The instruction usage is guarded by predicate in operand immXF(). 7728instruct storeX_imm( memory mem, immXF src) %{ 7729 match(Set mem (StoreF mem src)); 7730 7731 ins_cost(50); 7732 format %{ "MOV $mem,$src\t# store float" %} 7733 opcode(0xC7); /* C7 /0 */ 7734 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32XF_as_bits( src )); 7735 ins_pipe( ialu_mem_imm ); 7736%} 7737 7738// Store Integer to stack slot 7739instruct storeSSI(stackSlotI dst, eRegI src) %{ 7740 match(Set dst src); 7741 7742 ins_cost(100); 7743 format %{ "MOV $dst,$src" %} 7744 opcode(0x89); 7745 ins_encode( OpcPRegSS( dst, src ) ); 7746 ins_pipe( ialu_mem_reg ); 7747%} 7748 7749// Store Integer to stack slot 7750instruct storeSSP(stackSlotP dst, eRegP src) %{ 7751 match(Set dst src); 7752 7753 ins_cost(100); 7754 format %{ "MOV $dst,$src" %} 7755 opcode(0x89); 7756 ins_encode( OpcPRegSS( dst, src ) ); 7757 ins_pipe( ialu_mem_reg ); 7758%} 7759 7760// Store Long to stack slot 7761instruct storeSSL(stackSlotL dst, eRegL src) %{ 7762 match(Set dst src); 7763 7764 ins_cost(200); 7765 format %{ "MOV $dst,$src.lo\n\t" 7766 "MOV $dst+4,$src.hi" %} 7767 opcode(0x89, 0x89); 7768 ins_encode( OpcP, RegMem( src, dst ), OpcS, RegMem_Hi( src, dst ) ); 7769 ins_pipe( ialu_mem_long_reg ); 7770%} 7771 7772//----------MemBar Instructions----------------------------------------------- 7773// Memory barrier flavors 7774 7775instruct membar_acquire() %{ 7776 match(MemBarAcquire); 7777 ins_cost(400); 7778 7779 size(0); 7780 format %{ "MEMBAR-acquire ! (empty encoding)" %} 7781 ins_encode(); 7782 ins_pipe(empty); 7783%} 7784 7785instruct membar_acquire_lock() %{ 7786 match(MemBarAcquireLock); 7787 ins_cost(0); 7788 7789 size(0); 7790 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 7791 ins_encode( ); 7792 ins_pipe(empty); 7793%} 7794 7795instruct membar_release() %{ 7796 match(MemBarRelease); 7797 ins_cost(400); 7798 7799 size(0); 7800 format %{ "MEMBAR-release ! (empty encoding)" %} 7801 ins_encode( ); 7802 ins_pipe(empty); 7803%} 7804 7805instruct membar_release_lock() %{ 7806 match(MemBarReleaseLock); 7807 ins_cost(0); 7808 7809 size(0); 7810 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 7811 ins_encode( ); 7812 ins_pipe(empty); 7813%} 7814 7815instruct membar_volatile(eFlagsReg cr) %{ 7816 match(MemBarVolatile); 7817 effect(KILL cr); 7818 ins_cost(400); 7819 7820 format %{ 7821 $$template 7822 if (os::is_MP()) { 7823 $$emit$$"LOCK ADDL [ESP + #0], 0\t! membar_volatile" 7824 } else { 7825 $$emit$$"MEMBAR-volatile ! (empty encoding)" 7826 } 7827 %} 7828 ins_encode %{ 7829 __ membar(Assembler::StoreLoad); 7830 %} 7831 ins_pipe(pipe_slow); 7832%} 7833 7834instruct unnecessary_membar_volatile() %{ 7835 match(MemBarVolatile); 7836 predicate(Matcher::post_store_load_barrier(n)); 7837 ins_cost(0); 7838 7839 size(0); 7840 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 7841 ins_encode( ); 7842 ins_pipe(empty); 7843%} 7844 7845//----------Move Instructions-------------------------------------------------- 7846instruct castX2P(eAXRegP dst, eAXRegI src) %{ 7847 match(Set dst (CastX2P src)); 7848 format %{ "# X2P $dst, $src" %} 7849 ins_encode( /*empty encoding*/ ); 7850 ins_cost(0); 7851 ins_pipe(empty); 7852%} 7853 7854instruct castP2X(eRegI dst, eRegP src ) %{ 7855 match(Set dst (CastP2X src)); 7856 ins_cost(50); 7857 format %{ "MOV $dst, $src\t# CastP2X" %} 7858 ins_encode( enc_Copy( dst, src) ); 7859 ins_pipe( ialu_reg_reg ); 7860%} 7861 7862//----------Conditional Move--------------------------------------------------- 7863// Conditional move 7864instruct cmovI_reg(eRegI dst, eRegI src, eFlagsReg cr, cmpOp cop ) %{ 7865 predicate(VM_Version::supports_cmov() ); 7866 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7867 ins_cost(200); 7868 format %{ "CMOV$cop $dst,$src" %} 7869 opcode(0x0F,0x40); 7870 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7871 ins_pipe( pipe_cmov_reg ); 7872%} 7873 7874instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{ 7875 predicate(VM_Version::supports_cmov() ); 7876 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7877 ins_cost(200); 7878 format %{ "CMOV$cop $dst,$src" %} 7879 opcode(0x0F,0x40); 7880 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7881 ins_pipe( pipe_cmov_reg ); 7882%} 7883 7884instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{ 7885 predicate(VM_Version::supports_cmov() ); 7886 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7887 ins_cost(200); 7888 expand %{ 7889 cmovI_regU(cop, cr, dst, src); 7890 %} 7891%} 7892 7893// Conditional move 7894instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{ 7895 predicate(VM_Version::supports_cmov() ); 7896 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7897 ins_cost(250); 7898 format %{ "CMOV$cop $dst,$src" %} 7899 opcode(0x0F,0x40); 7900 ins_encode( enc_cmov(cop), RegMem( dst, src ) ); 7901 ins_pipe( pipe_cmov_mem ); 7902%} 7903 7904// Conditional move 7905instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{ 7906 predicate(VM_Version::supports_cmov() ); 7907 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7908 ins_cost(250); 7909 format %{ "CMOV$cop $dst,$src" %} 7910 opcode(0x0F,0x40); 7911 ins_encode( enc_cmov(cop), RegMem( dst, src ) ); 7912 ins_pipe( pipe_cmov_mem ); 7913%} 7914 7915instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{ 7916 predicate(VM_Version::supports_cmov() ); 7917 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7918 ins_cost(250); 7919 expand %{ 7920 cmovI_memU(cop, cr, dst, src); 7921 %} 7922%} 7923 7924// Conditional move 7925instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{ 7926 predicate(VM_Version::supports_cmov() ); 7927 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7928 ins_cost(200); 7929 format %{ "CMOV$cop $dst,$src\t# ptr" %} 7930 opcode(0x0F,0x40); 7931 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7932 ins_pipe( pipe_cmov_reg ); 7933%} 7934 7935// Conditional move (non-P6 version) 7936// Note: a CMoveP is generated for stubs and native wrappers 7937// regardless of whether we are on a P6, so we 7938// emulate a cmov here 7939instruct cmovP_reg_nonP6(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{ 7940 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7941 ins_cost(300); 7942 format %{ "Jn$cop skip\n\t" 7943 "MOV $dst,$src\t# pointer\n" 7944 "skip:" %} 7945 opcode(0x8b); 7946 ins_encode( enc_cmov_branch(cop, 0x2), OpcP, RegReg(dst, src)); 7947 ins_pipe( pipe_cmov_reg ); 7948%} 7949 7950// Conditional move 7951instruct cmovP_regU(cmpOpU cop, eFlagsRegU cr, eRegP dst, eRegP src ) %{ 7952 predicate(VM_Version::supports_cmov() ); 7953 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7954 ins_cost(200); 7955 format %{ "CMOV$cop $dst,$src\t# ptr" %} 7956 opcode(0x0F,0x40); 7957 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7958 ins_pipe( pipe_cmov_reg ); 7959%} 7960 7961instruct cmovP_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegP dst, eRegP src ) %{ 7962 predicate(VM_Version::supports_cmov() ); 7963 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7964 ins_cost(200); 7965 expand %{ 7966 cmovP_regU(cop, cr, dst, src); 7967 %} 7968%} 7969 7970// DISABLED: Requires the ADLC to emit a bottom_type call that 7971// correctly meets the two pointer arguments; one is an incoming 7972// register but the other is a memory operand. ALSO appears to 7973// be buggy with implicit null checks. 7974// 7975//// Conditional move 7976//instruct cmovP_mem(cmpOp cop, eFlagsReg cr, eRegP dst, memory src) %{ 7977// predicate(VM_Version::supports_cmov() ); 7978// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7979// ins_cost(250); 7980// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7981// opcode(0x0F,0x40); 7982// ins_encode( enc_cmov(cop), RegMem( dst, src ) ); 7983// ins_pipe( pipe_cmov_mem ); 7984//%} 7985// 7986//// Conditional move 7987//instruct cmovP_memU(cmpOpU cop, eFlagsRegU cr, eRegP dst, memory src) %{ 7988// predicate(VM_Version::supports_cmov() ); 7989// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7990// ins_cost(250); 7991// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7992// opcode(0x0F,0x40); 7993// ins_encode( enc_cmov(cop), RegMem( dst, src ) ); 7994// ins_pipe( pipe_cmov_mem ); 7995//%} 7996 7997// Conditional move 7998instruct fcmovD_regU(cmpOp_fcmov cop, eFlagsRegU cr, regDPR1 dst, regD src) %{ 7999 predicate(UseSSE<=1); 8000 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 8001 ins_cost(200); 8002 format %{ "FCMOV$cop $dst,$src\t# double" %} 8003 opcode(0xDA); 8004 ins_encode( enc_cmov_d(cop,src) ); 8005 ins_pipe( pipe_cmovD_reg ); 8006%} 8007 8008// Conditional move 8009instruct fcmovF_regU(cmpOp_fcmov cop, eFlagsRegU cr, regFPR1 dst, regF src) %{ 8010 predicate(UseSSE==0); 8011 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 8012 ins_cost(200); 8013 format %{ "FCMOV$cop $dst,$src\t# float" %} 8014 opcode(0xDA); 8015 ins_encode( enc_cmov_d(cop,src) ); 8016 ins_pipe( pipe_cmovD_reg ); 8017%} 8018 8019// Float CMOV on Intel doesn't handle *signed* compares, only unsigned. 8020instruct fcmovD_regS(cmpOp cop, eFlagsReg cr, regD dst, regD src) %{ 8021 predicate(UseSSE<=1); 8022 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 8023 ins_cost(200); 8024 format %{ "Jn$cop skip\n\t" 8025 "MOV $dst,$src\t# double\n" 8026 "skip:" %} 8027 opcode (0xdd, 0x3); /* DD D8+i or DD /3 */ 8028 ins_encode( enc_cmov_branch( cop, 0x4 ), Push_Reg_D(src), OpcP, RegOpc(dst) ); 8029 ins_pipe( pipe_cmovD_reg ); 8030%} 8031 8032// Float CMOV on Intel doesn't handle *signed* compares, only unsigned. 8033instruct fcmovF_regS(cmpOp cop, eFlagsReg cr, regF dst, regF src) %{ 8034 predicate(UseSSE==0); 8035 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 8036 ins_cost(200); 8037 format %{ "Jn$cop skip\n\t" 8038 "MOV $dst,$src\t# float\n" 8039 "skip:" %} 8040 opcode (0xdd, 0x3); /* DD D8+i or DD /3 */ 8041 ins_encode( enc_cmov_branch( cop, 0x4 ), Push_Reg_F(src), OpcP, RegOpc(dst) ); 8042 ins_pipe( pipe_cmovD_reg ); 8043%} 8044 8045// No CMOVE with SSE/SSE2 8046instruct fcmovX_regS(cmpOp cop, eFlagsReg cr, regX dst, regX src) %{ 8047 predicate (UseSSE>=1); 8048 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 8049 ins_cost(200); 8050 format %{ "Jn$cop skip\n\t" 8051 "MOVSS $dst,$src\t# float\n" 8052 "skip:" %} 8053 ins_encode %{ 8054 Label skip; 8055 // Invert sense of branch from sense of CMOV 8056 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip); 8057 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 8058 __ bind(skip); 8059 %} 8060 ins_pipe( pipe_slow ); 8061%} 8062 8063// No CMOVE with SSE/SSE2 8064instruct fcmovXD_regS(cmpOp cop, eFlagsReg cr, regXD dst, regXD src) %{ 8065 predicate (UseSSE>=2); 8066 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 8067 ins_cost(200); 8068 format %{ "Jn$cop skip\n\t" 8069 "MOVSD $dst,$src\t# float\n" 8070 "skip:" %} 8071 ins_encode %{ 8072 Label skip; 8073 // Invert sense of branch from sense of CMOV 8074 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip); 8075 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 8076 __ bind(skip); 8077 %} 8078 ins_pipe( pipe_slow ); 8079%} 8080 8081// unsigned version 8082instruct fcmovX_regU(cmpOpU cop, eFlagsRegU cr, regX dst, regX src) %{ 8083 predicate (UseSSE>=1); 8084 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 8085 ins_cost(200); 8086 format %{ "Jn$cop skip\n\t" 8087 "MOVSS $dst,$src\t# float\n" 8088 "skip:" %} 8089 ins_encode %{ 8090 Label skip; 8091 // Invert sense of branch from sense of CMOV 8092 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip); 8093 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 8094 __ bind(skip); 8095 %} 8096 ins_pipe( pipe_slow ); 8097%} 8098 8099instruct fcmovX_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regX dst, regX src) %{ 8100 predicate (UseSSE>=1); 8101 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 8102 ins_cost(200); 8103 expand %{ 8104 fcmovX_regU(cop, cr, dst, src); 8105 %} 8106%} 8107 8108// unsigned version 8109instruct fcmovXD_regU(cmpOpU cop, eFlagsRegU cr, regXD dst, regXD src) %{ 8110 predicate (UseSSE>=2); 8111 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 8112 ins_cost(200); 8113 format %{ "Jn$cop skip\n\t" 8114 "MOVSD $dst,$src\t# float\n" 8115 "skip:" %} 8116 ins_encode %{ 8117 Label skip; 8118 // Invert sense of branch from sense of CMOV 8119 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip); 8120 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 8121 __ bind(skip); 8122 %} 8123 ins_pipe( pipe_slow ); 8124%} 8125 8126instruct fcmovXD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regXD dst, regXD src) %{ 8127 predicate (UseSSE>=2); 8128 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 8129 ins_cost(200); 8130 expand %{ 8131 fcmovXD_regU(cop, cr, dst, src); 8132 %} 8133%} 8134 8135instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{ 8136 predicate(VM_Version::supports_cmov() ); 8137 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 8138 ins_cost(200); 8139 format %{ "CMOV$cop $dst.lo,$src.lo\n\t" 8140 "CMOV$cop $dst.hi,$src.hi" %} 8141 opcode(0x0F,0x40); 8142 ins_encode( enc_cmov(cop), RegReg_Lo2( dst, src ), enc_cmov(cop), RegReg_Hi2( dst, src ) ); 8143 ins_pipe( pipe_cmov_reg_long ); 8144%} 8145 8146instruct cmovL_regU(cmpOpU cop, eFlagsRegU cr, eRegL dst, eRegL src) %{ 8147 predicate(VM_Version::supports_cmov() ); 8148 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 8149 ins_cost(200); 8150 format %{ "CMOV$cop $dst.lo,$src.lo\n\t" 8151 "CMOV$cop $dst.hi,$src.hi" %} 8152 opcode(0x0F,0x40); 8153 ins_encode( enc_cmov(cop), RegReg_Lo2( dst, src ), enc_cmov(cop), RegReg_Hi2( dst, src ) ); 8154 ins_pipe( pipe_cmov_reg_long ); 8155%} 8156 8157instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{ 8158 predicate(VM_Version::supports_cmov() ); 8159 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 8160 ins_cost(200); 8161 expand %{ 8162 cmovL_regU(cop, cr, dst, src); 8163 %} 8164%} 8165 8166//----------Arithmetic Instructions-------------------------------------------- 8167//----------Addition Instructions---------------------------------------------- 8168// Integer Addition Instructions 8169instruct addI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{ 8170 match(Set dst (AddI dst src)); 8171 effect(KILL cr); 8172 8173 size(2); 8174 format %{ "ADD $dst,$src" %} 8175 opcode(0x03); 8176 ins_encode( OpcP, RegReg( dst, src) ); 8177 ins_pipe( ialu_reg_reg ); 8178%} 8179 8180instruct addI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{ 8181 match(Set dst (AddI dst src)); 8182 effect(KILL cr); 8183 8184 format %{ "ADD $dst,$src" %} 8185 opcode(0x81, 0x00); /* /0 id */ 8186 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 8187 ins_pipe( ialu_reg ); 8188%} 8189 8190instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 8191 predicate(UseIncDec); 8192 match(Set dst (AddI dst src)); 8193 effect(KILL cr); 8194 8195 size(1); 8196 format %{ "INC $dst" %} 8197 opcode(0x40); /* */ 8198 ins_encode( Opc_plus( primary, dst ) ); 8199 ins_pipe( ialu_reg ); 8200%} 8201 8202instruct leaI_eReg_immI(eRegI dst, eRegI src0, immI src1) %{ 8203 match(Set dst (AddI src0 src1)); 8204 ins_cost(110); 8205 8206 format %{ "LEA $dst,[$src0 + $src1]" %} 8207 opcode(0x8D); /* 0x8D /r */ 8208 ins_encode( OpcP, RegLea( dst, src0, src1 ) ); 8209 ins_pipe( ialu_reg_reg ); 8210%} 8211 8212instruct leaP_eReg_immI(eRegP dst, eRegP src0, immI src1) %{ 8213 match(Set dst (AddP src0 src1)); 8214 ins_cost(110); 8215 8216 format %{ "LEA $dst,[$src0 + $src1]\t# ptr" %} 8217 opcode(0x8D); /* 0x8D /r */ 8218 ins_encode( OpcP, RegLea( dst, src0, src1 ) ); 8219 ins_pipe( ialu_reg_reg ); 8220%} 8221 8222instruct decI_eReg(eRegI dst, immI_M1 src, eFlagsReg cr) %{ 8223 predicate(UseIncDec); 8224 match(Set dst (AddI dst src)); 8225 effect(KILL cr); 8226 8227 size(1); 8228 format %{ "DEC $dst" %} 8229 opcode(0x48); /* */ 8230 ins_encode( Opc_plus( primary, dst ) ); 8231 ins_pipe( ialu_reg ); 8232%} 8233 8234instruct addP_eReg(eRegP dst, eRegI src, eFlagsReg cr) %{ 8235 match(Set dst (AddP dst src)); 8236 effect(KILL cr); 8237 8238 size(2); 8239 format %{ "ADD $dst,$src" %} 8240 opcode(0x03); 8241 ins_encode( OpcP, RegReg( dst, src) ); 8242 ins_pipe( ialu_reg_reg ); 8243%} 8244 8245instruct addP_eReg_imm(eRegP dst, immI src, eFlagsReg cr) %{ 8246 match(Set dst (AddP dst src)); 8247 effect(KILL cr); 8248 8249 format %{ "ADD $dst,$src" %} 8250 opcode(0x81,0x00); /* Opcode 81 /0 id */ 8251 // ins_encode( RegImm( dst, src) ); 8252 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 8253 ins_pipe( ialu_reg ); 8254%} 8255 8256instruct addI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{ 8257 match(Set dst (AddI dst (LoadI src))); 8258 effect(KILL cr); 8259 8260 ins_cost(125); 8261 format %{ "ADD $dst,$src" %} 8262 opcode(0x03); 8263 ins_encode( OpcP, RegMem( dst, src) ); 8264 ins_pipe( ialu_reg_mem ); 8265%} 8266 8267instruct addI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{ 8268 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 8269 effect(KILL cr); 8270 8271 ins_cost(150); 8272 format %{ "ADD $dst,$src" %} 8273 opcode(0x01); /* Opcode 01 /r */ 8274 ins_encode( OpcP, RegMem( src, dst ) ); 8275 ins_pipe( ialu_mem_reg ); 8276%} 8277 8278// Add Memory with Immediate 8279instruct addI_mem_imm(memory dst, immI src, eFlagsReg cr) %{ 8280 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 8281 effect(KILL cr); 8282 8283 ins_cost(125); 8284 format %{ "ADD $dst,$src" %} 8285 opcode(0x81); /* Opcode 81 /0 id */ 8286 ins_encode( OpcSE( src ), RMopc_Mem(0x00,dst), Con8or32( src ) ); 8287 ins_pipe( ialu_mem_imm ); 8288%} 8289 8290instruct incI_mem(memory dst, immI1 src, eFlagsReg cr) %{ 8291 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 8292 effect(KILL cr); 8293 8294 ins_cost(125); 8295 format %{ "INC $dst" %} 8296 opcode(0xFF); /* Opcode FF /0 */ 8297 ins_encode( OpcP, RMopc_Mem(0x00,dst)); 8298 ins_pipe( ialu_mem_imm ); 8299%} 8300 8301instruct decI_mem(memory dst, immI_M1 src, eFlagsReg cr) %{ 8302 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 8303 effect(KILL cr); 8304 8305 ins_cost(125); 8306 format %{ "DEC $dst" %} 8307 opcode(0xFF); /* Opcode FF /1 */ 8308 ins_encode( OpcP, RMopc_Mem(0x01,dst)); 8309 ins_pipe( ialu_mem_imm ); 8310%} 8311 8312 8313instruct checkCastPP( eRegP dst ) %{ 8314 match(Set dst (CheckCastPP dst)); 8315 8316 size(0); 8317 format %{ "#checkcastPP of $dst" %} 8318 ins_encode( /*empty encoding*/ ); 8319 ins_pipe( empty ); 8320%} 8321 8322instruct castPP( eRegP dst ) %{ 8323 match(Set dst (CastPP dst)); 8324 format %{ "#castPP of $dst" %} 8325 ins_encode( /*empty encoding*/ ); 8326 ins_pipe( empty ); 8327%} 8328 8329instruct castII( eRegI dst ) %{ 8330 match(Set dst (CastII dst)); 8331 format %{ "#castII of $dst" %} 8332 ins_encode( /*empty encoding*/ ); 8333 ins_cost(0); 8334 ins_pipe( empty ); 8335%} 8336 8337 8338// Load-locked - same as a regular pointer load when used with compare-swap 8339instruct loadPLocked(eRegP dst, memory mem) %{ 8340 match(Set dst (LoadPLocked mem)); 8341 8342 ins_cost(125); 8343 format %{ "MOV $dst,$mem\t# Load ptr. locked" %} 8344 opcode(0x8B); 8345 ins_encode( OpcP, RegMem(dst,mem)); 8346 ins_pipe( ialu_reg_mem ); 8347%} 8348 8349// LoadLong-locked - same as a volatile long load when used with compare-swap 8350instruct loadLLocked(stackSlotL dst, load_long_memory mem) %{ 8351 predicate(UseSSE<=1); 8352 match(Set dst (LoadLLocked mem)); 8353 8354 ins_cost(200); 8355 format %{ "FILD $mem\t# Atomic volatile long load\n\t" 8356 "FISTp $dst" %} 8357 ins_encode(enc_loadL_volatile(mem,dst)); 8358 ins_pipe( fpu_reg_mem ); 8359%} 8360 8361instruct loadLX_Locked(stackSlotL dst, load_long_memory mem, regXD tmp) %{ 8362 predicate(UseSSE>=2); 8363 match(Set dst (LoadLLocked mem)); 8364 effect(TEMP tmp); 8365 ins_cost(180); 8366 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t" 8367 "MOVSD $dst,$tmp" %} 8368 ins_encode(enc_loadLX_volatile(mem, dst, tmp)); 8369 ins_pipe( pipe_slow ); 8370%} 8371 8372instruct loadLX_reg_Locked(eRegL dst, load_long_memory mem, regXD tmp) %{ 8373 predicate(UseSSE>=2); 8374 match(Set dst (LoadLLocked mem)); 8375 effect(TEMP tmp); 8376 ins_cost(160); 8377 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t" 8378 "MOVD $dst.lo,$tmp\n\t" 8379 "PSRLQ $tmp,32\n\t" 8380 "MOVD $dst.hi,$tmp" %} 8381 ins_encode(enc_loadLX_reg_volatile(mem, dst, tmp)); 8382 ins_pipe( pipe_slow ); 8383%} 8384 8385// Conditional-store of the updated heap-top. 8386// Used during allocation of the shared heap. 8387// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 8388instruct storePConditional( memory heap_top_ptr, eAXRegP oldval, eRegP newval, eFlagsReg cr ) %{ 8389 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8390 // EAX is killed if there is contention, but then it's also unused. 8391 // In the common case of no contention, EAX holds the new oop address. 8392 format %{ "CMPXCHG $heap_top_ptr,$newval\t# If EAX==$heap_top_ptr Then store $newval into $heap_top_ptr" %} 8393 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval,heap_top_ptr) ); 8394 ins_pipe( pipe_cmpxchg ); 8395%} 8396 8397// Conditional-store of an int value. 8398// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel. 8399instruct storeIConditional( memory mem, eAXRegI oldval, eRegI newval, eFlagsReg cr ) %{ 8400 match(Set cr (StoreIConditional mem (Binary oldval newval))); 8401 effect(KILL oldval); 8402 format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %} 8403 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) ); 8404 ins_pipe( pipe_cmpxchg ); 8405%} 8406 8407// Conditional-store of a long value. 8408// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel. 8409instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ 8410 match(Set cr (StoreLConditional mem (Binary oldval newval))); 8411 effect(KILL oldval); 8412 format %{ "XCHG EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t" 8413 "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t" 8414 "XCHG EBX,ECX" 8415 %} 8416 ins_encode %{ 8417 // Note: we need to swap rbx, and rcx before and after the 8418 // cmpxchg8 instruction because the instruction uses 8419 // rcx as the high order word of the new value to store but 8420 // our register encoding uses rbx. 8421 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc)); 8422 if( os::is_MP() ) 8423 __ lock(); 8424 __ cmpxchg8($mem$$Address); 8425 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc)); 8426 %} 8427 ins_pipe( pipe_cmpxchg ); 8428%} 8429 8430// No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 8431 8432instruct compareAndSwapL( eRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ 8433 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 8434 effect(KILL cr, KILL oldval); 8435 format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 8436 "MOV $res,0\n\t" 8437 "JNE,s fail\n\t" 8438 "MOV $res,1\n" 8439 "fail:" %} 8440 ins_encode( enc_cmpxchg8(mem_ptr), 8441 enc_flags_ne_to_boolean(res) ); 8442 ins_pipe( pipe_cmpxchg ); 8443%} 8444 8445instruct compareAndSwapP( eRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{ 8446 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 8447 effect(KILL cr, KILL oldval); 8448 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 8449 "MOV $res,0\n\t" 8450 "JNE,s fail\n\t" 8451 "MOV $res,1\n" 8452 "fail:" %} 8453 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) ); 8454 ins_pipe( pipe_cmpxchg ); 8455%} 8456 8457instruct compareAndSwapI( eRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{ 8458 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 8459 effect(KILL cr, KILL oldval); 8460 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 8461 "MOV $res,0\n\t" 8462 "JNE,s fail\n\t" 8463 "MOV $res,1\n" 8464 "fail:" %} 8465 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) ); 8466 ins_pipe( pipe_cmpxchg ); 8467%} 8468 8469//----------Subtraction Instructions------------------------------------------- 8470// Integer Subtraction Instructions 8471instruct subI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{ 8472 match(Set dst (SubI dst src)); 8473 effect(KILL cr); 8474 8475 size(2); 8476 format %{ "SUB $dst,$src" %} 8477 opcode(0x2B); 8478 ins_encode( OpcP, RegReg( dst, src) ); 8479 ins_pipe( ialu_reg_reg ); 8480%} 8481 8482instruct subI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{ 8483 match(Set dst (SubI dst src)); 8484 effect(KILL cr); 8485 8486 format %{ "SUB $dst,$src" %} 8487 opcode(0x81,0x05); /* Opcode 81 /5 */ 8488 // ins_encode( RegImm( dst, src) ); 8489 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 8490 ins_pipe( ialu_reg ); 8491%} 8492 8493instruct subI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{ 8494 match(Set dst (SubI dst (LoadI src))); 8495 effect(KILL cr); 8496 8497 ins_cost(125); 8498 format %{ "SUB $dst,$src" %} 8499 opcode(0x2B); 8500 ins_encode( OpcP, RegMem( dst, src) ); 8501 ins_pipe( ialu_reg_mem ); 8502%} 8503 8504instruct subI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{ 8505 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 8506 effect(KILL cr); 8507 8508 ins_cost(150); 8509 format %{ "SUB $dst,$src" %} 8510 opcode(0x29); /* Opcode 29 /r */ 8511 ins_encode( OpcP, RegMem( src, dst ) ); 8512 ins_pipe( ialu_mem_reg ); 8513%} 8514 8515// Subtract from a pointer 8516instruct subP_eReg(eRegP dst, eRegI src, immI0 zero, eFlagsReg cr) %{ 8517 match(Set dst (AddP dst (SubI zero src))); 8518 effect(KILL cr); 8519 8520 size(2); 8521 format %{ "SUB $dst,$src" %} 8522 opcode(0x2B); 8523 ins_encode( OpcP, RegReg( dst, src) ); 8524 ins_pipe( ialu_reg_reg ); 8525%} 8526 8527instruct negI_eReg(eRegI dst, immI0 zero, eFlagsReg cr) %{ 8528 match(Set dst (SubI zero dst)); 8529 effect(KILL cr); 8530 8531 size(2); 8532 format %{ "NEG $dst" %} 8533 opcode(0xF7,0x03); // Opcode F7 /3 8534 ins_encode( OpcP, RegOpc( dst ) ); 8535 ins_pipe( ialu_reg ); 8536%} 8537 8538 8539//----------Multiplication/Division Instructions------------------------------- 8540// Integer Multiplication Instructions 8541// Multiply Register 8542instruct mulI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{ 8543 match(Set dst (MulI dst src)); 8544 effect(KILL cr); 8545 8546 size(3); 8547 ins_cost(300); 8548 format %{ "IMUL $dst,$src" %} 8549 opcode(0xAF, 0x0F); 8550 ins_encode( OpcS, OpcP, RegReg( dst, src) ); 8551 ins_pipe( ialu_reg_reg_alu0 ); 8552%} 8553 8554// Multiply 32-bit Immediate 8555instruct mulI_eReg_imm(eRegI dst, eRegI src, immI imm, eFlagsReg cr) %{ 8556 match(Set dst (MulI src imm)); 8557 effect(KILL cr); 8558 8559 ins_cost(300); 8560 format %{ "IMUL $dst,$src,$imm" %} 8561 opcode(0x69); /* 69 /r id */ 8562 ins_encode( OpcSE(imm), RegReg( dst, src ), Con8or32( imm ) ); 8563 ins_pipe( ialu_reg_reg_alu0 ); 8564%} 8565 8566instruct loadConL_low_only(eADXRegL_low_only dst, immL32 src, eFlagsReg cr) %{ 8567 match(Set dst src); 8568 effect(KILL cr); 8569 8570 // Note that this is artificially increased to make it more expensive than loadConL 8571 ins_cost(250); 8572 format %{ "MOV EAX,$src\t// low word only" %} 8573 opcode(0xB8); 8574 ins_encode( LdImmL_Lo(dst, src) ); 8575 ins_pipe( ialu_reg_fat ); 8576%} 8577 8578// Multiply by 32-bit Immediate, taking the shifted high order results 8579// (special case for shift by 32) 8580instruct mulI_imm_high(eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32 cnt, eFlagsReg cr) %{ 8581 match(Set dst (ConvL2I (RShiftL (MulL (ConvI2L src1) src2) cnt))); 8582 predicate( _kids[0]->_kids[0]->_kids[1]->_leaf->Opcode() == Op_ConL && 8583 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() >= min_jint && 8584 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() <= max_jint ); 8585 effect(USE src1, KILL cr); 8586 8587 // Note that this is adjusted by 150 to compensate for the overcosting of loadConL_low_only 8588 ins_cost(0*100 + 1*400 - 150); 8589 format %{ "IMUL EDX:EAX,$src1" %} 8590 ins_encode( multiply_con_and_shift_high( dst, src1, src2, cnt, cr ) ); 8591 ins_pipe( pipe_slow ); 8592%} 8593 8594// Multiply by 32-bit Immediate, taking the shifted high order results 8595instruct mulI_imm_RShift_high(eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32_63 cnt, eFlagsReg cr) %{ 8596 match(Set dst (ConvL2I (RShiftL (MulL (ConvI2L src1) src2) cnt))); 8597 predicate( _kids[0]->_kids[0]->_kids[1]->_leaf->Opcode() == Op_ConL && 8598 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() >= min_jint && 8599 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() <= max_jint ); 8600 effect(USE src1, KILL cr); 8601 8602 // Note that this is adjusted by 150 to compensate for the overcosting of loadConL_low_only 8603 ins_cost(1*100 + 1*400 - 150); 8604 format %{ "IMUL EDX:EAX,$src1\n\t" 8605 "SAR EDX,$cnt-32" %} 8606 ins_encode( multiply_con_and_shift_high( dst, src1, src2, cnt, cr ) ); 8607 ins_pipe( pipe_slow ); 8608%} 8609 8610// Multiply Memory 32-bit Immediate 8611instruct mulI_mem_imm(eRegI dst, memory src, immI imm, eFlagsReg cr) %{ 8612 match(Set dst (MulI (LoadI src) imm)); 8613 effect(KILL cr); 8614 8615 ins_cost(300); 8616 format %{ "IMUL $dst,$src,$imm" %} 8617 opcode(0x69); /* 69 /r id */ 8618 ins_encode( OpcSE(imm), RegMem( dst, src ), Con8or32( imm ) ); 8619 ins_pipe( ialu_reg_mem_alu0 ); 8620%} 8621 8622// Multiply Memory 8623instruct mulI(eRegI dst, memory src, eFlagsReg cr) %{ 8624 match(Set dst (MulI dst (LoadI src))); 8625 effect(KILL cr); 8626 8627 ins_cost(350); 8628 format %{ "IMUL $dst,$src" %} 8629 opcode(0xAF, 0x0F); 8630 ins_encode( OpcS, OpcP, RegMem( dst, src) ); 8631 ins_pipe( ialu_reg_mem_alu0 ); 8632%} 8633 8634// Multiply Register Int to Long 8635instruct mulI2L(eADXRegL dst, eAXRegI src, nadxRegI src1, eFlagsReg flags) %{ 8636 // Basic Idea: long = (long)int * (long)int 8637 match(Set dst (MulL (ConvI2L src) (ConvI2L src1))); 8638 effect(DEF dst, USE src, USE src1, KILL flags); 8639 8640 ins_cost(300); 8641 format %{ "IMUL $dst,$src1" %} 8642 8643 ins_encode( long_int_multiply( dst, src1 ) ); 8644 ins_pipe( ialu_reg_reg_alu0 ); 8645%} 8646 8647instruct mulIS_eReg(eADXRegL dst, immL_32bits mask, eFlagsReg flags, eAXRegI src, nadxRegI src1) %{ 8648 // Basic Idea: long = (int & 0xffffffffL) * (int & 0xffffffffL) 8649 match(Set dst (MulL (AndL (ConvI2L src) mask) (AndL (ConvI2L src1) mask))); 8650 effect(KILL flags); 8651 8652 ins_cost(300); 8653 format %{ "MUL $dst,$src1" %} 8654 8655 ins_encode( long_uint_multiply(dst, src1) ); 8656 ins_pipe( ialu_reg_reg_alu0 ); 8657%} 8658 8659// Multiply Register Long 8660instruct mulL_eReg(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ 8661 match(Set dst (MulL dst src)); 8662 effect(KILL cr, TEMP tmp); 8663 ins_cost(4*100+3*400); 8664// Basic idea: lo(result) = lo(x_lo * y_lo) 8665// hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi) 8666 format %{ "MOV $tmp,$src.lo\n\t" 8667 "IMUL $tmp,EDX\n\t" 8668 "MOV EDX,$src.hi\n\t" 8669 "IMUL EDX,EAX\n\t" 8670 "ADD $tmp,EDX\n\t" 8671 "MUL EDX:EAX,$src.lo\n\t" 8672 "ADD EDX,$tmp" %} 8673 ins_encode( long_multiply( dst, src, tmp ) ); 8674 ins_pipe( pipe_slow ); 8675%} 8676 8677// Multiply Register Long where the left operand's high 32 bits are zero 8678instruct mulL_eReg_lhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ 8679 predicate(is_operand_hi32_zero(n->in(1))); 8680 match(Set dst (MulL dst src)); 8681 effect(KILL cr, TEMP tmp); 8682 ins_cost(2*100+2*400); 8683// Basic idea: lo(result) = lo(x_lo * y_lo) 8684// hi(result) = hi(x_lo * y_lo) + lo(x_lo * y_hi) where lo(x_hi * y_lo) = 0 because x_hi = 0 8685 format %{ "MOV $tmp,$src.hi\n\t" 8686 "IMUL $tmp,EAX\n\t" 8687 "MUL EDX:EAX,$src.lo\n\t" 8688 "ADD EDX,$tmp" %} 8689 ins_encode %{ 8690 __ movl($tmp$$Register, HIGH_FROM_LOW($src$$Register)); 8691 __ imull($tmp$$Register, rax); 8692 __ mull($src$$Register); 8693 __ addl(rdx, $tmp$$Register); 8694 %} 8695 ins_pipe( pipe_slow ); 8696%} 8697 8698// Multiply Register Long where the right operand's high 32 bits are zero 8699instruct mulL_eReg_rhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{ 8700 predicate(is_operand_hi32_zero(n->in(2))); 8701 match(Set dst (MulL dst src)); 8702 effect(KILL cr, TEMP tmp); 8703 ins_cost(2*100+2*400); 8704// Basic idea: lo(result) = lo(x_lo * y_lo) 8705// hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) where lo(x_lo * y_hi) = 0 because y_hi = 0 8706 format %{ "MOV $tmp,$src.lo\n\t" 8707 "IMUL $tmp,EDX\n\t" 8708 "MUL EDX:EAX,$src.lo\n\t" 8709 "ADD EDX,$tmp" %} 8710 ins_encode %{ 8711 __ movl($tmp$$Register, $src$$Register); 8712 __ imull($tmp$$Register, rdx); 8713 __ mull($src$$Register); 8714 __ addl(rdx, $tmp$$Register); 8715 %} 8716 ins_pipe( pipe_slow ); 8717%} 8718 8719// Multiply Register Long where the left and the right operands' high 32 bits are zero 8720instruct mulL_eReg_hi0(eADXRegL dst, eRegL src, eFlagsReg cr) %{ 8721 predicate(is_operand_hi32_zero(n->in(1)) && is_operand_hi32_zero(n->in(2))); 8722 match(Set dst (MulL dst src)); 8723 effect(KILL cr); 8724 ins_cost(1*400); 8725// Basic idea: lo(result) = lo(x_lo * y_lo) 8726// 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 8727 format %{ "MUL EDX:EAX,$src.lo\n\t" %} 8728 ins_encode %{ 8729 __ mull($src$$Register); 8730 %} 8731 ins_pipe( pipe_slow ); 8732%} 8733 8734// Multiply Register Long by small constant 8735instruct mulL_eReg_con(eADXRegL dst, immL_127 src, eRegI tmp, eFlagsReg cr) %{ 8736 match(Set dst (MulL dst src)); 8737 effect(KILL cr, TEMP tmp); 8738 ins_cost(2*100+2*400); 8739 size(12); 8740// Basic idea: lo(result) = lo(src * EAX) 8741// hi(result) = hi(src * EAX) + lo(src * EDX) 8742 format %{ "IMUL $tmp,EDX,$src\n\t" 8743 "MOV EDX,$src\n\t" 8744 "MUL EDX\t# EDX*EAX -> EDX:EAX\n\t" 8745 "ADD EDX,$tmp" %} 8746 ins_encode( long_multiply_con( dst, src, tmp ) ); 8747 ins_pipe( pipe_slow ); 8748%} 8749 8750// Integer DIV with Register 8751instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{ 8752 match(Set rax (DivI rax div)); 8753 effect(KILL rdx, KILL cr); 8754 size(26); 8755 ins_cost(30*100+10*100); 8756 format %{ "CMP EAX,0x80000000\n\t" 8757 "JNE,s normal\n\t" 8758 "XOR EDX,EDX\n\t" 8759 "CMP ECX,-1\n\t" 8760 "JE,s done\n" 8761 "normal: CDQ\n\t" 8762 "IDIV $div\n\t" 8763 "done:" %} 8764 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8765 ins_encode( cdq_enc, OpcP, RegOpc(div) ); 8766 ins_pipe( ialu_reg_reg_alu0 ); 8767%} 8768 8769// Divide Register Long 8770instruct divL_eReg( eADXRegL dst, eRegL src1, eRegL src2, eFlagsReg cr, eCXRegI cx, eBXRegI bx ) %{ 8771 match(Set dst (DivL src1 src2)); 8772 effect( KILL cr, KILL cx, KILL bx ); 8773 ins_cost(10000); 8774 format %{ "PUSH $src1.hi\n\t" 8775 "PUSH $src1.lo\n\t" 8776 "PUSH $src2.hi\n\t" 8777 "PUSH $src2.lo\n\t" 8778 "CALL SharedRuntime::ldiv\n\t" 8779 "ADD ESP,16" %} 8780 ins_encode( long_div(src1,src2) ); 8781 ins_pipe( pipe_slow ); 8782%} 8783 8784// Integer DIVMOD with Register, both quotient and mod results 8785instruct divModI_eReg_divmod(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{ 8786 match(DivModI rax div); 8787 effect(KILL cr); 8788 size(26); 8789 ins_cost(30*100+10*100); 8790 format %{ "CMP EAX,0x80000000\n\t" 8791 "JNE,s normal\n\t" 8792 "XOR EDX,EDX\n\t" 8793 "CMP ECX,-1\n\t" 8794 "JE,s done\n" 8795 "normal: CDQ\n\t" 8796 "IDIV $div\n\t" 8797 "done:" %} 8798 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8799 ins_encode( cdq_enc, OpcP, RegOpc(div) ); 8800 ins_pipe( pipe_slow ); 8801%} 8802 8803// Integer MOD with Register 8804instruct modI_eReg(eDXRegI rdx, eAXRegI rax, eCXRegI div, eFlagsReg cr) %{ 8805 match(Set rdx (ModI rax div)); 8806 effect(KILL rax, KILL cr); 8807 8808 size(26); 8809 ins_cost(300); 8810 format %{ "CDQ\n\t" 8811 "IDIV $div" %} 8812 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8813 ins_encode( cdq_enc, OpcP, RegOpc(div) ); 8814 ins_pipe( ialu_reg_reg_alu0 ); 8815%} 8816 8817// Remainder Register Long 8818instruct modL_eReg( eADXRegL dst, eRegL src1, eRegL src2, eFlagsReg cr, eCXRegI cx, eBXRegI bx ) %{ 8819 match(Set dst (ModL src1 src2)); 8820 effect( KILL cr, KILL cx, KILL bx ); 8821 ins_cost(10000); 8822 format %{ "PUSH $src1.hi\n\t" 8823 "PUSH $src1.lo\n\t" 8824 "PUSH $src2.hi\n\t" 8825 "PUSH $src2.lo\n\t" 8826 "CALL SharedRuntime::lrem\n\t" 8827 "ADD ESP,16" %} 8828 ins_encode( long_mod(src1,src2) ); 8829 ins_pipe( pipe_slow ); 8830%} 8831 8832// Divide Register Long (no special case since divisor != -1) 8833instruct divL_eReg_imm32( eADXRegL dst, immL32 imm, eRegI tmp, eRegI tmp2, eFlagsReg cr ) %{ 8834 match(Set dst (DivL dst imm)); 8835 effect( TEMP tmp, TEMP tmp2, KILL cr ); 8836 ins_cost(1000); 8837 format %{ "MOV $tmp,abs($imm) # ldiv EDX:EAX,$imm\n\t" 8838 "XOR $tmp2,$tmp2\n\t" 8839 "CMP $tmp,EDX\n\t" 8840 "JA,s fast\n\t" 8841 "MOV $tmp2,EAX\n\t" 8842 "MOV EAX,EDX\n\t" 8843 "MOV EDX,0\n\t" 8844 "JLE,s pos\n\t" 8845 "LNEG EAX : $tmp2\n\t" 8846 "DIV $tmp # unsigned division\n\t" 8847 "XCHG EAX,$tmp2\n\t" 8848 "DIV $tmp\n\t" 8849 "LNEG $tmp2 : EAX\n\t" 8850 "JMP,s done\n" 8851 "pos:\n\t" 8852 "DIV $tmp\n\t" 8853 "XCHG EAX,$tmp2\n" 8854 "fast:\n\t" 8855 "DIV $tmp\n" 8856 "done:\n\t" 8857 "MOV EDX,$tmp2\n\t" 8858 "NEG EDX:EAX # if $imm < 0" %} 8859 ins_encode %{ 8860 int con = (int)$imm$$constant; 8861 assert(con != 0 && con != -1 && con != min_jint, "wrong divisor"); 8862 int pcon = (con > 0) ? con : -con; 8863 Label Lfast, Lpos, Ldone; 8864 8865 __ movl($tmp$$Register, pcon); 8866 __ xorl($tmp2$$Register,$tmp2$$Register); 8867 __ cmpl($tmp$$Register, HIGH_FROM_LOW($dst$$Register)); 8868 __ jccb(Assembler::above, Lfast); // result fits into 32 bit 8869 8870 __ movl($tmp2$$Register, $dst$$Register); // save 8871 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register)); 8872 __ movl(HIGH_FROM_LOW($dst$$Register),0); // preserve flags 8873 __ jccb(Assembler::lessEqual, Lpos); // result is positive 8874 8875 // Negative dividend. 8876 // convert value to positive to use unsigned division 8877 __ lneg($dst$$Register, $tmp2$$Register); 8878 __ divl($tmp$$Register); 8879 __ xchgl($dst$$Register, $tmp2$$Register); 8880 __ divl($tmp$$Register); 8881 // revert result back to negative 8882 __ lneg($tmp2$$Register, $dst$$Register); 8883 __ jmpb(Ldone); 8884 8885 __ bind(Lpos); 8886 __ divl($tmp$$Register); // Use unsigned division 8887 __ xchgl($dst$$Register, $tmp2$$Register); 8888 // Fallthrow for final divide, tmp2 has 32 bit hi result 8889 8890 __ bind(Lfast); 8891 // fast path: src is positive 8892 __ divl($tmp$$Register); // Use unsigned division 8893 8894 __ bind(Ldone); 8895 __ movl(HIGH_FROM_LOW($dst$$Register),$tmp2$$Register); 8896 if (con < 0) { 8897 __ lneg(HIGH_FROM_LOW($dst$$Register), $dst$$Register); 8898 } 8899 %} 8900 ins_pipe( pipe_slow ); 8901%} 8902 8903// Remainder Register Long (remainder fit into 32 bits) 8904instruct modL_eReg_imm32( eADXRegL dst, immL32 imm, eRegI tmp, eRegI tmp2, eFlagsReg cr ) %{ 8905 match(Set dst (ModL dst imm)); 8906 effect( TEMP tmp, TEMP tmp2, KILL cr ); 8907 ins_cost(1000); 8908 format %{ "MOV $tmp,abs($imm) # lrem EDX:EAX,$imm\n\t" 8909 "CMP $tmp,EDX\n\t" 8910 "JA,s fast\n\t" 8911 "MOV $tmp2,EAX\n\t" 8912 "MOV EAX,EDX\n\t" 8913 "MOV EDX,0\n\t" 8914 "JLE,s pos\n\t" 8915 "LNEG EAX : $tmp2\n\t" 8916 "DIV $tmp # unsigned division\n\t" 8917 "MOV EAX,$tmp2\n\t" 8918 "DIV $tmp\n\t" 8919 "NEG EDX\n\t" 8920 "JMP,s done\n" 8921 "pos:\n\t" 8922 "DIV $tmp\n\t" 8923 "MOV EAX,$tmp2\n" 8924 "fast:\n\t" 8925 "DIV $tmp\n" 8926 "done:\n\t" 8927 "MOV EAX,EDX\n\t" 8928 "SAR EDX,31\n\t" %} 8929 ins_encode %{ 8930 int con = (int)$imm$$constant; 8931 assert(con != 0 && con != -1 && con != min_jint, "wrong divisor"); 8932 int pcon = (con > 0) ? con : -con; 8933 Label Lfast, Lpos, Ldone; 8934 8935 __ movl($tmp$$Register, pcon); 8936 __ cmpl($tmp$$Register, HIGH_FROM_LOW($dst$$Register)); 8937 __ jccb(Assembler::above, Lfast); // src is positive and result fits into 32 bit 8938 8939 __ movl($tmp2$$Register, $dst$$Register); // save 8940 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register)); 8941 __ movl(HIGH_FROM_LOW($dst$$Register),0); // preserve flags 8942 __ jccb(Assembler::lessEqual, Lpos); // result is positive 8943 8944 // Negative dividend. 8945 // convert value to positive to use unsigned division 8946 __ lneg($dst$$Register, $tmp2$$Register); 8947 __ divl($tmp$$Register); 8948 __ movl($dst$$Register, $tmp2$$Register); 8949 __ divl($tmp$$Register); 8950 // revert remainder back to negative 8951 __ negl(HIGH_FROM_LOW($dst$$Register)); 8952 __ jmpb(Ldone); 8953 8954 __ bind(Lpos); 8955 __ divl($tmp$$Register); 8956 __ movl($dst$$Register, $tmp2$$Register); 8957 8958 __ bind(Lfast); 8959 // fast path: src is positive 8960 __ divl($tmp$$Register); 8961 8962 __ bind(Ldone); 8963 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register)); 8964 __ sarl(HIGH_FROM_LOW($dst$$Register), 31); // result sign 8965 8966 %} 8967 ins_pipe( pipe_slow ); 8968%} 8969 8970// Integer Shift Instructions 8971// Shift Left by one 8972instruct shlI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{ 8973 match(Set dst (LShiftI dst shift)); 8974 effect(KILL cr); 8975 8976 size(2); 8977 format %{ "SHL $dst,$shift" %} 8978 opcode(0xD1, 0x4); /* D1 /4 */ 8979 ins_encode( OpcP, RegOpc( dst ) ); 8980 ins_pipe( ialu_reg ); 8981%} 8982 8983// Shift Left by 8-bit immediate 8984instruct salI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{ 8985 match(Set dst (LShiftI dst shift)); 8986 effect(KILL cr); 8987 8988 size(3); 8989 format %{ "SHL $dst,$shift" %} 8990 opcode(0xC1, 0x4); /* C1 /4 ib */ 8991 ins_encode( RegOpcImm( dst, shift) ); 8992 ins_pipe( ialu_reg ); 8993%} 8994 8995// Shift Left by variable 8996instruct salI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{ 8997 match(Set dst (LShiftI dst shift)); 8998 effect(KILL cr); 8999 9000 size(2); 9001 format %{ "SHL $dst,$shift" %} 9002 opcode(0xD3, 0x4); /* D3 /4 */ 9003 ins_encode( OpcP, RegOpc( dst ) ); 9004 ins_pipe( ialu_reg_reg ); 9005%} 9006 9007// Arithmetic shift right by one 9008instruct sarI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{ 9009 match(Set dst (RShiftI dst shift)); 9010 effect(KILL cr); 9011 9012 size(2); 9013 format %{ "SAR $dst,$shift" %} 9014 opcode(0xD1, 0x7); /* D1 /7 */ 9015 ins_encode( OpcP, RegOpc( dst ) ); 9016 ins_pipe( ialu_reg ); 9017%} 9018 9019// Arithmetic shift right by one 9020instruct sarI_mem_1(memory dst, immI1 shift, eFlagsReg cr) %{ 9021 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9022 effect(KILL cr); 9023 format %{ "SAR $dst,$shift" %} 9024 opcode(0xD1, 0x7); /* D1 /7 */ 9025 ins_encode( OpcP, RMopc_Mem(secondary,dst) ); 9026 ins_pipe( ialu_mem_imm ); 9027%} 9028 9029// Arithmetic Shift Right by 8-bit immediate 9030instruct sarI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{ 9031 match(Set dst (RShiftI dst shift)); 9032 effect(KILL cr); 9033 9034 size(3); 9035 format %{ "SAR $dst,$shift" %} 9036 opcode(0xC1, 0x7); /* C1 /7 ib */ 9037 ins_encode( RegOpcImm( dst, shift ) ); 9038 ins_pipe( ialu_mem_imm ); 9039%} 9040 9041// Arithmetic Shift Right by 8-bit immediate 9042instruct sarI_mem_imm(memory dst, immI8 shift, eFlagsReg cr) %{ 9043 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 9044 effect(KILL cr); 9045 9046 format %{ "SAR $dst,$shift" %} 9047 opcode(0xC1, 0x7); /* C1 /7 ib */ 9048 ins_encode( OpcP, RMopc_Mem(secondary, dst ), Con8or32( shift ) ); 9049 ins_pipe( ialu_mem_imm ); 9050%} 9051 9052// Arithmetic Shift Right by variable 9053instruct sarI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{ 9054 match(Set dst (RShiftI dst shift)); 9055 effect(KILL cr); 9056 9057 size(2); 9058 format %{ "SAR $dst,$shift" %} 9059 opcode(0xD3, 0x7); /* D3 /7 */ 9060 ins_encode( OpcP, RegOpc( dst ) ); 9061 ins_pipe( ialu_reg_reg ); 9062%} 9063 9064// Logical shift right by one 9065instruct shrI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{ 9066 match(Set dst (URShiftI dst shift)); 9067 effect(KILL cr); 9068 9069 size(2); 9070 format %{ "SHR $dst,$shift" %} 9071 opcode(0xD1, 0x5); /* D1 /5 */ 9072 ins_encode( OpcP, RegOpc( dst ) ); 9073 ins_pipe( ialu_reg ); 9074%} 9075 9076// Logical Shift Right by 8-bit immediate 9077instruct shrI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{ 9078 match(Set dst (URShiftI dst shift)); 9079 effect(KILL cr); 9080 9081 size(3); 9082 format %{ "SHR $dst,$shift" %} 9083 opcode(0xC1, 0x5); /* C1 /5 ib */ 9084 ins_encode( RegOpcImm( dst, shift) ); 9085 ins_pipe( ialu_reg ); 9086%} 9087 9088 9089// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 9090// This idiom is used by the compiler for the i2b bytecode. 9091instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour) %{ 9092 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 9093 9094 size(3); 9095 format %{ "MOVSX $dst,$src :8" %} 9096 ins_encode %{ 9097 __ movsbl($dst$$Register, $src$$Register); 9098 %} 9099 ins_pipe(ialu_reg_reg); 9100%} 9101 9102// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 9103// This idiom is used by the compiler the i2s bytecode. 9104instruct i2s(eRegI dst, xRegI src, immI_16 sixteen) %{ 9105 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 9106 9107 size(3); 9108 format %{ "MOVSX $dst,$src :16" %} 9109 ins_encode %{ 9110 __ movswl($dst$$Register, $src$$Register); 9111 %} 9112 ins_pipe(ialu_reg_reg); 9113%} 9114 9115 9116// Logical Shift Right by variable 9117instruct shrI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{ 9118 match(Set dst (URShiftI dst shift)); 9119 effect(KILL cr); 9120 9121 size(2); 9122 format %{ "SHR $dst,$shift" %} 9123 opcode(0xD3, 0x5); /* D3 /5 */ 9124 ins_encode( OpcP, RegOpc( dst ) ); 9125 ins_pipe( ialu_reg_reg ); 9126%} 9127 9128 9129//----------Logical Instructions----------------------------------------------- 9130//----------Integer Logical Instructions--------------------------------------- 9131// And Instructions 9132// And Register with Register 9133instruct andI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{ 9134 match(Set dst (AndI dst src)); 9135 effect(KILL cr); 9136 9137 size(2); 9138 format %{ "AND $dst,$src" %} 9139 opcode(0x23); 9140 ins_encode( OpcP, RegReg( dst, src) ); 9141 ins_pipe( ialu_reg_reg ); 9142%} 9143 9144// And Register with Immediate 9145instruct andI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{ 9146 match(Set dst (AndI dst src)); 9147 effect(KILL cr); 9148 9149 format %{ "AND $dst,$src" %} 9150 opcode(0x81,0x04); /* Opcode 81 /4 */ 9151 // ins_encode( RegImm( dst, src) ); 9152 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 9153 ins_pipe( ialu_reg ); 9154%} 9155 9156// And Register with Memory 9157instruct andI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{ 9158 match(Set dst (AndI dst (LoadI src))); 9159 effect(KILL cr); 9160 9161 ins_cost(125); 9162 format %{ "AND $dst,$src" %} 9163 opcode(0x23); 9164 ins_encode( OpcP, RegMem( dst, src) ); 9165 ins_pipe( ialu_reg_mem ); 9166%} 9167 9168// And Memory with Register 9169instruct andI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{ 9170 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9171 effect(KILL cr); 9172 9173 ins_cost(150); 9174 format %{ "AND $dst,$src" %} 9175 opcode(0x21); /* Opcode 21 /r */ 9176 ins_encode( OpcP, RegMem( src, dst ) ); 9177 ins_pipe( ialu_mem_reg ); 9178%} 9179 9180// And Memory with Immediate 9181instruct andI_mem_imm(memory dst, immI src, eFlagsReg cr) %{ 9182 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9183 effect(KILL cr); 9184 9185 ins_cost(125); 9186 format %{ "AND $dst,$src" %} 9187 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9188 // ins_encode( MemImm( dst, src) ); 9189 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) ); 9190 ins_pipe( ialu_mem_imm ); 9191%} 9192 9193// Or Instructions 9194// Or Register with Register 9195instruct orI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{ 9196 match(Set dst (OrI dst src)); 9197 effect(KILL cr); 9198 9199 size(2); 9200 format %{ "OR $dst,$src" %} 9201 opcode(0x0B); 9202 ins_encode( OpcP, RegReg( dst, src) ); 9203 ins_pipe( ialu_reg_reg ); 9204%} 9205 9206instruct orI_eReg_castP2X(eRegI dst, eRegP src, eFlagsReg cr) %{ 9207 match(Set dst (OrI dst (CastP2X src))); 9208 effect(KILL cr); 9209 9210 size(2); 9211 format %{ "OR $dst,$src" %} 9212 opcode(0x0B); 9213 ins_encode( OpcP, RegReg( dst, src) ); 9214 ins_pipe( ialu_reg_reg ); 9215%} 9216 9217 9218// Or Register with Immediate 9219instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{ 9220 match(Set dst (OrI dst src)); 9221 effect(KILL cr); 9222 9223 format %{ "OR $dst,$src" %} 9224 opcode(0x81,0x01); /* Opcode 81 /1 id */ 9225 // ins_encode( RegImm( dst, src) ); 9226 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 9227 ins_pipe( ialu_reg ); 9228%} 9229 9230// Or Register with Memory 9231instruct orI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{ 9232 match(Set dst (OrI dst (LoadI src))); 9233 effect(KILL cr); 9234 9235 ins_cost(125); 9236 format %{ "OR $dst,$src" %} 9237 opcode(0x0B); 9238 ins_encode( OpcP, RegMem( dst, src) ); 9239 ins_pipe( ialu_reg_mem ); 9240%} 9241 9242// Or Memory with Register 9243instruct orI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{ 9244 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9245 effect(KILL cr); 9246 9247 ins_cost(150); 9248 format %{ "OR $dst,$src" %} 9249 opcode(0x09); /* Opcode 09 /r */ 9250 ins_encode( OpcP, RegMem( src, dst ) ); 9251 ins_pipe( ialu_mem_reg ); 9252%} 9253 9254// Or Memory with Immediate 9255instruct orI_mem_imm(memory dst, immI src, eFlagsReg cr) %{ 9256 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9257 effect(KILL cr); 9258 9259 ins_cost(125); 9260 format %{ "OR $dst,$src" %} 9261 opcode(0x81,0x1); /* Opcode 81 /1 id */ 9262 // ins_encode( MemImm( dst, src) ); 9263 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) ); 9264 ins_pipe( ialu_mem_imm ); 9265%} 9266 9267// ROL/ROR 9268// ROL expand 9269instruct rolI_eReg_imm1(eRegI dst, immI1 shift, eFlagsReg cr) %{ 9270 effect(USE_DEF dst, USE shift, KILL cr); 9271 9272 format %{ "ROL $dst, $shift" %} 9273 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 9274 ins_encode( OpcP, RegOpc( dst )); 9275 ins_pipe( ialu_reg ); 9276%} 9277 9278instruct rolI_eReg_imm8(eRegI dst, immI8 shift, eFlagsReg cr) %{ 9279 effect(USE_DEF dst, USE shift, KILL cr); 9280 9281 format %{ "ROL $dst, $shift" %} 9282 opcode(0xC1, 0x0); /*Opcode /C1 /0 */ 9283 ins_encode( RegOpcImm(dst, shift) ); 9284 ins_pipe(ialu_reg); 9285%} 9286 9287instruct rolI_eReg_CL(ncxRegI dst, eCXRegI shift, eFlagsReg cr) %{ 9288 effect(USE_DEF dst, USE shift, KILL cr); 9289 9290 format %{ "ROL $dst, $shift" %} 9291 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 9292 ins_encode(OpcP, RegOpc(dst)); 9293 ins_pipe( ialu_reg_reg ); 9294%} 9295// end of ROL expand 9296 9297// ROL 32bit by one once 9298instruct rolI_eReg_i1(eRegI dst, immI1 lshift, immI_M1 rshift, eFlagsReg cr) %{ 9299 match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9300 9301 expand %{ 9302 rolI_eReg_imm1(dst, lshift, cr); 9303 %} 9304%} 9305 9306// ROL 32bit var by imm8 once 9307instruct rolI_eReg_i8(eRegI dst, immI8 lshift, immI8 rshift, eFlagsReg cr) %{ 9308 predicate( 0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9309 match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift))); 9310 9311 expand %{ 9312 rolI_eReg_imm8(dst, lshift, cr); 9313 %} 9314%} 9315 9316// ROL 32bit var by var once 9317instruct rolI_eReg_Var_C0(ncxRegI dst, eCXRegI shift, immI0 zero, eFlagsReg cr) %{ 9318 match(Set dst ( OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 9319 9320 expand %{ 9321 rolI_eReg_CL(dst, shift, cr); 9322 %} 9323%} 9324 9325// ROL 32bit var by var once 9326instruct rolI_eReg_Var_C32(ncxRegI dst, eCXRegI shift, immI_32 c32, eFlagsReg cr) %{ 9327 match(Set dst ( OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 9328 9329 expand %{ 9330 rolI_eReg_CL(dst, shift, cr); 9331 %} 9332%} 9333 9334// ROR expand 9335instruct rorI_eReg_imm1(eRegI dst, immI1 shift, eFlagsReg cr) %{ 9336 effect(USE_DEF dst, USE shift, KILL cr); 9337 9338 format %{ "ROR $dst, $shift" %} 9339 opcode(0xD1,0x1); /* Opcode D1 /1 */ 9340 ins_encode( OpcP, RegOpc( dst ) ); 9341 ins_pipe( ialu_reg ); 9342%} 9343 9344instruct rorI_eReg_imm8(eRegI dst, immI8 shift, eFlagsReg cr) %{ 9345 effect (USE_DEF dst, USE shift, KILL cr); 9346 9347 format %{ "ROR $dst, $shift" %} 9348 opcode(0xC1, 0x1); /* Opcode /C1 /1 ib */ 9349 ins_encode( RegOpcImm(dst, shift) ); 9350 ins_pipe( ialu_reg ); 9351%} 9352 9353instruct rorI_eReg_CL(ncxRegI dst, eCXRegI shift, eFlagsReg cr)%{ 9354 effect(USE_DEF dst, USE shift, KILL cr); 9355 9356 format %{ "ROR $dst, $shift" %} 9357 opcode(0xD3, 0x1); /* Opcode D3 /1 */ 9358 ins_encode(OpcP, RegOpc(dst)); 9359 ins_pipe( ialu_reg_reg ); 9360%} 9361// end of ROR expand 9362 9363// ROR right once 9364instruct rorI_eReg_i1(eRegI dst, immI1 rshift, immI_M1 lshift, eFlagsReg cr) %{ 9365 match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9366 9367 expand %{ 9368 rorI_eReg_imm1(dst, rshift, cr); 9369 %} 9370%} 9371 9372// ROR 32bit by immI8 once 9373instruct rorI_eReg_i8(eRegI dst, immI8 rshift, immI8 lshift, eFlagsReg cr) %{ 9374 predicate( 0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 9375 match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift))); 9376 9377 expand %{ 9378 rorI_eReg_imm8(dst, rshift, cr); 9379 %} 9380%} 9381 9382// ROR 32bit var by var once 9383instruct rorI_eReg_Var_C0(ncxRegI dst, eCXRegI shift, immI0 zero, eFlagsReg cr) %{ 9384 match(Set dst ( OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 9385 9386 expand %{ 9387 rorI_eReg_CL(dst, shift, cr); 9388 %} 9389%} 9390 9391// ROR 32bit var by var once 9392instruct rorI_eReg_Var_C32(ncxRegI dst, eCXRegI shift, immI_32 c32, eFlagsReg cr) %{ 9393 match(Set dst ( OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 9394 9395 expand %{ 9396 rorI_eReg_CL(dst, shift, cr); 9397 %} 9398%} 9399 9400// Xor Instructions 9401// Xor Register with Register 9402instruct xorI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{ 9403 match(Set dst (XorI dst src)); 9404 effect(KILL cr); 9405 9406 size(2); 9407 format %{ "XOR $dst,$src" %} 9408 opcode(0x33); 9409 ins_encode( OpcP, RegReg( dst, src) ); 9410 ins_pipe( ialu_reg_reg ); 9411%} 9412 9413// Xor Register with Immediate -1 9414instruct xorI_eReg_im1(eRegI dst, immI_M1 imm) %{ 9415 match(Set dst (XorI dst imm)); 9416 9417 size(2); 9418 format %{ "NOT $dst" %} 9419 ins_encode %{ 9420 __ notl($dst$$Register); 9421 %} 9422 ins_pipe( ialu_reg ); 9423%} 9424 9425// Xor Register with Immediate 9426instruct xorI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{ 9427 match(Set dst (XorI dst src)); 9428 effect(KILL cr); 9429 9430 format %{ "XOR $dst,$src" %} 9431 opcode(0x81,0x06); /* Opcode 81 /6 id */ 9432 // ins_encode( RegImm( dst, src) ); 9433 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 9434 ins_pipe( ialu_reg ); 9435%} 9436 9437// Xor Register with Memory 9438instruct xorI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{ 9439 match(Set dst (XorI dst (LoadI src))); 9440 effect(KILL cr); 9441 9442 ins_cost(125); 9443 format %{ "XOR $dst,$src" %} 9444 opcode(0x33); 9445 ins_encode( OpcP, RegMem(dst, src) ); 9446 ins_pipe( ialu_reg_mem ); 9447%} 9448 9449// Xor Memory with Register 9450instruct xorI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{ 9451 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9452 effect(KILL cr); 9453 9454 ins_cost(150); 9455 format %{ "XOR $dst,$src" %} 9456 opcode(0x31); /* Opcode 31 /r */ 9457 ins_encode( OpcP, RegMem( src, dst ) ); 9458 ins_pipe( ialu_mem_reg ); 9459%} 9460 9461// Xor Memory with Immediate 9462instruct xorI_mem_imm(memory dst, immI src, eFlagsReg cr) %{ 9463 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9464 effect(KILL cr); 9465 9466 ins_cost(125); 9467 format %{ "XOR $dst,$src" %} 9468 opcode(0x81,0x6); /* Opcode 81 /6 id */ 9469 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) ); 9470 ins_pipe( ialu_mem_imm ); 9471%} 9472 9473//----------Convert Int to Boolean--------------------------------------------- 9474 9475instruct movI_nocopy(eRegI dst, eRegI src) %{ 9476 effect( DEF dst, USE src ); 9477 format %{ "MOV $dst,$src" %} 9478 ins_encode( enc_Copy( dst, src) ); 9479 ins_pipe( ialu_reg_reg ); 9480%} 9481 9482instruct ci2b( eRegI dst, eRegI src, eFlagsReg cr ) %{ 9483 effect( USE_DEF dst, USE src, KILL cr ); 9484 9485 size(4); 9486 format %{ "NEG $dst\n\t" 9487 "ADC $dst,$src" %} 9488 ins_encode( neg_reg(dst), 9489 OpcRegReg(0x13,dst,src) ); 9490 ins_pipe( ialu_reg_reg_long ); 9491%} 9492 9493instruct convI2B( eRegI dst, eRegI src, eFlagsReg cr ) %{ 9494 match(Set dst (Conv2B src)); 9495 9496 expand %{ 9497 movI_nocopy(dst,src); 9498 ci2b(dst,src,cr); 9499 %} 9500%} 9501 9502instruct movP_nocopy(eRegI dst, eRegP src) %{ 9503 effect( DEF dst, USE src ); 9504 format %{ "MOV $dst,$src" %} 9505 ins_encode( enc_Copy( dst, src) ); 9506 ins_pipe( ialu_reg_reg ); 9507%} 9508 9509instruct cp2b( eRegI dst, eRegP src, eFlagsReg cr ) %{ 9510 effect( USE_DEF dst, USE src, KILL cr ); 9511 format %{ "NEG $dst\n\t" 9512 "ADC $dst,$src" %} 9513 ins_encode( neg_reg(dst), 9514 OpcRegReg(0x13,dst,src) ); 9515 ins_pipe( ialu_reg_reg_long ); 9516%} 9517 9518instruct convP2B( eRegI dst, eRegP src, eFlagsReg cr ) %{ 9519 match(Set dst (Conv2B src)); 9520 9521 expand %{ 9522 movP_nocopy(dst,src); 9523 cp2b(dst,src,cr); 9524 %} 9525%} 9526 9527instruct cmpLTMask( eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr ) %{ 9528 match(Set dst (CmpLTMask p q)); 9529 effect( KILL cr ); 9530 ins_cost(400); 9531 9532 // SETlt can only use low byte of EAX,EBX, ECX, or EDX as destination 9533 format %{ "XOR $dst,$dst\n\t" 9534 "CMP $p,$q\n\t" 9535 "SETlt $dst\n\t" 9536 "NEG $dst" %} 9537 ins_encode( OpcRegReg(0x33,dst,dst), 9538 OpcRegReg(0x3B,p,q), 9539 setLT_reg(dst), neg_reg(dst) ); 9540 ins_pipe( pipe_slow ); 9541%} 9542 9543instruct cmpLTMask0( eRegI dst, immI0 zero, eFlagsReg cr ) %{ 9544 match(Set dst (CmpLTMask dst zero)); 9545 effect( DEF dst, KILL cr ); 9546 ins_cost(100); 9547 9548 format %{ "SAR $dst,31" %} 9549 opcode(0xC1, 0x7); /* C1 /7 ib */ 9550 ins_encode( RegOpcImm( dst, 0x1F ) ); 9551 ins_pipe( ialu_reg ); 9552%} 9553 9554 9555instruct cadd_cmpLTMask( ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp, eFlagsReg cr ) %{ 9556 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9557 effect( KILL tmp, KILL cr ); 9558 ins_cost(400); 9559 // annoyingly, $tmp has no edges so you cant ask for it in 9560 // any format or encoding 9561 format %{ "SUB $p,$q\n\t" 9562 "SBB ECX,ECX\n\t" 9563 "AND ECX,$y\n\t" 9564 "ADD $p,ECX" %} 9565 ins_encode( enc_cmpLTP(p,q,y,tmp) ); 9566 ins_pipe( pipe_cmplt ); 9567%} 9568 9569/* If I enable this, I encourage spilling in the inner loop of compress. 9570instruct cadd_cmpLTMask_mem( ncxRegI p, ncxRegI q, memory y, eCXRegI tmp, eFlagsReg cr ) %{ 9571 match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q))); 9572 effect( USE_KILL tmp, KILL cr ); 9573 ins_cost(400); 9574 9575 format %{ "SUB $p,$q\n\t" 9576 "SBB ECX,ECX\n\t" 9577 "AND ECX,$y\n\t" 9578 "ADD $p,ECX" %} 9579 ins_encode( enc_cmpLTP_mem(p,q,y,tmp) ); 9580%} 9581*/ 9582 9583//----------Long Instructions------------------------------------------------ 9584// Add Long Register with Register 9585instruct addL_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 9586 match(Set dst (AddL dst src)); 9587 effect(KILL cr); 9588 ins_cost(200); 9589 format %{ "ADD $dst.lo,$src.lo\n\t" 9590 "ADC $dst.hi,$src.hi" %} 9591 opcode(0x03, 0x13); 9592 ins_encode( RegReg_Lo(dst, src), RegReg_Hi(dst,src) ); 9593 ins_pipe( ialu_reg_reg_long ); 9594%} 9595 9596// Add Long Register with Immediate 9597instruct addL_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{ 9598 match(Set dst (AddL dst src)); 9599 effect(KILL cr); 9600 format %{ "ADD $dst.lo,$src.lo\n\t" 9601 "ADC $dst.hi,$src.hi" %} 9602 opcode(0x81,0x00,0x02); /* Opcode 81 /0, 81 /2 */ 9603 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) ); 9604 ins_pipe( ialu_reg_long ); 9605%} 9606 9607// Add Long Register with Memory 9608instruct addL_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{ 9609 match(Set dst (AddL dst (LoadL mem))); 9610 effect(KILL cr); 9611 ins_cost(125); 9612 format %{ "ADD $dst.lo,$mem\n\t" 9613 "ADC $dst.hi,$mem+4" %} 9614 opcode(0x03, 0x13); 9615 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 9616 ins_pipe( ialu_reg_long_mem ); 9617%} 9618 9619// Subtract Long Register with Register. 9620instruct subL_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 9621 match(Set dst (SubL dst src)); 9622 effect(KILL cr); 9623 ins_cost(200); 9624 format %{ "SUB $dst.lo,$src.lo\n\t" 9625 "SBB $dst.hi,$src.hi" %} 9626 opcode(0x2B, 0x1B); 9627 ins_encode( RegReg_Lo(dst, src), RegReg_Hi(dst,src) ); 9628 ins_pipe( ialu_reg_reg_long ); 9629%} 9630 9631// Subtract Long Register with Immediate 9632instruct subL_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{ 9633 match(Set dst (SubL dst src)); 9634 effect(KILL cr); 9635 format %{ "SUB $dst.lo,$src.lo\n\t" 9636 "SBB $dst.hi,$src.hi" %} 9637 opcode(0x81,0x05,0x03); /* Opcode 81 /5, 81 /3 */ 9638 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) ); 9639 ins_pipe( ialu_reg_long ); 9640%} 9641 9642// Subtract Long Register with Memory 9643instruct subL_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{ 9644 match(Set dst (SubL dst (LoadL mem))); 9645 effect(KILL cr); 9646 ins_cost(125); 9647 format %{ "SUB $dst.lo,$mem\n\t" 9648 "SBB $dst.hi,$mem+4" %} 9649 opcode(0x2B, 0x1B); 9650 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 9651 ins_pipe( ialu_reg_long_mem ); 9652%} 9653 9654instruct negL_eReg(eRegL dst, immL0 zero, eFlagsReg cr) %{ 9655 match(Set dst (SubL zero dst)); 9656 effect(KILL cr); 9657 ins_cost(300); 9658 format %{ "NEG $dst.hi\n\tNEG $dst.lo\n\tSBB $dst.hi,0" %} 9659 ins_encode( neg_long(dst) ); 9660 ins_pipe( ialu_reg_reg_long ); 9661%} 9662 9663// And Long Register with Register 9664instruct andL_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 9665 match(Set dst (AndL dst src)); 9666 effect(KILL cr); 9667 format %{ "AND $dst.lo,$src.lo\n\t" 9668 "AND $dst.hi,$src.hi" %} 9669 opcode(0x23,0x23); 9670 ins_encode( RegReg_Lo( dst, src), RegReg_Hi( dst, src) ); 9671 ins_pipe( ialu_reg_reg_long ); 9672%} 9673 9674// And Long Register with Immediate 9675instruct andL_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{ 9676 match(Set dst (AndL dst src)); 9677 effect(KILL cr); 9678 format %{ "AND $dst.lo,$src.lo\n\t" 9679 "AND $dst.hi,$src.hi" %} 9680 opcode(0x81,0x04,0x04); /* Opcode 81 /4, 81 /4 */ 9681 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) ); 9682 ins_pipe( ialu_reg_long ); 9683%} 9684 9685// And Long Register with Memory 9686instruct andL_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{ 9687 match(Set dst (AndL dst (LoadL mem))); 9688 effect(KILL cr); 9689 ins_cost(125); 9690 format %{ "AND $dst.lo,$mem\n\t" 9691 "AND $dst.hi,$mem+4" %} 9692 opcode(0x23, 0x23); 9693 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 9694 ins_pipe( ialu_reg_long_mem ); 9695%} 9696 9697// Or Long Register with Register 9698instruct orl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 9699 match(Set dst (OrL dst src)); 9700 effect(KILL cr); 9701 format %{ "OR $dst.lo,$src.lo\n\t" 9702 "OR $dst.hi,$src.hi" %} 9703 opcode(0x0B,0x0B); 9704 ins_encode( RegReg_Lo( dst, src), RegReg_Hi( dst, src) ); 9705 ins_pipe( ialu_reg_reg_long ); 9706%} 9707 9708// Or Long Register with Immediate 9709instruct orl_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{ 9710 match(Set dst (OrL dst src)); 9711 effect(KILL cr); 9712 format %{ "OR $dst.lo,$src.lo\n\t" 9713 "OR $dst.hi,$src.hi" %} 9714 opcode(0x81,0x01,0x01); /* Opcode 81 /1, 81 /1 */ 9715 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) ); 9716 ins_pipe( ialu_reg_long ); 9717%} 9718 9719// Or Long Register with Memory 9720instruct orl_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{ 9721 match(Set dst (OrL dst (LoadL mem))); 9722 effect(KILL cr); 9723 ins_cost(125); 9724 format %{ "OR $dst.lo,$mem\n\t" 9725 "OR $dst.hi,$mem+4" %} 9726 opcode(0x0B,0x0B); 9727 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 9728 ins_pipe( ialu_reg_long_mem ); 9729%} 9730 9731// Xor Long Register with Register 9732instruct xorl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 9733 match(Set dst (XorL dst src)); 9734 effect(KILL cr); 9735 format %{ "XOR $dst.lo,$src.lo\n\t" 9736 "XOR $dst.hi,$src.hi" %} 9737 opcode(0x33,0x33); 9738 ins_encode( RegReg_Lo( dst, src), RegReg_Hi( dst, src) ); 9739 ins_pipe( ialu_reg_reg_long ); 9740%} 9741 9742// Xor Long Register with Immediate -1 9743instruct xorl_eReg_im1(eRegL dst, immL_M1 imm) %{ 9744 match(Set dst (XorL dst imm)); 9745 format %{ "NOT $dst.lo\n\t" 9746 "NOT $dst.hi" %} 9747 ins_encode %{ 9748 __ notl($dst$$Register); 9749 __ notl(HIGH_FROM_LOW($dst$$Register)); 9750 %} 9751 ins_pipe( ialu_reg_long ); 9752%} 9753 9754// Xor Long Register with Immediate 9755instruct xorl_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{ 9756 match(Set dst (XorL dst src)); 9757 effect(KILL cr); 9758 format %{ "XOR $dst.lo,$src.lo\n\t" 9759 "XOR $dst.hi,$src.hi" %} 9760 opcode(0x81,0x06,0x06); /* Opcode 81 /6, 81 /6 */ 9761 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) ); 9762 ins_pipe( ialu_reg_long ); 9763%} 9764 9765// Xor Long Register with Memory 9766instruct xorl_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{ 9767 match(Set dst (XorL dst (LoadL mem))); 9768 effect(KILL cr); 9769 ins_cost(125); 9770 format %{ "XOR $dst.lo,$mem\n\t" 9771 "XOR $dst.hi,$mem+4" %} 9772 opcode(0x33,0x33); 9773 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 9774 ins_pipe( ialu_reg_long_mem ); 9775%} 9776 9777// Shift Left Long by 1 9778instruct shlL_eReg_1(eRegL dst, immI_1 cnt, eFlagsReg cr) %{ 9779 predicate(UseNewLongLShift); 9780 match(Set dst (LShiftL dst cnt)); 9781 effect(KILL cr); 9782 ins_cost(100); 9783 format %{ "ADD $dst.lo,$dst.lo\n\t" 9784 "ADC $dst.hi,$dst.hi" %} 9785 ins_encode %{ 9786 __ addl($dst$$Register,$dst$$Register); 9787 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9788 %} 9789 ins_pipe( ialu_reg_long ); 9790%} 9791 9792// Shift Left Long by 2 9793instruct shlL_eReg_2(eRegL dst, immI_2 cnt, eFlagsReg cr) %{ 9794 predicate(UseNewLongLShift); 9795 match(Set dst (LShiftL dst cnt)); 9796 effect(KILL cr); 9797 ins_cost(100); 9798 format %{ "ADD $dst.lo,$dst.lo\n\t" 9799 "ADC $dst.hi,$dst.hi\n\t" 9800 "ADD $dst.lo,$dst.lo\n\t" 9801 "ADC $dst.hi,$dst.hi" %} 9802 ins_encode %{ 9803 __ addl($dst$$Register,$dst$$Register); 9804 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9805 __ addl($dst$$Register,$dst$$Register); 9806 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9807 %} 9808 ins_pipe( ialu_reg_long ); 9809%} 9810 9811// Shift Left Long by 3 9812instruct shlL_eReg_3(eRegL dst, immI_3 cnt, eFlagsReg cr) %{ 9813 predicate(UseNewLongLShift); 9814 match(Set dst (LShiftL dst cnt)); 9815 effect(KILL cr); 9816 ins_cost(100); 9817 format %{ "ADD $dst.lo,$dst.lo\n\t" 9818 "ADC $dst.hi,$dst.hi\n\t" 9819 "ADD $dst.lo,$dst.lo\n\t" 9820 "ADC $dst.hi,$dst.hi\n\t" 9821 "ADD $dst.lo,$dst.lo\n\t" 9822 "ADC $dst.hi,$dst.hi" %} 9823 ins_encode %{ 9824 __ addl($dst$$Register,$dst$$Register); 9825 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9826 __ addl($dst$$Register,$dst$$Register); 9827 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9828 __ addl($dst$$Register,$dst$$Register); 9829 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9830 %} 9831 ins_pipe( ialu_reg_long ); 9832%} 9833 9834// Shift Left Long by 1-31 9835instruct shlL_eReg_1_31(eRegL dst, immI_1_31 cnt, eFlagsReg cr) %{ 9836 match(Set dst (LShiftL dst cnt)); 9837 effect(KILL cr); 9838 ins_cost(200); 9839 format %{ "SHLD $dst.hi,$dst.lo,$cnt\n\t" 9840 "SHL $dst.lo,$cnt" %} 9841 opcode(0xC1, 0x4, 0xA4); /* 0F/A4, then C1 /4 ib */ 9842 ins_encode( move_long_small_shift(dst,cnt) ); 9843 ins_pipe( ialu_reg_long ); 9844%} 9845 9846// Shift Left Long by 32-63 9847instruct shlL_eReg_32_63(eRegL dst, immI_32_63 cnt, eFlagsReg cr) %{ 9848 match(Set dst (LShiftL dst cnt)); 9849 effect(KILL cr); 9850 ins_cost(300); 9851 format %{ "MOV $dst.hi,$dst.lo\n" 9852 "\tSHL $dst.hi,$cnt-32\n" 9853 "\tXOR $dst.lo,$dst.lo" %} 9854 opcode(0xC1, 0x4); /* C1 /4 ib */ 9855 ins_encode( move_long_big_shift_clr(dst,cnt) ); 9856 ins_pipe( ialu_reg_long ); 9857%} 9858 9859// Shift Left Long by variable 9860instruct salL_eReg_CL(eRegL dst, eCXRegI shift, eFlagsReg cr) %{ 9861 match(Set dst (LShiftL dst shift)); 9862 effect(KILL cr); 9863 ins_cost(500+200); 9864 size(17); 9865 format %{ "TEST $shift,32\n\t" 9866 "JEQ,s small\n\t" 9867 "MOV $dst.hi,$dst.lo\n\t" 9868 "XOR $dst.lo,$dst.lo\n" 9869 "small:\tSHLD $dst.hi,$dst.lo,$shift\n\t" 9870 "SHL $dst.lo,$shift" %} 9871 ins_encode( shift_left_long( dst, shift ) ); 9872 ins_pipe( pipe_slow ); 9873%} 9874 9875// Shift Right Long by 1-31 9876instruct shrL_eReg_1_31(eRegL dst, immI_1_31 cnt, eFlagsReg cr) %{ 9877 match(Set dst (URShiftL dst cnt)); 9878 effect(KILL cr); 9879 ins_cost(200); 9880 format %{ "SHRD $dst.lo,$dst.hi,$cnt\n\t" 9881 "SHR $dst.hi,$cnt" %} 9882 opcode(0xC1, 0x5, 0xAC); /* 0F/AC, then C1 /5 ib */ 9883 ins_encode( move_long_small_shift(dst,cnt) ); 9884 ins_pipe( ialu_reg_long ); 9885%} 9886 9887// Shift Right Long by 32-63 9888instruct shrL_eReg_32_63(eRegL dst, immI_32_63 cnt, eFlagsReg cr) %{ 9889 match(Set dst (URShiftL dst cnt)); 9890 effect(KILL cr); 9891 ins_cost(300); 9892 format %{ "MOV $dst.lo,$dst.hi\n" 9893 "\tSHR $dst.lo,$cnt-32\n" 9894 "\tXOR $dst.hi,$dst.hi" %} 9895 opcode(0xC1, 0x5); /* C1 /5 ib */ 9896 ins_encode( move_long_big_shift_clr(dst,cnt) ); 9897 ins_pipe( ialu_reg_long ); 9898%} 9899 9900// Shift Right Long by variable 9901instruct shrL_eReg_CL(eRegL dst, eCXRegI shift, eFlagsReg cr) %{ 9902 match(Set dst (URShiftL dst shift)); 9903 effect(KILL cr); 9904 ins_cost(600); 9905 size(17); 9906 format %{ "TEST $shift,32\n\t" 9907 "JEQ,s small\n\t" 9908 "MOV $dst.lo,$dst.hi\n\t" 9909 "XOR $dst.hi,$dst.hi\n" 9910 "small:\tSHRD $dst.lo,$dst.hi,$shift\n\t" 9911 "SHR $dst.hi,$shift" %} 9912 ins_encode( shift_right_long( dst, shift ) ); 9913 ins_pipe( pipe_slow ); 9914%} 9915 9916// Shift Right Long by 1-31 9917instruct sarL_eReg_1_31(eRegL dst, immI_1_31 cnt, eFlagsReg cr) %{ 9918 match(Set dst (RShiftL dst cnt)); 9919 effect(KILL cr); 9920 ins_cost(200); 9921 format %{ "SHRD $dst.lo,$dst.hi,$cnt\n\t" 9922 "SAR $dst.hi,$cnt" %} 9923 opcode(0xC1, 0x7, 0xAC); /* 0F/AC, then C1 /7 ib */ 9924 ins_encode( move_long_small_shift(dst,cnt) ); 9925 ins_pipe( ialu_reg_long ); 9926%} 9927 9928// Shift Right Long by 32-63 9929instruct sarL_eReg_32_63( eRegL dst, immI_32_63 cnt, eFlagsReg cr) %{ 9930 match(Set dst (RShiftL dst cnt)); 9931 effect(KILL cr); 9932 ins_cost(300); 9933 format %{ "MOV $dst.lo,$dst.hi\n" 9934 "\tSAR $dst.lo,$cnt-32\n" 9935 "\tSAR $dst.hi,31" %} 9936 opcode(0xC1, 0x7); /* C1 /7 ib */ 9937 ins_encode( move_long_big_shift_sign(dst,cnt) ); 9938 ins_pipe( ialu_reg_long ); 9939%} 9940 9941// Shift Right arithmetic Long by variable 9942instruct sarL_eReg_CL(eRegL dst, eCXRegI shift, eFlagsReg cr) %{ 9943 match(Set dst (RShiftL dst shift)); 9944 effect(KILL cr); 9945 ins_cost(600); 9946 size(18); 9947 format %{ "TEST $shift,32\n\t" 9948 "JEQ,s small\n\t" 9949 "MOV $dst.lo,$dst.hi\n\t" 9950 "SAR $dst.hi,31\n" 9951 "small:\tSHRD $dst.lo,$dst.hi,$shift\n\t" 9952 "SAR $dst.hi,$shift" %} 9953 ins_encode( shift_right_arith_long( dst, shift ) ); 9954 ins_pipe( pipe_slow ); 9955%} 9956 9957 9958//----------Double Instructions------------------------------------------------ 9959// Double Math 9960 9961// Compare & branch 9962 9963// P6 version of float compare, sets condition codes in EFLAGS 9964instruct cmpD_cc_P6(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{ 9965 predicate(VM_Version::supports_cmov() && UseSSE <=1); 9966 match(Set cr (CmpD src1 src2)); 9967 effect(KILL rax); 9968 ins_cost(150); 9969 format %{ "FLD $src1\n\t" 9970 "FUCOMIP ST,$src2 // P6 instruction\n\t" 9971 "JNP exit\n\t" 9972 "MOV ah,1 // saw a NaN, set CF\n\t" 9973 "SAHF\n" 9974 "exit:\tNOP // avoid branch to branch" %} 9975 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */ 9976 ins_encode( Push_Reg_D(src1), 9977 OpcP, RegOpc(src2), 9978 cmpF_P6_fixup ); 9979 ins_pipe( pipe_slow ); 9980%} 9981 9982instruct cmpD_cc_P6CF(eFlagsRegUCF cr, regD src1, regD src2) %{ 9983 predicate(VM_Version::supports_cmov() && UseSSE <=1); 9984 match(Set cr (CmpD src1 src2)); 9985 ins_cost(150); 9986 format %{ "FLD $src1\n\t" 9987 "FUCOMIP ST,$src2 // P6 instruction" %} 9988 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */ 9989 ins_encode( Push_Reg_D(src1), 9990 OpcP, RegOpc(src2)); 9991 ins_pipe( pipe_slow ); 9992%} 9993 9994// Compare & branch 9995instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2, eAXRegI rax) %{ 9996 predicate(UseSSE<=1); 9997 match(Set cr (CmpD src1 src2)); 9998 effect(KILL rax); 9999 ins_cost(200); 10000 format %{ "FLD $src1\n\t" 10001 "FCOMp $src2\n\t" 10002 "FNSTSW AX\n\t" 10003 "TEST AX,0x400\n\t" 10004 "JZ,s flags\n\t" 10005 "MOV AH,1\t# unordered treat as LT\n" 10006 "flags:\tSAHF" %} 10007 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */ 10008 ins_encode( Push_Reg_D(src1), 10009 OpcP, RegOpc(src2), 10010 fpu_flags); 10011 ins_pipe( pipe_slow ); 10012%} 10013 10014// Compare vs zero into -1,0,1 10015instruct cmpD_0(eRegI dst, regD src1, immD0 zero, eAXRegI rax, eFlagsReg cr) %{ 10016 predicate(UseSSE<=1); 10017 match(Set dst (CmpD3 src1 zero)); 10018 effect(KILL cr, KILL rax); 10019 ins_cost(280); 10020 format %{ "FTSTD $dst,$src1" %} 10021 opcode(0xE4, 0xD9); 10022 ins_encode( Push_Reg_D(src1), 10023 OpcS, OpcP, PopFPU, 10024 CmpF_Result(dst)); 10025 ins_pipe( pipe_slow ); 10026%} 10027 10028// Compare into -1,0,1 10029instruct cmpD_reg(eRegI dst, regD src1, regD src2, eAXRegI rax, eFlagsReg cr) %{ 10030 predicate(UseSSE<=1); 10031 match(Set dst (CmpD3 src1 src2)); 10032 effect(KILL cr, KILL rax); 10033 ins_cost(300); 10034 format %{ "FCMPD $dst,$src1,$src2" %} 10035 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */ 10036 ins_encode( Push_Reg_D(src1), 10037 OpcP, RegOpc(src2), 10038 CmpF_Result(dst)); 10039 ins_pipe( pipe_slow ); 10040%} 10041 10042// float compare and set condition codes in EFLAGS by XMM regs 10043instruct cmpXD_cc(eFlagsRegU cr, regXD dst, regXD src, eAXRegI rax) %{ 10044 predicate(UseSSE>=2); 10045 match(Set cr (CmpD dst src)); 10046 effect(KILL rax); 10047 ins_cost(125); 10048 format %{ "COMISD $dst,$src\n" 10049 "\tJNP exit\n" 10050 "\tMOV ah,1 // saw a NaN, set CF\n" 10051 "\tSAHF\n" 10052 "exit:\tNOP // avoid branch to branch" %} 10053 opcode(0x66, 0x0F, 0x2F); 10054 ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src), cmpF_P6_fixup); 10055 ins_pipe( pipe_slow ); 10056%} 10057 10058instruct cmpXD_ccCF(eFlagsRegUCF cr, regXD dst, regXD src) %{ 10059 predicate(UseSSE>=2); 10060 match(Set cr (CmpD dst src)); 10061 ins_cost(100); 10062 format %{ "COMISD $dst,$src" %} 10063 opcode(0x66, 0x0F, 0x2F); 10064 ins_encode(OpcP, OpcS, Opcode(tertiary), RegReg(dst, src)); 10065 ins_pipe( pipe_slow ); 10066%} 10067 10068// float compare and set condition codes in EFLAGS by XMM regs 10069instruct cmpXD_ccmem(eFlagsRegU cr, regXD dst, memory src, eAXRegI rax) %{ 10070 predicate(UseSSE>=2); 10071 match(Set cr (CmpD dst (LoadD src))); 10072 effect(KILL rax); 10073 ins_cost(145); 10074 format %{ "COMISD $dst,$src\n" 10075 "\tJNP exit\n" 10076 "\tMOV ah,1 // saw a NaN, set CF\n" 10077 "\tSAHF\n" 10078 "exit:\tNOP // avoid branch to branch" %} 10079 opcode(0x66, 0x0F, 0x2F); 10080 ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src), cmpF_P6_fixup); 10081 ins_pipe( pipe_slow ); 10082%} 10083 10084instruct cmpXD_ccmemCF(eFlagsRegUCF cr, regXD dst, memory src) %{ 10085 predicate(UseSSE>=2); 10086 match(Set cr (CmpD dst (LoadD src))); 10087 ins_cost(100); 10088 format %{ "COMISD $dst,$src" %} 10089 opcode(0x66, 0x0F, 0x2F); 10090 ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(dst, src)); 10091 ins_pipe( pipe_slow ); 10092%} 10093 10094// Compare into -1,0,1 in XMM 10095instruct cmpXD_reg(eRegI dst, regXD src1, regXD src2, eFlagsReg cr) %{ 10096 predicate(UseSSE>=2); 10097 match(Set dst (CmpD3 src1 src2)); 10098 effect(KILL cr); 10099 ins_cost(255); 10100 format %{ "XOR $dst,$dst\n" 10101 "\tCOMISD $src1,$src2\n" 10102 "\tJP,s nan\n" 10103 "\tJEQ,s exit\n" 10104 "\tJA,s inc\n" 10105 "nan:\tDEC $dst\n" 10106 "\tJMP,s exit\n" 10107 "inc:\tINC $dst\n" 10108 "exit:" 10109 %} 10110 opcode(0x66, 0x0F, 0x2F); 10111 ins_encode(Xor_Reg(dst), OpcP, OpcS, Opcode(tertiary), RegReg(src1, src2), 10112 CmpX_Result(dst)); 10113 ins_pipe( pipe_slow ); 10114%} 10115 10116// Compare into -1,0,1 in XMM and memory 10117instruct cmpXD_regmem(eRegI dst, regXD src1, memory mem, eFlagsReg cr) %{ 10118 predicate(UseSSE>=2); 10119 match(Set dst (CmpD3 src1 (LoadD mem))); 10120 effect(KILL cr); 10121 ins_cost(275); 10122 format %{ "COMISD $src1,$mem\n" 10123 "\tMOV $dst,0\t\t# do not blow flags\n" 10124 "\tJP,s nan\n" 10125 "\tJEQ,s exit\n" 10126 "\tJA,s inc\n" 10127 "nan:\tDEC $dst\n" 10128 "\tJMP,s exit\n" 10129 "inc:\tINC $dst\n" 10130 "exit:" 10131 %} 10132 opcode(0x66, 0x0F, 0x2F); 10133 ins_encode(OpcP, OpcS, Opcode(tertiary), RegMem(src1, mem), 10134 LdImmI(dst,0x0), CmpX_Result(dst)); 10135 ins_pipe( pipe_slow ); 10136%} 10137 10138 10139instruct subD_reg(regD dst, regD src) %{ 10140 predicate (UseSSE <=1); 10141 match(Set dst (SubD dst src)); 10142 10143 format %{ "FLD $src\n\t" 10144 "DSUBp $dst,ST" %} 10145 opcode(0xDE, 0x5); /* DE E8+i or DE /5 */ 10146 ins_cost(150); 10147 ins_encode( Push_Reg_D(src), 10148 OpcP, RegOpc(dst) ); 10149 ins_pipe( fpu_reg_reg ); 10150%} 10151 10152instruct subD_reg_round(stackSlotD dst, regD src1, regD src2) %{ 10153 predicate (UseSSE <=1); 10154 match(Set dst (RoundDouble (SubD src1 src2))); 10155 ins_cost(250); 10156 10157 format %{ "FLD $src2\n\t" 10158 "DSUB ST,$src1\n\t" 10159 "FSTP_D $dst\t# D-round" %} 10160 opcode(0xD8, 0x5); 10161 ins_encode( Push_Reg_D(src2), 10162 OpcP, RegOpc(src1), Pop_Mem_D(dst) ); 10163 ins_pipe( fpu_mem_reg_reg ); 10164%} 10165 10166 10167instruct subD_reg_mem(regD dst, memory src) %{ 10168 predicate (UseSSE <=1); 10169 match(Set dst (SubD dst (LoadD src))); 10170 ins_cost(150); 10171 10172 format %{ "FLD $src\n\t" 10173 "DSUBp $dst,ST" %} 10174 opcode(0xDE, 0x5, 0xDD); /* DE C0+i */ /* LoadD DD /0 */ 10175 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src), 10176 OpcP, RegOpc(dst) ); 10177 ins_pipe( fpu_reg_mem ); 10178%} 10179 10180instruct absD_reg(regDPR1 dst, regDPR1 src) %{ 10181 predicate (UseSSE<=1); 10182 match(Set dst (AbsD src)); 10183 ins_cost(100); 10184 format %{ "FABS" %} 10185 opcode(0xE1, 0xD9); 10186 ins_encode( OpcS, OpcP ); 10187 ins_pipe( fpu_reg_reg ); 10188%} 10189 10190instruct absXD_reg( regXD dst ) %{ 10191 predicate(UseSSE>=2); 10192 match(Set dst (AbsD dst)); 10193 format %{ "ANDPD $dst,[0x7FFFFFFFFFFFFFFF]\t# ABS D by sign masking" %} 10194 ins_encode( AbsXD_encoding(dst)); 10195 ins_pipe( pipe_slow ); 10196%} 10197 10198instruct negD_reg(regDPR1 dst, regDPR1 src) %{ 10199 predicate(UseSSE<=1); 10200 match(Set dst (NegD src)); 10201 ins_cost(100); 10202 format %{ "FCHS" %} 10203 opcode(0xE0, 0xD9); 10204 ins_encode( OpcS, OpcP ); 10205 ins_pipe( fpu_reg_reg ); 10206%} 10207 10208instruct negXD_reg( regXD dst ) %{ 10209 predicate(UseSSE>=2); 10210 match(Set dst (NegD dst)); 10211 format %{ "XORPD $dst,[0x8000000000000000]\t# CHS D by sign flipping" %} 10212 ins_encode %{ 10213 __ xorpd($dst$$XMMRegister, 10214 ExternalAddress((address)double_signflip_pool)); 10215 %} 10216 ins_pipe( pipe_slow ); 10217%} 10218 10219instruct addD_reg(regD dst, regD src) %{ 10220 predicate(UseSSE<=1); 10221 match(Set dst (AddD dst src)); 10222 format %{ "FLD $src\n\t" 10223 "DADD $dst,ST" %} 10224 size(4); 10225 ins_cost(150); 10226 opcode(0xDE, 0x0); /* DE C0+i or DE /0*/ 10227 ins_encode( Push_Reg_D(src), 10228 OpcP, RegOpc(dst) ); 10229 ins_pipe( fpu_reg_reg ); 10230%} 10231 10232 10233instruct addD_reg_round(stackSlotD dst, regD src1, regD src2) %{ 10234 predicate(UseSSE<=1); 10235 match(Set dst (RoundDouble (AddD src1 src2))); 10236 ins_cost(250); 10237 10238 format %{ "FLD $src2\n\t" 10239 "DADD ST,$src1\n\t" 10240 "FSTP_D $dst\t# D-round" %} 10241 opcode(0xD8, 0x0); /* D8 C0+i or D8 /0*/ 10242 ins_encode( Push_Reg_D(src2), 10243 OpcP, RegOpc(src1), Pop_Mem_D(dst) ); 10244 ins_pipe( fpu_mem_reg_reg ); 10245%} 10246 10247 10248instruct addD_reg_mem(regD dst, memory src) %{ 10249 predicate(UseSSE<=1); 10250 match(Set dst (AddD dst (LoadD src))); 10251 ins_cost(150); 10252 10253 format %{ "FLD $src\n\t" 10254 "DADDp $dst,ST" %} 10255 opcode(0xDE, 0x0, 0xDD); /* DE C0+i */ /* LoadD DD /0 */ 10256 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src), 10257 OpcP, RegOpc(dst) ); 10258 ins_pipe( fpu_reg_mem ); 10259%} 10260 10261// add-to-memory 10262instruct addD_mem_reg(memory dst, regD src) %{ 10263 predicate(UseSSE<=1); 10264 match(Set dst (StoreD dst (RoundDouble (AddD (LoadD dst) src)))); 10265 ins_cost(150); 10266 10267 format %{ "FLD_D $dst\n\t" 10268 "DADD ST,$src\n\t" 10269 "FST_D $dst" %} 10270 opcode(0xDD, 0x0); 10271 ins_encode( Opcode(0xDD), RMopc_Mem(0x00,dst), 10272 Opcode(0xD8), RegOpc(src), 10273 set_instruction_start, 10274 Opcode(0xDD), RMopc_Mem(0x03,dst) ); 10275 ins_pipe( fpu_reg_mem ); 10276%} 10277 10278instruct addD_reg_imm1(regD dst, immD1 con) %{ 10279 predicate(UseSSE<=1); 10280 match(Set dst (AddD dst con)); 10281 ins_cost(125); 10282 format %{ "FLD1\n\t" 10283 "DADDp $dst,ST" %} 10284 ins_encode %{ 10285 __ fld1(); 10286 __ faddp($dst$$reg); 10287 %} 10288 ins_pipe(fpu_reg); 10289%} 10290 10291instruct addD_reg_imm(regD dst, immD con) %{ 10292 predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 ); 10293 match(Set dst (AddD dst con)); 10294 ins_cost(200); 10295 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t" 10296 "DADDp $dst,ST" %} 10297 ins_encode %{ 10298 __ fld_d($constantaddress($con)); 10299 __ faddp($dst$$reg); 10300 %} 10301 ins_pipe(fpu_reg_mem); 10302%} 10303 10304instruct addD_reg_imm_round(stackSlotD dst, regD src, immD con) %{ 10305 predicate(UseSSE<=1 && _kids[0]->_kids[1]->_leaf->getd() != 0.0 && _kids[0]->_kids[1]->_leaf->getd() != 1.0 ); 10306 match(Set dst (RoundDouble (AddD src con))); 10307 ins_cost(200); 10308 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t" 10309 "DADD ST,$src\n\t" 10310 "FSTP_D $dst\t# D-round" %} 10311 ins_encode %{ 10312 __ fld_d($constantaddress($con)); 10313 __ fadd($src$$reg); 10314 __ fstp_d(Address(rsp, $dst$$disp)); 10315 %} 10316 ins_pipe(fpu_mem_reg_con); 10317%} 10318 10319// Add two double precision floating point values in xmm 10320instruct addXD_reg(regXD dst, regXD src) %{ 10321 predicate(UseSSE>=2); 10322 match(Set dst (AddD dst src)); 10323 format %{ "ADDSD $dst,$src" %} 10324 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegReg(dst, src)); 10325 ins_pipe( pipe_slow ); 10326%} 10327 10328instruct addXD_imm(regXD dst, immXD con) %{ 10329 predicate(UseSSE>=2); 10330 match(Set dst (AddD dst con)); 10331 format %{ "ADDSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 10332 ins_encode %{ 10333 __ addsd($dst$$XMMRegister, $constantaddress($con)); 10334 %} 10335 ins_pipe(pipe_slow); 10336%} 10337 10338instruct addXD_mem(regXD dst, memory mem) %{ 10339 predicate(UseSSE>=2); 10340 match(Set dst (AddD dst (LoadD mem))); 10341 format %{ "ADDSD $dst,$mem" %} 10342 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x58), RegMem(dst,mem)); 10343 ins_pipe( pipe_slow ); 10344%} 10345 10346// Sub two double precision floating point values in xmm 10347instruct subXD_reg(regXD dst, regXD src) %{ 10348 predicate(UseSSE>=2); 10349 match(Set dst (SubD dst src)); 10350 format %{ "SUBSD $dst,$src" %} 10351 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src)); 10352 ins_pipe( pipe_slow ); 10353%} 10354 10355instruct subXD_imm(regXD dst, immXD con) %{ 10356 predicate(UseSSE>=2); 10357 match(Set dst (SubD dst con)); 10358 format %{ "SUBSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 10359 ins_encode %{ 10360 __ subsd($dst$$XMMRegister, $constantaddress($con)); 10361 %} 10362 ins_pipe(pipe_slow); 10363%} 10364 10365instruct subXD_mem(regXD dst, memory mem) %{ 10366 predicate(UseSSE>=2); 10367 match(Set dst (SubD dst (LoadD mem))); 10368 format %{ "SUBSD $dst,$mem" %} 10369 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem)); 10370 ins_pipe( pipe_slow ); 10371%} 10372 10373// Mul two double precision floating point values in xmm 10374instruct mulXD_reg(regXD dst, regXD src) %{ 10375 predicate(UseSSE>=2); 10376 match(Set dst (MulD dst src)); 10377 format %{ "MULSD $dst,$src" %} 10378 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegReg(dst, src)); 10379 ins_pipe( pipe_slow ); 10380%} 10381 10382instruct mulXD_imm(regXD dst, immXD con) %{ 10383 predicate(UseSSE>=2); 10384 match(Set dst (MulD dst con)); 10385 format %{ "MULSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 10386 ins_encode %{ 10387 __ mulsd($dst$$XMMRegister, $constantaddress($con)); 10388 %} 10389 ins_pipe(pipe_slow); 10390%} 10391 10392instruct mulXD_mem(regXD dst, memory mem) %{ 10393 predicate(UseSSE>=2); 10394 match(Set dst (MulD dst (LoadD mem))); 10395 format %{ "MULSD $dst,$mem" %} 10396 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem)); 10397 ins_pipe( pipe_slow ); 10398%} 10399 10400// Div two double precision floating point values in xmm 10401instruct divXD_reg(regXD dst, regXD src) %{ 10402 predicate(UseSSE>=2); 10403 match(Set dst (DivD dst src)); 10404 format %{ "DIVSD $dst,$src" %} 10405 opcode(0xF2, 0x0F, 0x5E); 10406 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src)); 10407 ins_pipe( pipe_slow ); 10408%} 10409 10410instruct divXD_imm(regXD dst, immXD con) %{ 10411 predicate(UseSSE>=2); 10412 match(Set dst (DivD dst con)); 10413 format %{ "DIVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 10414 ins_encode %{ 10415 __ divsd($dst$$XMMRegister, $constantaddress($con)); 10416 %} 10417 ins_pipe(pipe_slow); 10418%} 10419 10420instruct divXD_mem(regXD dst, memory mem) %{ 10421 predicate(UseSSE>=2); 10422 match(Set dst (DivD dst (LoadD mem))); 10423 format %{ "DIVSD $dst,$mem" %} 10424 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem)); 10425 ins_pipe( pipe_slow ); 10426%} 10427 10428 10429instruct mulD_reg(regD dst, regD src) %{ 10430 predicate(UseSSE<=1); 10431 match(Set dst (MulD dst src)); 10432 format %{ "FLD $src\n\t" 10433 "DMULp $dst,ST" %} 10434 opcode(0xDE, 0x1); /* DE C8+i or DE /1*/ 10435 ins_cost(150); 10436 ins_encode( Push_Reg_D(src), 10437 OpcP, RegOpc(dst) ); 10438 ins_pipe( fpu_reg_reg ); 10439%} 10440 10441// Strict FP instruction biases argument before multiply then 10442// biases result to avoid double rounding of subnormals. 10443// 10444// scale arg1 by multiplying arg1 by 2^(-15360) 10445// load arg2 10446// multiply scaled arg1 by arg2 10447// rescale product by 2^(15360) 10448// 10449instruct strictfp_mulD_reg(regDPR1 dst, regnotDPR1 src) %{ 10450 predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() ); 10451 match(Set dst (MulD dst src)); 10452 ins_cost(1); // Select this instruction for all strict FP double multiplies 10453 10454 format %{ "FLD StubRoutines::_fpu_subnormal_bias1\n\t" 10455 "DMULp $dst,ST\n\t" 10456 "FLD $src\n\t" 10457 "DMULp $dst,ST\n\t" 10458 "FLD StubRoutines::_fpu_subnormal_bias2\n\t" 10459 "DMULp $dst,ST\n\t" %} 10460 opcode(0xDE, 0x1); /* DE C8+i or DE /1*/ 10461 ins_encode( strictfp_bias1(dst), 10462 Push_Reg_D(src), 10463 OpcP, RegOpc(dst), 10464 strictfp_bias2(dst) ); 10465 ins_pipe( fpu_reg_reg ); 10466%} 10467 10468instruct mulD_reg_imm(regD dst, immD con) %{ 10469 predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 ); 10470 match(Set dst (MulD dst con)); 10471 ins_cost(200); 10472 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t" 10473 "DMULp $dst,ST" %} 10474 ins_encode %{ 10475 __ fld_d($constantaddress($con)); 10476 __ fmulp($dst$$reg); 10477 %} 10478 ins_pipe(fpu_reg_mem); 10479%} 10480 10481 10482instruct mulD_reg_mem(regD dst, memory src) %{ 10483 predicate( UseSSE<=1 ); 10484 match(Set dst (MulD dst (LoadD src))); 10485 ins_cost(200); 10486 format %{ "FLD_D $src\n\t" 10487 "DMULp $dst,ST" %} 10488 opcode(0xDE, 0x1, 0xDD); /* DE C8+i or DE /1*/ /* LoadD DD /0 */ 10489 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src), 10490 OpcP, RegOpc(dst) ); 10491 ins_pipe( fpu_reg_mem ); 10492%} 10493 10494// 10495// Cisc-alternate to reg-reg multiply 10496instruct mulD_reg_mem_cisc(regD dst, regD src, memory mem) %{ 10497 predicate( UseSSE<=1 ); 10498 match(Set dst (MulD src (LoadD mem))); 10499 ins_cost(250); 10500 format %{ "FLD_D $mem\n\t" 10501 "DMUL ST,$src\n\t" 10502 "FSTP_D $dst" %} 10503 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i */ /* LoadD D9 /0 */ 10504 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,mem), 10505 OpcReg_F(src), 10506 Pop_Reg_D(dst) ); 10507 ins_pipe( fpu_reg_reg_mem ); 10508%} 10509 10510 10511// MACRO3 -- addD a mulD 10512// This instruction is a '2-address' instruction in that the result goes 10513// back to src2. This eliminates a move from the macro; possibly the 10514// register allocator will have to add it back (and maybe not). 10515instruct addD_mulD_reg(regD src2, regD src1, regD src0) %{ 10516 predicate( UseSSE<=1 ); 10517 match(Set src2 (AddD (MulD src0 src1) src2)); 10518 format %{ "FLD $src0\t# ===MACRO3d===\n\t" 10519 "DMUL ST,$src1\n\t" 10520 "DADDp $src2,ST" %} 10521 ins_cost(250); 10522 opcode(0xDD); /* LoadD DD /0 */ 10523 ins_encode( Push_Reg_F(src0), 10524 FMul_ST_reg(src1), 10525 FAddP_reg_ST(src2) ); 10526 ins_pipe( fpu_reg_reg_reg ); 10527%} 10528 10529 10530// MACRO3 -- subD a mulD 10531instruct subD_mulD_reg(regD src2, regD src1, regD src0) %{ 10532 predicate( UseSSE<=1 ); 10533 match(Set src2 (SubD (MulD src0 src1) src2)); 10534 format %{ "FLD $src0\t# ===MACRO3d===\n\t" 10535 "DMUL ST,$src1\n\t" 10536 "DSUBRp $src2,ST" %} 10537 ins_cost(250); 10538 ins_encode( Push_Reg_F(src0), 10539 FMul_ST_reg(src1), 10540 Opcode(0xDE), Opc_plus(0xE0,src2)); 10541 ins_pipe( fpu_reg_reg_reg ); 10542%} 10543 10544 10545instruct divD_reg(regD dst, regD src) %{ 10546 predicate( UseSSE<=1 ); 10547 match(Set dst (DivD dst src)); 10548 10549 format %{ "FLD $src\n\t" 10550 "FDIVp $dst,ST" %} 10551 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/ 10552 ins_cost(150); 10553 ins_encode( Push_Reg_D(src), 10554 OpcP, RegOpc(dst) ); 10555 ins_pipe( fpu_reg_reg ); 10556%} 10557 10558// Strict FP instruction biases argument before division then 10559// biases result, to avoid double rounding of subnormals. 10560// 10561// scale dividend by multiplying dividend by 2^(-15360) 10562// load divisor 10563// divide scaled dividend by divisor 10564// rescale quotient by 2^(15360) 10565// 10566instruct strictfp_divD_reg(regDPR1 dst, regnotDPR1 src) %{ 10567 predicate (UseSSE<=1); 10568 match(Set dst (DivD dst src)); 10569 predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() ); 10570 ins_cost(01); 10571 10572 format %{ "FLD StubRoutines::_fpu_subnormal_bias1\n\t" 10573 "DMULp $dst,ST\n\t" 10574 "FLD $src\n\t" 10575 "FDIVp $dst,ST\n\t" 10576 "FLD StubRoutines::_fpu_subnormal_bias2\n\t" 10577 "DMULp $dst,ST\n\t" %} 10578 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/ 10579 ins_encode( strictfp_bias1(dst), 10580 Push_Reg_D(src), 10581 OpcP, RegOpc(dst), 10582 strictfp_bias2(dst) ); 10583 ins_pipe( fpu_reg_reg ); 10584%} 10585 10586instruct divD_reg_round(stackSlotD dst, regD src1, regD src2) %{ 10587 predicate( UseSSE<=1 && !(Compile::current()->has_method() && Compile::current()->method()->is_strict()) ); 10588 match(Set dst (RoundDouble (DivD src1 src2))); 10589 10590 format %{ "FLD $src1\n\t" 10591 "FDIV ST,$src2\n\t" 10592 "FSTP_D $dst\t# D-round" %} 10593 opcode(0xD8, 0x6); /* D8 F0+i or D8 /6 */ 10594 ins_encode( Push_Reg_D(src1), 10595 OpcP, RegOpc(src2), Pop_Mem_D(dst) ); 10596 ins_pipe( fpu_mem_reg_reg ); 10597%} 10598 10599 10600instruct modD_reg(regD dst, regD src, eAXRegI rax, eFlagsReg cr) %{ 10601 predicate(UseSSE<=1); 10602 match(Set dst (ModD dst src)); 10603 effect(KILL rax, KILL cr); // emitModD() uses EAX and EFLAGS 10604 10605 format %{ "DMOD $dst,$src" %} 10606 ins_cost(250); 10607 ins_encode(Push_Reg_Mod_D(dst, src), 10608 emitModD(), 10609 Push_Result_Mod_D(src), 10610 Pop_Reg_D(dst)); 10611 ins_pipe( pipe_slow ); 10612%} 10613 10614instruct modXD_reg(regXD dst, regXD src0, regXD src1, eAXRegI rax, eFlagsReg cr) %{ 10615 predicate(UseSSE>=2); 10616 match(Set dst (ModD src0 src1)); 10617 effect(KILL rax, KILL cr); 10618 10619 format %{ "SUB ESP,8\t # DMOD\n" 10620 "\tMOVSD [ESP+0],$src1\n" 10621 "\tFLD_D [ESP+0]\n" 10622 "\tMOVSD [ESP+0],$src0\n" 10623 "\tFLD_D [ESP+0]\n" 10624 "loop:\tFPREM\n" 10625 "\tFWAIT\n" 10626 "\tFNSTSW AX\n" 10627 "\tSAHF\n" 10628 "\tJP loop\n" 10629 "\tFSTP_D [ESP+0]\n" 10630 "\tMOVSD $dst,[ESP+0]\n" 10631 "\tADD ESP,8\n" 10632 "\tFSTP ST0\t # Restore FPU Stack" 10633 %} 10634 ins_cost(250); 10635 ins_encode( Push_ModD_encoding(src0, src1), emitModD(), Push_ResultXD(dst), PopFPU); 10636 ins_pipe( pipe_slow ); 10637%} 10638 10639instruct sinD_reg(regDPR1 dst, regDPR1 src) %{ 10640 predicate (UseSSE<=1); 10641 match(Set dst (SinD src)); 10642 ins_cost(1800); 10643 format %{ "DSIN $dst" %} 10644 opcode(0xD9, 0xFE); 10645 ins_encode( OpcP, OpcS ); 10646 ins_pipe( pipe_slow ); 10647%} 10648 10649instruct sinXD_reg(regXD dst, eFlagsReg cr) %{ 10650 predicate (UseSSE>=2); 10651 match(Set dst (SinD dst)); 10652 effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8" 10653 ins_cost(1800); 10654 format %{ "DSIN $dst" %} 10655 opcode(0xD9, 0xFE); 10656 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 10657 ins_pipe( pipe_slow ); 10658%} 10659 10660instruct cosD_reg(regDPR1 dst, regDPR1 src) %{ 10661 predicate (UseSSE<=1); 10662 match(Set dst (CosD src)); 10663 ins_cost(1800); 10664 format %{ "DCOS $dst" %} 10665 opcode(0xD9, 0xFF); 10666 ins_encode( OpcP, OpcS ); 10667 ins_pipe( pipe_slow ); 10668%} 10669 10670instruct cosXD_reg(regXD dst, eFlagsReg cr) %{ 10671 predicate (UseSSE>=2); 10672 match(Set dst (CosD dst)); 10673 effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8" 10674 ins_cost(1800); 10675 format %{ "DCOS $dst" %} 10676 opcode(0xD9, 0xFF); 10677 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 10678 ins_pipe( pipe_slow ); 10679%} 10680 10681instruct tanD_reg(regDPR1 dst, regDPR1 src) %{ 10682 predicate (UseSSE<=1); 10683 match(Set dst(TanD src)); 10684 format %{ "DTAN $dst" %} 10685 ins_encode( Opcode(0xD9), Opcode(0xF2), // fptan 10686 Opcode(0xDD), Opcode(0xD8)); // fstp st 10687 ins_pipe( pipe_slow ); 10688%} 10689 10690instruct tanXD_reg(regXD dst, eFlagsReg cr) %{ 10691 predicate (UseSSE>=2); 10692 match(Set dst(TanD dst)); 10693 effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8" 10694 format %{ "DTAN $dst" %} 10695 ins_encode( Push_SrcXD(dst), 10696 Opcode(0xD9), Opcode(0xF2), // fptan 10697 Opcode(0xDD), Opcode(0xD8), // fstp st 10698 Push_ResultXD(dst) ); 10699 ins_pipe( pipe_slow ); 10700%} 10701 10702instruct atanD_reg(regD dst, regD src) %{ 10703 predicate (UseSSE<=1); 10704 match(Set dst(AtanD dst src)); 10705 format %{ "DATA $dst,$src" %} 10706 opcode(0xD9, 0xF3); 10707 ins_encode( Push_Reg_D(src), 10708 OpcP, OpcS, RegOpc(dst) ); 10709 ins_pipe( pipe_slow ); 10710%} 10711 10712instruct atanXD_reg(regXD dst, regXD src, eFlagsReg cr) %{ 10713 predicate (UseSSE>=2); 10714 match(Set dst(AtanD dst src)); 10715 effect(KILL cr); // Push_{Src|Result}XD() uses "{SUB|ADD} ESP,8" 10716 format %{ "DATA $dst,$src" %} 10717 opcode(0xD9, 0xF3); 10718 ins_encode( Push_SrcXD(src), 10719 OpcP, OpcS, Push_ResultXD(dst) ); 10720 ins_pipe( pipe_slow ); 10721%} 10722 10723instruct sqrtD_reg(regD dst, regD src) %{ 10724 predicate (UseSSE<=1); 10725 match(Set dst (SqrtD src)); 10726 format %{ "DSQRT $dst,$src" %} 10727 opcode(0xFA, 0xD9); 10728 ins_encode( Push_Reg_D(src), 10729 OpcS, OpcP, Pop_Reg_D(dst) ); 10730 ins_pipe( pipe_slow ); 10731%} 10732 10733instruct powD_reg(regD X, regDPR1 Y, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{ 10734 predicate (UseSSE<=1); 10735 match(Set Y (PowD X Y)); // Raise X to the Yth power 10736 effect(KILL rax, KILL rbx, KILL rcx); 10737 format %{ "SUB ESP,8\t\t# Fast-path POW encoding\n\t" 10738 "FLD_D $X\n\t" 10739 "FYL2X \t\t\t# Q=Y*ln2(X)\n\t" 10740 10741 "FDUP \t\t\t# Q Q\n\t" 10742 "FRNDINT\t\t\t# int(Q) Q\n\t" 10743 "FSUB ST(1),ST(0)\t# int(Q) frac(Q)\n\t" 10744 "FISTP dword [ESP]\n\t" 10745 "F2XM1 \t\t\t# 2^frac(Q)-1 int(Q)\n\t" 10746 "FLD1 \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t" 10747 "FADDP \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead 10748 "MOV EAX,[ESP]\t# Pick up int(Q)\n\t" 10749 "MOV ECX,0xFFFFF800\t# Overflow mask\n\t" 10750 "ADD EAX,1023\t\t# Double exponent bias\n\t" 10751 "MOV EBX,EAX\t\t# Preshifted biased expo\n\t" 10752 "SHL EAX,20\t\t# Shift exponent into place\n\t" 10753 "TEST EBX,ECX\t\t# Check for overflow\n\t" 10754 "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t" 10755 "MOV [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t" 10756 "MOV [ESP+0],0\n\t" 10757 "FMUL ST(0),[ESP+0]\t# Scale\n\t" 10758 10759 "ADD ESP,8" 10760 %} 10761 ins_encode( push_stack_temp_qword, 10762 Push_Reg_D(X), 10763 Opcode(0xD9), Opcode(0xF1), // fyl2x 10764 pow_exp_core_encoding, 10765 pop_stack_temp_qword); 10766 ins_pipe( pipe_slow ); 10767%} 10768 10769instruct powXD_reg(regXD dst, regXD src0, regXD src1, regDPR1 tmp1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx ) %{ 10770 predicate (UseSSE>=2); 10771 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 10772 effect(KILL tmp1, KILL rax, KILL rbx, KILL rcx ); 10773 format %{ "SUB ESP,8\t\t# Fast-path POW encoding\n\t" 10774 "MOVSD [ESP],$src1\n\t" 10775 "FLD FPR1,$src1\n\t" 10776 "MOVSD [ESP],$src0\n\t" 10777 "FLD FPR1,$src0\n\t" 10778 "FYL2X \t\t\t# Q=Y*ln2(X)\n\t" 10779 10780 "FDUP \t\t\t# Q Q\n\t" 10781 "FRNDINT\t\t\t# int(Q) Q\n\t" 10782 "FSUB ST(1),ST(0)\t# int(Q) frac(Q)\n\t" 10783 "FISTP dword [ESP]\n\t" 10784 "F2XM1 \t\t\t# 2^frac(Q)-1 int(Q)\n\t" 10785 "FLD1 \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t" 10786 "FADDP \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead 10787 "MOV EAX,[ESP]\t# Pick up int(Q)\n\t" 10788 "MOV ECX,0xFFFFF800\t# Overflow mask\n\t" 10789 "ADD EAX,1023\t\t# Double exponent bias\n\t" 10790 "MOV EBX,EAX\t\t# Preshifted biased expo\n\t" 10791 "SHL EAX,20\t\t# Shift exponent into place\n\t" 10792 "TEST EBX,ECX\t\t# Check for overflow\n\t" 10793 "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t" 10794 "MOV [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t" 10795 "MOV [ESP+0],0\n\t" 10796 "FMUL ST(0),[ESP+0]\t# Scale\n\t" 10797 10798 "FST_D [ESP]\n\t" 10799 "MOVSD $dst,[ESP]\n\t" 10800 "ADD ESP,8" 10801 %} 10802 ins_encode( push_stack_temp_qword, 10803 push_xmm_to_fpr1(src1), 10804 push_xmm_to_fpr1(src0), 10805 Opcode(0xD9), Opcode(0xF1), // fyl2x 10806 pow_exp_core_encoding, 10807 Push_ResultXD(dst) ); 10808 ins_pipe( pipe_slow ); 10809%} 10810 10811 10812instruct expD_reg(regDPR1 dpr1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{ 10813 predicate (UseSSE<=1); 10814 match(Set dpr1 (ExpD dpr1)); 10815 effect(KILL rax, KILL rbx, KILL rcx); 10816 format %{ "SUB ESP,8\t\t# Fast-path EXP encoding" 10817 "FLDL2E \t\t\t# Ld log2(e) X\n\t" 10818 "FMULP \t\t\t# Q=X*log2(e)\n\t" 10819 10820 "FDUP \t\t\t# Q Q\n\t" 10821 "FRNDINT\t\t\t# int(Q) Q\n\t" 10822 "FSUB ST(1),ST(0)\t# int(Q) frac(Q)\n\t" 10823 "FISTP dword [ESP]\n\t" 10824 "F2XM1 \t\t\t# 2^frac(Q)-1 int(Q)\n\t" 10825 "FLD1 \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t" 10826 "FADDP \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead 10827 "MOV EAX,[ESP]\t# Pick up int(Q)\n\t" 10828 "MOV ECX,0xFFFFF800\t# Overflow mask\n\t" 10829 "ADD EAX,1023\t\t# Double exponent bias\n\t" 10830 "MOV EBX,EAX\t\t# Preshifted biased expo\n\t" 10831 "SHL EAX,20\t\t# Shift exponent into place\n\t" 10832 "TEST EBX,ECX\t\t# Check for overflow\n\t" 10833 "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t" 10834 "MOV [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t" 10835 "MOV [ESP+0],0\n\t" 10836 "FMUL ST(0),[ESP+0]\t# Scale\n\t" 10837 10838 "ADD ESP,8" 10839 %} 10840 ins_encode( push_stack_temp_qword, 10841 Opcode(0xD9), Opcode(0xEA), // fldl2e 10842 Opcode(0xDE), Opcode(0xC9), // fmulp 10843 pow_exp_core_encoding, 10844 pop_stack_temp_qword); 10845 ins_pipe( pipe_slow ); 10846%} 10847 10848instruct expXD_reg(regXD dst, regXD src, regDPR1 tmp1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{ 10849 predicate (UseSSE>=2); 10850 match(Set dst (ExpD src)); 10851 effect(KILL tmp1, KILL rax, KILL rbx, KILL rcx); 10852 format %{ "SUB ESP,8\t\t# Fast-path EXP encoding\n\t" 10853 "MOVSD [ESP],$src\n\t" 10854 "FLDL2E \t\t\t# Ld log2(e) X\n\t" 10855 "FMULP \t\t\t# Q=X*log2(e) X\n\t" 10856 10857 "FDUP \t\t\t# Q Q\n\t" 10858 "FRNDINT\t\t\t# int(Q) Q\n\t" 10859 "FSUB ST(1),ST(0)\t# int(Q) frac(Q)\n\t" 10860 "FISTP dword [ESP]\n\t" 10861 "F2XM1 \t\t\t# 2^frac(Q)-1 int(Q)\n\t" 10862 "FLD1 \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t" 10863 "FADDP \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead 10864 "MOV EAX,[ESP]\t# Pick up int(Q)\n\t" 10865 "MOV ECX,0xFFFFF800\t# Overflow mask\n\t" 10866 "ADD EAX,1023\t\t# Double exponent bias\n\t" 10867 "MOV EBX,EAX\t\t# Preshifted biased expo\n\t" 10868 "SHL EAX,20\t\t# Shift exponent into place\n\t" 10869 "TEST EBX,ECX\t\t# Check for overflow\n\t" 10870 "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t" 10871 "MOV [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t" 10872 "MOV [ESP+0],0\n\t" 10873 "FMUL ST(0),[ESP+0]\t# Scale\n\t" 10874 10875 "FST_D [ESP]\n\t" 10876 "MOVSD $dst,[ESP]\n\t" 10877 "ADD ESP,8" 10878 %} 10879 ins_encode( Push_SrcXD(src), 10880 Opcode(0xD9), Opcode(0xEA), // fldl2e 10881 Opcode(0xDE), Opcode(0xC9), // fmulp 10882 pow_exp_core_encoding, 10883 Push_ResultXD(dst) ); 10884 ins_pipe( pipe_slow ); 10885%} 10886 10887 10888 10889instruct log10D_reg(regDPR1 dst, regDPR1 src) %{ 10890 predicate (UseSSE<=1); 10891 // The source Double operand on FPU stack 10892 match(Set dst (Log10D src)); 10893 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 10894 // fxch ; swap ST(0) with ST(1) 10895 // fyl2x ; compute log_10(2) * log_2(x) 10896 format %{ "FLDLG2 \t\t\t#Log10\n\t" 10897 "FXCH \n\t" 10898 "FYL2X \t\t\t# Q=Log10*Log_2(x)" 10899 %} 10900 ins_encode( Opcode(0xD9), Opcode(0xEC), // fldlg2 10901 Opcode(0xD9), Opcode(0xC9), // fxch 10902 Opcode(0xD9), Opcode(0xF1)); // fyl2x 10903 10904 ins_pipe( pipe_slow ); 10905%} 10906 10907instruct log10XD_reg(regXD dst, regXD src, eFlagsReg cr) %{ 10908 predicate (UseSSE>=2); 10909 effect(KILL cr); 10910 match(Set dst (Log10D src)); 10911 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 10912 // fyl2x ; compute log_10(2) * log_2(x) 10913 format %{ "FLDLG2 \t\t\t#Log10\n\t" 10914 "FYL2X \t\t\t# Q=Log10*Log_2(x)" 10915 %} 10916 ins_encode( Opcode(0xD9), Opcode(0xEC), // fldlg2 10917 Push_SrcXD(src), 10918 Opcode(0xD9), Opcode(0xF1), // fyl2x 10919 Push_ResultXD(dst)); 10920 10921 ins_pipe( pipe_slow ); 10922%} 10923 10924instruct logD_reg(regDPR1 dst, regDPR1 src) %{ 10925 predicate (UseSSE<=1); 10926 // The source Double operand on FPU stack 10927 match(Set dst (LogD src)); 10928 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 10929 // fxch ; swap ST(0) with ST(1) 10930 // fyl2x ; compute log_e(2) * log_2(x) 10931 format %{ "FLDLN2 \t\t\t#Log_e\n\t" 10932 "FXCH \n\t" 10933 "FYL2X \t\t\t# Q=Log_e*Log_2(x)" 10934 %} 10935 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 10936 Opcode(0xD9), Opcode(0xC9), // fxch 10937 Opcode(0xD9), Opcode(0xF1)); // fyl2x 10938 10939 ins_pipe( pipe_slow ); 10940%} 10941 10942instruct logXD_reg(regXD dst, regXD src, eFlagsReg cr) %{ 10943 predicate (UseSSE>=2); 10944 effect(KILL cr); 10945 // The source and result Double operands in XMM registers 10946 match(Set dst (LogD src)); 10947 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 10948 // fyl2x ; compute log_e(2) * log_2(x) 10949 format %{ "FLDLN2 \t\t\t#Log_e\n\t" 10950 "FYL2X \t\t\t# Q=Log_e*Log_2(x)" 10951 %} 10952 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 10953 Push_SrcXD(src), 10954 Opcode(0xD9), Opcode(0xF1), // fyl2x 10955 Push_ResultXD(dst)); 10956 ins_pipe( pipe_slow ); 10957%} 10958 10959//-------------Float Instructions------------------------------- 10960// Float Math 10961 10962// Code for float compare: 10963// fcompp(); 10964// fwait(); fnstsw_ax(); 10965// sahf(); 10966// movl(dst, unordered_result); 10967// jcc(Assembler::parity, exit); 10968// movl(dst, less_result); 10969// jcc(Assembler::below, exit); 10970// movl(dst, equal_result); 10971// jcc(Assembler::equal, exit); 10972// movl(dst, greater_result); 10973// exit: 10974 10975// P6 version of float compare, sets condition codes in EFLAGS 10976instruct cmpF_cc_P6(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{ 10977 predicate(VM_Version::supports_cmov() && UseSSE == 0); 10978 match(Set cr (CmpF src1 src2)); 10979 effect(KILL rax); 10980 ins_cost(150); 10981 format %{ "FLD $src1\n\t" 10982 "FUCOMIP ST,$src2 // P6 instruction\n\t" 10983 "JNP exit\n\t" 10984 "MOV ah,1 // saw a NaN, set CF (treat as LT)\n\t" 10985 "SAHF\n" 10986 "exit:\tNOP // avoid branch to branch" %} 10987 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */ 10988 ins_encode( Push_Reg_D(src1), 10989 OpcP, RegOpc(src2), 10990 cmpF_P6_fixup ); 10991 ins_pipe( pipe_slow ); 10992%} 10993 10994instruct cmpF_cc_P6CF(eFlagsRegUCF cr, regF src1, regF src2) %{ 10995 predicate(VM_Version::supports_cmov() && UseSSE == 0); 10996 match(Set cr (CmpF src1 src2)); 10997 ins_cost(100); 10998 format %{ "FLD $src1\n\t" 10999 "FUCOMIP ST,$src2 // P6 instruction" %} 11000 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */ 11001 ins_encode( Push_Reg_D(src1), 11002 OpcP, RegOpc(src2)); 11003 ins_pipe( pipe_slow ); 11004%} 11005 11006 11007// Compare & branch 11008instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2, eAXRegI rax) %{ 11009 predicate(UseSSE == 0); 11010 match(Set cr (CmpF src1 src2)); 11011 effect(KILL rax); 11012 ins_cost(200); 11013 format %{ "FLD $src1\n\t" 11014 "FCOMp $src2\n\t" 11015 "FNSTSW AX\n\t" 11016 "TEST AX,0x400\n\t" 11017 "JZ,s flags\n\t" 11018 "MOV AH,1\t# unordered treat as LT\n" 11019 "flags:\tSAHF" %} 11020 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */ 11021 ins_encode( Push_Reg_D(src1), 11022 OpcP, RegOpc(src2), 11023 fpu_flags); 11024 ins_pipe( pipe_slow ); 11025%} 11026 11027// Compare vs zero into -1,0,1 11028instruct cmpF_0(eRegI dst, regF src1, immF0 zero, eAXRegI rax, eFlagsReg cr) %{ 11029 predicate(UseSSE == 0); 11030 match(Set dst (CmpF3 src1 zero)); 11031 effect(KILL cr, KILL rax); 11032 ins_cost(280); 11033 format %{ "FTSTF $dst,$src1" %} 11034 opcode(0xE4, 0xD9); 11035 ins_encode( Push_Reg_D(src1), 11036 OpcS, OpcP, PopFPU, 11037 CmpF_Result(dst)); 11038 ins_pipe( pipe_slow ); 11039%} 11040 11041// Compare into -1,0,1 11042instruct cmpF_reg(eRegI dst, regF src1, regF src2, eAXRegI rax, eFlagsReg cr) %{ 11043 predicate(UseSSE == 0); 11044 match(Set dst (CmpF3 src1 src2)); 11045 effect(KILL cr, KILL rax); 11046 ins_cost(300); 11047 format %{ "FCMPF $dst,$src1,$src2" %} 11048 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */ 11049 ins_encode( Push_Reg_D(src1), 11050 OpcP, RegOpc(src2), 11051 CmpF_Result(dst)); 11052 ins_pipe( pipe_slow ); 11053%} 11054 11055// float compare and set condition codes in EFLAGS by XMM regs 11056instruct cmpX_cc(eFlagsRegU cr, regX dst, regX src, eAXRegI rax) %{ 11057 predicate(UseSSE>=1); 11058 match(Set cr (CmpF dst src)); 11059 effect(KILL rax); 11060 ins_cost(145); 11061 format %{ "COMISS $dst,$src\n" 11062 "\tJNP exit\n" 11063 "\tMOV ah,1 // saw a NaN, set CF\n" 11064 "\tSAHF\n" 11065 "exit:\tNOP // avoid branch to branch" %} 11066 opcode(0x0F, 0x2F); 11067 ins_encode(OpcP, OpcS, RegReg(dst, src), cmpF_P6_fixup); 11068 ins_pipe( pipe_slow ); 11069%} 11070 11071instruct cmpX_ccCF(eFlagsRegUCF cr, regX dst, regX src) %{ 11072 predicate(UseSSE>=1); 11073 match(Set cr (CmpF dst src)); 11074 ins_cost(100); 11075 format %{ "COMISS $dst,$src" %} 11076 opcode(0x0F, 0x2F); 11077 ins_encode(OpcP, OpcS, RegReg(dst, src)); 11078 ins_pipe( pipe_slow ); 11079%} 11080 11081// float compare and set condition codes in EFLAGS by XMM regs 11082instruct cmpX_ccmem(eFlagsRegU cr, regX dst, memory src, eAXRegI rax) %{ 11083 predicate(UseSSE>=1); 11084 match(Set cr (CmpF dst (LoadF src))); 11085 effect(KILL rax); 11086 ins_cost(165); 11087 format %{ "COMISS $dst,$src\n" 11088 "\tJNP exit\n" 11089 "\tMOV ah,1 // saw a NaN, set CF\n" 11090 "\tSAHF\n" 11091 "exit:\tNOP // avoid branch to branch" %} 11092 opcode(0x0F, 0x2F); 11093 ins_encode(OpcP, OpcS, RegMem(dst, src), cmpF_P6_fixup); 11094 ins_pipe( pipe_slow ); 11095%} 11096 11097instruct cmpX_ccmemCF(eFlagsRegUCF cr, regX dst, memory src) %{ 11098 predicate(UseSSE>=1); 11099 match(Set cr (CmpF dst (LoadF src))); 11100 ins_cost(100); 11101 format %{ "COMISS $dst,$src" %} 11102 opcode(0x0F, 0x2F); 11103 ins_encode(OpcP, OpcS, RegMem(dst, src)); 11104 ins_pipe( pipe_slow ); 11105%} 11106 11107// Compare into -1,0,1 in XMM 11108instruct cmpX_reg(eRegI dst, regX src1, regX src2, eFlagsReg cr) %{ 11109 predicate(UseSSE>=1); 11110 match(Set dst (CmpF3 src1 src2)); 11111 effect(KILL cr); 11112 ins_cost(255); 11113 format %{ "XOR $dst,$dst\n" 11114 "\tCOMISS $src1,$src2\n" 11115 "\tJP,s nan\n" 11116 "\tJEQ,s exit\n" 11117 "\tJA,s inc\n" 11118 "nan:\tDEC $dst\n" 11119 "\tJMP,s exit\n" 11120 "inc:\tINC $dst\n" 11121 "exit:" 11122 %} 11123 opcode(0x0F, 0x2F); 11124 ins_encode(Xor_Reg(dst), OpcP, OpcS, RegReg(src1, src2), CmpX_Result(dst)); 11125 ins_pipe( pipe_slow ); 11126%} 11127 11128// Compare into -1,0,1 in XMM and memory 11129instruct cmpX_regmem(eRegI dst, regX src1, memory mem, eFlagsReg cr) %{ 11130 predicate(UseSSE>=1); 11131 match(Set dst (CmpF3 src1 (LoadF mem))); 11132 effect(KILL cr); 11133 ins_cost(275); 11134 format %{ "COMISS $src1,$mem\n" 11135 "\tMOV $dst,0\t\t# do not blow flags\n" 11136 "\tJP,s nan\n" 11137 "\tJEQ,s exit\n" 11138 "\tJA,s inc\n" 11139 "nan:\tDEC $dst\n" 11140 "\tJMP,s exit\n" 11141 "inc:\tINC $dst\n" 11142 "exit:" 11143 %} 11144 opcode(0x0F, 0x2F); 11145 ins_encode(OpcP, OpcS, RegMem(src1, mem), LdImmI(dst,0x0), CmpX_Result(dst)); 11146 ins_pipe( pipe_slow ); 11147%} 11148 11149// Spill to obtain 24-bit precision 11150instruct subF24_reg(stackSlotF dst, regF src1, regF src2) %{ 11151 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11152 match(Set dst (SubF src1 src2)); 11153 11154 format %{ "FSUB $dst,$src1 - $src2" %} 11155 opcode(0xD8, 0x4); /* D8 E0+i or D8 /4 mod==0x3 ;; result in TOS */ 11156 ins_encode( Push_Reg_F(src1), 11157 OpcReg_F(src2), 11158 Pop_Mem_F(dst) ); 11159 ins_pipe( fpu_mem_reg_reg ); 11160%} 11161// 11162// This instruction does not round to 24-bits 11163instruct subF_reg(regF dst, regF src) %{ 11164 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11165 match(Set dst (SubF dst src)); 11166 11167 format %{ "FSUB $dst,$src" %} 11168 opcode(0xDE, 0x5); /* DE E8+i or DE /5 */ 11169 ins_encode( Push_Reg_F(src), 11170 OpcP, RegOpc(dst) ); 11171 ins_pipe( fpu_reg_reg ); 11172%} 11173 11174// Spill to obtain 24-bit precision 11175instruct addF24_reg(stackSlotF dst, regF src1, regF src2) %{ 11176 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11177 match(Set dst (AddF src1 src2)); 11178 11179 format %{ "FADD $dst,$src1,$src2" %} 11180 opcode(0xD8, 0x0); /* D8 C0+i */ 11181 ins_encode( Push_Reg_F(src2), 11182 OpcReg_F(src1), 11183 Pop_Mem_F(dst) ); 11184 ins_pipe( fpu_mem_reg_reg ); 11185%} 11186// 11187// This instruction does not round to 24-bits 11188instruct addF_reg(regF dst, regF src) %{ 11189 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11190 match(Set dst (AddF dst src)); 11191 11192 format %{ "FLD $src\n\t" 11193 "FADDp $dst,ST" %} 11194 opcode(0xDE, 0x0); /* DE C0+i or DE /0*/ 11195 ins_encode( Push_Reg_F(src), 11196 OpcP, RegOpc(dst) ); 11197 ins_pipe( fpu_reg_reg ); 11198%} 11199 11200// Add two single precision floating point values in xmm 11201instruct addX_reg(regX dst, regX src) %{ 11202 predicate(UseSSE>=1); 11203 match(Set dst (AddF dst src)); 11204 format %{ "ADDSS $dst,$src" %} 11205 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegReg(dst, src)); 11206 ins_pipe( pipe_slow ); 11207%} 11208 11209instruct addX_imm(regX dst, immXF con) %{ 11210 predicate(UseSSE>=1); 11211 match(Set dst (AddF dst con)); 11212 format %{ "ADDSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 11213 ins_encode %{ 11214 __ addss($dst$$XMMRegister, $constantaddress($con)); 11215 %} 11216 ins_pipe(pipe_slow); 11217%} 11218 11219instruct addX_mem(regX dst, memory mem) %{ 11220 predicate(UseSSE>=1); 11221 match(Set dst (AddF dst (LoadF mem))); 11222 format %{ "ADDSS $dst,$mem" %} 11223 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x58), RegMem(dst, mem)); 11224 ins_pipe( pipe_slow ); 11225%} 11226 11227// Subtract two single precision floating point values in xmm 11228instruct subX_reg(regX dst, regX src) %{ 11229 predicate(UseSSE>=1); 11230 match(Set dst (SubF dst src)); 11231 format %{ "SUBSS $dst,$src" %} 11232 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegReg(dst, src)); 11233 ins_pipe( pipe_slow ); 11234%} 11235 11236instruct subX_imm(regX dst, immXF con) %{ 11237 predicate(UseSSE>=1); 11238 match(Set dst (SubF dst con)); 11239 format %{ "SUBSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 11240 ins_encode %{ 11241 __ subss($dst$$XMMRegister, $constantaddress($con)); 11242 %} 11243 ins_pipe(pipe_slow); 11244%} 11245 11246instruct subX_mem(regX dst, memory mem) %{ 11247 predicate(UseSSE>=1); 11248 match(Set dst (SubF dst (LoadF mem))); 11249 format %{ "SUBSS $dst,$mem" %} 11250 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5C), RegMem(dst,mem)); 11251 ins_pipe( pipe_slow ); 11252%} 11253 11254// Multiply two single precision floating point values in xmm 11255instruct mulX_reg(regX dst, regX src) %{ 11256 predicate(UseSSE>=1); 11257 match(Set dst (MulF dst src)); 11258 format %{ "MULSS $dst,$src" %} 11259 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegReg(dst, src)); 11260 ins_pipe( pipe_slow ); 11261%} 11262 11263instruct mulX_imm(regX dst, immXF con) %{ 11264 predicate(UseSSE>=1); 11265 match(Set dst (MulF dst con)); 11266 format %{ "MULSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 11267 ins_encode %{ 11268 __ mulss($dst$$XMMRegister, $constantaddress($con)); 11269 %} 11270 ins_pipe(pipe_slow); 11271%} 11272 11273instruct mulX_mem(regX dst, memory mem) %{ 11274 predicate(UseSSE>=1); 11275 match(Set dst (MulF dst (LoadF mem))); 11276 format %{ "MULSS $dst,$mem" %} 11277 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x59), RegMem(dst,mem)); 11278 ins_pipe( pipe_slow ); 11279%} 11280 11281// Divide two single precision floating point values in xmm 11282instruct divX_reg(regX dst, regX src) %{ 11283 predicate(UseSSE>=1); 11284 match(Set dst (DivF dst src)); 11285 format %{ "DIVSS $dst,$src" %} 11286 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegReg(dst, src)); 11287 ins_pipe( pipe_slow ); 11288%} 11289 11290instruct divX_imm(regX dst, immXF con) %{ 11291 predicate(UseSSE>=1); 11292 match(Set dst (DivF dst con)); 11293 format %{ "DIVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 11294 ins_encode %{ 11295 __ divss($dst$$XMMRegister, $constantaddress($con)); 11296 %} 11297 ins_pipe(pipe_slow); 11298%} 11299 11300instruct divX_mem(regX dst, memory mem) %{ 11301 predicate(UseSSE>=1); 11302 match(Set dst (DivF dst (LoadF mem))); 11303 format %{ "DIVSS $dst,$mem" %} 11304 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x5E), RegMem(dst,mem)); 11305 ins_pipe( pipe_slow ); 11306%} 11307 11308// Get the square root of a single precision floating point values in xmm 11309instruct sqrtX_reg(regX dst, regX src) %{ 11310 predicate(UseSSE>=1); 11311 match(Set dst (ConvD2F (SqrtD (ConvF2D src)))); 11312 format %{ "SQRTSS $dst,$src" %} 11313 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x51), RegReg(dst, src)); 11314 ins_pipe( pipe_slow ); 11315%} 11316 11317instruct sqrtX_mem(regX dst, memory mem) %{ 11318 predicate(UseSSE>=1); 11319 match(Set dst (ConvD2F (SqrtD (ConvF2D (LoadF mem))))); 11320 format %{ "SQRTSS $dst,$mem" %} 11321 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x51), RegMem(dst, mem)); 11322 ins_pipe( pipe_slow ); 11323%} 11324 11325// Get the square root of a double precision floating point values in xmm 11326instruct sqrtXD_reg(regXD dst, regXD src) %{ 11327 predicate(UseSSE>=2); 11328 match(Set dst (SqrtD src)); 11329 format %{ "SQRTSD $dst,$src" %} 11330 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x51), RegReg(dst, src)); 11331 ins_pipe( pipe_slow ); 11332%} 11333 11334instruct sqrtXD_mem(regXD dst, memory mem) %{ 11335 predicate(UseSSE>=2); 11336 match(Set dst (SqrtD (LoadD mem))); 11337 format %{ "SQRTSD $dst,$mem" %} 11338 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x51), RegMem(dst, mem)); 11339 ins_pipe( pipe_slow ); 11340%} 11341 11342instruct absF_reg(regFPR1 dst, regFPR1 src) %{ 11343 predicate(UseSSE==0); 11344 match(Set dst (AbsF src)); 11345 ins_cost(100); 11346 format %{ "FABS" %} 11347 opcode(0xE1, 0xD9); 11348 ins_encode( OpcS, OpcP ); 11349 ins_pipe( fpu_reg_reg ); 11350%} 11351 11352instruct absX_reg(regX dst ) %{ 11353 predicate(UseSSE>=1); 11354 match(Set dst (AbsF dst)); 11355 format %{ "ANDPS $dst,[0x7FFFFFFF]\t# ABS F by sign masking" %} 11356 ins_encode( AbsXF_encoding(dst)); 11357 ins_pipe( pipe_slow ); 11358%} 11359 11360instruct negF_reg(regFPR1 dst, regFPR1 src) %{ 11361 predicate(UseSSE==0); 11362 match(Set dst (NegF src)); 11363 ins_cost(100); 11364 format %{ "FCHS" %} 11365 opcode(0xE0, 0xD9); 11366 ins_encode( OpcS, OpcP ); 11367 ins_pipe( fpu_reg_reg ); 11368%} 11369 11370instruct negX_reg( regX dst ) %{ 11371 predicate(UseSSE>=1); 11372 match(Set dst (NegF dst)); 11373 format %{ "XORPS $dst,[0x80000000]\t# CHS F by sign flipping" %} 11374 ins_encode( NegXF_encoding(dst)); 11375 ins_pipe( pipe_slow ); 11376%} 11377 11378// Cisc-alternate to addF_reg 11379// Spill to obtain 24-bit precision 11380instruct addF24_reg_mem(stackSlotF dst, regF src1, memory src2) %{ 11381 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11382 match(Set dst (AddF src1 (LoadF src2))); 11383 11384 format %{ "FLD $src2\n\t" 11385 "FADD ST,$src1\n\t" 11386 "FSTP_S $dst" %} 11387 opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */ 11388 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 11389 OpcReg_F(src1), 11390 Pop_Mem_F(dst) ); 11391 ins_pipe( fpu_mem_reg_mem ); 11392%} 11393// 11394// Cisc-alternate to addF_reg 11395// This instruction does not round to 24-bits 11396instruct addF_reg_mem(regF dst, memory src) %{ 11397 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11398 match(Set dst (AddF dst (LoadF src))); 11399 11400 format %{ "FADD $dst,$src" %} 11401 opcode(0xDE, 0x0, 0xD9); /* DE C0+i or DE /0*/ /* LoadF D9 /0 */ 11402 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src), 11403 OpcP, RegOpc(dst) ); 11404 ins_pipe( fpu_reg_mem ); 11405%} 11406 11407// // Following two instructions for _222_mpegaudio 11408// Spill to obtain 24-bit precision 11409instruct addF24_mem_reg(stackSlotF dst, regF src2, memory src1 ) %{ 11410 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11411 match(Set dst (AddF src1 src2)); 11412 11413 format %{ "FADD $dst,$src1,$src2" %} 11414 opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */ 11415 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src1), 11416 OpcReg_F(src2), 11417 Pop_Mem_F(dst) ); 11418 ins_pipe( fpu_mem_reg_mem ); 11419%} 11420 11421// Cisc-spill variant 11422// Spill to obtain 24-bit precision 11423instruct addF24_mem_cisc(stackSlotF dst, memory src1, memory src2) %{ 11424 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11425 match(Set dst (AddF src1 (LoadF src2))); 11426 11427 format %{ "FADD $dst,$src1,$src2 cisc" %} 11428 opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */ 11429 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 11430 set_instruction_start, 11431 OpcP, RMopc_Mem(secondary,src1), 11432 Pop_Mem_F(dst) ); 11433 ins_pipe( fpu_mem_mem_mem ); 11434%} 11435 11436// Spill to obtain 24-bit precision 11437instruct addF24_mem_mem(stackSlotF dst, memory src1, memory src2) %{ 11438 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11439 match(Set dst (AddF src1 src2)); 11440 11441 format %{ "FADD $dst,$src1,$src2" %} 11442 opcode(0xD8, 0x0, 0xD9); /* D8 /0 */ /* LoadF D9 /0 */ 11443 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 11444 set_instruction_start, 11445 OpcP, RMopc_Mem(secondary,src1), 11446 Pop_Mem_F(dst) ); 11447 ins_pipe( fpu_mem_mem_mem ); 11448%} 11449 11450 11451// Spill to obtain 24-bit precision 11452instruct addF24_reg_imm(stackSlotF dst, regF src, immF con) %{ 11453 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11454 match(Set dst (AddF src con)); 11455 format %{ "FLD $src\n\t" 11456 "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t" 11457 "FSTP_S $dst" %} 11458 ins_encode %{ 11459 __ fld_s($src$$reg - 1); // FLD ST(i-1) 11460 __ fadd_s($constantaddress($con)); 11461 __ fstp_s(Address(rsp, $dst$$disp)); 11462 %} 11463 ins_pipe(fpu_mem_reg_con); 11464%} 11465// 11466// This instruction does not round to 24-bits 11467instruct addF_reg_imm(regF dst, regF src, immF con) %{ 11468 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11469 match(Set dst (AddF src con)); 11470 format %{ "FLD $src\n\t" 11471 "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t" 11472 "FSTP $dst" %} 11473 ins_encode %{ 11474 __ fld_s($src$$reg - 1); // FLD ST(i-1) 11475 __ fadd_s($constantaddress($con)); 11476 __ fstp_d($dst$$reg); 11477 %} 11478 ins_pipe(fpu_reg_reg_con); 11479%} 11480 11481// Spill to obtain 24-bit precision 11482instruct mulF24_reg(stackSlotF dst, regF src1, regF src2) %{ 11483 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11484 match(Set dst (MulF src1 src2)); 11485 11486 format %{ "FLD $src1\n\t" 11487 "FMUL $src2\n\t" 11488 "FSTP_S $dst" %} 11489 opcode(0xD8, 0x1); /* D8 C8+i or D8 /1 ;; result in TOS */ 11490 ins_encode( Push_Reg_F(src1), 11491 OpcReg_F(src2), 11492 Pop_Mem_F(dst) ); 11493 ins_pipe( fpu_mem_reg_reg ); 11494%} 11495// 11496// This instruction does not round to 24-bits 11497instruct mulF_reg(regF dst, regF src1, regF src2) %{ 11498 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11499 match(Set dst (MulF src1 src2)); 11500 11501 format %{ "FLD $src1\n\t" 11502 "FMUL $src2\n\t" 11503 "FSTP_S $dst" %} 11504 opcode(0xD8, 0x1); /* D8 C8+i */ 11505 ins_encode( Push_Reg_F(src2), 11506 OpcReg_F(src1), 11507 Pop_Reg_F(dst) ); 11508 ins_pipe( fpu_reg_reg_reg ); 11509%} 11510 11511 11512// Spill to obtain 24-bit precision 11513// Cisc-alternate to reg-reg multiply 11514instruct mulF24_reg_mem(stackSlotF dst, regF src1, memory src2) %{ 11515 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11516 match(Set dst (MulF src1 (LoadF src2))); 11517 11518 format %{ "FLD_S $src2\n\t" 11519 "FMUL $src1\n\t" 11520 "FSTP_S $dst" %} 11521 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i or DE /1*/ /* LoadF D9 /0 */ 11522 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 11523 OpcReg_F(src1), 11524 Pop_Mem_F(dst) ); 11525 ins_pipe( fpu_mem_reg_mem ); 11526%} 11527// 11528// This instruction does not round to 24-bits 11529// Cisc-alternate to reg-reg multiply 11530instruct mulF_reg_mem(regF dst, regF src1, memory src2) %{ 11531 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11532 match(Set dst (MulF src1 (LoadF src2))); 11533 11534 format %{ "FMUL $dst,$src1,$src2" %} 11535 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i */ /* LoadF D9 /0 */ 11536 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 11537 OpcReg_F(src1), 11538 Pop_Reg_F(dst) ); 11539 ins_pipe( fpu_reg_reg_mem ); 11540%} 11541 11542// Spill to obtain 24-bit precision 11543instruct mulF24_mem_mem(stackSlotF dst, memory src1, memory src2) %{ 11544 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11545 match(Set dst (MulF src1 src2)); 11546 11547 format %{ "FMUL $dst,$src1,$src2" %} 11548 opcode(0xD8, 0x1, 0xD9); /* D8 /1 */ /* LoadF D9 /0 */ 11549 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 11550 set_instruction_start, 11551 OpcP, RMopc_Mem(secondary,src1), 11552 Pop_Mem_F(dst) ); 11553 ins_pipe( fpu_mem_mem_mem ); 11554%} 11555 11556// Spill to obtain 24-bit precision 11557instruct mulF24_reg_imm(stackSlotF dst, regF src, immF con) %{ 11558 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11559 match(Set dst (MulF src con)); 11560 11561 format %{ "FLD $src\n\t" 11562 "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t" 11563 "FSTP_S $dst" %} 11564 ins_encode %{ 11565 __ fld_s($src$$reg - 1); // FLD ST(i-1) 11566 __ fmul_s($constantaddress($con)); 11567 __ fstp_s(Address(rsp, $dst$$disp)); 11568 %} 11569 ins_pipe(fpu_mem_reg_con); 11570%} 11571// 11572// This instruction does not round to 24-bits 11573instruct mulF_reg_imm(regF dst, regF src, immF con) %{ 11574 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11575 match(Set dst (MulF src con)); 11576 11577 format %{ "FLD $src\n\t" 11578 "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t" 11579 "FSTP $dst" %} 11580 ins_encode %{ 11581 __ fld_s($src$$reg - 1); // FLD ST(i-1) 11582 __ fmul_s($constantaddress($con)); 11583 __ fstp_d($dst$$reg); 11584 %} 11585 ins_pipe(fpu_reg_reg_con); 11586%} 11587 11588 11589// 11590// MACRO1 -- subsume unshared load into mulF 11591// This instruction does not round to 24-bits 11592instruct mulF_reg_load1(regF dst, regF src, memory mem1 ) %{ 11593 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11594 match(Set dst (MulF (LoadF mem1) src)); 11595 11596 format %{ "FLD $mem1 ===MACRO1===\n\t" 11597 "FMUL ST,$src\n\t" 11598 "FSTP $dst" %} 11599 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i or D8 /1 */ /* LoadF D9 /0 */ 11600 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,mem1), 11601 OpcReg_F(src), 11602 Pop_Reg_F(dst) ); 11603 ins_pipe( fpu_reg_reg_mem ); 11604%} 11605// 11606// MACRO2 -- addF a mulF which subsumed an unshared load 11607// This instruction does not round to 24-bits 11608instruct addF_mulF_reg_load1(regF dst, memory mem1, regF src1, regF src2) %{ 11609 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11610 match(Set dst (AddF (MulF (LoadF mem1) src1) src2)); 11611 ins_cost(95); 11612 11613 format %{ "FLD $mem1 ===MACRO2===\n\t" 11614 "FMUL ST,$src1 subsume mulF left load\n\t" 11615 "FADD ST,$src2\n\t" 11616 "FSTP $dst" %} 11617 opcode(0xD9); /* LoadF D9 /0 */ 11618 ins_encode( OpcP, RMopc_Mem(0x00,mem1), 11619 FMul_ST_reg(src1), 11620 FAdd_ST_reg(src2), 11621 Pop_Reg_F(dst) ); 11622 ins_pipe( fpu_reg_mem_reg_reg ); 11623%} 11624 11625// MACRO3 -- addF a mulF 11626// This instruction does not round to 24-bits. It is a '2-address' 11627// instruction in that the result goes back to src2. This eliminates 11628// a move from the macro; possibly the register allocator will have 11629// to add it back (and maybe not). 11630instruct addF_mulF_reg(regF src2, regF src1, regF src0) %{ 11631 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11632 match(Set src2 (AddF (MulF src0 src1) src2)); 11633 11634 format %{ "FLD $src0 ===MACRO3===\n\t" 11635 "FMUL ST,$src1\n\t" 11636 "FADDP $src2,ST" %} 11637 opcode(0xD9); /* LoadF D9 /0 */ 11638 ins_encode( Push_Reg_F(src0), 11639 FMul_ST_reg(src1), 11640 FAddP_reg_ST(src2) ); 11641 ins_pipe( fpu_reg_reg_reg ); 11642%} 11643 11644// MACRO4 -- divF subF 11645// This instruction does not round to 24-bits 11646instruct subF_divF_reg(regF dst, regF src1, regF src2, regF src3) %{ 11647 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11648 match(Set dst (DivF (SubF src2 src1) src3)); 11649 11650 format %{ "FLD $src2 ===MACRO4===\n\t" 11651 "FSUB ST,$src1\n\t" 11652 "FDIV ST,$src3\n\t" 11653 "FSTP $dst" %} 11654 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/ 11655 ins_encode( Push_Reg_F(src2), 11656 subF_divF_encode(src1,src3), 11657 Pop_Reg_F(dst) ); 11658 ins_pipe( fpu_reg_reg_reg_reg ); 11659%} 11660 11661// Spill to obtain 24-bit precision 11662instruct divF24_reg(stackSlotF dst, regF src1, regF src2) %{ 11663 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 11664 match(Set dst (DivF src1 src2)); 11665 11666 format %{ "FDIV $dst,$src1,$src2" %} 11667 opcode(0xD8, 0x6); /* D8 F0+i or DE /6*/ 11668 ins_encode( Push_Reg_F(src1), 11669 OpcReg_F(src2), 11670 Pop_Mem_F(dst) ); 11671 ins_pipe( fpu_mem_reg_reg ); 11672%} 11673// 11674// This instruction does not round to 24-bits 11675instruct divF_reg(regF dst, regF src) %{ 11676 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11677 match(Set dst (DivF dst src)); 11678 11679 format %{ "FDIV $dst,$src" %} 11680 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/ 11681 ins_encode( Push_Reg_F(src), 11682 OpcP, RegOpc(dst) ); 11683 ins_pipe( fpu_reg_reg ); 11684%} 11685 11686 11687// Spill to obtain 24-bit precision 11688instruct modF24_reg(stackSlotF dst, regF src1, regF src2, eAXRegI rax, eFlagsReg cr) %{ 11689 predicate( UseSSE==0 && Compile::current()->select_24_bit_instr()); 11690 match(Set dst (ModF src1 src2)); 11691 effect(KILL rax, KILL cr); // emitModD() uses EAX and EFLAGS 11692 11693 format %{ "FMOD $dst,$src1,$src2" %} 11694 ins_encode( Push_Reg_Mod_D(src1, src2), 11695 emitModD(), 11696 Push_Result_Mod_D(src2), 11697 Pop_Mem_F(dst)); 11698 ins_pipe( pipe_slow ); 11699%} 11700// 11701// This instruction does not round to 24-bits 11702instruct modF_reg(regF dst, regF src, eAXRegI rax, eFlagsReg cr) %{ 11703 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11704 match(Set dst (ModF dst src)); 11705 effect(KILL rax, KILL cr); // emitModD() uses EAX and EFLAGS 11706 11707 format %{ "FMOD $dst,$src" %} 11708 ins_encode(Push_Reg_Mod_D(dst, src), 11709 emitModD(), 11710 Push_Result_Mod_D(src), 11711 Pop_Reg_F(dst)); 11712 ins_pipe( pipe_slow ); 11713%} 11714 11715instruct modX_reg(regX dst, regX src0, regX src1, eAXRegI rax, eFlagsReg cr) %{ 11716 predicate(UseSSE>=1); 11717 match(Set dst (ModF src0 src1)); 11718 effect(KILL rax, KILL cr); 11719 format %{ "SUB ESP,4\t # FMOD\n" 11720 "\tMOVSS [ESP+0],$src1\n" 11721 "\tFLD_S [ESP+0]\n" 11722 "\tMOVSS [ESP+0],$src0\n" 11723 "\tFLD_S [ESP+0]\n" 11724 "loop:\tFPREM\n" 11725 "\tFWAIT\n" 11726 "\tFNSTSW AX\n" 11727 "\tSAHF\n" 11728 "\tJP loop\n" 11729 "\tFSTP_S [ESP+0]\n" 11730 "\tMOVSS $dst,[ESP+0]\n" 11731 "\tADD ESP,4\n" 11732 "\tFSTP ST0\t # Restore FPU Stack" 11733 %} 11734 ins_cost(250); 11735 ins_encode( Push_ModX_encoding(src0, src1), emitModD(), Push_ResultX(dst,0x4), PopFPU); 11736 ins_pipe( pipe_slow ); 11737%} 11738 11739 11740//----------Arithmetic Conversion Instructions--------------------------------- 11741// The conversions operations are all Alpha sorted. Please keep it that way! 11742 11743instruct roundFloat_mem_reg(stackSlotF dst, regF src) %{ 11744 predicate(UseSSE==0); 11745 match(Set dst (RoundFloat src)); 11746 ins_cost(125); 11747 format %{ "FST_S $dst,$src\t# F-round" %} 11748 ins_encode( Pop_Mem_Reg_F(dst, src) ); 11749 ins_pipe( fpu_mem_reg ); 11750%} 11751 11752instruct roundDouble_mem_reg(stackSlotD dst, regD src) %{ 11753 predicate(UseSSE<=1); 11754 match(Set dst (RoundDouble src)); 11755 ins_cost(125); 11756 format %{ "FST_D $dst,$src\t# D-round" %} 11757 ins_encode( Pop_Mem_Reg_D(dst, src) ); 11758 ins_pipe( fpu_mem_reg ); 11759%} 11760 11761// Force rounding to 24-bit precision and 6-bit exponent 11762instruct convD2F_reg(stackSlotF dst, regD src) %{ 11763 predicate(UseSSE==0); 11764 match(Set dst (ConvD2F src)); 11765 format %{ "FST_S $dst,$src\t# F-round" %} 11766 expand %{ 11767 roundFloat_mem_reg(dst,src); 11768 %} 11769%} 11770 11771// Force rounding to 24-bit precision and 6-bit exponent 11772instruct convD2X_reg(regX dst, regD src, eFlagsReg cr) %{ 11773 predicate(UseSSE==1); 11774 match(Set dst (ConvD2F src)); 11775 effect( KILL cr ); 11776 format %{ "SUB ESP,4\n\t" 11777 "FST_S [ESP],$src\t# F-round\n\t" 11778 "MOVSS $dst,[ESP]\n\t" 11779 "ADD ESP,4" %} 11780 ins_encode( D2X_encoding(dst, src) ); 11781 ins_pipe( pipe_slow ); 11782%} 11783 11784// Force rounding double precision to single precision 11785instruct convXD2X_reg(regX dst, regXD src) %{ 11786 predicate(UseSSE>=2); 11787 match(Set dst (ConvD2F src)); 11788 format %{ "CVTSD2SS $dst,$src\t# F-round" %} 11789 opcode(0xF2, 0x0F, 0x5A); 11790 ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src)); 11791 ins_pipe( pipe_slow ); 11792%} 11793 11794instruct convF2D_reg_reg(regD dst, regF src) %{ 11795 predicate(UseSSE==0); 11796 match(Set dst (ConvF2D src)); 11797 format %{ "FST_S $dst,$src\t# D-round" %} 11798 ins_encode( Pop_Reg_Reg_D(dst, src)); 11799 ins_pipe( fpu_reg_reg ); 11800%} 11801 11802instruct convF2D_reg(stackSlotD dst, regF src) %{ 11803 predicate(UseSSE==1); 11804 match(Set dst (ConvF2D src)); 11805 format %{ "FST_D $dst,$src\t# D-round" %} 11806 expand %{ 11807 roundDouble_mem_reg(dst,src); 11808 %} 11809%} 11810 11811instruct convX2D_reg(regD dst, regX src, eFlagsReg cr) %{ 11812 predicate(UseSSE==1); 11813 match(Set dst (ConvF2D src)); 11814 effect( KILL cr ); 11815 format %{ "SUB ESP,4\n\t" 11816 "MOVSS [ESP] $src\n\t" 11817 "FLD_S [ESP]\n\t" 11818 "ADD ESP,4\n\t" 11819 "FSTP $dst\t# D-round" %} 11820 ins_encode( X2D_encoding(dst, src), Pop_Reg_D(dst)); 11821 ins_pipe( pipe_slow ); 11822%} 11823 11824instruct convX2XD_reg(regXD dst, regX src) %{ 11825 predicate(UseSSE>=2); 11826 match(Set dst (ConvF2D src)); 11827 format %{ "CVTSS2SD $dst,$src\t# D-round" %} 11828 opcode(0xF3, 0x0F, 0x5A); 11829 ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src)); 11830 ins_pipe( pipe_slow ); 11831%} 11832 11833// Convert a double to an int. If the double is a NAN, stuff a zero in instead. 11834instruct convD2I_reg_reg( eAXRegI dst, eDXRegI tmp, regD src, eFlagsReg cr ) %{ 11835 predicate(UseSSE<=1); 11836 match(Set dst (ConvD2I src)); 11837 effect( KILL tmp, KILL cr ); 11838 format %{ "FLD $src\t# Convert double to int \n\t" 11839 "FLDCW trunc mode\n\t" 11840 "SUB ESP,4\n\t" 11841 "FISTp [ESP + #0]\n\t" 11842 "FLDCW std/24-bit mode\n\t" 11843 "POP EAX\n\t" 11844 "CMP EAX,0x80000000\n\t" 11845 "JNE,s fast\n\t" 11846 "FLD_D $src\n\t" 11847 "CALL d2i_wrapper\n" 11848 "fast:" %} 11849 ins_encode( Push_Reg_D(src), D2I_encoding(src) ); 11850 ins_pipe( pipe_slow ); 11851%} 11852 11853// Convert a double to an int. If the double is a NAN, stuff a zero in instead. 11854instruct convXD2I_reg_reg( eAXRegI dst, eDXRegI tmp, regXD src, eFlagsReg cr ) %{ 11855 predicate(UseSSE>=2); 11856 match(Set dst (ConvD2I src)); 11857 effect( KILL tmp, KILL cr ); 11858 format %{ "CVTTSD2SI $dst, $src\n\t" 11859 "CMP $dst,0x80000000\n\t" 11860 "JNE,s fast\n\t" 11861 "SUB ESP, 8\n\t" 11862 "MOVSD [ESP], $src\n\t" 11863 "FLD_D [ESP]\n\t" 11864 "ADD ESP, 8\n\t" 11865 "CALL d2i_wrapper\n" 11866 "fast:" %} 11867 opcode(0x1); // double-precision conversion 11868 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x2C), FX2I_encoding(src,dst)); 11869 ins_pipe( pipe_slow ); 11870%} 11871 11872instruct convD2L_reg_reg( eADXRegL dst, regD src, eFlagsReg cr ) %{ 11873 predicate(UseSSE<=1); 11874 match(Set dst (ConvD2L src)); 11875 effect( KILL cr ); 11876 format %{ "FLD $src\t# Convert double to long\n\t" 11877 "FLDCW trunc mode\n\t" 11878 "SUB ESP,8\n\t" 11879 "FISTp [ESP + #0]\n\t" 11880 "FLDCW std/24-bit mode\n\t" 11881 "POP EAX\n\t" 11882 "POP EDX\n\t" 11883 "CMP EDX,0x80000000\n\t" 11884 "JNE,s fast\n\t" 11885 "TEST EAX,EAX\n\t" 11886 "JNE,s fast\n\t" 11887 "FLD $src\n\t" 11888 "CALL d2l_wrapper\n" 11889 "fast:" %} 11890 ins_encode( Push_Reg_D(src), D2L_encoding(src) ); 11891 ins_pipe( pipe_slow ); 11892%} 11893 11894// XMM lacks a float/double->long conversion, so use the old FPU stack. 11895instruct convXD2L_reg_reg( eADXRegL dst, regXD src, eFlagsReg cr ) %{ 11896 predicate (UseSSE>=2); 11897 match(Set dst (ConvD2L src)); 11898 effect( KILL cr ); 11899 format %{ "SUB ESP,8\t# Convert double to long\n\t" 11900 "MOVSD [ESP],$src\n\t" 11901 "FLD_D [ESP]\n\t" 11902 "FLDCW trunc mode\n\t" 11903 "FISTp [ESP + #0]\n\t" 11904 "FLDCW std/24-bit mode\n\t" 11905 "POP EAX\n\t" 11906 "POP EDX\n\t" 11907 "CMP EDX,0x80000000\n\t" 11908 "JNE,s fast\n\t" 11909 "TEST EAX,EAX\n\t" 11910 "JNE,s fast\n\t" 11911 "SUB ESP,8\n\t" 11912 "MOVSD [ESP],$src\n\t" 11913 "FLD_D [ESP]\n\t" 11914 "CALL d2l_wrapper\n" 11915 "fast:" %} 11916 ins_encode( XD2L_encoding(src) ); 11917 ins_pipe( pipe_slow ); 11918%} 11919 11920// Convert a double to an int. Java semantics require we do complex 11921// manglations in the corner cases. So we set the rounding mode to 11922// 'zero', store the darned double down as an int, and reset the 11923// rounding mode to 'nearest'. The hardware stores a flag value down 11924// if we would overflow or converted a NAN; we check for this and 11925// and go the slow path if needed. 11926instruct convF2I_reg_reg(eAXRegI dst, eDXRegI tmp, regF src, eFlagsReg cr ) %{ 11927 predicate(UseSSE==0); 11928 match(Set dst (ConvF2I src)); 11929 effect( KILL tmp, KILL cr ); 11930 format %{ "FLD $src\t# Convert float to int \n\t" 11931 "FLDCW trunc mode\n\t" 11932 "SUB ESP,4\n\t" 11933 "FISTp [ESP + #0]\n\t" 11934 "FLDCW std/24-bit mode\n\t" 11935 "POP EAX\n\t" 11936 "CMP EAX,0x80000000\n\t" 11937 "JNE,s fast\n\t" 11938 "FLD $src\n\t" 11939 "CALL d2i_wrapper\n" 11940 "fast:" %} 11941 // D2I_encoding works for F2I 11942 ins_encode( Push_Reg_F(src), D2I_encoding(src) ); 11943 ins_pipe( pipe_slow ); 11944%} 11945 11946// Convert a float in xmm to an int reg. 11947instruct convX2I_reg(eAXRegI dst, eDXRegI tmp, regX src, eFlagsReg cr ) %{ 11948 predicate(UseSSE>=1); 11949 match(Set dst (ConvF2I src)); 11950 effect( KILL tmp, KILL cr ); 11951 format %{ "CVTTSS2SI $dst, $src\n\t" 11952 "CMP $dst,0x80000000\n\t" 11953 "JNE,s fast\n\t" 11954 "SUB ESP, 4\n\t" 11955 "MOVSS [ESP], $src\n\t" 11956 "FLD [ESP]\n\t" 11957 "ADD ESP, 4\n\t" 11958 "CALL d2i_wrapper\n" 11959 "fast:" %} 11960 opcode(0x0); // single-precision conversion 11961 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x2C), FX2I_encoding(src,dst)); 11962 ins_pipe( pipe_slow ); 11963%} 11964 11965instruct convF2L_reg_reg( eADXRegL dst, regF src, eFlagsReg cr ) %{ 11966 predicate(UseSSE==0); 11967 match(Set dst (ConvF2L src)); 11968 effect( KILL cr ); 11969 format %{ "FLD $src\t# Convert float to long\n\t" 11970 "FLDCW trunc mode\n\t" 11971 "SUB ESP,8\n\t" 11972 "FISTp [ESP + #0]\n\t" 11973 "FLDCW std/24-bit mode\n\t" 11974 "POP EAX\n\t" 11975 "POP EDX\n\t" 11976 "CMP EDX,0x80000000\n\t" 11977 "JNE,s fast\n\t" 11978 "TEST EAX,EAX\n\t" 11979 "JNE,s fast\n\t" 11980 "FLD $src\n\t" 11981 "CALL d2l_wrapper\n" 11982 "fast:" %} 11983 // D2L_encoding works for F2L 11984 ins_encode( Push_Reg_F(src), D2L_encoding(src) ); 11985 ins_pipe( pipe_slow ); 11986%} 11987 11988// XMM lacks a float/double->long conversion, so use the old FPU stack. 11989instruct convX2L_reg_reg( eADXRegL dst, regX src, eFlagsReg cr ) %{ 11990 predicate (UseSSE>=1); 11991 match(Set dst (ConvF2L src)); 11992 effect( KILL cr ); 11993 format %{ "SUB ESP,8\t# Convert float to long\n\t" 11994 "MOVSS [ESP],$src\n\t" 11995 "FLD_S [ESP]\n\t" 11996 "FLDCW trunc mode\n\t" 11997 "FISTp [ESP + #0]\n\t" 11998 "FLDCW std/24-bit mode\n\t" 11999 "POP EAX\n\t" 12000 "POP EDX\n\t" 12001 "CMP EDX,0x80000000\n\t" 12002 "JNE,s fast\n\t" 12003 "TEST EAX,EAX\n\t" 12004 "JNE,s fast\n\t" 12005 "SUB ESP,4\t# Convert float to long\n\t" 12006 "MOVSS [ESP],$src\n\t" 12007 "FLD_S [ESP]\n\t" 12008 "ADD ESP,4\n\t" 12009 "CALL d2l_wrapper\n" 12010 "fast:" %} 12011 ins_encode( X2L_encoding(src) ); 12012 ins_pipe( pipe_slow ); 12013%} 12014 12015instruct convI2D_reg(regD dst, stackSlotI src) %{ 12016 predicate( UseSSE<=1 ); 12017 match(Set dst (ConvI2D src)); 12018 format %{ "FILD $src\n\t" 12019 "FSTP $dst" %} 12020 opcode(0xDB, 0x0); /* DB /0 */ 12021 ins_encode(Push_Mem_I(src), Pop_Reg_D(dst)); 12022 ins_pipe( fpu_reg_mem ); 12023%} 12024 12025instruct convI2XD_reg(regXD dst, eRegI src) %{ 12026 predicate( UseSSE>=2 && !UseXmmI2D ); 12027 match(Set dst (ConvI2D src)); 12028 format %{ "CVTSI2SD $dst,$src" %} 12029 opcode(0xF2, 0x0F, 0x2A); 12030 ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src)); 12031 ins_pipe( pipe_slow ); 12032%} 12033 12034instruct convI2XD_mem(regXD dst, memory mem) %{ 12035 predicate( UseSSE>=2 ); 12036 match(Set dst (ConvI2D (LoadI mem))); 12037 format %{ "CVTSI2SD $dst,$mem" %} 12038 opcode(0xF2, 0x0F, 0x2A); 12039 ins_encode( OpcP, OpcS, Opcode(tertiary), RegMem(dst, mem)); 12040 ins_pipe( pipe_slow ); 12041%} 12042 12043instruct convXI2XD_reg(regXD dst, eRegI src) 12044%{ 12045 predicate( UseSSE>=2 && UseXmmI2D ); 12046 match(Set dst (ConvI2D src)); 12047 12048 format %{ "MOVD $dst,$src\n\t" 12049 "CVTDQ2PD $dst,$dst\t# i2d" %} 12050 ins_encode %{ 12051 __ movdl($dst$$XMMRegister, $src$$Register); 12052 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 12053 %} 12054 ins_pipe(pipe_slow); // XXX 12055%} 12056 12057instruct convI2D_mem(regD dst, memory mem) %{ 12058 predicate( UseSSE<=1 && !Compile::current()->select_24_bit_instr()); 12059 match(Set dst (ConvI2D (LoadI mem))); 12060 format %{ "FILD $mem\n\t" 12061 "FSTP $dst" %} 12062 opcode(0xDB); /* DB /0 */ 12063 ins_encode( OpcP, RMopc_Mem(0x00,mem), 12064 Pop_Reg_D(dst)); 12065 ins_pipe( fpu_reg_mem ); 12066%} 12067 12068// Convert a byte to a float; no rounding step needed. 12069instruct conv24I2F_reg(regF dst, stackSlotI src) %{ 12070 predicate( UseSSE==0 && n->in(1)->Opcode() == Op_AndI && n->in(1)->in(2)->is_Con() && n->in(1)->in(2)->get_int() == 255 ); 12071 match(Set dst (ConvI2F src)); 12072 format %{ "FILD $src\n\t" 12073 "FSTP $dst" %} 12074 12075 opcode(0xDB, 0x0); /* DB /0 */ 12076 ins_encode(Push_Mem_I(src), Pop_Reg_F(dst)); 12077 ins_pipe( fpu_reg_mem ); 12078%} 12079 12080// In 24-bit mode, force exponent rounding by storing back out 12081instruct convI2F_SSF(stackSlotF dst, stackSlotI src) %{ 12082 predicate( UseSSE==0 && Compile::current()->select_24_bit_instr()); 12083 match(Set dst (ConvI2F src)); 12084 ins_cost(200); 12085 format %{ "FILD $src\n\t" 12086 "FSTP_S $dst" %} 12087 opcode(0xDB, 0x0); /* DB /0 */ 12088 ins_encode( Push_Mem_I(src), 12089 Pop_Mem_F(dst)); 12090 ins_pipe( fpu_mem_mem ); 12091%} 12092 12093// In 24-bit mode, force exponent rounding by storing back out 12094instruct convI2F_SSF_mem(stackSlotF dst, memory mem) %{ 12095 predicate( UseSSE==0 && Compile::current()->select_24_bit_instr()); 12096 match(Set dst (ConvI2F (LoadI mem))); 12097 ins_cost(200); 12098 format %{ "FILD $mem\n\t" 12099 "FSTP_S $dst" %} 12100 opcode(0xDB); /* DB /0 */ 12101 ins_encode( OpcP, RMopc_Mem(0x00,mem), 12102 Pop_Mem_F(dst)); 12103 ins_pipe( fpu_mem_mem ); 12104%} 12105 12106// This instruction does not round to 24-bits 12107instruct convI2F_reg(regF dst, stackSlotI src) %{ 12108 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr()); 12109 match(Set dst (ConvI2F src)); 12110 format %{ "FILD $src\n\t" 12111 "FSTP $dst" %} 12112 opcode(0xDB, 0x0); /* DB /0 */ 12113 ins_encode( Push_Mem_I(src), 12114 Pop_Reg_F(dst)); 12115 ins_pipe( fpu_reg_mem ); 12116%} 12117 12118// This instruction does not round to 24-bits 12119instruct convI2F_mem(regF dst, memory mem) %{ 12120 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr()); 12121 match(Set dst (ConvI2F (LoadI mem))); 12122 format %{ "FILD $mem\n\t" 12123 "FSTP $dst" %} 12124 opcode(0xDB); /* DB /0 */ 12125 ins_encode( OpcP, RMopc_Mem(0x00,mem), 12126 Pop_Reg_F(dst)); 12127 ins_pipe( fpu_reg_mem ); 12128%} 12129 12130// Convert an int to a float in xmm; no rounding step needed. 12131instruct convI2X_reg(regX dst, eRegI src) %{ 12132 predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F ); 12133 match(Set dst (ConvI2F src)); 12134 format %{ "CVTSI2SS $dst, $src" %} 12135 12136 opcode(0xF3, 0x0F, 0x2A); /* F3 0F 2A /r */ 12137 ins_encode( OpcP, OpcS, Opcode(tertiary), RegReg(dst, src)); 12138 ins_pipe( pipe_slow ); 12139%} 12140 12141 instruct convXI2X_reg(regX dst, eRegI src) 12142%{ 12143 predicate( UseSSE>=2 && UseXmmI2F ); 12144 match(Set dst (ConvI2F src)); 12145 12146 format %{ "MOVD $dst,$src\n\t" 12147 "CVTDQ2PS $dst,$dst\t# i2f" %} 12148 ins_encode %{ 12149 __ movdl($dst$$XMMRegister, $src$$Register); 12150 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 12151 %} 12152 ins_pipe(pipe_slow); // XXX 12153%} 12154 12155instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{ 12156 match(Set dst (ConvI2L src)); 12157 effect(KILL cr); 12158 ins_cost(375); 12159 format %{ "MOV $dst.lo,$src\n\t" 12160 "MOV $dst.hi,$src\n\t" 12161 "SAR $dst.hi,31" %} 12162 ins_encode(convert_int_long(dst,src)); 12163 ins_pipe( ialu_reg_reg_long ); 12164%} 12165 12166// Zero-extend convert int to long 12167instruct convI2L_reg_zex(eRegL dst, eRegI src, immL_32bits mask, eFlagsReg flags ) %{ 12168 match(Set dst (AndL (ConvI2L src) mask) ); 12169 effect( KILL flags ); 12170 ins_cost(250); 12171 format %{ "MOV $dst.lo,$src\n\t" 12172 "XOR $dst.hi,$dst.hi" %} 12173 opcode(0x33); // XOR 12174 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) ); 12175 ins_pipe( ialu_reg_reg_long ); 12176%} 12177 12178// Zero-extend long 12179instruct zerox_long(eRegL dst, eRegL src, immL_32bits mask, eFlagsReg flags ) %{ 12180 match(Set dst (AndL src mask) ); 12181 effect( KILL flags ); 12182 ins_cost(250); 12183 format %{ "MOV $dst.lo,$src.lo\n\t" 12184 "XOR $dst.hi,$dst.hi\n\t" %} 12185 opcode(0x33); // XOR 12186 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) ); 12187 ins_pipe( ialu_reg_reg_long ); 12188%} 12189 12190instruct convL2D_reg( stackSlotD dst, eRegL src, eFlagsReg cr) %{ 12191 predicate (UseSSE<=1); 12192 match(Set dst (ConvL2D src)); 12193 effect( KILL cr ); 12194 format %{ "PUSH $src.hi\t# Convert long to double\n\t" 12195 "PUSH $src.lo\n\t" 12196 "FILD ST,[ESP + #0]\n\t" 12197 "ADD ESP,8\n\t" 12198 "FSTP_D $dst\t# D-round" %} 12199 opcode(0xDF, 0x5); /* DF /5 */ 12200 ins_encode(convert_long_double(src), Pop_Mem_D(dst)); 12201 ins_pipe( pipe_slow ); 12202%} 12203 12204instruct convL2XD_reg( regXD dst, eRegL src, eFlagsReg cr) %{ 12205 predicate (UseSSE>=2); 12206 match(Set dst (ConvL2D src)); 12207 effect( KILL cr ); 12208 format %{ "PUSH $src.hi\t# Convert long to double\n\t" 12209 "PUSH $src.lo\n\t" 12210 "FILD_D [ESP]\n\t" 12211 "FSTP_D [ESP]\n\t" 12212 "MOVSD $dst,[ESP]\n\t" 12213 "ADD ESP,8" %} 12214 opcode(0xDF, 0x5); /* DF /5 */ 12215 ins_encode(convert_long_double2(src), Push_ResultXD(dst)); 12216 ins_pipe( pipe_slow ); 12217%} 12218 12219instruct convL2X_reg( regX dst, eRegL src, eFlagsReg cr) %{ 12220 predicate (UseSSE>=1); 12221 match(Set dst (ConvL2F src)); 12222 effect( KILL cr ); 12223 format %{ "PUSH $src.hi\t# Convert long to single float\n\t" 12224 "PUSH $src.lo\n\t" 12225 "FILD_D [ESP]\n\t" 12226 "FSTP_S [ESP]\n\t" 12227 "MOVSS $dst,[ESP]\n\t" 12228 "ADD ESP,8" %} 12229 opcode(0xDF, 0x5); /* DF /5 */ 12230 ins_encode(convert_long_double2(src), Push_ResultX(dst,0x8)); 12231 ins_pipe( pipe_slow ); 12232%} 12233 12234instruct convL2F_reg( stackSlotF dst, eRegL src, eFlagsReg cr) %{ 12235 match(Set dst (ConvL2F src)); 12236 effect( KILL cr ); 12237 format %{ "PUSH $src.hi\t# Convert long to single float\n\t" 12238 "PUSH $src.lo\n\t" 12239 "FILD ST,[ESP + #0]\n\t" 12240 "ADD ESP,8\n\t" 12241 "FSTP_S $dst\t# F-round" %} 12242 opcode(0xDF, 0x5); /* DF /5 */ 12243 ins_encode(convert_long_double(src), Pop_Mem_F(dst)); 12244 ins_pipe( pipe_slow ); 12245%} 12246 12247instruct convL2I_reg( eRegI dst, eRegL src ) %{ 12248 match(Set dst (ConvL2I src)); 12249 effect( DEF dst, USE src ); 12250 format %{ "MOV $dst,$src.lo" %} 12251 ins_encode(enc_CopyL_Lo(dst,src)); 12252 ins_pipe( ialu_reg_reg ); 12253%} 12254 12255 12256instruct MoveF2I_stack_reg(eRegI dst, stackSlotF src) %{ 12257 match(Set dst (MoveF2I src)); 12258 effect( DEF dst, USE src ); 12259 ins_cost(100); 12260 format %{ "MOV $dst,$src\t# MoveF2I_stack_reg" %} 12261 opcode(0x8B); 12262 ins_encode( OpcP, RegMem(dst,src)); 12263 ins_pipe( ialu_reg_mem ); 12264%} 12265 12266instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 12267 predicate(UseSSE==0); 12268 match(Set dst (MoveF2I src)); 12269 effect( DEF dst, USE src ); 12270 12271 ins_cost(125); 12272 format %{ "FST_S $dst,$src\t# MoveF2I_reg_stack" %} 12273 ins_encode( Pop_Mem_Reg_F(dst, src) ); 12274 ins_pipe( fpu_mem_reg ); 12275%} 12276 12277instruct MoveF2I_reg_stack_sse(stackSlotI dst, regX src) %{ 12278 predicate(UseSSE>=1); 12279 match(Set dst (MoveF2I src)); 12280 effect( DEF dst, USE src ); 12281 12282 ins_cost(95); 12283 format %{ "MOVSS $dst,$src\t# MoveF2I_reg_stack_sse" %} 12284 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x11), RegMem(src, dst)); 12285 ins_pipe( pipe_slow ); 12286%} 12287 12288instruct MoveF2I_reg_reg_sse(eRegI dst, regX src) %{ 12289 predicate(UseSSE>=2); 12290 match(Set dst (MoveF2I src)); 12291 effect( DEF dst, USE src ); 12292 ins_cost(85); 12293 format %{ "MOVD $dst,$src\t# MoveF2I_reg_reg_sse" %} 12294 ins_encode( MovX2I_reg(dst, src)); 12295 ins_pipe( pipe_slow ); 12296%} 12297 12298instruct MoveI2F_reg_stack(stackSlotF dst, eRegI src) %{ 12299 match(Set dst (MoveI2F src)); 12300 effect( DEF dst, USE src ); 12301 12302 ins_cost(100); 12303 format %{ "MOV $dst,$src\t# MoveI2F_reg_stack" %} 12304 opcode(0x89); 12305 ins_encode( OpcPRegSS( dst, src ) ); 12306 ins_pipe( ialu_mem_reg ); 12307%} 12308 12309 12310instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 12311 predicate(UseSSE==0); 12312 match(Set dst (MoveI2F src)); 12313 effect(DEF dst, USE src); 12314 12315 ins_cost(125); 12316 format %{ "FLD_S $src\n\t" 12317 "FSTP $dst\t# MoveI2F_stack_reg" %} 12318 opcode(0xD9); /* D9 /0, FLD m32real */ 12319 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src), 12320 Pop_Reg_F(dst) ); 12321 ins_pipe( fpu_reg_mem ); 12322%} 12323 12324instruct MoveI2F_stack_reg_sse(regX dst, stackSlotI src) %{ 12325 predicate(UseSSE>=1); 12326 match(Set dst (MoveI2F src)); 12327 effect( DEF dst, USE src ); 12328 12329 ins_cost(95); 12330 format %{ "MOVSS $dst,$src\t# MoveI2F_stack_reg_sse" %} 12331 ins_encode( Opcode(0xF3), Opcode(0x0F), Opcode(0x10), RegMem(dst,src)); 12332 ins_pipe( pipe_slow ); 12333%} 12334 12335instruct MoveI2F_reg_reg_sse(regX dst, eRegI src) %{ 12336 predicate(UseSSE>=2); 12337 match(Set dst (MoveI2F src)); 12338 effect( DEF dst, USE src ); 12339 12340 ins_cost(85); 12341 format %{ "MOVD $dst,$src\t# MoveI2F_reg_reg_sse" %} 12342 ins_encode( MovI2X_reg(dst, src) ); 12343 ins_pipe( pipe_slow ); 12344%} 12345 12346instruct MoveD2L_stack_reg(eRegL dst, stackSlotD src) %{ 12347 match(Set dst (MoveD2L src)); 12348 effect(DEF dst, USE src); 12349 12350 ins_cost(250); 12351 format %{ "MOV $dst.lo,$src\n\t" 12352 "MOV $dst.hi,$src+4\t# MoveD2L_stack_reg" %} 12353 opcode(0x8B, 0x8B); 12354 ins_encode( OpcP, RegMem(dst,src), OpcS, RegMem_Hi(dst,src)); 12355 ins_pipe( ialu_mem_long_reg ); 12356%} 12357 12358instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 12359 predicate(UseSSE<=1); 12360 match(Set dst (MoveD2L src)); 12361 effect(DEF dst, USE src); 12362 12363 ins_cost(125); 12364 format %{ "FST_D $dst,$src\t# MoveD2L_reg_stack" %} 12365 ins_encode( Pop_Mem_Reg_D(dst, src) ); 12366 ins_pipe( fpu_mem_reg ); 12367%} 12368 12369instruct MoveD2L_reg_stack_sse(stackSlotL dst, regXD src) %{ 12370 predicate(UseSSE>=2); 12371 match(Set dst (MoveD2L src)); 12372 effect(DEF dst, USE src); 12373 ins_cost(95); 12374 12375 format %{ "MOVSD $dst,$src\t# MoveD2L_reg_stack_sse" %} 12376 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x11), RegMem(src,dst)); 12377 ins_pipe( pipe_slow ); 12378%} 12379 12380instruct MoveD2L_reg_reg_sse(eRegL dst, regXD src, regXD tmp) %{ 12381 predicate(UseSSE>=2); 12382 match(Set dst (MoveD2L src)); 12383 effect(DEF dst, USE src, TEMP tmp); 12384 ins_cost(85); 12385 format %{ "MOVD $dst.lo,$src\n\t" 12386 "PSHUFLW $tmp,$src,0x4E\n\t" 12387 "MOVD $dst.hi,$tmp\t# MoveD2L_reg_reg_sse" %} 12388 ins_encode( MovXD2L_reg(dst, src, tmp) ); 12389 ins_pipe( pipe_slow ); 12390%} 12391 12392instruct MoveL2D_reg_stack(stackSlotD dst, eRegL src) %{ 12393 match(Set dst (MoveL2D src)); 12394 effect(DEF dst, USE src); 12395 12396 ins_cost(200); 12397 format %{ "MOV $dst,$src.lo\n\t" 12398 "MOV $dst+4,$src.hi\t# MoveL2D_reg_stack" %} 12399 opcode(0x89, 0x89); 12400 ins_encode( OpcP, RegMem( src, dst ), OpcS, RegMem_Hi( src, dst ) ); 12401 ins_pipe( ialu_mem_long_reg ); 12402%} 12403 12404 12405instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 12406 predicate(UseSSE<=1); 12407 match(Set dst (MoveL2D src)); 12408 effect(DEF dst, USE src); 12409 ins_cost(125); 12410 12411 format %{ "FLD_D $src\n\t" 12412 "FSTP $dst\t# MoveL2D_stack_reg" %} 12413 opcode(0xDD); /* DD /0, FLD m64real */ 12414 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src), 12415 Pop_Reg_D(dst) ); 12416 ins_pipe( fpu_reg_mem ); 12417%} 12418 12419 12420instruct MoveL2D_stack_reg_sse(regXD dst, stackSlotL src) %{ 12421 predicate(UseSSE>=2 && UseXmmLoadAndClearUpper); 12422 match(Set dst (MoveL2D src)); 12423 effect(DEF dst, USE src); 12424 12425 ins_cost(95); 12426 format %{ "MOVSD $dst,$src\t# MoveL2D_stack_reg_sse" %} 12427 ins_encode( Opcode(0xF2), Opcode(0x0F), Opcode(0x10), RegMem(dst,src)); 12428 ins_pipe( pipe_slow ); 12429%} 12430 12431instruct MoveL2D_stack_reg_sse_partial(regXD dst, stackSlotL src) %{ 12432 predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper); 12433 match(Set dst (MoveL2D src)); 12434 effect(DEF dst, USE src); 12435 12436 ins_cost(95); 12437 format %{ "MOVLPD $dst,$src\t# MoveL2D_stack_reg_sse" %} 12438 ins_encode( Opcode(0x66), Opcode(0x0F), Opcode(0x12), RegMem(dst,src)); 12439 ins_pipe( pipe_slow ); 12440%} 12441 12442instruct MoveL2D_reg_reg_sse(regXD dst, eRegL src, regXD tmp) %{ 12443 predicate(UseSSE>=2); 12444 match(Set dst (MoveL2D src)); 12445 effect(TEMP dst, USE src, TEMP tmp); 12446 ins_cost(85); 12447 format %{ "MOVD $dst,$src.lo\n\t" 12448 "MOVD $tmp,$src.hi\n\t" 12449 "PUNPCKLDQ $dst,$tmp\t# MoveL2D_reg_reg_sse" %} 12450 ins_encode( MovL2XD_reg(dst, src, tmp) ); 12451 ins_pipe( pipe_slow ); 12452%} 12453 12454// Replicate scalar to packed byte (1 byte) values in xmm 12455instruct Repl8B_reg(regXD dst, regXD src) %{ 12456 predicate(UseSSE>=2); 12457 match(Set dst (Replicate8B src)); 12458 format %{ "MOVDQA $dst,$src\n\t" 12459 "PUNPCKLBW $dst,$dst\n\t" 12460 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 12461 ins_encode( pshufd_8x8(dst, src)); 12462 ins_pipe( pipe_slow ); 12463%} 12464 12465// Replicate scalar to packed byte (1 byte) values in xmm 12466instruct Repl8B_eRegI(regXD dst, eRegI src) %{ 12467 predicate(UseSSE>=2); 12468 match(Set dst (Replicate8B src)); 12469 format %{ "MOVD $dst,$src\n\t" 12470 "PUNPCKLBW $dst,$dst\n\t" 12471 "PSHUFLW $dst,$dst,0x00\t! replicate8B" %} 12472 ins_encode( mov_i2x(dst, src), pshufd_8x8(dst, dst)); 12473 ins_pipe( pipe_slow ); 12474%} 12475 12476// Replicate scalar zero to packed byte (1 byte) values in xmm 12477instruct Repl8B_immI0(regXD dst, immI0 zero) %{ 12478 predicate(UseSSE>=2); 12479 match(Set dst (Replicate8B zero)); 12480 format %{ "PXOR $dst,$dst\t! replicate8B" %} 12481 ins_encode( pxor(dst, dst)); 12482 ins_pipe( fpu_reg_reg ); 12483%} 12484 12485// Replicate scalar to packed shore (2 byte) values in xmm 12486instruct Repl4S_reg(regXD dst, regXD src) %{ 12487 predicate(UseSSE>=2); 12488 match(Set dst (Replicate4S src)); 12489 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %} 12490 ins_encode( pshufd_4x16(dst, src)); 12491 ins_pipe( fpu_reg_reg ); 12492%} 12493 12494// Replicate scalar to packed shore (2 byte) values in xmm 12495instruct Repl4S_eRegI(regXD dst, eRegI src) %{ 12496 predicate(UseSSE>=2); 12497 match(Set dst (Replicate4S src)); 12498 format %{ "MOVD $dst,$src\n\t" 12499 "PSHUFLW $dst,$dst,0x00\t! replicate4S" %} 12500 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst)); 12501 ins_pipe( fpu_reg_reg ); 12502%} 12503 12504// Replicate scalar zero to packed short (2 byte) values in xmm 12505instruct Repl4S_immI0(regXD dst, immI0 zero) %{ 12506 predicate(UseSSE>=2); 12507 match(Set dst (Replicate4S zero)); 12508 format %{ "PXOR $dst,$dst\t! replicate4S" %} 12509 ins_encode( pxor(dst, dst)); 12510 ins_pipe( fpu_reg_reg ); 12511%} 12512 12513// Replicate scalar to packed char (2 byte) values in xmm 12514instruct Repl4C_reg(regXD dst, regXD src) %{ 12515 predicate(UseSSE>=2); 12516 match(Set dst (Replicate4C src)); 12517 format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %} 12518 ins_encode( pshufd_4x16(dst, src)); 12519 ins_pipe( fpu_reg_reg ); 12520%} 12521 12522// Replicate scalar to packed char (2 byte) values in xmm 12523instruct Repl4C_eRegI(regXD dst, eRegI src) %{ 12524 predicate(UseSSE>=2); 12525 match(Set dst (Replicate4C src)); 12526 format %{ "MOVD $dst,$src\n\t" 12527 "PSHUFLW $dst,$dst,0x00\t! replicate4C" %} 12528 ins_encode( mov_i2x(dst, src), pshufd_4x16(dst, dst)); 12529 ins_pipe( fpu_reg_reg ); 12530%} 12531 12532// Replicate scalar zero to packed char (2 byte) values in xmm 12533instruct Repl4C_immI0(regXD dst, immI0 zero) %{ 12534 predicate(UseSSE>=2); 12535 match(Set dst (Replicate4C zero)); 12536 format %{ "PXOR $dst,$dst\t! replicate4C" %} 12537 ins_encode( pxor(dst, dst)); 12538 ins_pipe( fpu_reg_reg ); 12539%} 12540 12541// Replicate scalar to packed integer (4 byte) values in xmm 12542instruct Repl2I_reg(regXD dst, regXD src) %{ 12543 predicate(UseSSE>=2); 12544 match(Set dst (Replicate2I src)); 12545 format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %} 12546 ins_encode( pshufd(dst, src, 0x00)); 12547 ins_pipe( fpu_reg_reg ); 12548%} 12549 12550// Replicate scalar to packed integer (4 byte) values in xmm 12551instruct Repl2I_eRegI(regXD dst, eRegI src) %{ 12552 predicate(UseSSE>=2); 12553 match(Set dst (Replicate2I src)); 12554 format %{ "MOVD $dst,$src\n\t" 12555 "PSHUFD $dst,$dst,0x00\t! replicate2I" %} 12556 ins_encode( mov_i2x(dst, src), pshufd(dst, dst, 0x00)); 12557 ins_pipe( fpu_reg_reg ); 12558%} 12559 12560// Replicate scalar zero to packed integer (2 byte) values in xmm 12561instruct Repl2I_immI0(regXD dst, immI0 zero) %{ 12562 predicate(UseSSE>=2); 12563 match(Set dst (Replicate2I zero)); 12564 format %{ "PXOR $dst,$dst\t! replicate2I" %} 12565 ins_encode( pxor(dst, dst)); 12566 ins_pipe( fpu_reg_reg ); 12567%} 12568 12569// Replicate scalar to packed single precision floating point values in xmm 12570instruct Repl2F_reg(regXD dst, regXD src) %{ 12571 predicate(UseSSE>=2); 12572 match(Set dst (Replicate2F src)); 12573 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 12574 ins_encode( pshufd(dst, src, 0xe0)); 12575 ins_pipe( fpu_reg_reg ); 12576%} 12577 12578// Replicate scalar to packed single precision floating point values in xmm 12579instruct Repl2F_regX(regXD dst, regX src) %{ 12580 predicate(UseSSE>=2); 12581 match(Set dst (Replicate2F src)); 12582 format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %} 12583 ins_encode( pshufd(dst, src, 0xe0)); 12584 ins_pipe( fpu_reg_reg ); 12585%} 12586 12587// Replicate scalar to packed single precision floating point values in xmm 12588instruct Repl2F_immXF0(regXD dst, immXF0 zero) %{ 12589 predicate(UseSSE>=2); 12590 match(Set dst (Replicate2F zero)); 12591 format %{ "PXOR $dst,$dst\t! replicate2F" %} 12592 ins_encode( pxor(dst, dst)); 12593 ins_pipe( fpu_reg_reg ); 12594%} 12595 12596// ======================================================================= 12597// fast clearing of an array 12598instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ 12599 match(Set dummy (ClearArray cnt base)); 12600 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 12601 format %{ "SHL ECX,1\t# Convert doublewords to words\n\t" 12602 "XOR EAX,EAX\n\t" 12603 "REP STOS\t# store EAX into [EDI++] while ECX--" %} 12604 opcode(0,0x4); 12605 ins_encode( Opcode(0xD1), RegOpc(ECX), 12606 OpcRegReg(0x33,EAX,EAX), 12607 Opcode(0xF3), Opcode(0xAB) ); 12608 ins_pipe( pipe_slow ); 12609%} 12610 12611instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2, 12612 eAXRegI result, regXD tmp1, eFlagsReg cr) %{ 12613 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 12614 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 12615 12616 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 12617 ins_encode %{ 12618 __ string_compare($str1$$Register, $str2$$Register, 12619 $cnt1$$Register, $cnt2$$Register, $result$$Register, 12620 $tmp1$$XMMRegister); 12621 %} 12622 ins_pipe( pipe_slow ); 12623%} 12624 12625// fast string equals 12626instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result, 12627 regXD tmp1, regXD tmp2, eBXRegI tmp3, eFlagsReg cr) %{ 12628 match(Set result (StrEquals (Binary str1 str2) cnt)); 12629 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 12630 12631 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 12632 ins_encode %{ 12633 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 12634 $cnt$$Register, $result$$Register, $tmp3$$Register, 12635 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 12636 %} 12637 ins_pipe( pipe_slow ); 12638%} 12639 12640// fast search of substring with known size. 12641instruct string_indexof_con(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2, 12642 eBXRegI result, regXD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{ 12643 predicate(UseSSE42Intrinsics); 12644 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 12645 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 12646 12647 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 12648 ins_encode %{ 12649 int icnt2 = (int)$int_cnt2$$constant; 12650 if (icnt2 >= 8) { 12651 // IndexOf for constant substrings with size >= 8 elements 12652 // which don't need to be loaded through stack. 12653 __ string_indexofC8($str1$$Register, $str2$$Register, 12654 $cnt1$$Register, $cnt2$$Register, 12655 icnt2, $result$$Register, 12656 $vec$$XMMRegister, $tmp$$Register); 12657 } else { 12658 // Small strings are loaded through stack if they cross page boundary. 12659 __ string_indexof($str1$$Register, $str2$$Register, 12660 $cnt1$$Register, $cnt2$$Register, 12661 icnt2, $result$$Register, 12662 $vec$$XMMRegister, $tmp$$Register); 12663 } 12664 %} 12665 ins_pipe( pipe_slow ); 12666%} 12667 12668instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2, 12669 eBXRegI result, regXD vec, eCXRegI tmp, eFlagsReg cr) %{ 12670 predicate(UseSSE42Intrinsics); 12671 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 12672 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 12673 12674 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 12675 ins_encode %{ 12676 __ string_indexof($str1$$Register, $str2$$Register, 12677 $cnt1$$Register, $cnt2$$Register, 12678 (-1), $result$$Register, 12679 $vec$$XMMRegister, $tmp$$Register); 12680 %} 12681 ins_pipe( pipe_slow ); 12682%} 12683 12684// fast array equals 12685instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result, 12686 regXD tmp1, regXD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr) 12687%{ 12688 match(Set result (AryEq ary1 ary2)); 12689 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 12690 //ins_cost(300); 12691 12692 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 12693 ins_encode %{ 12694 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 12695 $tmp3$$Register, $result$$Register, $tmp4$$Register, 12696 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 12697 %} 12698 ins_pipe( pipe_slow ); 12699%} 12700 12701//----------Control Flow Instructions------------------------------------------ 12702// Signed compare Instructions 12703instruct compI_eReg(eFlagsReg cr, eRegI op1, eRegI op2) %{ 12704 match(Set cr (CmpI op1 op2)); 12705 effect( DEF cr, USE op1, USE op2 ); 12706 format %{ "CMP $op1,$op2" %} 12707 opcode(0x3B); /* Opcode 3B /r */ 12708 ins_encode( OpcP, RegReg( op1, op2) ); 12709 ins_pipe( ialu_cr_reg_reg ); 12710%} 12711 12712instruct compI_eReg_imm(eFlagsReg cr, eRegI op1, immI op2) %{ 12713 match(Set cr (CmpI op1 op2)); 12714 effect( DEF cr, USE op1 ); 12715 format %{ "CMP $op1,$op2" %} 12716 opcode(0x81,0x07); /* Opcode 81 /7 */ 12717 // ins_encode( RegImm( op1, op2) ); /* Was CmpImm */ 12718 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) ); 12719 ins_pipe( ialu_cr_reg_imm ); 12720%} 12721 12722// Cisc-spilled version of cmpI_eReg 12723instruct compI_eReg_mem(eFlagsReg cr, eRegI op1, memory op2) %{ 12724 match(Set cr (CmpI op1 (LoadI op2))); 12725 12726 format %{ "CMP $op1,$op2" %} 12727 ins_cost(500); 12728 opcode(0x3B); /* Opcode 3B /r */ 12729 ins_encode( OpcP, RegMem( op1, op2) ); 12730 ins_pipe( ialu_cr_reg_mem ); 12731%} 12732 12733instruct testI_reg( eFlagsReg cr, eRegI src, immI0 zero ) %{ 12734 match(Set cr (CmpI src zero)); 12735 effect( DEF cr, USE src ); 12736 12737 format %{ "TEST $src,$src" %} 12738 opcode(0x85); 12739 ins_encode( OpcP, RegReg( src, src ) ); 12740 ins_pipe( ialu_cr_reg_imm ); 12741%} 12742 12743instruct testI_reg_imm( eFlagsReg cr, eRegI src, immI con, immI0 zero ) %{ 12744 match(Set cr (CmpI (AndI src con) zero)); 12745 12746 format %{ "TEST $src,$con" %} 12747 opcode(0xF7,0x00); 12748 ins_encode( OpcP, RegOpc(src), Con32(con) ); 12749 ins_pipe( ialu_cr_reg_imm ); 12750%} 12751 12752instruct testI_reg_mem( eFlagsReg cr, eRegI src, memory mem, immI0 zero ) %{ 12753 match(Set cr (CmpI (AndI src mem) zero)); 12754 12755 format %{ "TEST $src,$mem" %} 12756 opcode(0x85); 12757 ins_encode( OpcP, RegMem( src, mem ) ); 12758 ins_pipe( ialu_cr_reg_mem ); 12759%} 12760 12761// Unsigned compare Instructions; really, same as signed except they 12762// produce an eFlagsRegU instead of eFlagsReg. 12763instruct compU_eReg(eFlagsRegU cr, eRegI op1, eRegI op2) %{ 12764 match(Set cr (CmpU op1 op2)); 12765 12766 format %{ "CMPu $op1,$op2" %} 12767 opcode(0x3B); /* Opcode 3B /r */ 12768 ins_encode( OpcP, RegReg( op1, op2) ); 12769 ins_pipe( ialu_cr_reg_reg ); 12770%} 12771 12772instruct compU_eReg_imm(eFlagsRegU cr, eRegI op1, immI op2) %{ 12773 match(Set cr (CmpU op1 op2)); 12774 12775 format %{ "CMPu $op1,$op2" %} 12776 opcode(0x81,0x07); /* Opcode 81 /7 */ 12777 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) ); 12778 ins_pipe( ialu_cr_reg_imm ); 12779%} 12780 12781// // Cisc-spilled version of cmpU_eReg 12782instruct compU_eReg_mem(eFlagsRegU cr, eRegI op1, memory op2) %{ 12783 match(Set cr (CmpU op1 (LoadI op2))); 12784 12785 format %{ "CMPu $op1,$op2" %} 12786 ins_cost(500); 12787 opcode(0x3B); /* Opcode 3B /r */ 12788 ins_encode( OpcP, RegMem( op1, op2) ); 12789 ins_pipe( ialu_cr_reg_mem ); 12790%} 12791 12792// // Cisc-spilled version of cmpU_eReg 12793//instruct compU_mem_eReg(eFlagsRegU cr, memory op1, eRegI op2) %{ 12794// match(Set cr (CmpU (LoadI op1) op2)); 12795// 12796// format %{ "CMPu $op1,$op2" %} 12797// ins_cost(500); 12798// opcode(0x39); /* Opcode 39 /r */ 12799// ins_encode( OpcP, RegMem( op1, op2) ); 12800//%} 12801 12802instruct testU_reg( eFlagsRegU cr, eRegI src, immI0 zero ) %{ 12803 match(Set cr (CmpU src zero)); 12804 12805 format %{ "TESTu $src,$src" %} 12806 opcode(0x85); 12807 ins_encode( OpcP, RegReg( src, src ) ); 12808 ins_pipe( ialu_cr_reg_imm ); 12809%} 12810 12811// Unsigned pointer compare Instructions 12812instruct compP_eReg(eFlagsRegU cr, eRegP op1, eRegP op2) %{ 12813 match(Set cr (CmpP op1 op2)); 12814 12815 format %{ "CMPu $op1,$op2" %} 12816 opcode(0x3B); /* Opcode 3B /r */ 12817 ins_encode( OpcP, RegReg( op1, op2) ); 12818 ins_pipe( ialu_cr_reg_reg ); 12819%} 12820 12821instruct compP_eReg_imm(eFlagsRegU cr, eRegP op1, immP op2) %{ 12822 match(Set cr (CmpP op1 op2)); 12823 12824 format %{ "CMPu $op1,$op2" %} 12825 opcode(0x81,0x07); /* Opcode 81 /7 */ 12826 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) ); 12827 ins_pipe( ialu_cr_reg_imm ); 12828%} 12829 12830// // Cisc-spilled version of cmpP_eReg 12831instruct compP_eReg_mem(eFlagsRegU cr, eRegP op1, memory op2) %{ 12832 match(Set cr (CmpP op1 (LoadP op2))); 12833 12834 format %{ "CMPu $op1,$op2" %} 12835 ins_cost(500); 12836 opcode(0x3B); /* Opcode 3B /r */ 12837 ins_encode( OpcP, RegMem( op1, op2) ); 12838 ins_pipe( ialu_cr_reg_mem ); 12839%} 12840 12841// // Cisc-spilled version of cmpP_eReg 12842//instruct compP_mem_eReg(eFlagsRegU cr, memory op1, eRegP op2) %{ 12843// match(Set cr (CmpP (LoadP op1) op2)); 12844// 12845// format %{ "CMPu $op1,$op2" %} 12846// ins_cost(500); 12847// opcode(0x39); /* Opcode 39 /r */ 12848// ins_encode( OpcP, RegMem( op1, op2) ); 12849//%} 12850 12851// Compare raw pointer (used in out-of-heap check). 12852// Only works because non-oop pointers must be raw pointers 12853// and raw pointers have no anti-dependencies. 12854instruct compP_mem_eReg( eFlagsRegU cr, eRegP op1, memory op2 ) %{ 12855 predicate( !n->in(2)->in(2)->bottom_type()->isa_oop_ptr() ); 12856 match(Set cr (CmpP op1 (LoadP op2))); 12857 12858 format %{ "CMPu $op1,$op2" %} 12859 opcode(0x3B); /* Opcode 3B /r */ 12860 ins_encode( OpcP, RegMem( op1, op2) ); 12861 ins_pipe( ialu_cr_reg_mem ); 12862%} 12863 12864// 12865// This will generate a signed flags result. This should be ok 12866// since any compare to a zero should be eq/neq. 12867instruct testP_reg( eFlagsReg cr, eRegP src, immP0 zero ) %{ 12868 match(Set cr (CmpP src zero)); 12869 12870 format %{ "TEST $src,$src" %} 12871 opcode(0x85); 12872 ins_encode( OpcP, RegReg( src, src ) ); 12873 ins_pipe( ialu_cr_reg_imm ); 12874%} 12875 12876// Cisc-spilled version of testP_reg 12877// This will generate a signed flags result. This should be ok 12878// since any compare to a zero should be eq/neq. 12879instruct testP_Reg_mem( eFlagsReg cr, memory op, immI0 zero ) %{ 12880 match(Set cr (CmpP (LoadP op) zero)); 12881 12882 format %{ "TEST $op,0xFFFFFFFF" %} 12883 ins_cost(500); 12884 opcode(0xF7); /* Opcode F7 /0 */ 12885 ins_encode( OpcP, RMopc_Mem(0x00,op), Con_d32(0xFFFFFFFF) ); 12886 ins_pipe( ialu_cr_reg_imm ); 12887%} 12888 12889// Yanked all unsigned pointer compare operations. 12890// Pointer compares are done with CmpP which is already unsigned. 12891 12892//----------Max and Min-------------------------------------------------------- 12893// Min Instructions 12894//// 12895// *** Min and Max using the conditional move are slower than the 12896// *** branch version on a Pentium III. 12897// // Conditional move for min 12898//instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{ 12899// effect( USE_DEF op2, USE op1, USE cr ); 12900// format %{ "CMOVlt $op2,$op1\t! min" %} 12901// opcode(0x4C,0x0F); 12902// ins_encode( OpcS, OpcP, RegReg( op2, op1 ) ); 12903// ins_pipe( pipe_cmov_reg ); 12904//%} 12905// 12906//// Min Register with Register (P6 version) 12907//instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{ 12908// predicate(VM_Version::supports_cmov() ); 12909// match(Set op2 (MinI op1 op2)); 12910// ins_cost(200); 12911// expand %{ 12912// eFlagsReg cr; 12913// compI_eReg(cr,op1,op2); 12914// cmovI_reg_lt(op2,op1,cr); 12915// %} 12916//%} 12917 12918// Min Register with Register (generic version) 12919instruct minI_eReg(eRegI dst, eRegI src, eFlagsReg flags) %{ 12920 match(Set dst (MinI dst src)); 12921 effect(KILL flags); 12922 ins_cost(300); 12923 12924 format %{ "MIN $dst,$src" %} 12925 opcode(0xCC); 12926 ins_encode( min_enc(dst,src) ); 12927 ins_pipe( pipe_slow ); 12928%} 12929 12930// Max Register with Register 12931// *** Min and Max using the conditional move are slower than the 12932// *** branch version on a Pentium III. 12933// // Conditional move for max 12934//instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{ 12935// effect( USE_DEF op2, USE op1, USE cr ); 12936// format %{ "CMOVgt $op2,$op1\t! max" %} 12937// opcode(0x4F,0x0F); 12938// ins_encode( OpcS, OpcP, RegReg( op2, op1 ) ); 12939// ins_pipe( pipe_cmov_reg ); 12940//%} 12941// 12942// // Max Register with Register (P6 version) 12943//instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{ 12944// predicate(VM_Version::supports_cmov() ); 12945// match(Set op2 (MaxI op1 op2)); 12946// ins_cost(200); 12947// expand %{ 12948// eFlagsReg cr; 12949// compI_eReg(cr,op1,op2); 12950// cmovI_reg_gt(op2,op1,cr); 12951// %} 12952//%} 12953 12954// Max Register with Register (generic version) 12955instruct maxI_eReg(eRegI dst, eRegI src, eFlagsReg flags) %{ 12956 match(Set dst (MaxI dst src)); 12957 effect(KILL flags); 12958 ins_cost(300); 12959 12960 format %{ "MAX $dst,$src" %} 12961 opcode(0xCC); 12962 ins_encode( max_enc(dst,src) ); 12963 ins_pipe( pipe_slow ); 12964%} 12965 12966// ============================================================================ 12967// Counted Loop limit node which represents exact final iterator value. 12968// Note: the resulting value should fit into integer range since 12969// counted loops have limit check on overflow. 12970instruct loopLimit_eReg(eAXRegI limit, nadxRegI init, immI stride, eDXRegI limit_hi, nadxRegI tmp, eFlagsReg flags) %{ 12971 match(Set limit (LoopLimit (Binary init limit) stride)); 12972 effect(TEMP limit_hi, TEMP tmp, KILL flags); 12973 ins_cost(300); 12974 12975 format %{ "loopLimit $init,$limit,$stride # $limit = $init + $stride *( $limit - $init + $stride -1)/ $stride, kills $limit_hi" %} 12976 ins_encode %{ 12977 int strd = (int)$stride$$constant; 12978 assert(strd != 1 && strd != -1, "sanity"); 12979 int m1 = (strd > 0) ? 1 : -1; 12980 // Convert limit to long (EAX:EDX) 12981 __ cdql(); 12982 // Convert init to long (init:tmp) 12983 __ movl($tmp$$Register, $init$$Register); 12984 __ sarl($tmp$$Register, 31); 12985 // $limit - $init 12986 __ subl($limit$$Register, $init$$Register); 12987 __ sbbl($limit_hi$$Register, $tmp$$Register); 12988 // + ($stride - 1) 12989 if (strd > 0) { 12990 __ addl($limit$$Register, (strd - 1)); 12991 __ adcl($limit_hi$$Register, 0); 12992 __ movl($tmp$$Register, strd); 12993 } else { 12994 __ addl($limit$$Register, (strd + 1)); 12995 __ adcl($limit_hi$$Register, -1); 12996 __ lneg($limit_hi$$Register, $limit$$Register); 12997 __ movl($tmp$$Register, -strd); 12998 } 12999 // signed devision: (EAX:EDX) / pos_stride 13000 __ idivl($tmp$$Register); 13001 if (strd < 0) { 13002 // restore sign 13003 __ negl($tmp$$Register); 13004 } 13005 // (EAX) * stride 13006 __ mull($tmp$$Register); 13007 // + init (ignore upper bits) 13008 __ addl($limit$$Register, $init$$Register); 13009 %} 13010 ins_pipe( pipe_slow ); 13011%} 13012 13013// ============================================================================ 13014// Branch Instructions 13015// Jump Table 13016instruct jumpXtnd(eRegI switch_val) %{ 13017 match(Jump switch_val); 13018 ins_cost(350); 13019 format %{ "JMP [$constantaddress](,$switch_val,1)\n\t" %} 13020 ins_encode %{ 13021 // Jump to Address(table_base + switch_reg) 13022 Address index(noreg, $switch_val$$Register, Address::times_1); 13023 __ jump(ArrayAddress($constantaddress, index)); 13024 %} 13025 ins_pipe(pipe_jmp); 13026%} 13027 13028// Jump Direct - Label defines a relative address from JMP+1 13029instruct jmpDir(label labl) %{ 13030 match(Goto); 13031 effect(USE labl); 13032 13033 ins_cost(300); 13034 format %{ "JMP $labl" %} 13035 size(5); 13036 ins_encode %{ 13037 Label* L = $labl$$label; 13038 __ jmp(*L, false); // Always long jump 13039 %} 13040 ins_pipe( pipe_jmp ); 13041%} 13042 13043// Jump Direct Conditional - Label defines a relative address from Jcc+1 13044instruct jmpCon(cmpOp cop, eFlagsReg cr, label labl) %{ 13045 match(If cop cr); 13046 effect(USE labl); 13047 13048 ins_cost(300); 13049 format %{ "J$cop $labl" %} 13050 size(6); 13051 ins_encode %{ 13052 Label* L = $labl$$label; 13053 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13054 %} 13055 ins_pipe( pipe_jcc ); 13056%} 13057 13058// Jump Direct Conditional - Label defines a relative address from Jcc+1 13059instruct jmpLoopEnd(cmpOp cop, eFlagsReg cr, label labl) %{ 13060 match(CountedLoopEnd cop cr); 13061 effect(USE labl); 13062 13063 ins_cost(300); 13064 format %{ "J$cop $labl\t# Loop end" %} 13065 size(6); 13066 ins_encode %{ 13067 Label* L = $labl$$label; 13068 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13069 %} 13070 ins_pipe( pipe_jcc ); 13071%} 13072 13073// Jump Direct Conditional - Label defines a relative address from Jcc+1 13074instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 13075 match(CountedLoopEnd cop cmp); 13076 effect(USE labl); 13077 13078 ins_cost(300); 13079 format %{ "J$cop,u $labl\t# Loop end" %} 13080 size(6); 13081 ins_encode %{ 13082 Label* L = $labl$$label; 13083 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13084 %} 13085 ins_pipe( pipe_jcc ); 13086%} 13087 13088instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 13089 match(CountedLoopEnd cop cmp); 13090 effect(USE labl); 13091 13092 ins_cost(200); 13093 format %{ "J$cop,u $labl\t# Loop end" %} 13094 size(6); 13095 ins_encode %{ 13096 Label* L = $labl$$label; 13097 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13098 %} 13099 ins_pipe( pipe_jcc ); 13100%} 13101 13102// Jump Direct Conditional - using unsigned comparison 13103instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 13104 match(If cop cmp); 13105 effect(USE labl); 13106 13107 ins_cost(300); 13108 format %{ "J$cop,u $labl" %} 13109 size(6); 13110 ins_encode %{ 13111 Label* L = $labl$$label; 13112 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13113 %} 13114 ins_pipe(pipe_jcc); 13115%} 13116 13117instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 13118 match(If cop cmp); 13119 effect(USE labl); 13120 13121 ins_cost(200); 13122 format %{ "J$cop,u $labl" %} 13123 size(6); 13124 ins_encode %{ 13125 Label* L = $labl$$label; 13126 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 13127 %} 13128 ins_pipe(pipe_jcc); 13129%} 13130 13131instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{ 13132 match(If cop cmp); 13133 effect(USE labl); 13134 13135 ins_cost(200); 13136 format %{ $$template 13137 if ($cop$$cmpcode == Assembler::notEqual) { 13138 $$emit$$"JP,u $labl\n\t" 13139 $$emit$$"J$cop,u $labl" 13140 } else { 13141 $$emit$$"JP,u done\n\t" 13142 $$emit$$"J$cop,u $labl\n\t" 13143 $$emit$$"done:" 13144 } 13145 %} 13146 ins_encode %{ 13147 Label* l = $labl$$label; 13148 if ($cop$$cmpcode == Assembler::notEqual) { 13149 __ jcc(Assembler::parity, *l, false); 13150 __ jcc(Assembler::notEqual, *l, false); 13151 } else if ($cop$$cmpcode == Assembler::equal) { 13152 Label done; 13153 __ jccb(Assembler::parity, done); 13154 __ jcc(Assembler::equal, *l, false); 13155 __ bind(done); 13156 } else { 13157 ShouldNotReachHere(); 13158 } 13159 %} 13160 ins_pipe(pipe_jcc); 13161%} 13162 13163// ============================================================================ 13164// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 13165// array for an instance of the superklass. Set a hidden internal cache on a 13166// hit (cache is checked with exposed code in gen_subtype_check()). Return 13167// NZ for a miss or zero for a hit. The encoding ALSO sets flags. 13168instruct partialSubtypeCheck( eDIRegP result, eSIRegP sub, eAXRegP super, eCXRegI rcx, eFlagsReg cr ) %{ 13169 match(Set result (PartialSubtypeCheck sub super)); 13170 effect( KILL rcx, KILL cr ); 13171 13172 ins_cost(1100); // slightly larger than the next version 13173 format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t" 13174 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t" 13175 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" 13176 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" 13177 "JNE,s miss\t\t# Missed: EDI not-zero\n\t" 13178 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache\n\t" 13179 "XOR $result,$result\t\t Hit: EDI zero\n\t" 13180 "miss:\t" %} 13181 13182 opcode(0x1); // Force a XOR of EDI 13183 ins_encode( enc_PartialSubtypeCheck() ); 13184 ins_pipe( pipe_slow ); 13185%} 13186 13187instruct partialSubtypeCheck_vs_Zero( eFlagsReg cr, eSIRegP sub, eAXRegP super, eCXRegI rcx, eDIRegP result, immP0 zero ) %{ 13188 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 13189 effect( KILL rcx, KILL result ); 13190 13191 ins_cost(1000); 13192 format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t" 13193 "MOV ECX,[EDI+arrayKlass::length]\t# length to scan\n\t" 13194 "ADD EDI,arrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" 13195 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" 13196 "JNE,s miss\t\t# Missed: flags NZ\n\t" 13197 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache, flags Z\n\t" 13198 "miss:\t" %} 13199 13200 opcode(0x0); // No need to XOR EDI 13201 ins_encode( enc_PartialSubtypeCheck() ); 13202 ins_pipe( pipe_slow ); 13203%} 13204 13205// ============================================================================ 13206// Branch Instructions -- short offset versions 13207// 13208// These instructions are used to replace jumps of a long offset (the default 13209// match) with jumps of a shorter offset. These instructions are all tagged 13210// with the ins_short_branch attribute, which causes the ADLC to suppress the 13211// match rules in general matching. Instead, the ADLC generates a conversion 13212// method in the MachNode which can be used to do in-place replacement of the 13213// long variant with the shorter variant. The compiler will determine if a 13214// branch can be taken by the is_short_branch_offset() predicate in the machine 13215// specific code section of the file. 13216 13217// Jump Direct - Label defines a relative address from JMP+1 13218instruct jmpDir_short(label labl) %{ 13219 match(Goto); 13220 effect(USE labl); 13221 13222 ins_cost(300); 13223 format %{ "JMP,s $labl" %} 13224 size(2); 13225 ins_encode %{ 13226 Label* L = $labl$$label; 13227 __ jmpb(*L); 13228 %} 13229 ins_pipe( pipe_jmp ); 13230 ins_short_branch(1); 13231%} 13232 13233// Jump Direct Conditional - Label defines a relative address from Jcc+1 13234instruct jmpCon_short(cmpOp cop, eFlagsReg cr, label labl) %{ 13235 match(If cop cr); 13236 effect(USE labl); 13237 13238 ins_cost(300); 13239 format %{ "J$cop,s $labl" %} 13240 size(2); 13241 ins_encode %{ 13242 Label* L = $labl$$label; 13243 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 13244 %} 13245 ins_pipe( pipe_jcc ); 13246 ins_short_branch(1); 13247%} 13248 13249// Jump Direct Conditional - Label defines a relative address from Jcc+1 13250instruct jmpLoopEnd_short(cmpOp cop, eFlagsReg cr, label labl) %{ 13251 match(CountedLoopEnd cop cr); 13252 effect(USE labl); 13253 13254 ins_cost(300); 13255 format %{ "J$cop,s $labl\t# Loop end" %} 13256 size(2); 13257 ins_encode %{ 13258 Label* L = $labl$$label; 13259 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 13260 %} 13261 ins_pipe( pipe_jcc ); 13262 ins_short_branch(1); 13263%} 13264 13265// Jump Direct Conditional - Label defines a relative address from Jcc+1 13266instruct jmpLoopEndU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 13267 match(CountedLoopEnd cop cmp); 13268 effect(USE labl); 13269 13270 ins_cost(300); 13271 format %{ "J$cop,us $labl\t# Loop end" %} 13272 size(2); 13273 ins_encode %{ 13274 Label* L = $labl$$label; 13275 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 13276 %} 13277 ins_pipe( pipe_jcc ); 13278 ins_short_branch(1); 13279%} 13280 13281instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 13282 match(CountedLoopEnd cop cmp); 13283 effect(USE labl); 13284 13285 ins_cost(300); 13286 format %{ "J$cop,us $labl\t# Loop end" %} 13287 size(2); 13288 ins_encode %{ 13289 Label* L = $labl$$label; 13290 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 13291 %} 13292 ins_pipe( pipe_jcc ); 13293 ins_short_branch(1); 13294%} 13295 13296// Jump Direct Conditional - using unsigned comparison 13297instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 13298 match(If cop cmp); 13299 effect(USE labl); 13300 13301 ins_cost(300); 13302 format %{ "J$cop,us $labl" %} 13303 size(2); 13304 ins_encode %{ 13305 Label* L = $labl$$label; 13306 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 13307 %} 13308 ins_pipe( pipe_jcc ); 13309 ins_short_branch(1); 13310%} 13311 13312instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 13313 match(If cop cmp); 13314 effect(USE labl); 13315 13316 ins_cost(300); 13317 format %{ "J$cop,us $labl" %} 13318 size(2); 13319 ins_encode %{ 13320 Label* L = $labl$$label; 13321 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 13322 %} 13323 ins_pipe( pipe_jcc ); 13324 ins_short_branch(1); 13325%} 13326 13327instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{ 13328 match(If cop cmp); 13329 effect(USE labl); 13330 13331 ins_cost(300); 13332 format %{ $$template 13333 if ($cop$$cmpcode == Assembler::notEqual) { 13334 $$emit$$"JP,u,s $labl\n\t" 13335 $$emit$$"J$cop,u,s $labl" 13336 } else { 13337 $$emit$$"JP,u,s done\n\t" 13338 $$emit$$"J$cop,u,s $labl\n\t" 13339 $$emit$$"done:" 13340 } 13341 %} 13342 size(4); 13343 ins_encode %{ 13344 Label* l = $labl$$label; 13345 if ($cop$$cmpcode == Assembler::notEqual) { 13346 __ jccb(Assembler::parity, *l); 13347 __ jccb(Assembler::notEqual, *l); 13348 } else if ($cop$$cmpcode == Assembler::equal) { 13349 Label done; 13350 __ jccb(Assembler::parity, done); 13351 __ jccb(Assembler::equal, *l); 13352 __ bind(done); 13353 } else { 13354 ShouldNotReachHere(); 13355 } 13356 %} 13357 ins_pipe(pipe_jcc); 13358 ins_short_branch(1); 13359%} 13360 13361// ============================================================================ 13362// Long Compare 13363// 13364// Currently we hold longs in 2 registers. Comparing such values efficiently 13365// is tricky. The flavor of compare used depends on whether we are testing 13366// for LT, LE, or EQ. For a simple LT test we can check just the sign bit. 13367// The GE test is the negated LT test. The LE test can be had by commuting 13368// the operands (yielding a GE test) and then negating; negate again for the 13369// GT test. The EQ test is done by ORcc'ing the high and low halves, and the 13370// NE test is negated from that. 13371 13372// Due to a shortcoming in the ADLC, it mixes up expressions like: 13373// (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)). Note the 13374// difference between 'Y' and '0L'. The tree-matches for the CmpI sections 13375// are collapsed internally in the ADLC's dfa-gen code. The match for 13376// (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the 13377// foo match ends up with the wrong leaf. One fix is to not match both 13378// reg-reg and reg-zero forms of long-compare. This is unfortunate because 13379// both forms beat the trinary form of long-compare and both are very useful 13380// on Intel which has so few registers. 13381 13382// Manifest a CmpL result in an integer register. Very painful. 13383// This is the test to avoid. 13384instruct cmpL3_reg_reg(eSIRegI dst, eRegL src1, eRegL src2, eFlagsReg flags ) %{ 13385 match(Set dst (CmpL3 src1 src2)); 13386 effect( KILL flags ); 13387 ins_cost(1000); 13388 format %{ "XOR $dst,$dst\n\t" 13389 "CMP $src1.hi,$src2.hi\n\t" 13390 "JLT,s m_one\n\t" 13391 "JGT,s p_one\n\t" 13392 "CMP $src1.lo,$src2.lo\n\t" 13393 "JB,s m_one\n\t" 13394 "JEQ,s done\n" 13395 "p_one:\tINC $dst\n\t" 13396 "JMP,s done\n" 13397 "m_one:\tDEC $dst\n" 13398 "done:" %} 13399 ins_encode %{ 13400 Label p_one, m_one, done; 13401 __ xorptr($dst$$Register, $dst$$Register); 13402 __ cmpl(HIGH_FROM_LOW($src1$$Register), HIGH_FROM_LOW($src2$$Register)); 13403 __ jccb(Assembler::less, m_one); 13404 __ jccb(Assembler::greater, p_one); 13405 __ cmpl($src1$$Register, $src2$$Register); 13406 __ jccb(Assembler::below, m_one); 13407 __ jccb(Assembler::equal, done); 13408 __ bind(p_one); 13409 __ incrementl($dst$$Register); 13410 __ jmpb(done); 13411 __ bind(m_one); 13412 __ decrementl($dst$$Register); 13413 __ bind(done); 13414 %} 13415 ins_pipe( pipe_slow ); 13416%} 13417 13418//====== 13419// Manifest a CmpL result in the normal flags. Only good for LT or GE 13420// compares. Can be used for LE or GT compares by reversing arguments. 13421// NOT GOOD FOR EQ/NE tests. 13422instruct cmpL_zero_flags_LTGE( flagsReg_long_LTGE flags, eRegL src, immL0 zero ) %{ 13423 match( Set flags (CmpL src zero )); 13424 ins_cost(100); 13425 format %{ "TEST $src.hi,$src.hi" %} 13426 opcode(0x85); 13427 ins_encode( OpcP, RegReg_Hi2( src, src ) ); 13428 ins_pipe( ialu_cr_reg_reg ); 13429%} 13430 13431// Manifest a CmpL result in the normal flags. Only good for LT or GE 13432// compares. Can be used for LE or GT compares by reversing arguments. 13433// NOT GOOD FOR EQ/NE tests. 13434instruct cmpL_reg_flags_LTGE( flagsReg_long_LTGE flags, eRegL src1, eRegL src2, eRegI tmp ) %{ 13435 match( Set flags (CmpL src1 src2 )); 13436 effect( TEMP tmp ); 13437 ins_cost(300); 13438 format %{ "CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t" 13439 "MOV $tmp,$src1.hi\n\t" 13440 "SBB $tmp,$src2.hi\t! Compute flags for long compare" %} 13441 ins_encode( long_cmp_flags2( src1, src2, tmp ) ); 13442 ins_pipe( ialu_cr_reg_reg ); 13443%} 13444 13445// Long compares reg < zero/req OR reg >= zero/req. 13446// Just a wrapper for a normal branch, plus the predicate test. 13447instruct cmpL_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, label labl) %{ 13448 match(If cmp flags); 13449 effect(USE labl); 13450 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); 13451 expand %{ 13452 jmpCon(cmp,flags,labl); // JLT or JGE... 13453 %} 13454%} 13455 13456// Compare 2 longs and CMOVE longs. 13457instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{ 13458 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); 13459 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 )); 13460 ins_cost(400); 13461 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 13462 "CMOV$cmp $dst.hi,$src.hi" %} 13463 opcode(0x0F,0x40); 13464 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) ); 13465 ins_pipe( pipe_cmov_reg_long ); 13466%} 13467 13468instruct cmovLL_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, load_long_memory src) %{ 13469 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src)))); 13470 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 )); 13471 ins_cost(500); 13472 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 13473 "CMOV$cmp $dst.hi,$src.hi" %} 13474 opcode(0x0F,0x40); 13475 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) ); 13476 ins_pipe( pipe_cmov_reg_long ); 13477%} 13478 13479// Compare 2 longs and CMOVE ints. 13480instruct cmovII_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegI dst, eRegI src) %{ 13481 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 )); 13482 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src))); 13483 ins_cost(200); 13484 format %{ "CMOV$cmp $dst,$src" %} 13485 opcode(0x0F,0x40); 13486 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 13487 ins_pipe( pipe_cmov_reg ); 13488%} 13489 13490instruct cmovII_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegI dst, memory src) %{ 13491 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 )); 13492 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src)))); 13493 ins_cost(250); 13494 format %{ "CMOV$cmp $dst,$src" %} 13495 opcode(0x0F,0x40); 13496 ins_encode( enc_cmov(cmp), RegMem( dst, src ) ); 13497 ins_pipe( pipe_cmov_mem ); 13498%} 13499 13500// Compare 2 longs and CMOVE ints. 13501instruct cmovPP_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegP dst, eRegP src) %{ 13502 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 )); 13503 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src))); 13504 ins_cost(200); 13505 format %{ "CMOV$cmp $dst,$src" %} 13506 opcode(0x0F,0x40); 13507 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 13508 ins_pipe( pipe_cmov_reg ); 13509%} 13510 13511// Compare 2 longs and CMOVE doubles 13512instruct cmovDD_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regD dst, regD src) %{ 13513 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 ); 13514 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 13515 ins_cost(200); 13516 expand %{ 13517 fcmovD_regS(cmp,flags,dst,src); 13518 %} 13519%} 13520 13521// Compare 2 longs and CMOVE doubles 13522instruct cmovXDD_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regXD dst, regXD src) %{ 13523 predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); 13524 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 13525 ins_cost(200); 13526 expand %{ 13527 fcmovXD_regS(cmp,flags,dst,src); 13528 %} 13529%} 13530 13531instruct cmovFF_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regF dst, regF src) %{ 13532 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 ); 13533 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 13534 ins_cost(200); 13535 expand %{ 13536 fcmovF_regS(cmp,flags,dst,src); 13537 %} 13538%} 13539 13540instruct cmovXX_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regX dst, regX src) %{ 13541 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 ); 13542 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 13543 ins_cost(200); 13544 expand %{ 13545 fcmovX_regS(cmp,flags,dst,src); 13546 %} 13547%} 13548 13549//====== 13550// Manifest a CmpL result in the normal flags. Only good for EQ/NE compares. 13551instruct cmpL_zero_flags_EQNE( flagsReg_long_EQNE flags, eRegL src, immL0 zero, eRegI tmp ) %{ 13552 match( Set flags (CmpL src zero )); 13553 effect(TEMP tmp); 13554 ins_cost(200); 13555 format %{ "MOV $tmp,$src.lo\n\t" 13556 "OR $tmp,$src.hi\t! Long is EQ/NE 0?" %} 13557 ins_encode( long_cmp_flags0( src, tmp ) ); 13558 ins_pipe( ialu_reg_reg_long ); 13559%} 13560 13561// Manifest a CmpL result in the normal flags. Only good for EQ/NE compares. 13562instruct cmpL_reg_flags_EQNE( flagsReg_long_EQNE flags, eRegL src1, eRegL src2 ) %{ 13563 match( Set flags (CmpL src1 src2 )); 13564 ins_cost(200+300); 13565 format %{ "CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t" 13566 "JNE,s skip\n\t" 13567 "CMP $src1.hi,$src2.hi\n\t" 13568 "skip:\t" %} 13569 ins_encode( long_cmp_flags1( src1, src2 ) ); 13570 ins_pipe( ialu_cr_reg_reg ); 13571%} 13572 13573// Long compare reg == zero/reg OR reg != zero/reg 13574// Just a wrapper for a normal branch, plus the predicate test. 13575instruct cmpL_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, label labl) %{ 13576 match(If cmp flags); 13577 effect(USE labl); 13578 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); 13579 expand %{ 13580 jmpCon(cmp,flags,labl); // JEQ or JNE... 13581 %} 13582%} 13583 13584// Compare 2 longs and CMOVE longs. 13585instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{ 13586 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); 13587 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 )); 13588 ins_cost(400); 13589 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 13590 "CMOV$cmp $dst.hi,$src.hi" %} 13591 opcode(0x0F,0x40); 13592 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) ); 13593 ins_pipe( pipe_cmov_reg_long ); 13594%} 13595 13596instruct cmovLL_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, load_long_memory src) %{ 13597 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src)))); 13598 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 )); 13599 ins_cost(500); 13600 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 13601 "CMOV$cmp $dst.hi,$src.hi" %} 13602 opcode(0x0F,0x40); 13603 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) ); 13604 ins_pipe( pipe_cmov_reg_long ); 13605%} 13606 13607// Compare 2 longs and CMOVE ints. 13608instruct cmovII_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegI dst, eRegI src) %{ 13609 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 )); 13610 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src))); 13611 ins_cost(200); 13612 format %{ "CMOV$cmp $dst,$src" %} 13613 opcode(0x0F,0x40); 13614 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 13615 ins_pipe( pipe_cmov_reg ); 13616%} 13617 13618instruct cmovII_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegI dst, memory src) %{ 13619 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 )); 13620 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src)))); 13621 ins_cost(250); 13622 format %{ "CMOV$cmp $dst,$src" %} 13623 opcode(0x0F,0x40); 13624 ins_encode( enc_cmov(cmp), RegMem( dst, src ) ); 13625 ins_pipe( pipe_cmov_mem ); 13626%} 13627 13628// Compare 2 longs and CMOVE ints. 13629instruct cmovPP_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegP dst, eRegP src) %{ 13630 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 )); 13631 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src))); 13632 ins_cost(200); 13633 format %{ "CMOV$cmp $dst,$src" %} 13634 opcode(0x0F,0x40); 13635 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 13636 ins_pipe( pipe_cmov_reg ); 13637%} 13638 13639// Compare 2 longs and CMOVE doubles 13640instruct cmovDD_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regD dst, regD src) %{ 13641 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 ); 13642 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 13643 ins_cost(200); 13644 expand %{ 13645 fcmovD_regS(cmp,flags,dst,src); 13646 %} 13647%} 13648 13649// Compare 2 longs and CMOVE doubles 13650instruct cmovXDD_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regXD dst, regXD src) %{ 13651 predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); 13652 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 13653 ins_cost(200); 13654 expand %{ 13655 fcmovXD_regS(cmp,flags,dst,src); 13656 %} 13657%} 13658 13659instruct cmovFF_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regF dst, regF src) %{ 13660 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 ); 13661 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 13662 ins_cost(200); 13663 expand %{ 13664 fcmovF_regS(cmp,flags,dst,src); 13665 %} 13666%} 13667 13668instruct cmovXX_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regX dst, regX src) %{ 13669 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 ); 13670 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 13671 ins_cost(200); 13672 expand %{ 13673 fcmovX_regS(cmp,flags,dst,src); 13674 %} 13675%} 13676 13677//====== 13678// Manifest a CmpL result in the normal flags. Only good for LE or GT compares. 13679// Same as cmpL_reg_flags_LEGT except must negate src 13680instruct cmpL_zero_flags_LEGT( flagsReg_long_LEGT flags, eRegL src, immL0 zero, eRegI tmp ) %{ 13681 match( Set flags (CmpL src zero )); 13682 effect( TEMP tmp ); 13683 ins_cost(300); 13684 format %{ "XOR $tmp,$tmp\t# Long compare for -$src < 0, use commuted test\n\t" 13685 "CMP $tmp,$src.lo\n\t" 13686 "SBB $tmp,$src.hi\n\t" %} 13687 ins_encode( long_cmp_flags3(src, tmp) ); 13688 ins_pipe( ialu_reg_reg_long ); 13689%} 13690 13691// Manifest a CmpL result in the normal flags. Only good for LE or GT compares. 13692// Same as cmpL_reg_flags_LTGE except operands swapped. Swapping operands 13693// requires a commuted test to get the same result. 13694instruct cmpL_reg_flags_LEGT( flagsReg_long_LEGT flags, eRegL src1, eRegL src2, eRegI tmp ) %{ 13695 match( Set flags (CmpL src1 src2 )); 13696 effect( TEMP tmp ); 13697 ins_cost(300); 13698 format %{ "CMP $src2.lo,$src1.lo\t! Long compare, swapped operands, use with commuted test\n\t" 13699 "MOV $tmp,$src2.hi\n\t" 13700 "SBB $tmp,$src1.hi\t! Compute flags for long compare" %} 13701 ins_encode( long_cmp_flags2( src2, src1, tmp ) ); 13702 ins_pipe( ialu_cr_reg_reg ); 13703%} 13704 13705// Long compares reg < zero/req OR reg >= zero/req. 13706// Just a wrapper for a normal branch, plus the predicate test 13707instruct cmpL_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, label labl) %{ 13708 match(If cmp flags); 13709 effect(USE labl); 13710 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le ); 13711 ins_cost(300); 13712 expand %{ 13713 jmpCon(cmp,flags,labl); // JGT or JLE... 13714 %} 13715%} 13716 13717// Compare 2 longs and CMOVE longs. 13718instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{ 13719 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); 13720 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 )); 13721 ins_cost(400); 13722 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 13723 "CMOV$cmp $dst.hi,$src.hi" %} 13724 opcode(0x0F,0x40); 13725 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) ); 13726 ins_pipe( pipe_cmov_reg_long ); 13727%} 13728 13729instruct cmovLL_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, load_long_memory src) %{ 13730 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src)))); 13731 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 )); 13732 ins_cost(500); 13733 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 13734 "CMOV$cmp $dst.hi,$src.hi+4" %} 13735 opcode(0x0F,0x40); 13736 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) ); 13737 ins_pipe( pipe_cmov_reg_long ); 13738%} 13739 13740// Compare 2 longs and CMOVE ints. 13741instruct cmovII_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegI dst, eRegI src) %{ 13742 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 )); 13743 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src))); 13744 ins_cost(200); 13745 format %{ "CMOV$cmp $dst,$src" %} 13746 opcode(0x0F,0x40); 13747 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 13748 ins_pipe( pipe_cmov_reg ); 13749%} 13750 13751instruct cmovII_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegI dst, memory src) %{ 13752 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 )); 13753 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src)))); 13754 ins_cost(250); 13755 format %{ "CMOV$cmp $dst,$src" %} 13756 opcode(0x0F,0x40); 13757 ins_encode( enc_cmov(cmp), RegMem( dst, src ) ); 13758 ins_pipe( pipe_cmov_mem ); 13759%} 13760 13761// Compare 2 longs and CMOVE ptrs. 13762instruct cmovPP_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegP dst, eRegP src) %{ 13763 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 )); 13764 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src))); 13765 ins_cost(200); 13766 format %{ "CMOV$cmp $dst,$src" %} 13767 opcode(0x0F,0x40); 13768 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 13769 ins_pipe( pipe_cmov_reg ); 13770%} 13771 13772// Compare 2 longs and CMOVE doubles 13773instruct cmovDD_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regD dst, regD src) %{ 13774 predicate( UseSSE<=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); 13775 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 13776 ins_cost(200); 13777 expand %{ 13778 fcmovD_regS(cmp,flags,dst,src); 13779 %} 13780%} 13781 13782// Compare 2 longs and CMOVE doubles 13783instruct cmovXDD_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regXD dst, regXD src) %{ 13784 predicate( UseSSE>=2 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); 13785 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 13786 ins_cost(200); 13787 expand %{ 13788 fcmovXD_regS(cmp,flags,dst,src); 13789 %} 13790%} 13791 13792instruct cmovFF_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regF dst, regF src) %{ 13793 predicate( UseSSE==0 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); 13794 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 13795 ins_cost(200); 13796 expand %{ 13797 fcmovF_regS(cmp,flags,dst,src); 13798 %} 13799%} 13800 13801 13802instruct cmovXX_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regX dst, regX src) %{ 13803 predicate( UseSSE>=1 && _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ); 13804 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 13805 ins_cost(200); 13806 expand %{ 13807 fcmovX_regS(cmp,flags,dst,src); 13808 %} 13809%} 13810 13811 13812// ============================================================================ 13813// Procedure Call/Return Instructions 13814// Call Java Static Instruction 13815// Note: If this code changes, the corresponding ret_addr_offset() and 13816// compute_padding() functions will have to be adjusted. 13817instruct CallStaticJavaDirect(method meth) %{ 13818 match(CallStaticJava); 13819 predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke()); 13820 effect(USE meth); 13821 13822 ins_cost(300); 13823 format %{ "CALL,static " %} 13824 opcode(0xE8); /* E8 cd */ 13825 ins_encode( pre_call_FPU, 13826 Java_Static_Call( meth ), 13827 call_epilog, 13828 post_call_FPU ); 13829 ins_pipe( pipe_slow ); 13830 ins_alignment(4); 13831%} 13832 13833// Call Java Static Instruction (method handle version) 13834// Note: If this code changes, the corresponding ret_addr_offset() and 13835// compute_padding() functions will have to be adjusted. 13836instruct CallStaticJavaHandle(method meth, eBPRegP ebp_mh_SP_save) %{ 13837 match(CallStaticJava); 13838 predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke()); 13839 effect(USE meth); 13840 // EBP is saved by all callees (for interpreter stack correction). 13841 // We use it here for a similar purpose, in {preserve,restore}_SP. 13842 13843 ins_cost(300); 13844 format %{ "CALL,static/MethodHandle " %} 13845 opcode(0xE8); /* E8 cd */ 13846 ins_encode( pre_call_FPU, 13847 preserve_SP, 13848 Java_Static_Call( meth ), 13849 restore_SP, 13850 call_epilog, 13851 post_call_FPU ); 13852 ins_pipe( pipe_slow ); 13853 ins_alignment(4); 13854%} 13855 13856// Call Java Dynamic Instruction 13857// Note: If this code changes, the corresponding ret_addr_offset() and 13858// compute_padding() functions will have to be adjusted. 13859instruct CallDynamicJavaDirect(method meth) %{ 13860 match(CallDynamicJava); 13861 effect(USE meth); 13862 13863 ins_cost(300); 13864 format %{ "MOV EAX,(oop)-1\n\t" 13865 "CALL,dynamic" %} 13866 opcode(0xE8); /* E8 cd */ 13867 ins_encode( pre_call_FPU, 13868 Java_Dynamic_Call( meth ), 13869 call_epilog, 13870 post_call_FPU ); 13871 ins_pipe( pipe_slow ); 13872 ins_alignment(4); 13873%} 13874 13875// Call Runtime Instruction 13876instruct CallRuntimeDirect(method meth) %{ 13877 match(CallRuntime ); 13878 effect(USE meth); 13879 13880 ins_cost(300); 13881 format %{ "CALL,runtime " %} 13882 opcode(0xE8); /* E8 cd */ 13883 // Use FFREEs to clear entries in float stack 13884 ins_encode( pre_call_FPU, 13885 FFree_Float_Stack_All, 13886 Java_To_Runtime( meth ), 13887 post_call_FPU ); 13888 ins_pipe( pipe_slow ); 13889%} 13890 13891// Call runtime without safepoint 13892instruct CallLeafDirect(method meth) %{ 13893 match(CallLeaf); 13894 effect(USE meth); 13895 13896 ins_cost(300); 13897 format %{ "CALL_LEAF,runtime " %} 13898 opcode(0xE8); /* E8 cd */ 13899 ins_encode( pre_call_FPU, 13900 FFree_Float_Stack_All, 13901 Java_To_Runtime( meth ), 13902 Verify_FPU_For_Leaf, post_call_FPU ); 13903 ins_pipe( pipe_slow ); 13904%} 13905 13906instruct CallLeafNoFPDirect(method meth) %{ 13907 match(CallLeafNoFP); 13908 effect(USE meth); 13909 13910 ins_cost(300); 13911 format %{ "CALL_LEAF_NOFP,runtime " %} 13912 opcode(0xE8); /* E8 cd */ 13913 ins_encode(Java_To_Runtime(meth)); 13914 ins_pipe( pipe_slow ); 13915%} 13916 13917 13918// Return Instruction 13919// Remove the return address & jump to it. 13920instruct Ret() %{ 13921 match(Return); 13922 format %{ "RET" %} 13923 opcode(0xC3); 13924 ins_encode(OpcP); 13925 ins_pipe( pipe_jmp ); 13926%} 13927 13928// Tail Call; Jump from runtime stub to Java code. 13929// Also known as an 'interprocedural jump'. 13930// Target of jump will eventually return to caller. 13931// TailJump below removes the return address. 13932instruct TailCalljmpInd(eRegP_no_EBP jump_target, eBXRegP method_oop) %{ 13933 match(TailCall jump_target method_oop ); 13934 ins_cost(300); 13935 format %{ "JMP $jump_target \t# EBX holds method oop" %} 13936 opcode(0xFF, 0x4); /* Opcode FF /4 */ 13937 ins_encode( OpcP, RegOpc(jump_target) ); 13938 ins_pipe( pipe_jmp ); 13939%} 13940 13941 13942// Tail Jump; remove the return address; jump to target. 13943// TailCall above leaves the return address around. 13944instruct tailjmpInd(eRegP_no_EBP jump_target, eAXRegP ex_oop) %{ 13945 match( TailJump jump_target ex_oop ); 13946 ins_cost(300); 13947 format %{ "POP EDX\t# pop return address into dummy\n\t" 13948 "JMP $jump_target " %} 13949 opcode(0xFF, 0x4); /* Opcode FF /4 */ 13950 ins_encode( enc_pop_rdx, 13951 OpcP, RegOpc(jump_target) ); 13952 ins_pipe( pipe_jmp ); 13953%} 13954 13955// Create exception oop: created by stack-crawling runtime code. 13956// Created exception is now available to this handler, and is setup 13957// just prior to jumping to this handler. No code emitted. 13958instruct CreateException( eAXRegP ex_oop ) 13959%{ 13960 match(Set ex_oop (CreateEx)); 13961 13962 size(0); 13963 // use the following format syntax 13964 format %{ "# exception oop is in EAX; no code emitted" %} 13965 ins_encode(); 13966 ins_pipe( empty ); 13967%} 13968 13969 13970// Rethrow exception: 13971// The exception oop will come in the first argument position. 13972// Then JUMP (not call) to the rethrow stub code. 13973instruct RethrowException() 13974%{ 13975 match(Rethrow); 13976 13977 // use the following format syntax 13978 format %{ "JMP rethrow_stub" %} 13979 ins_encode(enc_rethrow); 13980 ins_pipe( pipe_jmp ); 13981%} 13982 13983// inlined locking and unlocking 13984 13985 13986instruct cmpFastLock( eFlagsReg cr, eRegP object, eRegP box, eAXRegI tmp, eRegP scr) %{ 13987 match( Set cr (FastLock object box) ); 13988 effect( TEMP tmp, TEMP scr ); 13989 ins_cost(300); 13990 format %{ "FASTLOCK $object, $box KILLS $tmp,$scr" %} 13991 ins_encode( Fast_Lock(object,box,tmp,scr) ); 13992 ins_pipe( pipe_slow ); 13993%} 13994 13995instruct cmpFastUnlock( eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{ 13996 match( Set cr (FastUnlock object box) ); 13997 effect( TEMP tmp ); 13998 ins_cost(300); 13999 format %{ "FASTUNLOCK $object, $box, $tmp" %} 14000 ins_encode( Fast_Unlock(object,box,tmp) ); 14001 ins_pipe( pipe_slow ); 14002%} 14003 14004 14005 14006// ============================================================================ 14007// Safepoint Instruction 14008instruct safePoint_poll(eFlagsReg cr) %{ 14009 match(SafePoint); 14010 effect(KILL cr); 14011 14012 // TODO-FIXME: we currently poll at offset 0 of the safepoint polling page. 14013 // On SPARC that might be acceptable as we can generate the address with 14014 // just a sethi, saving an or. By polling at offset 0 we can end up 14015 // putting additional pressure on the index-0 in the D$. Because of 14016 // alignment (just like the situation at hand) the lower indices tend 14017 // to see more traffic. It'd be better to change the polling address 14018 // to offset 0 of the last $line in the polling page. 14019 14020 format %{ "TSTL #polladdr,EAX\t! Safepoint: poll for GC" %} 14021 ins_cost(125); 14022 size(6) ; 14023 ins_encode( Safepoint_Poll() ); 14024 ins_pipe( ialu_reg_mem ); 14025%} 14026 14027//----------PEEPHOLE RULES----------------------------------------------------- 14028// These must follow all instruction definitions as they use the names 14029// defined in the instructions definitions. 14030// 14031// peepmatch ( root_instr_name [preceding_instruction]* ); 14032// 14033// peepconstraint %{ 14034// (instruction_number.operand_name relational_op instruction_number.operand_name 14035// [, ...] ); 14036// // instruction numbers are zero-based using left to right order in peepmatch 14037// 14038// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 14039// // provide an instruction_number.operand_name for each operand that appears 14040// // in the replacement instruction's match rule 14041// 14042// ---------VM FLAGS--------------------------------------------------------- 14043// 14044// All peephole optimizations can be turned off using -XX:-OptoPeephole 14045// 14046// Each peephole rule is given an identifying number starting with zero and 14047// increasing by one in the order seen by the parser. An individual peephole 14048// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 14049// on the command-line. 14050// 14051// ---------CURRENT LIMITATIONS---------------------------------------------- 14052// 14053// Only match adjacent instructions in same basic block 14054// Only equality constraints 14055// Only constraints between operands, not (0.dest_reg == EAX_enc) 14056// Only one replacement instruction 14057// 14058// ---------EXAMPLE---------------------------------------------------------- 14059// 14060// // pertinent parts of existing instructions in architecture description 14061// instruct movI(eRegI dst, eRegI src) %{ 14062// match(Set dst (CopyI src)); 14063// %} 14064// 14065// instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{ 14066// match(Set dst (AddI dst src)); 14067// effect(KILL cr); 14068// %} 14069// 14070// // Change (inc mov) to lea 14071// peephole %{ 14072// // increment preceeded by register-register move 14073// peepmatch ( incI_eReg movI ); 14074// // require that the destination register of the increment 14075// // match the destination register of the move 14076// peepconstraint ( 0.dst == 1.dst ); 14077// // construct a replacement instruction that sets 14078// // the destination to ( move's source register + one ) 14079// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14080// %} 14081// 14082// Implementation no longer uses movX instructions since 14083// machine-independent system no longer uses CopyX nodes. 14084// 14085// peephole %{ 14086// peepmatch ( incI_eReg movI ); 14087// peepconstraint ( 0.dst == 1.dst ); 14088// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14089// %} 14090// 14091// peephole %{ 14092// peepmatch ( decI_eReg movI ); 14093// peepconstraint ( 0.dst == 1.dst ); 14094// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14095// %} 14096// 14097// peephole %{ 14098// peepmatch ( addI_eReg_imm movI ); 14099// peepconstraint ( 0.dst == 1.dst ); 14100// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 14101// %} 14102// 14103// peephole %{ 14104// peepmatch ( addP_eReg_imm movP ); 14105// peepconstraint ( 0.dst == 1.dst ); 14106// peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 14107// %} 14108 14109// // Change load of spilled value to only a spill 14110// instruct storeI(memory mem, eRegI src) %{ 14111// match(Set mem (StoreI mem src)); 14112// %} 14113// 14114// instruct loadI(eRegI dst, memory mem) %{ 14115// match(Set dst (LoadI mem)); 14116// %} 14117// 14118peephole %{ 14119 peepmatch ( loadI storeI ); 14120 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 14121 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 14122%} 14123 14124//----------SMARTSPILL RULES--------------------------------------------------- 14125// These must follow all instruction definitions as they use the names 14126// defined in the instructions definitions. 14127