x86_32.ad revision 4438:e961c11b85fe
1// 2// Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4// 5// This code is free software; you can redistribute it and/or modify it 6// under the terms of the GNU General Public License version 2 only, as 7// published by the Free Software Foundation. 8// 9// This code is distributed in the hope that it will be useful, but WITHOUT 10// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12// version 2 for more details (a copy is included in the LICENSE file that 13// accompanied this code). 14// 15// You should have received a copy of the GNU General Public License version 16// 2 along with this work; if not, write to the Free Software Foundation, 17// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18// 19// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20// or visit www.oracle.com if you need additional information or have any 21// questions. 22// 23// 24 25// 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// Float registers. We treat TOS/FPR0 special. It is invisible to the 78// allocator, and only shows up in the encodings. 79reg_def FPR0L( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad()); 80reg_def FPR0H( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad()); 81// Ok so here's the trick FPR1 is really st(0) except in the midst 82// of emission of assembly for a machnode. During the emission the fpu stack 83// is pushed making FPR1 == st(1) temporarily. However at any safepoint 84// the stack will not have this element so FPR1 == st(0) from the 85// oopMap viewpoint. This same weirdness with numbering causes 86// instruction encoding to have to play games with the register 87// encode to correct for this 0/1 issue. See MachSpillCopyNode::implementation 88// where it does flt->flt moves to see an example 89// 90reg_def FPR1L( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg()); 91reg_def FPR1H( SOC, SOC, Op_RegF, 1, as_FloatRegister(0)->as_VMReg()->next()); 92reg_def FPR2L( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg()); 93reg_def FPR2H( SOC, SOC, Op_RegF, 2, as_FloatRegister(1)->as_VMReg()->next()); 94reg_def FPR3L( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg()); 95reg_def FPR3H( SOC, SOC, Op_RegF, 3, as_FloatRegister(2)->as_VMReg()->next()); 96reg_def FPR4L( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg()); 97reg_def FPR4H( SOC, SOC, Op_RegF, 4, as_FloatRegister(3)->as_VMReg()->next()); 98reg_def FPR5L( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg()); 99reg_def FPR5H( SOC, SOC, Op_RegF, 5, as_FloatRegister(4)->as_VMReg()->next()); 100reg_def FPR6L( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg()); 101reg_def FPR6H( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg()->next()); 102reg_def FPR7L( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()); 103reg_def FPR7H( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next()); 104 105// Specify priority of register selection within phases of register 106// allocation. Highest priority is first. A useful heuristic is to 107// give registers a low priority when they are required by machine 108// instructions, like EAX and EDX. Registers which are used as 109// pairs must fall on an even boundary (witness the FPR#L's in this list). 110// For the Intel integer registers, the equivalent Long pairs are 111// EDX:EAX, EBX:ECX, and EDI:EBP. 112alloc_class chunk0( ECX, EBX, EBP, EDI, EAX, EDX, ESI, ESP, 113 FPR0L, FPR0H, FPR1L, FPR1H, FPR2L, FPR2H, 114 FPR3L, FPR3H, FPR4L, FPR4H, FPR5L, FPR5H, 115 FPR6L, FPR6H, FPR7L, FPR7H ); 116 117 118//----------Architecture Description Register Classes-------------------------- 119// Several register classes are automatically defined based upon information in 120// this architecture description. 121// 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 122// 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 123// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 124// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 125// 126// Class for all registers 127reg_class any_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX, ESP); 128// Class for general registers 129reg_class int_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX); 130// Class for general registers which may be used for implicit null checks on win95 131// Also safe for use by tailjump. We don't want to allocate in rbp, 132reg_class int_reg_no_rbp(EAX, EDX, EDI, ESI, ECX, EBX); 133// Class of "X" registers 134reg_class int_x_reg(EBX, ECX, EDX, EAX); 135// Class of registers that can appear in an address with no offset. 136// EBP and ESP require an extra instruction byte for zero offset. 137// Used in fast-unlock 138reg_class p_reg(EDX, EDI, ESI, EBX); 139// Class for general registers not including ECX 140reg_class ncx_reg(EAX, EDX, EBP, EDI, ESI, EBX); 141// Class for general registers not including EAX 142reg_class nax_reg(EDX, EDI, ESI, ECX, EBX); 143// Class for general registers not including EAX or EBX. 144reg_class nabx_reg(EDX, EDI, ESI, ECX, EBP); 145// Class of EAX (for multiply and divide operations) 146reg_class eax_reg(EAX); 147// Class of EBX (for atomic add) 148reg_class ebx_reg(EBX); 149// Class of ECX (for shift and JCXZ operations and cmpLTMask) 150reg_class ecx_reg(ECX); 151// Class of EDX (for multiply and divide operations) 152reg_class edx_reg(EDX); 153// Class of EDI (for synchronization) 154reg_class edi_reg(EDI); 155// Class of ESI (for synchronization) 156reg_class esi_reg(ESI); 157// Singleton class for interpreter's stack pointer 158reg_class ebp_reg(EBP); 159// Singleton class for stack pointer 160reg_class sp_reg(ESP); 161// Singleton class for instruction pointer 162// reg_class ip_reg(EIP); 163// Class of integer register pairs 164reg_class long_reg( EAX,EDX, ECX,EBX, EBP,EDI ); 165// Class of integer register pairs that aligns with calling convention 166reg_class eadx_reg( EAX,EDX ); 167reg_class ebcx_reg( ECX,EBX ); 168// Not AX or DX, used in divides 169reg_class nadx_reg( EBX,ECX,ESI,EDI,EBP ); 170 171// Floating point registers. Notice FPR0 is not a choice. 172// FPR0 is not ever allocated; we use clever encodings to fake 173// a 2-address instructions out of Intels FP stack. 174reg_class fp_flt_reg( FPR1L,FPR2L,FPR3L,FPR4L,FPR5L,FPR6L,FPR7L ); 175 176reg_class fp_dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H, 177 FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H, 178 FPR7L,FPR7H ); 179 180reg_class fp_flt_reg0( FPR1L ); 181reg_class fp_dbl_reg0( FPR1L,FPR1H ); 182reg_class fp_dbl_reg1( FPR2L,FPR2H ); 183reg_class fp_dbl_notreg0( FPR2L,FPR2H, FPR3L,FPR3H, FPR4L,FPR4H, 184 FPR5L,FPR5H, FPR6L,FPR6H, FPR7L,FPR7H ); 185 186%} 187 188 189//----------SOURCE BLOCK------------------------------------------------------- 190// This is a block of C++ code which provides values, functions, and 191// definitions necessary in the rest of the architecture description 192source_hpp %{ 193// Must be visible to the DFA in dfa_x86_32.cpp 194extern bool is_operand_hi32_zero(Node* n); 195%} 196 197source %{ 198#define RELOC_IMM32 Assembler::imm_operand 199#define RELOC_DISP32 Assembler::disp32_operand 200 201#define __ _masm. 202 203// How to find the high register of a Long pair, given the low register 204#define HIGH_FROM_LOW(x) ((x)+2) 205 206// These masks are used to provide 128-bit aligned bitmasks to the XMM 207// instructions, to allow sign-masking or sign-bit flipping. They allow 208// fast versions of NegF/NegD and AbsF/AbsD. 209 210// Note: 'double' and 'long long' have 32-bits alignment on x86. 211static jlong* double_quadword(jlong *adr, jlong lo, jlong hi) { 212 // Use the expression (adr)&(~0xF) to provide 128-bits aligned address 213 // of 128-bits operands for SSE instructions. 214 jlong *operand = (jlong*)(((uintptr_t)adr)&((uintptr_t)(~0xF))); 215 // Store the value to a 128-bits operand. 216 operand[0] = lo; 217 operand[1] = hi; 218 return operand; 219} 220 221// Buffer for 128-bits masks used by SSE instructions. 222static jlong fp_signmask_pool[(4+1)*2]; // 4*128bits(data) + 128bits(alignment) 223 224// Static initialization during VM startup. 225static jlong *float_signmask_pool = double_quadword(&fp_signmask_pool[1*2], CONST64(0x7FFFFFFF7FFFFFFF), CONST64(0x7FFFFFFF7FFFFFFF)); 226static jlong *double_signmask_pool = double_quadword(&fp_signmask_pool[2*2], CONST64(0x7FFFFFFFFFFFFFFF), CONST64(0x7FFFFFFFFFFFFFFF)); 227static jlong *float_signflip_pool = double_quadword(&fp_signmask_pool[3*2], CONST64(0x8000000080000000), CONST64(0x8000000080000000)); 228static jlong *double_signflip_pool = double_quadword(&fp_signmask_pool[4*2], CONST64(0x8000000000000000), CONST64(0x8000000000000000)); 229 230// Offset hacking within calls. 231static int pre_call_resets_size() { 232 int size = 0; 233 Compile* C = Compile::current(); 234 if (C->in_24_bit_fp_mode()) { 235 size += 6; // fldcw 236 } 237 if (C->max_vector_size() > 16) { 238 size += 3; // vzeroupper 239 } 240 return size; 241} 242 243static int preserve_SP_size() { 244 return 2; // op, rm(reg/reg) 245} 246 247// !!!!! Special hack to get all type of calls to specify the byte offset 248// from the start of the call to the point where the return address 249// will point. 250int MachCallStaticJavaNode::ret_addr_offset() { 251 int offset = 5 + pre_call_resets_size(); // 5 bytes from start of call to where return address points 252 if (_method_handle_invoke) 253 offset += preserve_SP_size(); 254 return offset; 255} 256 257int MachCallDynamicJavaNode::ret_addr_offset() { 258 return 10 + pre_call_resets_size(); // 10 bytes from start of call to where return address points 259} 260 261static int sizeof_FFree_Float_Stack_All = -1; 262 263int MachCallRuntimeNode::ret_addr_offset() { 264 assert(sizeof_FFree_Float_Stack_All != -1, "must have been emitted already"); 265 return sizeof_FFree_Float_Stack_All + 5 + pre_call_resets_size(); 266} 267 268// Indicate if the safepoint node needs the polling page as an input. 269// Since x86 does have absolute addressing, it doesn't. 270bool SafePointNode::needs_polling_address_input() { 271 return false; 272} 273 274// 275// Compute padding required for nodes which need alignment 276// 277 278// The address of the call instruction needs to be 4-byte aligned to 279// ensure that it does not span a cache line so that it can be patched. 280int CallStaticJavaDirectNode::compute_padding(int current_offset) const { 281 current_offset += pre_call_resets_size(); // skip fldcw, if any 282 current_offset += 1; // skip call opcode byte 283 return round_to(current_offset, alignment_required()) - current_offset; 284} 285 286// The address of the call instruction needs to be 4-byte aligned to 287// ensure that it does not span a cache line so that it can be patched. 288int CallStaticJavaHandleNode::compute_padding(int current_offset) const { 289 current_offset += pre_call_resets_size(); // skip fldcw, if any 290 current_offset += preserve_SP_size(); // skip mov rbp, rsp 291 current_offset += 1; // skip call opcode byte 292 return round_to(current_offset, alignment_required()) - current_offset; 293} 294 295// The address of the call instruction needs to be 4-byte aligned to 296// ensure that it does not span a cache line so that it can be patched. 297int CallDynamicJavaDirectNode::compute_padding(int current_offset) const { 298 current_offset += pre_call_resets_size(); // skip fldcw, if any 299 current_offset += 5; // skip MOV instruction 300 current_offset += 1; // skip call opcode byte 301 return round_to(current_offset, alignment_required()) - current_offset; 302} 303 304// EMIT_RM() 305void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 306 unsigned char c = (unsigned char)((f1 << 6) | (f2 << 3) | f3); 307 cbuf.insts()->emit_int8(c); 308} 309 310// EMIT_CC() 311void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 312 unsigned char c = (unsigned char)( f1 | f2 ); 313 cbuf.insts()->emit_int8(c); 314} 315 316// EMIT_OPCODE() 317void emit_opcode(CodeBuffer &cbuf, int code) { 318 cbuf.insts()->emit_int8((unsigned char) code); 319} 320 321// EMIT_OPCODE() w/ relocation information 322void emit_opcode(CodeBuffer &cbuf, int code, relocInfo::relocType reloc, int offset = 0) { 323 cbuf.relocate(cbuf.insts_mark() + offset, reloc); 324 emit_opcode(cbuf, code); 325} 326 327// EMIT_D8() 328void emit_d8(CodeBuffer &cbuf, int d8) { 329 cbuf.insts()->emit_int8((unsigned char) d8); 330} 331 332// EMIT_D16() 333void emit_d16(CodeBuffer &cbuf, int d16) { 334 cbuf.insts()->emit_int16(d16); 335} 336 337// EMIT_D32() 338void emit_d32(CodeBuffer &cbuf, int d32) { 339 cbuf.insts()->emit_int32(d32); 340} 341 342// emit 32 bit value and construct relocation entry from relocInfo::relocType 343void emit_d32_reloc(CodeBuffer &cbuf, int d32, relocInfo::relocType reloc, 344 int format) { 345 cbuf.relocate(cbuf.insts_mark(), reloc, format); 346 cbuf.insts()->emit_int32(d32); 347} 348 349// emit 32 bit value and construct relocation entry from RelocationHolder 350void emit_d32_reloc(CodeBuffer &cbuf, int d32, RelocationHolder const& rspec, 351 int format) { 352#ifdef ASSERT 353 if (rspec.reloc()->type() == relocInfo::oop_type && d32 != 0 && d32 != (int)Universe::non_oop_word()) { 354 assert(oop(d32)->is_oop() && (ScavengeRootsInCode || !oop(d32)->is_scavengable()), "cannot embed scavengable oops in code"); 355 } 356#endif 357 cbuf.relocate(cbuf.insts_mark(), rspec, format); 358 cbuf.insts()->emit_int32(d32); 359} 360 361// Access stack slot for load or store 362void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) { 363 emit_opcode( cbuf, opcode ); // (e.g., FILD [ESP+src]) 364 if( -128 <= disp && disp <= 127 ) { 365 emit_rm( cbuf, 0x01, rm_field, ESP_enc ); // R/M byte 366 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte 367 emit_d8 (cbuf, disp); // Displacement // R/M byte 368 } else { 369 emit_rm( cbuf, 0x02, rm_field, ESP_enc ); // R/M byte 370 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte 371 emit_d32(cbuf, disp); // Displacement // R/M byte 372 } 373} 374 375 // rRegI ereg, memory mem) %{ // emit_reg_mem 376void encode_RegMem( CodeBuffer &cbuf, int reg_encoding, int base, int index, int scale, int displace, relocInfo::relocType disp_reloc ) { 377 // There is no index & no scale, use form without SIB byte 378 if ((index == 0x4) && 379 (scale == 0) && (base != ESP_enc)) { 380 // If no displacement, mode is 0x0; unless base is [EBP] 381 if ( (displace == 0) && (base != EBP_enc) ) { 382 emit_rm(cbuf, 0x0, reg_encoding, base); 383 } 384 else { // If 8-bit displacement, mode 0x1 385 if ((displace >= -128) && (displace <= 127) 386 && (disp_reloc == relocInfo::none) ) { 387 emit_rm(cbuf, 0x1, reg_encoding, base); 388 emit_d8(cbuf, displace); 389 } 390 else { // If 32-bit displacement 391 if (base == -1) { // Special flag for absolute address 392 emit_rm(cbuf, 0x0, reg_encoding, 0x5); 393 // (manual lies; no SIB needed here) 394 if ( disp_reloc != relocInfo::none ) { 395 emit_d32_reloc(cbuf, displace, disp_reloc, 1); 396 } else { 397 emit_d32 (cbuf, displace); 398 } 399 } 400 else { // Normal base + offset 401 emit_rm(cbuf, 0x2, reg_encoding, base); 402 if ( disp_reloc != relocInfo::none ) { 403 emit_d32_reloc(cbuf, displace, disp_reloc, 1); 404 } else { 405 emit_d32 (cbuf, displace); 406 } 407 } 408 } 409 } 410 } 411 else { // Else, encode with the SIB byte 412 // If no displacement, mode is 0x0; unless base is [EBP] 413 if (displace == 0 && (base != EBP_enc)) { // If no displacement 414 emit_rm(cbuf, 0x0, reg_encoding, 0x4); 415 emit_rm(cbuf, scale, index, base); 416 } 417 else { // If 8-bit displacement, mode 0x1 418 if ((displace >= -128) && (displace <= 127) 419 && (disp_reloc == relocInfo::none) ) { 420 emit_rm(cbuf, 0x1, reg_encoding, 0x4); 421 emit_rm(cbuf, scale, index, base); 422 emit_d8(cbuf, displace); 423 } 424 else { // If 32-bit displacement 425 if (base == 0x04 ) { 426 emit_rm(cbuf, 0x2, reg_encoding, 0x4); 427 emit_rm(cbuf, scale, index, 0x04); 428 } else { 429 emit_rm(cbuf, 0x2, reg_encoding, 0x4); 430 emit_rm(cbuf, scale, index, base); 431 } 432 if ( disp_reloc != relocInfo::none ) { 433 emit_d32_reloc(cbuf, displace, disp_reloc, 1); 434 } else { 435 emit_d32 (cbuf, displace); 436 } 437 } 438 } 439 } 440} 441 442 443void encode_Copy( CodeBuffer &cbuf, int dst_encoding, int src_encoding ) { 444 if( dst_encoding == src_encoding ) { 445 // reg-reg copy, use an empty encoding 446 } else { 447 emit_opcode( cbuf, 0x8B ); 448 emit_rm(cbuf, 0x3, dst_encoding, src_encoding ); 449 } 450} 451 452void emit_cmpfp_fixup(MacroAssembler& _masm) { 453 Label exit; 454 __ jccb(Assembler::noParity, exit); 455 __ pushf(); 456 // 457 // comiss/ucomiss instructions set ZF,PF,CF flags and 458 // zero OF,AF,SF for NaN values. 459 // Fixup flags by zeroing ZF,PF so that compare of NaN 460 // values returns 'less than' result (CF is set). 461 // Leave the rest of flags unchanged. 462 // 463 // 7 6 5 4 3 2 1 0 464 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 465 // 0 0 1 0 1 0 1 1 (0x2B) 466 // 467 __ andl(Address(rsp, 0), 0xffffff2b); 468 __ popf(); 469 __ bind(exit); 470} 471 472void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 473 Label done; 474 __ movl(dst, -1); 475 __ jcc(Assembler::parity, done); 476 __ jcc(Assembler::below, done); 477 __ setb(Assembler::notEqual, dst); 478 __ movzbl(dst, dst); 479 __ bind(done); 480} 481 482 483//============================================================================= 484const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 485 486int Compile::ConstantTable::calculate_table_base_offset() const { 487 return 0; // absolute addressing, no offset 488} 489 490void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 491 // Empty encoding 492} 493 494uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 495 return 0; 496} 497 498#ifndef PRODUCT 499void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 500 st->print("# MachConstantBaseNode (empty encoding)"); 501} 502#endif 503 504 505//============================================================================= 506#ifndef PRODUCT 507void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 508 Compile* C = ra_->C; 509 510 int framesize = C->frame_slots() << LogBytesPerInt; 511 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 512 // Remove wordSize for return addr which is already pushed. 513 framesize -= wordSize; 514 515 if (C->need_stack_bang(framesize)) { 516 framesize -= wordSize; 517 st->print("# stack bang"); 518 st->print("\n\t"); 519 st->print("PUSH EBP\t# Save EBP"); 520 if (framesize) { 521 st->print("\n\t"); 522 st->print("SUB ESP, #%d\t# Create frame",framesize); 523 } 524 } else { 525 st->print("SUB ESP, #%d\t# Create frame",framesize); 526 st->print("\n\t"); 527 framesize -= wordSize; 528 st->print("MOV [ESP + #%d], EBP\t# Save EBP",framesize); 529 } 530 531 if (VerifyStackAtCalls) { 532 st->print("\n\t"); 533 framesize -= wordSize; 534 st->print("MOV [ESP + #%d], 0xBADB100D\t# Majik cookie for stack depth check",framesize); 535 } 536 537 if( C->in_24_bit_fp_mode() ) { 538 st->print("\n\t"); 539 st->print("FLDCW \t# load 24 bit fpu control word"); 540 } 541 if (UseSSE >= 2 && VerifyFPU) { 542 st->print("\n\t"); 543 st->print("# verify FPU stack (must be clean on entry)"); 544 } 545 546#ifdef ASSERT 547 if (VerifyStackAtCalls) { 548 st->print("\n\t"); 549 st->print("# stack alignment check"); 550 } 551#endif 552 st->cr(); 553} 554#endif 555 556 557void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 558 Compile* C = ra_->C; 559 MacroAssembler _masm(&cbuf); 560 561 int framesize = C->frame_slots() << LogBytesPerInt; 562 563 __ verified_entry(framesize, C->need_stack_bang(framesize), C->in_24_bit_fp_mode()); 564 565 C->set_frame_complete(cbuf.insts_size()); 566 567 if (C->has_mach_constant_base_node()) { 568 // NOTE: We set the table base offset here because users might be 569 // emitted before MachConstantBaseNode. 570 Compile::ConstantTable& constant_table = C->constant_table(); 571 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 572 } 573} 574 575uint MachPrologNode::size(PhaseRegAlloc *ra_) const { 576 return MachNode::size(ra_); // too many variables; just compute it the hard way 577} 578 579int MachPrologNode::reloc() const { 580 return 0; // a large enough number 581} 582 583//============================================================================= 584#ifndef PRODUCT 585void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 586 Compile *C = ra_->C; 587 int framesize = C->frame_slots() << LogBytesPerInt; 588 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 589 // Remove two words for return addr and rbp, 590 framesize -= 2*wordSize; 591 592 if (C->max_vector_size() > 16) { 593 st->print("VZEROUPPER"); 594 st->cr(); st->print("\t"); 595 } 596 if (C->in_24_bit_fp_mode()) { 597 st->print("FLDCW standard control word"); 598 st->cr(); st->print("\t"); 599 } 600 if (framesize) { 601 st->print("ADD ESP,%d\t# Destroy frame",framesize); 602 st->cr(); st->print("\t"); 603 } 604 st->print_cr("POPL EBP"); st->print("\t"); 605 if (do_polling() && C->is_method_compilation()) { 606 st->print("TEST PollPage,EAX\t! Poll Safepoint"); 607 st->cr(); st->print("\t"); 608 } 609} 610#endif 611 612void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 613 Compile *C = ra_->C; 614 615 if (C->max_vector_size() > 16) { 616 // Clear upper bits of YMM registers when current compiled code uses 617 // wide vectors to avoid AVX <-> SSE transition penalty during call. 618 MacroAssembler masm(&cbuf); 619 masm.vzeroupper(); 620 } 621 // If method set FPU control word, restore to standard control word 622 if (C->in_24_bit_fp_mode()) { 623 MacroAssembler masm(&cbuf); 624 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); 625 } 626 627 int framesize = C->frame_slots() << LogBytesPerInt; 628 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 629 // Remove two words for return addr and rbp, 630 framesize -= 2*wordSize; 631 632 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 633 634 if (framesize >= 128) { 635 emit_opcode(cbuf, 0x81); // add SP, #framesize 636 emit_rm(cbuf, 0x3, 0x00, ESP_enc); 637 emit_d32(cbuf, framesize); 638 } else if (framesize) { 639 emit_opcode(cbuf, 0x83); // add SP, #framesize 640 emit_rm(cbuf, 0x3, 0x00, ESP_enc); 641 emit_d8(cbuf, framesize); 642 } 643 644 emit_opcode(cbuf, 0x58 | EBP_enc); 645 646 if (do_polling() && C->is_method_compilation()) { 647 cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0); 648 emit_opcode(cbuf,0x85); 649 emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX 650 emit_d32(cbuf, (intptr_t)os::get_polling_page()); 651 } 652} 653 654uint MachEpilogNode::size(PhaseRegAlloc *ra_) const { 655 Compile *C = ra_->C; 656 // If method set FPU control word, restore to standard control word 657 int size = C->in_24_bit_fp_mode() ? 6 : 0; 658 if (C->max_vector_size() > 16) size += 3; // vzeroupper 659 if (do_polling() && C->is_method_compilation()) size += 6; 660 661 int framesize = C->frame_slots() << LogBytesPerInt; 662 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 663 // Remove two words for return addr and rbp, 664 framesize -= 2*wordSize; 665 666 size++; // popl rbp, 667 668 if (framesize >= 128) { 669 size += 6; 670 } else { 671 size += framesize ? 3 : 0; 672 } 673 return size; 674} 675 676int MachEpilogNode::reloc() const { 677 return 0; // a large enough number 678} 679 680const Pipeline * MachEpilogNode::pipeline() const { 681 return MachNode::pipeline_class(); 682} 683 684int MachEpilogNode::safepoint_offset() const { return 0; } 685 686//============================================================================= 687 688enum RC { rc_bad, rc_int, rc_float, rc_xmm, rc_stack }; 689static enum RC rc_class( OptoReg::Name reg ) { 690 691 if( !OptoReg::is_valid(reg) ) return rc_bad; 692 if (OptoReg::is_stack(reg)) return rc_stack; 693 694 VMReg r = OptoReg::as_VMReg(reg); 695 if (r->is_Register()) return rc_int; 696 if (r->is_FloatRegister()) { 697 assert(UseSSE < 2, "shouldn't be used in SSE2+ mode"); 698 return rc_float; 699 } 700 assert(r->is_XMMRegister(), "must be"); 701 return rc_xmm; 702} 703 704static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset, int reg, 705 int opcode, const char *op_str, int size, outputStream* st ) { 706 if( cbuf ) { 707 emit_opcode (*cbuf, opcode ); 708 encode_RegMem(*cbuf, Matcher::_regEncode[reg], ESP_enc, 0x4, 0, offset, relocInfo::none); 709#ifndef PRODUCT 710 } else if( !do_size ) { 711 if( size != 0 ) st->print("\n\t"); 712 if( opcode == 0x8B || opcode == 0x89 ) { // MOV 713 if( is_load ) st->print("%s %s,[ESP + #%d]",op_str,Matcher::regName[reg],offset); 714 else st->print("%s [ESP + #%d],%s",op_str,offset,Matcher::regName[reg]); 715 } else { // FLD, FST, PUSH, POP 716 st->print("%s [ESP + #%d]",op_str,offset); 717 } 718#endif 719 } 720 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4); 721 return size+3+offset_size; 722} 723 724// Helper for XMM registers. Extra opcode bits, limited syntax. 725static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load, 726 int offset, int reg_lo, int reg_hi, int size, outputStream* st ) { 727 if (cbuf) { 728 MacroAssembler _masm(cbuf); 729 if (reg_lo+1 == reg_hi) { // double move? 730 if (is_load) { 731 __ movdbl(as_XMMRegister(Matcher::_regEncode[reg_lo]), Address(rsp, offset)); 732 } else { 733 __ movdbl(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[reg_lo])); 734 } 735 } else { 736 if (is_load) { 737 __ movflt(as_XMMRegister(Matcher::_regEncode[reg_lo]), Address(rsp, offset)); 738 } else { 739 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[reg_lo])); 740 } 741 } 742#ifndef PRODUCT 743 } else if (!do_size) { 744 if (size != 0) st->print("\n\t"); 745 if (reg_lo+1 == reg_hi) { // double move? 746 if (is_load) st->print("%s %s,[ESP + #%d]", 747 UseXmmLoadAndClearUpper ? "MOVSD " : "MOVLPD", 748 Matcher::regName[reg_lo], offset); 749 else st->print("MOVSD [ESP + #%d],%s", 750 offset, Matcher::regName[reg_lo]); 751 } else { 752 if (is_load) st->print("MOVSS %s,[ESP + #%d]", 753 Matcher::regName[reg_lo], offset); 754 else st->print("MOVSS [ESP + #%d],%s", 755 offset, Matcher::regName[reg_lo]); 756 } 757#endif 758 } 759 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4); 760 // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes as SIMD prefix. 761 return size+5+offset_size; 762} 763 764 765static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 766 int src_hi, int dst_hi, int size, outputStream* st ) { 767 if (cbuf) { 768 MacroAssembler _masm(cbuf); 769 if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move? 770 __ movdbl(as_XMMRegister(Matcher::_regEncode[dst_lo]), 771 as_XMMRegister(Matcher::_regEncode[src_lo])); 772 } else { 773 __ movflt(as_XMMRegister(Matcher::_regEncode[dst_lo]), 774 as_XMMRegister(Matcher::_regEncode[src_lo])); 775 } 776#ifndef PRODUCT 777 } else if (!do_size) { 778 if (size != 0) st->print("\n\t"); 779 if (UseXmmRegToRegMoveAll) {//Use movaps,movapd to move between xmm registers 780 if (src_lo+1 == src_hi && dst_lo+1 == dst_hi) { // double move? 781 st->print("MOVAPD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 782 } else { 783 st->print("MOVAPS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 784 } 785 } else { 786 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double move? 787 st->print("MOVSD %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 788 } else { 789 st->print("MOVSS %s,%s",Matcher::regName[dst_lo],Matcher::regName[src_lo]); 790 } 791 } 792#endif 793 } 794 // VEX_2bytes prefix is used if UseAVX > 0, and it takes the same 2 bytes as SIMD prefix. 795 // Only MOVAPS SSE prefix uses 1 byte. 796 int sz = 4; 797 if (!(src_lo+1 == src_hi && dst_lo+1 == dst_hi) && 798 UseXmmRegToRegMoveAll && (UseAVX == 0)) sz = 3; 799 return size + sz; 800} 801 802static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 803 int src_hi, int dst_hi, int size, outputStream* st ) { 804 // 32-bit 805 if (cbuf) { 806 MacroAssembler _masm(cbuf); 807 __ movdl(as_XMMRegister(Matcher::_regEncode[dst_lo]), 808 as_Register(Matcher::_regEncode[src_lo])); 809#ifndef PRODUCT 810 } else if (!do_size) { 811 st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 812#endif 813 } 814 return 4; 815} 816 817 818static int impl_movx2gpr_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 819 int src_hi, int dst_hi, int size, outputStream* st ) { 820 // 32-bit 821 if (cbuf) { 822 MacroAssembler _masm(cbuf); 823 __ movdl(as_Register(Matcher::_regEncode[dst_lo]), 824 as_XMMRegister(Matcher::_regEncode[src_lo])); 825#ifndef PRODUCT 826 } else if (!do_size) { 827 st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]); 828#endif 829 } 830 return 4; 831} 832 833static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) { 834 if( cbuf ) { 835 emit_opcode(*cbuf, 0x8B ); 836 emit_rm (*cbuf, 0x3, Matcher::_regEncode[dst], Matcher::_regEncode[src] ); 837#ifndef PRODUCT 838 } else if( !do_size ) { 839 if( size != 0 ) st->print("\n\t"); 840 st->print("MOV %s,%s",Matcher::regName[dst],Matcher::regName[src]); 841#endif 842 } 843 return size+2; 844} 845 846static int impl_fp_store_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int src_hi, int dst_lo, int dst_hi, 847 int offset, int size, outputStream* st ) { 848 if( src_lo != FPR1L_num ) { // Move value to top of FP stack, if not already there 849 if( cbuf ) { 850 emit_opcode( *cbuf, 0xD9 ); // FLD (i.e., push it) 851 emit_d8( *cbuf, 0xC0-1+Matcher::_regEncode[src_lo] ); 852#ifndef PRODUCT 853 } else if( !do_size ) { 854 if( size != 0 ) st->print("\n\t"); 855 st->print("FLD %s",Matcher::regName[src_lo]); 856#endif 857 } 858 size += 2; 859 } 860 861 int st_op = (src_lo != FPR1L_num) ? EBX_num /*store & pop*/ : EDX_num /*store no pop*/; 862 const char *op_str; 863 int op; 864 if( src_lo+1 == src_hi && dst_lo+1 == dst_hi ) { // double store? 865 op_str = (src_lo != FPR1L_num) ? "FSTP_D" : "FST_D "; 866 op = 0xDD; 867 } else { // 32-bit store 868 op_str = (src_lo != FPR1L_num) ? "FSTP_S" : "FST_S "; 869 op = 0xD9; 870 assert( !OptoReg::is_valid(src_hi) && !OptoReg::is_valid(dst_hi), "no non-adjacent float-stores" ); 871 } 872 873 return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st); 874} 875 876// Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 877static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 878 int src_hi, int dst_hi, uint ireg, outputStream* st); 879 880static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 881 int stack_offset, int reg, uint ireg, outputStream* st); 882 883static int vec_stack_to_stack_helper(CodeBuffer *cbuf, bool do_size, int src_offset, 884 int dst_offset, uint ireg, outputStream* st) { 885 int calc_size = 0; 886 int src_offset_size = (src_offset == 0) ? 0 : ((src_offset < 0x80) ? 1 : 4); 887 int dst_offset_size = (dst_offset == 0) ? 0 : ((dst_offset < 0x80) ? 1 : 4); 888 switch (ireg) { 889 case Op_VecS: 890 calc_size = 3+src_offset_size + 3+dst_offset_size; 891 break; 892 case Op_VecD: 893 calc_size = 3+src_offset_size + 3+dst_offset_size; 894 src_offset += 4; 895 dst_offset += 4; 896 src_offset_size = (src_offset == 0) ? 0 : ((src_offset < 0x80) ? 1 : 4); 897 dst_offset_size = (dst_offset == 0) ? 0 : ((dst_offset < 0x80) ? 1 : 4); 898 calc_size += 3+src_offset_size + 3+dst_offset_size; 899 break; 900 case Op_VecX: 901 calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size; 902 break; 903 case Op_VecY: 904 calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size; 905 break; 906 default: 907 ShouldNotReachHere(); 908 } 909 if (cbuf) { 910 MacroAssembler _masm(cbuf); 911 int offset = __ offset(); 912 switch (ireg) { 913 case Op_VecS: 914 __ pushl(Address(rsp, src_offset)); 915 __ popl (Address(rsp, dst_offset)); 916 break; 917 case Op_VecD: 918 __ pushl(Address(rsp, src_offset)); 919 __ popl (Address(rsp, dst_offset)); 920 __ pushl(Address(rsp, src_offset+4)); 921 __ popl (Address(rsp, dst_offset+4)); 922 break; 923 case Op_VecX: 924 __ movdqu(Address(rsp, -16), xmm0); 925 __ movdqu(xmm0, Address(rsp, src_offset)); 926 __ movdqu(Address(rsp, dst_offset), xmm0); 927 __ movdqu(xmm0, Address(rsp, -16)); 928 break; 929 case Op_VecY: 930 __ vmovdqu(Address(rsp, -32), xmm0); 931 __ vmovdqu(xmm0, Address(rsp, src_offset)); 932 __ vmovdqu(Address(rsp, dst_offset), xmm0); 933 __ vmovdqu(xmm0, Address(rsp, -32)); 934 break; 935 default: 936 ShouldNotReachHere(); 937 } 938 int size = __ offset() - offset; 939 assert(size == calc_size, "incorrect size calculattion"); 940 return size; 941#ifndef PRODUCT 942 } else if (!do_size) { 943 switch (ireg) { 944 case Op_VecS: 945 st->print("pushl [rsp + #%d]\t# 32-bit mem-mem spill\n\t" 946 "popl [rsp + #%d]", 947 src_offset, dst_offset); 948 break; 949 case Op_VecD: 950 st->print("pushl [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 951 "popq [rsp + #%d]\n\t" 952 "pushl [rsp + #%d]\n\t" 953 "popq [rsp + #%d]", 954 src_offset, dst_offset, src_offset+4, dst_offset+4); 955 break; 956 case Op_VecX: 957 st->print("movdqu [rsp - #16], xmm0\t# 128-bit mem-mem spill\n\t" 958 "movdqu xmm0, [rsp + #%d]\n\t" 959 "movdqu [rsp + #%d], xmm0\n\t" 960 "movdqu xmm0, [rsp - #16]", 961 src_offset, dst_offset); 962 break; 963 case Op_VecY: 964 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 965 "vmovdqu xmm0, [rsp + #%d]\n\t" 966 "vmovdqu [rsp + #%d], xmm0\n\t" 967 "vmovdqu xmm0, [rsp - #32]", 968 src_offset, dst_offset); 969 break; 970 default: 971 ShouldNotReachHere(); 972 } 973#endif 974 } 975 return calc_size; 976} 977 978uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const { 979 // Get registers to move 980 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 981 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 982 OptoReg::Name dst_second = ra_->get_reg_second(this ); 983 OptoReg::Name dst_first = ra_->get_reg_first(this ); 984 985 enum RC src_second_rc = rc_class(src_second); 986 enum RC src_first_rc = rc_class(src_first); 987 enum RC dst_second_rc = rc_class(dst_second); 988 enum RC dst_first_rc = rc_class(dst_first); 989 990 assert( OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), "must move at least 1 register" ); 991 992 // Generate spill code! 993 int size = 0; 994 995 if( src_first == dst_first && src_second == dst_second ) 996 return size; // Self copy, no move 997 998 if (bottom_type()->isa_vect() != NULL) { 999 uint ireg = ideal_reg(); 1000 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1001 assert((src_first_rc != rc_float && dst_first_rc != rc_float), "sanity"); 1002 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity"); 1003 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1004 // mem -> mem 1005 int src_offset = ra_->reg2offset(src_first); 1006 int dst_offset = ra_->reg2offset(dst_first); 1007 return vec_stack_to_stack_helper(cbuf, do_size, src_offset, dst_offset, ireg, st); 1008 } else if (src_first_rc == rc_xmm && dst_first_rc == rc_xmm ) { 1009 return vec_mov_helper(cbuf, do_size, src_first, dst_first, src_second, dst_second, ireg, st); 1010 } else if (src_first_rc == rc_xmm && dst_first_rc == rc_stack ) { 1011 int stack_offset = ra_->reg2offset(dst_first); 1012 return vec_spill_helper(cbuf, do_size, false, stack_offset, src_first, ireg, st); 1013 } else if (src_first_rc == rc_stack && dst_first_rc == rc_xmm ) { 1014 int stack_offset = ra_->reg2offset(src_first); 1015 return vec_spill_helper(cbuf, do_size, true, stack_offset, dst_first, ireg, st); 1016 } else { 1017 ShouldNotReachHere(); 1018 } 1019 } 1020 1021 // -------------------------------------- 1022 // Check for mem-mem move. push/pop to move. 1023 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1024 if( src_second == dst_first ) { // overlapping stack copy ranges 1025 assert( src_second_rc == rc_stack && dst_second_rc == rc_stack, "we only expect a stk-stk copy here" ); 1026 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st); 1027 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st); 1028 src_second_rc = dst_second_rc = rc_bad; // flag as already moved the second bits 1029 } 1030 // move low bits 1031 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),ESI_num,0xFF,"PUSH ",size, st); 1032 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),EAX_num,0x8F,"POP ",size, st); 1033 if( src_second_rc == rc_stack && dst_second_rc == rc_stack ) { // mov second bits 1034 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),ESI_num,0xFF,"PUSH ",size, st); 1035 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),EAX_num,0x8F,"POP ",size, st); 1036 } 1037 return size; 1038 } 1039 1040 // -------------------------------------- 1041 // Check for integer reg-reg copy 1042 if( src_first_rc == rc_int && dst_first_rc == rc_int ) 1043 size = impl_mov_helper(cbuf,do_size,src_first,dst_first,size, st); 1044 1045 // Check for integer store 1046 if( src_first_rc == rc_int && dst_first_rc == rc_stack ) 1047 size = impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first,0x89,"MOV ",size, st); 1048 1049 // Check for integer load 1050 if( dst_first_rc == rc_int && src_first_rc == rc_stack ) 1051 size = impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first,0x8B,"MOV ",size, st); 1052 1053 // Check for integer reg-xmm reg copy 1054 if( src_first_rc == rc_int && dst_first_rc == rc_xmm ) { 1055 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad), 1056 "no 64 bit integer-float reg moves" ); 1057 return impl_movgpr2x_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st); 1058 } 1059 // -------------------------------------- 1060 // Check for float reg-reg copy 1061 if( src_first_rc == rc_float && dst_first_rc == rc_float ) { 1062 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) || 1063 (src_first+1 == src_second && dst_first+1 == dst_second), "no non-adjacent float-moves" ); 1064 if( cbuf ) { 1065 1066 // Note the mucking with the register encode to compensate for the 0/1 1067 // indexing issue mentioned in a comment in the reg_def sections 1068 // for FPR registers many lines above here. 1069 1070 if( src_first != FPR1L_num ) { 1071 emit_opcode (*cbuf, 0xD9 ); // FLD ST(i) 1072 emit_d8 (*cbuf, 0xC0+Matcher::_regEncode[src_first]-1 ); 1073 emit_opcode (*cbuf, 0xDD ); // FSTP ST(i) 1074 emit_d8 (*cbuf, 0xD8+Matcher::_regEncode[dst_first] ); 1075 } else { 1076 emit_opcode (*cbuf, 0xDD ); // FST ST(i) 1077 emit_d8 (*cbuf, 0xD0+Matcher::_regEncode[dst_first]-1 ); 1078 } 1079#ifndef PRODUCT 1080 } else if( !do_size ) { 1081 if( size != 0 ) st->print("\n\t"); 1082 if( src_first != FPR1L_num ) st->print("FLD %s\n\tFSTP %s",Matcher::regName[src_first],Matcher::regName[dst_first]); 1083 else st->print( "FST %s", Matcher::regName[dst_first]); 1084#endif 1085 } 1086 return size + ((src_first != FPR1L_num) ? 2+2 : 2); 1087 } 1088 1089 // Check for float store 1090 if( src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1091 return impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,ra_->reg2offset(dst_first),size, st); 1092 } 1093 1094 // Check for float load 1095 if( dst_first_rc == rc_float && src_first_rc == rc_stack ) { 1096 int offset = ra_->reg2offset(src_first); 1097 const char *op_str; 1098 int op; 1099 if( src_first+1 == src_second && dst_first+1 == dst_second ) { // double load? 1100 op_str = "FLD_D"; 1101 op = 0xDD; 1102 } else { // 32-bit load 1103 op_str = "FLD_S"; 1104 op = 0xD9; 1105 assert( src_second_rc == rc_bad && dst_second_rc == rc_bad, "no non-adjacent float-loads" ); 1106 } 1107 if( cbuf ) { 1108 emit_opcode (*cbuf, op ); 1109 encode_RegMem(*cbuf, 0x0, ESP_enc, 0x4, 0, offset, relocInfo::none); 1110 emit_opcode (*cbuf, 0xDD ); // FSTP ST(i) 1111 emit_d8 (*cbuf, 0xD8+Matcher::_regEncode[dst_first] ); 1112#ifndef PRODUCT 1113 } else if( !do_size ) { 1114 if( size != 0 ) st->print("\n\t"); 1115 st->print("%s ST,[ESP + #%d]\n\tFSTP %s",op_str, offset,Matcher::regName[dst_first]); 1116#endif 1117 } 1118 int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4); 1119 return size + 3+offset_size+2; 1120 } 1121 1122 // Check for xmm reg-reg copy 1123 if( src_first_rc == rc_xmm && dst_first_rc == rc_xmm ) { 1124 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad) || 1125 (src_first+1 == src_second && dst_first+1 == dst_second), 1126 "no non-adjacent float-moves" ); 1127 return impl_movx_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st); 1128 } 1129 1130 // Check for xmm reg-integer reg copy 1131 if( src_first_rc == rc_xmm && dst_first_rc == rc_int ) { 1132 assert( (src_second_rc == rc_bad && dst_second_rc == rc_bad), 1133 "no 64 bit float-integer reg moves" ); 1134 return impl_movx2gpr_helper(cbuf,do_size,src_first,dst_first,src_second, dst_second, size, st); 1135 } 1136 1137 // Check for xmm store 1138 if( src_first_rc == rc_xmm && dst_first_rc == rc_stack ) { 1139 return impl_x_helper(cbuf,do_size,false,ra_->reg2offset(dst_first),src_first, src_second, size, st); 1140 } 1141 1142 // Check for float xmm load 1143 if( dst_first_rc == rc_xmm && src_first_rc == rc_stack ) { 1144 return impl_x_helper(cbuf,do_size,true ,ra_->reg2offset(src_first),dst_first, dst_second, size, st); 1145 } 1146 1147 // Copy from float reg to xmm reg 1148 if( dst_first_rc == rc_xmm && src_first_rc == rc_float ) { 1149 // copy to the top of stack from floating point reg 1150 // and use LEA to preserve flags 1151 if( cbuf ) { 1152 emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP-8] 1153 emit_rm(*cbuf, 0x1, ESP_enc, 0x04); 1154 emit_rm(*cbuf, 0x0, 0x04, ESP_enc); 1155 emit_d8(*cbuf,0xF8); 1156#ifndef PRODUCT 1157 } else if( !do_size ) { 1158 if( size != 0 ) st->print("\n\t"); 1159 st->print("LEA ESP,[ESP-8]"); 1160#endif 1161 } 1162 size += 4; 1163 1164 size = impl_fp_store_helper(cbuf,do_size,src_first,src_second,dst_first,dst_second,0,size, st); 1165 1166 // Copy from the temp memory to the xmm reg. 1167 size = impl_x_helper(cbuf,do_size,true ,0,dst_first, dst_second, size, st); 1168 1169 if( cbuf ) { 1170 emit_opcode(*cbuf,0x8D); // LEA ESP,[ESP+8] 1171 emit_rm(*cbuf, 0x1, ESP_enc, 0x04); 1172 emit_rm(*cbuf, 0x0, 0x04, ESP_enc); 1173 emit_d8(*cbuf,0x08); 1174#ifndef PRODUCT 1175 } else if( !do_size ) { 1176 if( size != 0 ) st->print("\n\t"); 1177 st->print("LEA ESP,[ESP+8]"); 1178#endif 1179 } 1180 size += 4; 1181 return size; 1182 } 1183 1184 assert( size > 0, "missed a case" ); 1185 1186 // -------------------------------------------------------------------- 1187 // Check for second bits still needing moving. 1188 if( src_second == dst_second ) 1189 return size; // Self copy; no move 1190 assert( src_second_rc != rc_bad && dst_second_rc != rc_bad, "src_second & dst_second cannot be Bad" ); 1191 1192 // Check for second word int-int move 1193 if( src_second_rc == rc_int && dst_second_rc == rc_int ) 1194 return impl_mov_helper(cbuf,do_size,src_second,dst_second,size, st); 1195 1196 // Check for second word integer store 1197 if( src_second_rc == rc_int && dst_second_rc == rc_stack ) 1198 return impl_helper(cbuf,do_size,false,ra_->reg2offset(dst_second),src_second,0x89,"MOV ",size, st); 1199 1200 // Check for second word integer load 1201 if( dst_second_rc == rc_int && src_second_rc == rc_stack ) 1202 return impl_helper(cbuf,do_size,true ,ra_->reg2offset(src_second),dst_second,0x8B,"MOV ",size, st); 1203 1204 1205 Unimplemented(); 1206} 1207 1208#ifndef PRODUCT 1209void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1210 implementation( NULL, ra_, false, st ); 1211} 1212#endif 1213 1214void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1215 implementation( &cbuf, ra_, false, NULL ); 1216} 1217 1218uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1219 return implementation( NULL, ra_, true, NULL ); 1220} 1221 1222 1223//============================================================================= 1224#ifndef PRODUCT 1225void BoxLockNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 1226 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1227 int reg = ra_->get_reg_first(this); 1228 st->print("LEA %s,[ESP + #%d]",Matcher::regName[reg],offset); 1229} 1230#endif 1231 1232void BoxLockNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1233 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1234 int reg = ra_->get_encode(this); 1235 if( offset >= 128 ) { 1236 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1237 emit_rm(cbuf, 0x2, reg, 0x04); 1238 emit_rm(cbuf, 0x0, 0x04, ESP_enc); 1239 emit_d32(cbuf, offset); 1240 } 1241 else { 1242 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1243 emit_rm(cbuf, 0x1, reg, 0x04); 1244 emit_rm(cbuf, 0x0, 0x04, ESP_enc); 1245 emit_d8(cbuf, offset); 1246 } 1247} 1248 1249uint BoxLockNode::size(PhaseRegAlloc *ra_) const { 1250 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1251 if( offset >= 128 ) { 1252 return 7; 1253 } 1254 else { 1255 return 4; 1256 } 1257} 1258 1259//============================================================================= 1260 1261// emit call stub, compiled java to interpreter 1262void emit_java_to_interp(CodeBuffer &cbuf ) { 1263 // Stub is fixed up when the corresponding call is converted from calling 1264 // compiled code to calling interpreted code. 1265 // mov rbx,0 1266 // jmp -1 1267 1268 address mark = cbuf.insts_mark(); // get mark within main instrs section 1269 1270 // Note that the code buffer's insts_mark is always relative to insts. 1271 // That's why we must use the macroassembler to generate a stub. 1272 MacroAssembler _masm(&cbuf); 1273 1274 address base = 1275 __ start_a_stub(Compile::MAX_stubs_size); 1276 if (base == NULL) return; // CodeBuffer::expand failed 1277 // static stub relocation stores the instruction address of the call 1278 __ relocate(static_stub_Relocation::spec(mark), RELOC_IMM32); 1279 // static stub relocation also tags the Method* in the code-stream. 1280 __ mov_metadata(rbx, (Metadata*)NULL); // method is zapped till fixup time 1281 // This is recognized as unresolved by relocs/nativeInst/ic code 1282 __ jump(RuntimeAddress(__ pc())); 1283 1284 __ end_a_stub(); 1285 // Update current stubs pointer and restore insts_end. 1286} 1287// size of call stub, compiled java to interpretor 1288uint size_java_to_interp() { 1289 return 10; // movl; jmp 1290} 1291// relocation entries for call stub, compiled java to interpretor 1292uint reloc_java_to_interp() { 1293 return 4; // 3 in emit_java_to_interp + 1 in Java_Static_Call 1294} 1295 1296//============================================================================= 1297#ifndef PRODUCT 1298void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream* st ) const { 1299 st->print_cr( "CMP EAX,[ECX+4]\t# Inline cache check"); 1300 st->print_cr("\tJNE SharedRuntime::handle_ic_miss_stub"); 1301 st->print_cr("\tNOP"); 1302 st->print_cr("\tNOP"); 1303 if( !OptoBreakpoint ) 1304 st->print_cr("\tNOP"); 1305} 1306#endif 1307 1308void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1309 MacroAssembler masm(&cbuf); 1310#ifdef ASSERT 1311 uint insts_size = cbuf.insts_size(); 1312#endif 1313 masm.cmpptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes())); 1314 masm.jump_cc(Assembler::notEqual, 1315 RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1316 /* WARNING these NOPs are critical so that verified entry point is properly 1317 aligned for patching by NativeJump::patch_verified_entry() */ 1318 int nops_cnt = 2; 1319 if( !OptoBreakpoint ) // Leave space for int3 1320 nops_cnt += 1; 1321 masm.nop(nops_cnt); 1322 1323 assert(cbuf.insts_size() - insts_size == size(ra_), "checking code size of inline cache node"); 1324} 1325 1326uint MachUEPNode::size(PhaseRegAlloc *ra_) const { 1327 return OptoBreakpoint ? 11 : 12; 1328} 1329 1330 1331//============================================================================= 1332uint size_exception_handler() { 1333 // NativeCall instruction size is the same as NativeJump. 1334 // exception handler starts out as jump and can be patched to 1335 // a call be deoptimization. (4932387) 1336 // Note that this value is also credited (in output.cpp) to 1337 // the size of the code section. 1338 return NativeJump::instruction_size; 1339} 1340 1341// Emit exception handler code. Stuff framesize into a register 1342// and call a VM stub routine. 1343int emit_exception_handler(CodeBuffer& cbuf) { 1344 1345 // Note that the code buffer's insts_mark is always relative to insts. 1346 // That's why we must use the macroassembler to generate a handler. 1347 MacroAssembler _masm(&cbuf); 1348 address base = 1349 __ start_a_stub(size_exception_handler()); 1350 if (base == NULL) return 0; // CodeBuffer::expand failed 1351 int offset = __ offset(); 1352 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1353 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1354 __ end_a_stub(); 1355 return offset; 1356} 1357 1358uint size_deopt_handler() { 1359 // NativeCall instruction size is the same as NativeJump. 1360 // exception handler starts out as jump and can be patched to 1361 // a call be deoptimization. (4932387) 1362 // Note that this value is also credited (in output.cpp) to 1363 // the size of the code section. 1364 return 5 + NativeJump::instruction_size; // pushl(); jmp; 1365} 1366 1367// Emit deopt handler code. 1368int emit_deopt_handler(CodeBuffer& cbuf) { 1369 1370 // Note that the code buffer's insts_mark is always relative to insts. 1371 // That's why we must use the macroassembler to generate a handler. 1372 MacroAssembler _masm(&cbuf); 1373 address base = 1374 __ start_a_stub(size_exception_handler()); 1375 if (base == NULL) return 0; // CodeBuffer::expand failed 1376 int offset = __ offset(); 1377 InternalAddress here(__ pc()); 1378 __ pushptr(here.addr()); 1379 1380 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1381 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1382 __ end_a_stub(); 1383 return offset; 1384} 1385 1386int Matcher::regnum_to_fpu_offset(int regnum) { 1387 return regnum - 32; // The FP registers are in the second chunk 1388} 1389 1390// This is UltraSparc specific, true just means we have fast l2f conversion 1391const bool Matcher::convL2FSupported(void) { 1392 return true; 1393} 1394 1395// Is this branch offset short enough that a short branch can be used? 1396// 1397// NOTE: If the platform does not provide any short branch variants, then 1398// this method should return false for offset 0. 1399bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1400 // The passed offset is relative to address of the branch. 1401 // On 86 a branch displacement is calculated relative to address 1402 // of a next instruction. 1403 offset -= br_size; 1404 1405 // the short version of jmpConUCF2 contains multiple branches, 1406 // making the reach slightly less 1407 if (rule == jmpConUCF2_rule) 1408 return (-126 <= offset && offset <= 125); 1409 return (-128 <= offset && offset <= 127); 1410} 1411 1412const bool Matcher::isSimpleConstant64(jlong value) { 1413 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1414 return false; 1415} 1416 1417// The ecx parameter to rep stos for the ClearArray node is in dwords. 1418const bool Matcher::init_array_count_is_in_bytes = false; 1419 1420// Threshold size for cleararray. 1421const int Matcher::init_array_short_size = 8 * BytesPerLong; 1422 1423// Needs 2 CMOV's for longs. 1424const int Matcher::long_cmove_cost() { return 1; } 1425 1426// No CMOVF/CMOVD with SSE/SSE2 1427const int Matcher::float_cmove_cost() { return (UseSSE>=1) ? ConditionalMoveLimit : 0; } 1428 1429// Should the Matcher clone shifts on addressing modes, expecting them to 1430// be subsumed into complex addressing expressions or compute them into 1431// registers? True for Intel but false for most RISCs 1432const bool Matcher::clone_shift_expressions = true; 1433 1434// Do we need to mask the count passed to shift instructions or does 1435// the cpu only look at the lower 5/6 bits anyway? 1436const bool Matcher::need_masked_shift_count = false; 1437 1438bool Matcher::narrow_oop_use_complex_address() { 1439 ShouldNotCallThis(); 1440 return true; 1441} 1442 1443bool Matcher::narrow_klass_use_complex_address() { 1444 ShouldNotCallThis(); 1445 return true; 1446} 1447 1448 1449// Is it better to copy float constants, or load them directly from memory? 1450// Intel can load a float constant from a direct address, requiring no 1451// extra registers. Most RISCs will have to materialize an address into a 1452// register first, so they would do better to copy the constant from stack. 1453const bool Matcher::rematerialize_float_constants = true; 1454 1455// If CPU can load and store mis-aligned doubles directly then no fixup is 1456// needed. Else we split the double into 2 integer pieces and move it 1457// piece-by-piece. Only happens when passing doubles into C code as the 1458// Java calling convention forces doubles to be aligned. 1459const bool Matcher::misaligned_doubles_ok = true; 1460 1461 1462void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) { 1463 // Get the memory operand from the node 1464 uint numopnds = node->num_opnds(); // Virtual call for number of operands 1465 uint skipped = node->oper_input_base(); // Sum of leaves skipped so far 1466 assert( idx >= skipped, "idx too low in pd_implicit_null_fixup" ); 1467 uint opcnt = 1; // First operand 1468 uint num_edges = node->_opnds[1]->num_edges(); // leaves for first operand 1469 while( idx >= skipped+num_edges ) { 1470 skipped += num_edges; 1471 opcnt++; // Bump operand count 1472 assert( opcnt < numopnds, "Accessing non-existent operand" ); 1473 num_edges = node->_opnds[opcnt]->num_edges(); // leaves for next operand 1474 } 1475 1476 MachOper *memory = node->_opnds[opcnt]; 1477 MachOper *new_memory = NULL; 1478 switch (memory->opcode()) { 1479 case DIRECT: 1480 case INDOFFSET32X: 1481 // No transformation necessary. 1482 return; 1483 case INDIRECT: 1484 new_memory = new (C) indirect_win95_safeOper( ); 1485 break; 1486 case INDOFFSET8: 1487 new_memory = new (C) indOffset8_win95_safeOper(memory->disp(NULL, NULL, 0)); 1488 break; 1489 case INDOFFSET32: 1490 new_memory = new (C) indOffset32_win95_safeOper(memory->disp(NULL, NULL, 0)); 1491 break; 1492 case INDINDEXOFFSET: 1493 new_memory = new (C) indIndexOffset_win95_safeOper(memory->disp(NULL, NULL, 0)); 1494 break; 1495 case INDINDEXSCALE: 1496 new_memory = new (C) indIndexScale_win95_safeOper(memory->scale()); 1497 break; 1498 case INDINDEXSCALEOFFSET: 1499 new_memory = new (C) indIndexScaleOffset_win95_safeOper(memory->scale(), memory->disp(NULL, NULL, 0)); 1500 break; 1501 case LOAD_LONG_INDIRECT: 1502 case LOAD_LONG_INDOFFSET32: 1503 // Does not use EBP as address register, use { EDX, EBX, EDI, ESI} 1504 return; 1505 default: 1506 assert(false, "unexpected memory operand in pd_implicit_null_fixup()"); 1507 return; 1508 } 1509 node->_opnds[opcnt] = new_memory; 1510} 1511 1512// Advertise here if the CPU requires explicit rounding operations 1513// to implement the UseStrictFP mode. 1514const bool Matcher::strict_fp_requires_explicit_rounding = true; 1515 1516// Are floats conerted to double when stored to stack during deoptimization? 1517// On x32 it is stored with convertion only when FPU is used for floats. 1518bool Matcher::float_in_double() { return (UseSSE == 0); } 1519 1520// Do ints take an entire long register or just half? 1521const bool Matcher::int_in_long = false; 1522 1523// Return whether or not this register is ever used as an argument. This 1524// function is used on startup to build the trampoline stubs in generateOptoStub. 1525// Registers not mentioned will be killed by the VM call in the trampoline, and 1526// arguments in those registers not be available to the callee. 1527bool Matcher::can_be_java_arg( int reg ) { 1528 if( reg == ECX_num || reg == EDX_num ) return true; 1529 if( (reg == XMM0_num || reg == XMM1_num ) && UseSSE>=1 ) return true; 1530 if( (reg == XMM0b_num || reg == XMM1b_num) && UseSSE>=2 ) return true; 1531 return false; 1532} 1533 1534bool Matcher::is_spillable_arg( int reg ) { 1535 return can_be_java_arg(reg); 1536} 1537 1538bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1539 // Use hardware integer DIV instruction when 1540 // it is faster than a code which use multiply. 1541 // Only when constant divisor fits into 32 bit 1542 // (min_jint is excluded to get only correct 1543 // positive 32 bit values from negative). 1544 return VM_Version::has_fast_idiv() && 1545 (divisor == (int)divisor && divisor != min_jint); 1546} 1547 1548// Register for DIVI projection of divmodI 1549RegMask Matcher::divI_proj_mask() { 1550 return EAX_REG_mask(); 1551} 1552 1553// Register for MODI projection of divmodI 1554RegMask Matcher::modI_proj_mask() { 1555 return EDX_REG_mask(); 1556} 1557 1558// Register for DIVL projection of divmodL 1559RegMask Matcher::divL_proj_mask() { 1560 ShouldNotReachHere(); 1561 return RegMask(); 1562} 1563 1564// Register for MODL projection of divmodL 1565RegMask Matcher::modL_proj_mask() { 1566 ShouldNotReachHere(); 1567 return RegMask(); 1568} 1569 1570const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1571 return EBP_REG_mask(); 1572} 1573 1574// Returns true if the high 32 bits of the value is known to be zero. 1575bool is_operand_hi32_zero(Node* n) { 1576 int opc = n->Opcode(); 1577 if (opc == Op_AndL) { 1578 Node* o2 = n->in(2); 1579 if (o2->is_Con() && (o2->get_long() & 0xFFFFFFFF00000000LL) == 0LL) { 1580 return true; 1581 } 1582 } 1583 if (opc == Op_ConL && (n->get_long() & 0xFFFFFFFF00000000LL) == 0LL) { 1584 return true; 1585 } 1586 return false; 1587} 1588 1589%} 1590 1591//----------ENCODING BLOCK----------------------------------------------------- 1592// This block specifies the encoding classes used by the compiler to output 1593// byte streams. Encoding classes generate functions which are called by 1594// Machine Instruction Nodes in order to generate the bit encoding of the 1595// instruction. Operands specify their base encoding interface with the 1596// interface keyword. There are currently supported four interfaces, 1597// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER. REG_INTER causes an 1598// operand to generate a function which returns its register number when 1599// queried. CONST_INTER causes an operand to generate a function which 1600// returns the value of the constant when queried. MEMORY_INTER causes an 1601// operand to generate four functions which return the Base Register, the 1602// Index Register, the Scale Value, and the Offset Value of the operand when 1603// queried. COND_INTER causes an operand to generate six functions which 1604// return the encoding code (ie - encoding bits for the instruction) 1605// associated with each basic boolean condition for a conditional instruction. 1606// Instructions specify two basic values for encoding. They use the 1607// ins_encode keyword to specify their encoding class (which must be one of 1608// the class names specified in the encoding block), and they use the 1609// opcode keyword to specify, in order, their primary, secondary, and 1610// tertiary opcode. Only the opcode sections which a particular instruction 1611// needs for encoding need to be specified. 1612encode %{ 1613 // Build emit functions for each basic byte or larger field in the intel 1614 // encoding scheme (opcode, rm, sib, immediate), and call them from C++ 1615 // code in the enc_class source block. Emit functions will live in the 1616 // main source block for now. In future, we can generalize this by 1617 // adding a syntax that specifies the sizes of fields in an order, 1618 // so that the adlc can build the emit functions automagically 1619 1620 // Emit primary opcode 1621 enc_class OpcP %{ 1622 emit_opcode(cbuf, $primary); 1623 %} 1624 1625 // Emit secondary opcode 1626 enc_class OpcS %{ 1627 emit_opcode(cbuf, $secondary); 1628 %} 1629 1630 // Emit opcode directly 1631 enc_class Opcode(immI d8) %{ 1632 emit_opcode(cbuf, $d8$$constant); 1633 %} 1634 1635 enc_class SizePrefix %{ 1636 emit_opcode(cbuf,0x66); 1637 %} 1638 1639 enc_class RegReg (rRegI dst, rRegI src) %{ // RegReg(Many) 1640 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 1641 %} 1642 1643 enc_class OpcRegReg (immI opcode, rRegI dst, rRegI src) %{ // OpcRegReg(Many) 1644 emit_opcode(cbuf,$opcode$$constant); 1645 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 1646 %} 1647 1648 enc_class mov_r32_imm0( rRegI dst ) %{ 1649 emit_opcode( cbuf, 0xB8 + $dst$$reg ); // 0xB8+ rd -- MOV r32 ,imm32 1650 emit_d32 ( cbuf, 0x0 ); // imm32==0x0 1651 %} 1652 1653 enc_class cdq_enc %{ 1654 // Full implementation of Java idiv and irem; checks for 1655 // special case as described in JVM spec., p.243 & p.271. 1656 // 1657 // normal case special case 1658 // 1659 // input : rax,: dividend min_int 1660 // reg: divisor -1 1661 // 1662 // output: rax,: quotient (= rax, idiv reg) min_int 1663 // rdx: remainder (= rax, irem reg) 0 1664 // 1665 // Code sequnce: 1666 // 1667 // 81 F8 00 00 00 80 cmp rax,80000000h 1668 // 0F 85 0B 00 00 00 jne normal_case 1669 // 33 D2 xor rdx,edx 1670 // 83 F9 FF cmp rcx,0FFh 1671 // 0F 84 03 00 00 00 je done 1672 // normal_case: 1673 // 99 cdq 1674 // F7 F9 idiv rax,ecx 1675 // done: 1676 // 1677 emit_opcode(cbuf,0x81); emit_d8(cbuf,0xF8); 1678 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); 1679 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x80); // cmp rax,80000000h 1680 emit_opcode(cbuf,0x0F); emit_d8(cbuf,0x85); 1681 emit_opcode(cbuf,0x0B); emit_d8(cbuf,0x00); 1682 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); // jne normal_case 1683 emit_opcode(cbuf,0x33); emit_d8(cbuf,0xD2); // xor rdx,edx 1684 emit_opcode(cbuf,0x83); emit_d8(cbuf,0xF9); emit_d8(cbuf,0xFF); // cmp rcx,0FFh 1685 emit_opcode(cbuf,0x0F); emit_d8(cbuf,0x84); 1686 emit_opcode(cbuf,0x03); emit_d8(cbuf,0x00); 1687 emit_opcode(cbuf,0x00); emit_d8(cbuf,0x00); // je done 1688 // normal_case: 1689 emit_opcode(cbuf,0x99); // cdq 1690 // idiv (note: must be emitted by the user of this rule) 1691 // normal: 1692 %} 1693 1694 // Dense encoding for older common ops 1695 enc_class Opc_plus(immI opcode, rRegI reg) %{ 1696 emit_opcode(cbuf, $opcode$$constant + $reg$$reg); 1697 %} 1698 1699 1700 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1701 enc_class OpcSE (immI imm) %{ // Emit primary opcode and set sign-extend bit 1702 // Check for 8-bit immediate, and set sign extend bit in opcode 1703 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) { 1704 emit_opcode(cbuf, $primary | 0x02); 1705 } 1706 else { // If 32-bit immediate 1707 emit_opcode(cbuf, $primary); 1708 } 1709 %} 1710 1711 enc_class OpcSErm (rRegI dst, immI imm) %{ // OpcSEr/m 1712 // Emit primary opcode and set sign-extend bit 1713 // Check for 8-bit immediate, and set sign extend bit in opcode 1714 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) { 1715 emit_opcode(cbuf, $primary | 0x02); } 1716 else { // If 32-bit immediate 1717 emit_opcode(cbuf, $primary); 1718 } 1719 // Emit r/m byte with secondary opcode, after primary opcode. 1720 emit_rm(cbuf, 0x3, $secondary, $dst$$reg); 1721 %} 1722 1723 enc_class Con8or32 (immI imm) %{ // Con8or32(storeImmI), 8 or 32 bits 1724 // Check for 8-bit immediate, and set sign extend bit in opcode 1725 if (($imm$$constant >= -128) && ($imm$$constant <= 127)) { 1726 $$$emit8$imm$$constant; 1727 } 1728 else { // If 32-bit immediate 1729 // Output immediate 1730 $$$emit32$imm$$constant; 1731 } 1732 %} 1733 1734 enc_class Long_OpcSErm_Lo(eRegL dst, immL imm) %{ 1735 // Emit primary opcode and set sign-extend bit 1736 // Check for 8-bit immediate, and set sign extend bit in opcode 1737 int con = (int)$imm$$constant; // Throw away top bits 1738 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary); 1739 // Emit r/m byte with secondary opcode, after primary opcode. 1740 emit_rm(cbuf, 0x3, $secondary, $dst$$reg); 1741 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con); 1742 else emit_d32(cbuf,con); 1743 %} 1744 1745 enc_class Long_OpcSErm_Hi(eRegL dst, immL imm) %{ 1746 // Emit primary opcode and set sign-extend bit 1747 // Check for 8-bit immediate, and set sign extend bit in opcode 1748 int con = (int)($imm$$constant >> 32); // Throw away bottom bits 1749 emit_opcode(cbuf, ((con >= -128) && (con <= 127)) ? ($primary | 0x02) : $primary); 1750 // Emit r/m byte with tertiary opcode, after primary opcode. 1751 emit_rm(cbuf, 0x3, $tertiary, HIGH_FROM_LOW($dst$$reg)); 1752 if ((con >= -128) && (con <= 127)) emit_d8 (cbuf,con); 1753 else emit_d32(cbuf,con); 1754 %} 1755 1756 enc_class OpcSReg (rRegI dst) %{ // BSWAP 1757 emit_cc(cbuf, $secondary, $dst$$reg ); 1758 %} 1759 1760 enc_class bswap_long_bytes(eRegL dst) %{ // BSWAP 1761 int destlo = $dst$$reg; 1762 int desthi = HIGH_FROM_LOW(destlo); 1763 // bswap lo 1764 emit_opcode(cbuf, 0x0F); 1765 emit_cc(cbuf, 0xC8, destlo); 1766 // bswap hi 1767 emit_opcode(cbuf, 0x0F); 1768 emit_cc(cbuf, 0xC8, desthi); 1769 // xchg lo and hi 1770 emit_opcode(cbuf, 0x87); 1771 emit_rm(cbuf, 0x3, destlo, desthi); 1772 %} 1773 1774 enc_class RegOpc (rRegI div) %{ // IDIV, IMOD, JMP indirect, ... 1775 emit_rm(cbuf, 0x3, $secondary, $div$$reg ); 1776 %} 1777 1778 enc_class enc_cmov(cmpOp cop ) %{ // CMOV 1779 $$$emit8$primary; 1780 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1781 %} 1782 1783 enc_class enc_cmov_dpr(cmpOp cop, regDPR src ) %{ // CMOV 1784 int op = 0xDA00 + $cop$$cmpcode + ($src$$reg-1); 1785 emit_d8(cbuf, op >> 8 ); 1786 emit_d8(cbuf, op & 255); 1787 %} 1788 1789 // emulate a CMOV with a conditional branch around a MOV 1790 enc_class enc_cmov_branch( cmpOp cop, immI brOffs ) %{ // CMOV 1791 // Invert sense of branch from sense of CMOV 1792 emit_cc( cbuf, 0x70, ($cop$$cmpcode^1) ); 1793 emit_d8( cbuf, $brOffs$$constant ); 1794 %} 1795 1796 enc_class enc_PartialSubtypeCheck( ) %{ 1797 Register Redi = as_Register(EDI_enc); // result register 1798 Register Reax = as_Register(EAX_enc); // super class 1799 Register Recx = as_Register(ECX_enc); // killed 1800 Register Resi = as_Register(ESI_enc); // sub class 1801 Label miss; 1802 1803 MacroAssembler _masm(&cbuf); 1804 __ check_klass_subtype_slow_path(Resi, Reax, Recx, Redi, 1805 NULL, &miss, 1806 /*set_cond_codes:*/ true); 1807 if ($primary) { 1808 __ xorptr(Redi, Redi); 1809 } 1810 __ bind(miss); 1811 %} 1812 1813 enc_class FFree_Float_Stack_All %{ // Free_Float_Stack_All 1814 MacroAssembler masm(&cbuf); 1815 int start = masm.offset(); 1816 if (UseSSE >= 2) { 1817 if (VerifyFPU) { 1818 masm.verify_FPU(0, "must be empty in SSE2+ mode"); 1819 } 1820 } else { 1821 // External c_calling_convention expects the FPU stack to be 'clean'. 1822 // Compiled code leaves it dirty. Do cleanup now. 1823 masm.empty_FPU_stack(); 1824 } 1825 if (sizeof_FFree_Float_Stack_All == -1) { 1826 sizeof_FFree_Float_Stack_All = masm.offset() - start; 1827 } else { 1828 assert(masm.offset() - start == sizeof_FFree_Float_Stack_All, "wrong size"); 1829 } 1830 %} 1831 1832 enc_class Verify_FPU_For_Leaf %{ 1833 if( VerifyFPU ) { 1834 MacroAssembler masm(&cbuf); 1835 masm.verify_FPU( -3, "Returning from Runtime Leaf call"); 1836 } 1837 %} 1838 1839 enc_class Java_To_Runtime (method meth) %{ // CALL Java_To_Runtime, Java_To_Runtime_Leaf 1840 // This is the instruction starting address for relocation info. 1841 cbuf.set_insts_mark(); 1842 $$$emit8$primary; 1843 // CALL directly to the runtime 1844 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4), 1845 runtime_call_Relocation::spec(), RELOC_IMM32 ); 1846 1847 if (UseSSE >= 2) { 1848 MacroAssembler _masm(&cbuf); 1849 BasicType rt = tf()->return_type(); 1850 1851 if ((rt == T_FLOAT || rt == T_DOUBLE) && !return_value_is_used()) { 1852 // A C runtime call where the return value is unused. In SSE2+ 1853 // mode the result needs to be removed from the FPU stack. It's 1854 // likely that this function call could be removed by the 1855 // optimizer if the C function is a pure function. 1856 __ ffree(0); 1857 } else if (rt == T_FLOAT) { 1858 __ lea(rsp, Address(rsp, -4)); 1859 __ fstp_s(Address(rsp, 0)); 1860 __ movflt(xmm0, Address(rsp, 0)); 1861 __ lea(rsp, Address(rsp, 4)); 1862 } else if (rt == T_DOUBLE) { 1863 __ lea(rsp, Address(rsp, -8)); 1864 __ fstp_d(Address(rsp, 0)); 1865 __ movdbl(xmm0, Address(rsp, 0)); 1866 __ lea(rsp, Address(rsp, 8)); 1867 } 1868 } 1869 %} 1870 1871 1872 enc_class pre_call_resets %{ 1873 // If method sets FPU control word restore it here 1874 debug_only(int off0 = cbuf.insts_size()); 1875 if (ra_->C->in_24_bit_fp_mode()) { 1876 MacroAssembler _masm(&cbuf); 1877 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); 1878 } 1879 if (ra_->C->max_vector_size() > 16) { 1880 // Clear upper bits of YMM registers when current compiled code uses 1881 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1882 MacroAssembler _masm(&cbuf); 1883 __ vzeroupper(); 1884 } 1885 debug_only(int off1 = cbuf.insts_size()); 1886 assert(off1 - off0 == pre_call_resets_size(), "correct size prediction"); 1887 %} 1888 1889 enc_class post_call_FPU %{ 1890 // If method sets FPU control word do it here also 1891 if (Compile::current()->in_24_bit_fp_mode()) { 1892 MacroAssembler masm(&cbuf); 1893 masm.fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24())); 1894 } 1895 %} 1896 1897 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL 1898 // CALL to fixup routine. Fixup routine uses ScopeDesc info to determine 1899 // who we intended to call. 1900 cbuf.set_insts_mark(); 1901 $$$emit8$primary; 1902 if (!_method) { 1903 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4), 1904 runtime_call_Relocation::spec(), RELOC_IMM32 ); 1905 } else if (_optimized_virtual) { 1906 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4), 1907 opt_virtual_call_Relocation::spec(), RELOC_IMM32 ); 1908 } else { 1909 emit_d32_reloc(cbuf, ($meth$$method - (int)(cbuf.insts_end()) - 4), 1910 static_call_Relocation::spec(), RELOC_IMM32 ); 1911 } 1912 if (_method) { // Emit stub for static call 1913 emit_java_to_interp(cbuf); 1914 } 1915 %} 1916 1917 enc_class Java_Dynamic_Call (method meth) %{ // JAVA DYNAMIC CALL 1918 MacroAssembler _masm(&cbuf); 1919 __ ic_call((address)$meth$$method); 1920 %} 1921 1922 enc_class Java_Compiled_Call (method meth) %{ // JAVA COMPILED CALL 1923 int disp = in_bytes(Method::from_compiled_offset()); 1924 assert( -128 <= disp && disp <= 127, "compiled_code_offset isn't small"); 1925 1926 // CALL *[EAX+in_bytes(Method::from_compiled_code_entry_point_offset())] 1927 cbuf.set_insts_mark(); 1928 $$$emit8$primary; 1929 emit_rm(cbuf, 0x01, $secondary, EAX_enc ); // R/M byte 1930 emit_d8(cbuf, disp); // Displacement 1931 1932 %} 1933 1934// Following encoding is no longer used, but may be restored if calling 1935// convention changes significantly. 1936// Became: Xor_Reg(EBP), Java_To_Runtime( labl ) 1937// 1938// enc_class Java_Interpreter_Call (label labl) %{ // JAVA INTERPRETER CALL 1939// // int ic_reg = Matcher::inline_cache_reg(); 1940// // int ic_encode = Matcher::_regEncode[ic_reg]; 1941// // int imo_reg = Matcher::interpreter_method_oop_reg(); 1942// // int imo_encode = Matcher::_regEncode[imo_reg]; 1943// 1944// // // Interpreter expects method_oop in EBX, currently a callee-saved register, 1945// // // so we load it immediately before the call 1946// // emit_opcode(cbuf, 0x8B); // MOV imo_reg,ic_reg # method_oop 1947// // emit_rm(cbuf, 0x03, imo_encode, ic_encode ); // R/M byte 1948// 1949// // xor rbp,ebp 1950// emit_opcode(cbuf, 0x33); 1951// emit_rm(cbuf, 0x3, EBP_enc, EBP_enc); 1952// 1953// // CALL to interpreter. 1954// cbuf.set_insts_mark(); 1955// $$$emit8$primary; 1956// emit_d32_reloc(cbuf, ($labl$$label - (int)(cbuf.insts_end()) - 4), 1957// runtime_call_Relocation::spec(), RELOC_IMM32 ); 1958// %} 1959 1960 enc_class RegOpcImm (rRegI dst, immI8 shift) %{ // SHL, SAR, SHR 1961 $$$emit8$primary; 1962 emit_rm(cbuf, 0x3, $secondary, $dst$$reg); 1963 $$$emit8$shift$$constant; 1964 %} 1965 1966 enc_class LdImmI (rRegI dst, immI src) %{ // Load Immediate 1967 // Load immediate does not have a zero or sign extended version 1968 // for 8-bit immediates 1969 emit_opcode(cbuf, 0xB8 + $dst$$reg); 1970 $$$emit32$src$$constant; 1971 %} 1972 1973 enc_class LdImmP (rRegI dst, immI src) %{ // Load Immediate 1974 // Load immediate does not have a zero or sign extended version 1975 // for 8-bit immediates 1976 emit_opcode(cbuf, $primary + $dst$$reg); 1977 $$$emit32$src$$constant; 1978 %} 1979 1980 enc_class LdImmL_Lo( eRegL dst, immL src) %{ // Load Immediate 1981 // Load immediate does not have a zero or sign extended version 1982 // for 8-bit immediates 1983 int dst_enc = $dst$$reg; 1984 int src_con = $src$$constant & 0x0FFFFFFFFL; 1985 if (src_con == 0) { 1986 // xor dst, dst 1987 emit_opcode(cbuf, 0x33); 1988 emit_rm(cbuf, 0x3, dst_enc, dst_enc); 1989 } else { 1990 emit_opcode(cbuf, $primary + dst_enc); 1991 emit_d32(cbuf, src_con); 1992 } 1993 %} 1994 1995 enc_class LdImmL_Hi( eRegL dst, immL src) %{ // Load Immediate 1996 // Load immediate does not have a zero or sign extended version 1997 // for 8-bit immediates 1998 int dst_enc = $dst$$reg + 2; 1999 int src_con = ((julong)($src$$constant)) >> 32; 2000 if (src_con == 0) { 2001 // xor dst, dst 2002 emit_opcode(cbuf, 0x33); 2003 emit_rm(cbuf, 0x3, dst_enc, dst_enc); 2004 } else { 2005 emit_opcode(cbuf, $primary + dst_enc); 2006 emit_d32(cbuf, src_con); 2007 } 2008 %} 2009 2010 2011 // Encode a reg-reg copy. If it is useless, then empty encoding. 2012 enc_class enc_Copy( rRegI dst, rRegI src ) %{ 2013 encode_Copy( cbuf, $dst$$reg, $src$$reg ); 2014 %} 2015 2016 enc_class enc_CopyL_Lo( rRegI dst, eRegL src ) %{ 2017 encode_Copy( cbuf, $dst$$reg, $src$$reg ); 2018 %} 2019 2020 enc_class RegReg (rRegI dst, rRegI src) %{ // RegReg(Many) 2021 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2022 %} 2023 2024 enc_class RegReg_Lo(eRegL dst, eRegL src) %{ // RegReg(Many) 2025 $$$emit8$primary; 2026 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2027 %} 2028 2029 enc_class RegReg_Hi(eRegL dst, eRegL src) %{ // RegReg(Many) 2030 $$$emit8$secondary; 2031 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg)); 2032 %} 2033 2034 enc_class RegReg_Lo2(eRegL dst, eRegL src) %{ // RegReg(Many) 2035 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2036 %} 2037 2038 enc_class RegReg_Hi2(eRegL dst, eRegL src) %{ // RegReg(Many) 2039 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg)); 2040 %} 2041 2042 enc_class RegReg_HiLo( eRegL src, rRegI dst ) %{ 2043 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($src$$reg)); 2044 %} 2045 2046 enc_class Con32 (immI src) %{ // Con32(storeImmI) 2047 // Output immediate 2048 $$$emit32$src$$constant; 2049 %} 2050 2051 enc_class Con32FPR_as_bits(immFPR src) %{ // storeF_imm 2052 // Output Float immediate bits 2053 jfloat jf = $src$$constant; 2054 int jf_as_bits = jint_cast( jf ); 2055 emit_d32(cbuf, jf_as_bits); 2056 %} 2057 2058 enc_class Con32F_as_bits(immF src) %{ // storeX_imm 2059 // Output Float immediate bits 2060 jfloat jf = $src$$constant; 2061 int jf_as_bits = jint_cast( jf ); 2062 emit_d32(cbuf, jf_as_bits); 2063 %} 2064 2065 enc_class Con16 (immI src) %{ // Con16(storeImmI) 2066 // Output immediate 2067 $$$emit16$src$$constant; 2068 %} 2069 2070 enc_class Con_d32(immI src) %{ 2071 emit_d32(cbuf,$src$$constant); 2072 %} 2073 2074 enc_class conmemref (eRegP t1) %{ // Con32(storeImmI) 2075 // Output immediate memory reference 2076 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2077 emit_d32(cbuf, 0x00); 2078 %} 2079 2080 enc_class lock_prefix( ) %{ 2081 if( os::is_MP() ) 2082 emit_opcode(cbuf,0xF0); // [Lock] 2083 %} 2084 2085 // Cmp-xchg long value. 2086 // Note: we need to swap rbx, and rcx before and after the 2087 // cmpxchg8 instruction because the instruction uses 2088 // rcx as the high order word of the new value to store but 2089 // our register encoding uses rbx,. 2090 enc_class enc_cmpxchg8(eSIRegP mem_ptr) %{ 2091 2092 // XCHG rbx,ecx 2093 emit_opcode(cbuf,0x87); 2094 emit_opcode(cbuf,0xD9); 2095 // [Lock] 2096 if( os::is_MP() ) 2097 emit_opcode(cbuf,0xF0); 2098 // CMPXCHG8 [Eptr] 2099 emit_opcode(cbuf,0x0F); 2100 emit_opcode(cbuf,0xC7); 2101 emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg ); 2102 // XCHG rbx,ecx 2103 emit_opcode(cbuf,0x87); 2104 emit_opcode(cbuf,0xD9); 2105 %} 2106 2107 enc_class enc_cmpxchg(eSIRegP mem_ptr) %{ 2108 // [Lock] 2109 if( os::is_MP() ) 2110 emit_opcode(cbuf,0xF0); 2111 2112 // CMPXCHG [Eptr] 2113 emit_opcode(cbuf,0x0F); 2114 emit_opcode(cbuf,0xB1); 2115 emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg ); 2116 %} 2117 2118 enc_class enc_flags_ne_to_boolean( iRegI res ) %{ 2119 int res_encoding = $res$$reg; 2120 2121 // MOV res,0 2122 emit_opcode( cbuf, 0xB8 + res_encoding); 2123 emit_d32( cbuf, 0 ); 2124 // JNE,s fail 2125 emit_opcode(cbuf,0x75); 2126 emit_d8(cbuf, 5 ); 2127 // MOV res,1 2128 emit_opcode( cbuf, 0xB8 + res_encoding); 2129 emit_d32( cbuf, 1 ); 2130 // fail: 2131 %} 2132 2133 enc_class set_instruction_start( ) %{ 2134 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand 2135 %} 2136 2137 enc_class RegMem (rRegI ereg, memory mem) %{ // emit_reg_mem 2138 int reg_encoding = $ereg$$reg; 2139 int base = $mem$$base; 2140 int index = $mem$$index; 2141 int scale = $mem$$scale; 2142 int displace = $mem$$disp; 2143 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2144 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_reloc); 2145 %} 2146 2147 enc_class RegMem_Hi(eRegL ereg, memory mem) %{ // emit_reg_mem 2148 int reg_encoding = HIGH_FROM_LOW($ereg$$reg); // Hi register of pair, computed from lo 2149 int base = $mem$$base; 2150 int index = $mem$$index; 2151 int scale = $mem$$scale; 2152 int displace = $mem$$disp + 4; // Offset is 4 further in memory 2153 assert( $mem->disp_reloc() == relocInfo::none, "Cannot add 4 to oop" ); 2154 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, relocInfo::none); 2155 %} 2156 2157 enc_class move_long_small_shift( eRegL dst, immI_1_31 cnt ) %{ 2158 int r1, r2; 2159 if( $tertiary == 0xA4 ) { r1 = $dst$$reg; r2 = HIGH_FROM_LOW($dst$$reg); } 2160 else { r2 = $dst$$reg; r1 = HIGH_FROM_LOW($dst$$reg); } 2161 emit_opcode(cbuf,0x0F); 2162 emit_opcode(cbuf,$tertiary); 2163 emit_rm(cbuf, 0x3, r1, r2); 2164 emit_d8(cbuf,$cnt$$constant); 2165 emit_d8(cbuf,$primary); 2166 emit_rm(cbuf, 0x3, $secondary, r1); 2167 emit_d8(cbuf,$cnt$$constant); 2168 %} 2169 2170 enc_class move_long_big_shift_sign( eRegL dst, immI_32_63 cnt ) %{ 2171 emit_opcode( cbuf, 0x8B ); // Move 2172 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg)); 2173 if( $cnt$$constant > 32 ) { // Shift, if not by zero 2174 emit_d8(cbuf,$primary); 2175 emit_rm(cbuf, 0x3, $secondary, $dst$$reg); 2176 emit_d8(cbuf,$cnt$$constant-32); 2177 } 2178 emit_d8(cbuf,$primary); 2179 emit_rm(cbuf, 0x3, $secondary, HIGH_FROM_LOW($dst$$reg)); 2180 emit_d8(cbuf,31); 2181 %} 2182 2183 enc_class move_long_big_shift_clr( eRegL dst, immI_32_63 cnt ) %{ 2184 int r1, r2; 2185 if( $secondary == 0x5 ) { r1 = $dst$$reg; r2 = HIGH_FROM_LOW($dst$$reg); } 2186 else { r2 = $dst$$reg; r1 = HIGH_FROM_LOW($dst$$reg); } 2187 2188 emit_opcode( cbuf, 0x8B ); // Move r1,r2 2189 emit_rm(cbuf, 0x3, r1, r2); 2190 if( $cnt$$constant > 32 ) { // Shift, if not by zero 2191 emit_opcode(cbuf,$primary); 2192 emit_rm(cbuf, 0x3, $secondary, r1); 2193 emit_d8(cbuf,$cnt$$constant-32); 2194 } 2195 emit_opcode(cbuf,0x33); // XOR r2,r2 2196 emit_rm(cbuf, 0x3, r2, r2); 2197 %} 2198 2199 // Clone of RegMem but accepts an extra parameter to access each 2200 // half of a double in memory; it never needs relocation info. 2201 enc_class Mov_MemD_half_to_Reg (immI opcode, memory mem, immI disp_for_half, rRegI rm_reg) %{ 2202 emit_opcode(cbuf,$opcode$$constant); 2203 int reg_encoding = $rm_reg$$reg; 2204 int base = $mem$$base; 2205 int index = $mem$$index; 2206 int scale = $mem$$scale; 2207 int displace = $mem$$disp + $disp_for_half$$constant; 2208 relocInfo::relocType disp_reloc = relocInfo::none; 2209 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_reloc); 2210 %} 2211 2212 // !!!!! Special Custom Code used by MemMove, and stack access instructions !!!!! 2213 // 2214 // Clone of RegMem except the RM-byte's reg/opcode field is an ADLC-time constant 2215 // and it never needs relocation information. 2216 // Frequently used to move data between FPU's Stack Top and memory. 2217 enc_class RMopc_Mem_no_oop (immI rm_opcode, memory mem) %{ 2218 int rm_byte_opcode = $rm_opcode$$constant; 2219 int base = $mem$$base; 2220 int index = $mem$$index; 2221 int scale = $mem$$scale; 2222 int displace = $mem$$disp; 2223 assert( $mem->disp_reloc() == relocInfo::none, "No oops here because no reloc info allowed" ); 2224 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, relocInfo::none); 2225 %} 2226 2227 enc_class RMopc_Mem (immI rm_opcode, memory mem) %{ 2228 int rm_byte_opcode = $rm_opcode$$constant; 2229 int base = $mem$$base; 2230 int index = $mem$$index; 2231 int scale = $mem$$scale; 2232 int displace = $mem$$disp; 2233 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when working with static globals 2234 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_reloc); 2235 %} 2236 2237 enc_class RegLea (rRegI dst, rRegI src0, immI src1 ) %{ // emit_reg_lea 2238 int reg_encoding = $dst$$reg; 2239 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2240 int index = 0x04; // 0x04 indicates no index 2241 int scale = 0x00; // 0x00 indicates no scale 2242 int displace = $src1$$constant; // 0x00 indicates no displacement 2243 relocInfo::relocType disp_reloc = relocInfo::none; 2244 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_reloc); 2245 %} 2246 2247 enc_class min_enc (rRegI dst, rRegI src) %{ // MIN 2248 // Compare dst,src 2249 emit_opcode(cbuf,0x3B); 2250 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2251 // jmp dst < src around move 2252 emit_opcode(cbuf,0x7C); 2253 emit_d8(cbuf,2); 2254 // move dst,src 2255 emit_opcode(cbuf,0x8B); 2256 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2257 %} 2258 2259 enc_class max_enc (rRegI dst, rRegI src) %{ // MAX 2260 // Compare dst,src 2261 emit_opcode(cbuf,0x3B); 2262 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2263 // jmp dst > src around move 2264 emit_opcode(cbuf,0x7F); 2265 emit_d8(cbuf,2); 2266 // move dst,src 2267 emit_opcode(cbuf,0x8B); 2268 emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg); 2269 %} 2270 2271 enc_class enc_FPR_store(memory mem, regDPR src) %{ 2272 // If src is FPR1, we can just FST to store it. 2273 // Else we need to FLD it to FPR1, then FSTP to store/pop it. 2274 int reg_encoding = 0x2; // Just store 2275 int base = $mem$$base; 2276 int index = $mem$$index; 2277 int scale = $mem$$scale; 2278 int displace = $mem$$disp; 2279 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when working with static globals 2280 if( $src$$reg != FPR1L_enc ) { 2281 reg_encoding = 0x3; // Store & pop 2282 emit_opcode( cbuf, 0xD9 ); // FLD (i.e., push it) 2283 emit_d8( cbuf, 0xC0-1+$src$$reg ); 2284 } 2285 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand 2286 emit_opcode(cbuf,$primary); 2287 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_reloc); 2288 %} 2289 2290 enc_class neg_reg(rRegI dst) %{ 2291 // NEG $dst 2292 emit_opcode(cbuf,0xF7); 2293 emit_rm(cbuf, 0x3, 0x03, $dst$$reg ); 2294 %} 2295 2296 enc_class setLT_reg(eCXRegI dst) %{ 2297 // SETLT $dst 2298 emit_opcode(cbuf,0x0F); 2299 emit_opcode(cbuf,0x9C); 2300 emit_rm( cbuf, 0x3, 0x4, $dst$$reg ); 2301 %} 2302 2303 enc_class enc_cmpLTP(ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp) %{ // cadd_cmpLT 2304 int tmpReg = $tmp$$reg; 2305 2306 // SUB $p,$q 2307 emit_opcode(cbuf,0x2B); 2308 emit_rm(cbuf, 0x3, $p$$reg, $q$$reg); 2309 // SBB $tmp,$tmp 2310 emit_opcode(cbuf,0x1B); 2311 emit_rm(cbuf, 0x3, tmpReg, tmpReg); 2312 // AND $tmp,$y 2313 emit_opcode(cbuf,0x23); 2314 emit_rm(cbuf, 0x3, tmpReg, $y$$reg); 2315 // ADD $p,$tmp 2316 emit_opcode(cbuf,0x03); 2317 emit_rm(cbuf, 0x3, $p$$reg, tmpReg); 2318 %} 2319 2320 enc_class enc_cmpLTP_mem(rRegI p, rRegI q, memory mem, eCXRegI tmp) %{ // cadd_cmpLT 2321 int tmpReg = $tmp$$reg; 2322 2323 // SUB $p,$q 2324 emit_opcode(cbuf,0x2B); 2325 emit_rm(cbuf, 0x3, $p$$reg, $q$$reg); 2326 // SBB $tmp,$tmp 2327 emit_opcode(cbuf,0x1B); 2328 emit_rm(cbuf, 0x3, tmpReg, tmpReg); 2329 // AND $tmp,$y 2330 cbuf.set_insts_mark(); // Mark start of opcode for reloc info in mem operand 2331 emit_opcode(cbuf,0x23); 2332 int reg_encoding = tmpReg; 2333 int base = $mem$$base; 2334 int index = $mem$$index; 2335 int scale = $mem$$scale; 2336 int displace = $mem$$disp; 2337 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2338 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_reloc); 2339 // ADD $p,$tmp 2340 emit_opcode(cbuf,0x03); 2341 emit_rm(cbuf, 0x3, $p$$reg, tmpReg); 2342 %} 2343 2344 enc_class shift_left_long( eRegL dst, eCXRegI shift ) %{ 2345 // TEST shift,32 2346 emit_opcode(cbuf,0xF7); 2347 emit_rm(cbuf, 0x3, 0, ECX_enc); 2348 emit_d32(cbuf,0x20); 2349 // JEQ,s small 2350 emit_opcode(cbuf, 0x74); 2351 emit_d8(cbuf, 0x04); 2352 // MOV $dst.hi,$dst.lo 2353 emit_opcode( cbuf, 0x8B ); 2354 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg ); 2355 // CLR $dst.lo 2356 emit_opcode(cbuf, 0x33); 2357 emit_rm(cbuf, 0x3, $dst$$reg, $dst$$reg); 2358// small: 2359 // SHLD $dst.hi,$dst.lo,$shift 2360 emit_opcode(cbuf,0x0F); 2361 emit_opcode(cbuf,0xA5); 2362 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg)); 2363 // SHL $dst.lo,$shift" 2364 emit_opcode(cbuf,0xD3); 2365 emit_rm(cbuf, 0x3, 0x4, $dst$$reg ); 2366 %} 2367 2368 enc_class shift_right_long( eRegL dst, eCXRegI shift ) %{ 2369 // TEST shift,32 2370 emit_opcode(cbuf,0xF7); 2371 emit_rm(cbuf, 0x3, 0, ECX_enc); 2372 emit_d32(cbuf,0x20); 2373 // JEQ,s small 2374 emit_opcode(cbuf, 0x74); 2375 emit_d8(cbuf, 0x04); 2376 // MOV $dst.lo,$dst.hi 2377 emit_opcode( cbuf, 0x8B ); 2378 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg) ); 2379 // CLR $dst.hi 2380 emit_opcode(cbuf, 0x33); 2381 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($dst$$reg)); 2382// small: 2383 // SHRD $dst.lo,$dst.hi,$shift 2384 emit_opcode(cbuf,0x0F); 2385 emit_opcode(cbuf,0xAD); 2386 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg); 2387 // SHR $dst.hi,$shift" 2388 emit_opcode(cbuf,0xD3); 2389 emit_rm(cbuf, 0x3, 0x5, HIGH_FROM_LOW($dst$$reg) ); 2390 %} 2391 2392 enc_class shift_right_arith_long( eRegL dst, eCXRegI shift ) %{ 2393 // TEST shift,32 2394 emit_opcode(cbuf,0xF7); 2395 emit_rm(cbuf, 0x3, 0, ECX_enc); 2396 emit_d32(cbuf,0x20); 2397 // JEQ,s small 2398 emit_opcode(cbuf, 0x74); 2399 emit_d8(cbuf, 0x05); 2400 // MOV $dst.lo,$dst.hi 2401 emit_opcode( cbuf, 0x8B ); 2402 emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($dst$$reg) ); 2403 // SAR $dst.hi,31 2404 emit_opcode(cbuf, 0xC1); 2405 emit_rm(cbuf, 0x3, 7, HIGH_FROM_LOW($dst$$reg) ); 2406 emit_d8(cbuf, 0x1F ); 2407// small: 2408 // SHRD $dst.lo,$dst.hi,$shift 2409 emit_opcode(cbuf,0x0F); 2410 emit_opcode(cbuf,0xAD); 2411 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg); 2412 // SAR $dst.hi,$shift" 2413 emit_opcode(cbuf,0xD3); 2414 emit_rm(cbuf, 0x3, 0x7, HIGH_FROM_LOW($dst$$reg) ); 2415 %} 2416 2417 2418 // ----------------- Encodings for floating point unit ----------------- 2419 // May leave result in FPU-TOS or FPU reg depending on opcodes 2420 enc_class OpcReg_FPR(regFPR src) %{ // FMUL, FDIV 2421 $$$emit8$primary; 2422 emit_rm(cbuf, 0x3, $secondary, $src$$reg ); 2423 %} 2424 2425 // Pop argument in FPR0 with FSTP ST(0) 2426 enc_class PopFPU() %{ 2427 emit_opcode( cbuf, 0xDD ); 2428 emit_d8( cbuf, 0xD8 ); 2429 %} 2430 2431 // !!!!! equivalent to Pop_Reg_F 2432 enc_class Pop_Reg_DPR( regDPR dst ) %{ 2433 emit_opcode( cbuf, 0xDD ); // FSTP ST(i) 2434 emit_d8( cbuf, 0xD8+$dst$$reg ); 2435 %} 2436 2437 enc_class Push_Reg_DPR( regDPR dst ) %{ 2438 emit_opcode( cbuf, 0xD9 ); 2439 emit_d8( cbuf, 0xC0-1+$dst$$reg ); // FLD ST(i-1) 2440 %} 2441 2442 enc_class strictfp_bias1( regDPR dst ) %{ 2443 emit_opcode( cbuf, 0xDB ); // FLD m80real 2444 emit_opcode( cbuf, 0x2D ); 2445 emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias1() ); 2446 emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0 2447 emit_opcode( cbuf, 0xC8+$dst$$reg ); 2448 %} 2449 2450 enc_class strictfp_bias2( regDPR dst ) %{ 2451 emit_opcode( cbuf, 0xDB ); // FLD m80real 2452 emit_opcode( cbuf, 0x2D ); 2453 emit_d32( cbuf, (int)StubRoutines::addr_fpu_subnormal_bias2() ); 2454 emit_opcode( cbuf, 0xDE ); // FMULP ST(dst), ST0 2455 emit_opcode( cbuf, 0xC8+$dst$$reg ); 2456 %} 2457 2458 // Special case for moving an integer register to a stack slot. 2459 enc_class OpcPRegSS( stackSlotI dst, rRegI src ) %{ // RegSS 2460 store_to_stackslot( cbuf, $primary, $src$$reg, $dst$$disp ); 2461 %} 2462 2463 // Special case for moving a register to a stack slot. 2464 enc_class RegSS( stackSlotI dst, rRegI src ) %{ // RegSS 2465 // Opcode already emitted 2466 emit_rm( cbuf, 0x02, $src$$reg, ESP_enc ); // R/M byte 2467 emit_rm( cbuf, 0x00, ESP_enc, ESP_enc); // SIB byte 2468 emit_d32(cbuf, $dst$$disp); // Displacement 2469 %} 2470 2471 // Push the integer in stackSlot 'src' onto FP-stack 2472 enc_class Push_Mem_I( memory src ) %{ // FILD [ESP+src] 2473 store_to_stackslot( cbuf, $primary, $secondary, $src$$disp ); 2474 %} 2475 2476 // Push FPU's TOS float to a stack-slot, and pop FPU-stack 2477 enc_class Pop_Mem_FPR( stackSlotF dst ) %{ // FSTP_S [ESP+dst] 2478 store_to_stackslot( cbuf, 0xD9, 0x03, $dst$$disp ); 2479 %} 2480 2481 // Same as Pop_Mem_F except for opcode 2482 // Push FPU's TOS double to a stack-slot, and pop FPU-stack 2483 enc_class Pop_Mem_DPR( stackSlotD dst ) %{ // FSTP_D [ESP+dst] 2484 store_to_stackslot( cbuf, 0xDD, 0x03, $dst$$disp ); 2485 %} 2486 2487 enc_class Pop_Reg_FPR( regFPR dst ) %{ 2488 emit_opcode( cbuf, 0xDD ); // FSTP ST(i) 2489 emit_d8( cbuf, 0xD8+$dst$$reg ); 2490 %} 2491 2492 enc_class Push_Reg_FPR( regFPR dst ) %{ 2493 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1) 2494 emit_d8( cbuf, 0xC0-1+$dst$$reg ); 2495 %} 2496 2497 // Push FPU's float to a stack-slot, and pop FPU-stack 2498 enc_class Pop_Mem_Reg_FPR( stackSlotF dst, regFPR src ) %{ 2499 int pop = 0x02; 2500 if ($src$$reg != FPR1L_enc) { 2501 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1) 2502 emit_d8( cbuf, 0xC0-1+$src$$reg ); 2503 pop = 0x03; 2504 } 2505 store_to_stackslot( cbuf, 0xD9, pop, $dst$$disp ); // FST<P>_S [ESP+dst] 2506 %} 2507 2508 // Push FPU's double to a stack-slot, and pop FPU-stack 2509 enc_class Pop_Mem_Reg_DPR( stackSlotD dst, regDPR src ) %{ 2510 int pop = 0x02; 2511 if ($src$$reg != FPR1L_enc) { 2512 emit_opcode( cbuf, 0xD9 ); // FLD ST(i-1) 2513 emit_d8( cbuf, 0xC0-1+$src$$reg ); 2514 pop = 0x03; 2515 } 2516 store_to_stackslot( cbuf, 0xDD, pop, $dst$$disp ); // FST<P>_D [ESP+dst] 2517 %} 2518 2519 // Push FPU's double to a FPU-stack-slot, and pop FPU-stack 2520 enc_class Pop_Reg_Reg_DPR( regDPR dst, regFPR src ) %{ 2521 int pop = 0xD0 - 1; // -1 since we skip FLD 2522 if ($src$$reg != FPR1L_enc) { 2523 emit_opcode( cbuf, 0xD9 ); // FLD ST(src-1) 2524 emit_d8( cbuf, 0xC0-1+$src$$reg ); 2525 pop = 0xD8; 2526 } 2527 emit_opcode( cbuf, 0xDD ); 2528 emit_d8( cbuf, pop+$dst$$reg ); // FST<P> ST(i) 2529 %} 2530 2531 2532 enc_class Push_Reg_Mod_DPR( regDPR dst, regDPR src) %{ 2533 // load dst in FPR0 2534 emit_opcode( cbuf, 0xD9 ); 2535 emit_d8( cbuf, 0xC0-1+$dst$$reg ); 2536 if ($src$$reg != FPR1L_enc) { 2537 // fincstp 2538 emit_opcode (cbuf, 0xD9); 2539 emit_opcode (cbuf, 0xF7); 2540 // swap src with FPR1: 2541 // FXCH FPR1 with src 2542 emit_opcode(cbuf, 0xD9); 2543 emit_d8(cbuf, 0xC8-1+$src$$reg ); 2544 // fdecstp 2545 emit_opcode (cbuf, 0xD9); 2546 emit_opcode (cbuf, 0xF6); 2547 } 2548 %} 2549 2550 enc_class Push_ModD_encoding(regD src0, regD src1) %{ 2551 MacroAssembler _masm(&cbuf); 2552 __ subptr(rsp, 8); 2553 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 2554 __ fld_d(Address(rsp, 0)); 2555 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 2556 __ fld_d(Address(rsp, 0)); 2557 %} 2558 2559 enc_class Push_ModF_encoding(regF src0, regF src1) %{ 2560 MacroAssembler _masm(&cbuf); 2561 __ subptr(rsp, 4); 2562 __ movflt(Address(rsp, 0), $src1$$XMMRegister); 2563 __ fld_s(Address(rsp, 0)); 2564 __ movflt(Address(rsp, 0), $src0$$XMMRegister); 2565 __ fld_s(Address(rsp, 0)); 2566 %} 2567 2568 enc_class Push_ResultD(regD dst) %{ 2569 MacroAssembler _masm(&cbuf); 2570 __ fstp_d(Address(rsp, 0)); 2571 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2572 __ addptr(rsp, 8); 2573 %} 2574 2575 enc_class Push_ResultF(regF dst, immI d8) %{ 2576 MacroAssembler _masm(&cbuf); 2577 __ fstp_s(Address(rsp, 0)); 2578 __ movflt($dst$$XMMRegister, Address(rsp, 0)); 2579 __ addptr(rsp, $d8$$constant); 2580 %} 2581 2582 enc_class Push_SrcD(regD src) %{ 2583 MacroAssembler _masm(&cbuf); 2584 __ subptr(rsp, 8); 2585 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2586 __ fld_d(Address(rsp, 0)); 2587 %} 2588 2589 enc_class push_stack_temp_qword() %{ 2590 MacroAssembler _masm(&cbuf); 2591 __ subptr(rsp, 8); 2592 %} 2593 2594 enc_class pop_stack_temp_qword() %{ 2595 MacroAssembler _masm(&cbuf); 2596 __ addptr(rsp, 8); 2597 %} 2598 2599 enc_class push_xmm_to_fpr1(regD src) %{ 2600 MacroAssembler _masm(&cbuf); 2601 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2602 __ fld_d(Address(rsp, 0)); 2603 %} 2604 2605 enc_class Push_Result_Mod_DPR( regDPR src) %{ 2606 if ($src$$reg != FPR1L_enc) { 2607 // fincstp 2608 emit_opcode (cbuf, 0xD9); 2609 emit_opcode (cbuf, 0xF7); 2610 // FXCH FPR1 with src 2611 emit_opcode(cbuf, 0xD9); 2612 emit_d8(cbuf, 0xC8-1+$src$$reg ); 2613 // fdecstp 2614 emit_opcode (cbuf, 0xD9); 2615 emit_opcode (cbuf, 0xF6); 2616 } 2617 // // following asm replaced with Pop_Reg_F or Pop_Mem_F 2618 // // FSTP FPR$dst$$reg 2619 // emit_opcode( cbuf, 0xDD ); 2620 // emit_d8( cbuf, 0xD8+$dst$$reg ); 2621 %} 2622 2623 enc_class fnstsw_sahf_skip_parity() %{ 2624 // fnstsw ax 2625 emit_opcode( cbuf, 0xDF ); 2626 emit_opcode( cbuf, 0xE0 ); 2627 // sahf 2628 emit_opcode( cbuf, 0x9E ); 2629 // jnp ::skip 2630 emit_opcode( cbuf, 0x7B ); 2631 emit_opcode( cbuf, 0x05 ); 2632 %} 2633 2634 enc_class emitModDPR() %{ 2635 // fprem must be iterative 2636 // :: loop 2637 // fprem 2638 emit_opcode( cbuf, 0xD9 ); 2639 emit_opcode( cbuf, 0xF8 ); 2640 // wait 2641 emit_opcode( cbuf, 0x9b ); 2642 // fnstsw ax 2643 emit_opcode( cbuf, 0xDF ); 2644 emit_opcode( cbuf, 0xE0 ); 2645 // sahf 2646 emit_opcode( cbuf, 0x9E ); 2647 // jp ::loop 2648 emit_opcode( cbuf, 0x0F ); 2649 emit_opcode( cbuf, 0x8A ); 2650 emit_opcode( cbuf, 0xF4 ); 2651 emit_opcode( cbuf, 0xFF ); 2652 emit_opcode( cbuf, 0xFF ); 2653 emit_opcode( cbuf, 0xFF ); 2654 %} 2655 2656 enc_class fpu_flags() %{ 2657 // fnstsw_ax 2658 emit_opcode( cbuf, 0xDF); 2659 emit_opcode( cbuf, 0xE0); 2660 // test ax,0x0400 2661 emit_opcode( cbuf, 0x66 ); // operand-size prefix for 16-bit immediate 2662 emit_opcode( cbuf, 0xA9 ); 2663 emit_d16 ( cbuf, 0x0400 ); 2664 // // // This sequence works, but stalls for 12-16 cycles on PPro 2665 // // test rax,0x0400 2666 // emit_opcode( cbuf, 0xA9 ); 2667 // emit_d32 ( cbuf, 0x00000400 ); 2668 // 2669 // jz exit (no unordered comparison) 2670 emit_opcode( cbuf, 0x74 ); 2671 emit_d8 ( cbuf, 0x02 ); 2672 // mov ah,1 - treat as LT case (set carry flag) 2673 emit_opcode( cbuf, 0xB4 ); 2674 emit_d8 ( cbuf, 0x01 ); 2675 // sahf 2676 emit_opcode( cbuf, 0x9E); 2677 %} 2678 2679 enc_class cmpF_P6_fixup() %{ 2680 // Fixup the integer flags in case comparison involved a NaN 2681 // 2682 // JNP exit (no unordered comparison, P-flag is set by NaN) 2683 emit_opcode( cbuf, 0x7B ); 2684 emit_d8 ( cbuf, 0x03 ); 2685 // MOV AH,1 - treat as LT case (set carry flag) 2686 emit_opcode( cbuf, 0xB4 ); 2687 emit_d8 ( cbuf, 0x01 ); 2688 // SAHF 2689 emit_opcode( cbuf, 0x9E); 2690 // NOP // target for branch to avoid branch to branch 2691 emit_opcode( cbuf, 0x90); 2692 %} 2693 2694// fnstsw_ax(); 2695// sahf(); 2696// movl(dst, nan_result); 2697// jcc(Assembler::parity, exit); 2698// movl(dst, less_result); 2699// jcc(Assembler::below, exit); 2700// movl(dst, equal_result); 2701// jcc(Assembler::equal, exit); 2702// movl(dst, greater_result); 2703 2704// less_result = 1; 2705// greater_result = -1; 2706// equal_result = 0; 2707// nan_result = -1; 2708 2709 enc_class CmpF_Result(rRegI dst) %{ 2710 // fnstsw_ax(); 2711 emit_opcode( cbuf, 0xDF); 2712 emit_opcode( cbuf, 0xE0); 2713 // sahf 2714 emit_opcode( cbuf, 0x9E); 2715 // movl(dst, nan_result); 2716 emit_opcode( cbuf, 0xB8 + $dst$$reg); 2717 emit_d32( cbuf, -1 ); 2718 // jcc(Assembler::parity, exit); 2719 emit_opcode( cbuf, 0x7A ); 2720 emit_d8 ( cbuf, 0x13 ); 2721 // movl(dst, less_result); 2722 emit_opcode( cbuf, 0xB8 + $dst$$reg); 2723 emit_d32( cbuf, -1 ); 2724 // jcc(Assembler::below, exit); 2725 emit_opcode( cbuf, 0x72 ); 2726 emit_d8 ( cbuf, 0x0C ); 2727 // movl(dst, equal_result); 2728 emit_opcode( cbuf, 0xB8 + $dst$$reg); 2729 emit_d32( cbuf, 0 ); 2730 // jcc(Assembler::equal, exit); 2731 emit_opcode( cbuf, 0x74 ); 2732 emit_d8 ( cbuf, 0x05 ); 2733 // movl(dst, greater_result); 2734 emit_opcode( cbuf, 0xB8 + $dst$$reg); 2735 emit_d32( cbuf, 1 ); 2736 %} 2737 2738 2739 // Compare the longs and set flags 2740 // BROKEN! Do Not use as-is 2741 enc_class cmpl_test( eRegL src1, eRegL src2 ) %{ 2742 // CMP $src1.hi,$src2.hi 2743 emit_opcode( cbuf, 0x3B ); 2744 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) ); 2745 // JNE,s done 2746 emit_opcode(cbuf,0x75); 2747 emit_d8(cbuf, 2 ); 2748 // CMP $src1.lo,$src2.lo 2749 emit_opcode( cbuf, 0x3B ); 2750 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg ); 2751// done: 2752 %} 2753 2754 enc_class convert_int_long( regL dst, rRegI src ) %{ 2755 // mov $dst.lo,$src 2756 int dst_encoding = $dst$$reg; 2757 int src_encoding = $src$$reg; 2758 encode_Copy( cbuf, dst_encoding , src_encoding ); 2759 // mov $dst.hi,$src 2760 encode_Copy( cbuf, HIGH_FROM_LOW(dst_encoding), src_encoding ); 2761 // sar $dst.hi,31 2762 emit_opcode( cbuf, 0xC1 ); 2763 emit_rm(cbuf, 0x3, 7, HIGH_FROM_LOW(dst_encoding) ); 2764 emit_d8(cbuf, 0x1F ); 2765 %} 2766 2767 enc_class convert_long_double( eRegL src ) %{ 2768 // push $src.hi 2769 emit_opcode(cbuf, 0x50+HIGH_FROM_LOW($src$$reg)); 2770 // push $src.lo 2771 emit_opcode(cbuf, 0x50+$src$$reg ); 2772 // fild 64-bits at [SP] 2773 emit_opcode(cbuf,0xdf); 2774 emit_d8(cbuf, 0x6C); 2775 emit_d8(cbuf, 0x24); 2776 emit_d8(cbuf, 0x00); 2777 // pop stack 2778 emit_opcode(cbuf, 0x83); // add SP, #8 2779 emit_rm(cbuf, 0x3, 0x00, ESP_enc); 2780 emit_d8(cbuf, 0x8); 2781 %} 2782 2783 enc_class multiply_con_and_shift_high( eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32_63 cnt, eFlagsReg cr ) %{ 2784 // IMUL EDX:EAX,$src1 2785 emit_opcode( cbuf, 0xF7 ); 2786 emit_rm( cbuf, 0x3, 0x5, $src1$$reg ); 2787 // SAR EDX,$cnt-32 2788 int shift_count = ((int)$cnt$$constant) - 32; 2789 if (shift_count > 0) { 2790 emit_opcode(cbuf, 0xC1); 2791 emit_rm(cbuf, 0x3, 7, $dst$$reg ); 2792 emit_d8(cbuf, shift_count); 2793 } 2794 %} 2795 2796 // this version doesn't have add sp, 8 2797 enc_class convert_long_double2( eRegL src ) %{ 2798 // push $src.hi 2799 emit_opcode(cbuf, 0x50+HIGH_FROM_LOW($src$$reg)); 2800 // push $src.lo 2801 emit_opcode(cbuf, 0x50+$src$$reg ); 2802 // fild 64-bits at [SP] 2803 emit_opcode(cbuf,0xdf); 2804 emit_d8(cbuf, 0x6C); 2805 emit_d8(cbuf, 0x24); 2806 emit_d8(cbuf, 0x00); 2807 %} 2808 2809 enc_class long_int_multiply( eADXRegL dst, nadxRegI src) %{ 2810 // Basic idea: long = (long)int * (long)int 2811 // IMUL EDX:EAX, src 2812 emit_opcode( cbuf, 0xF7 ); 2813 emit_rm( cbuf, 0x3, 0x5, $src$$reg); 2814 %} 2815 2816 enc_class long_uint_multiply( eADXRegL dst, nadxRegI src) %{ 2817 // Basic Idea: long = (int & 0xffffffffL) * (int & 0xffffffffL) 2818 // MUL EDX:EAX, src 2819 emit_opcode( cbuf, 0xF7 ); 2820 emit_rm( cbuf, 0x3, 0x4, $src$$reg); 2821 %} 2822 2823 enc_class long_multiply( eADXRegL dst, eRegL src, rRegI tmp ) %{ 2824 // Basic idea: lo(result) = lo(x_lo * y_lo) 2825 // hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi) 2826 // MOV $tmp,$src.lo 2827 encode_Copy( cbuf, $tmp$$reg, $src$$reg ); 2828 // IMUL $tmp,EDX 2829 emit_opcode( cbuf, 0x0F ); 2830 emit_opcode( cbuf, 0xAF ); 2831 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) ); 2832 // MOV EDX,$src.hi 2833 encode_Copy( cbuf, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg) ); 2834 // IMUL EDX,EAX 2835 emit_opcode( cbuf, 0x0F ); 2836 emit_opcode( cbuf, 0xAF ); 2837 emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $dst$$reg ); 2838 // ADD $tmp,EDX 2839 emit_opcode( cbuf, 0x03 ); 2840 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) ); 2841 // MUL EDX:EAX,$src.lo 2842 emit_opcode( cbuf, 0xF7 ); 2843 emit_rm( cbuf, 0x3, 0x4, $src$$reg ); 2844 // ADD EDX,ESI 2845 emit_opcode( cbuf, 0x03 ); 2846 emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $tmp$$reg ); 2847 %} 2848 2849 enc_class long_multiply_con( eADXRegL dst, immL_127 src, rRegI tmp ) %{ 2850 // Basic idea: lo(result) = lo(src * y_lo) 2851 // hi(result) = hi(src * y_lo) + lo(src * y_hi) 2852 // IMUL $tmp,EDX,$src 2853 emit_opcode( cbuf, 0x6B ); 2854 emit_rm( cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($dst$$reg) ); 2855 emit_d8( cbuf, (int)$src$$constant ); 2856 // MOV EDX,$src 2857 emit_opcode(cbuf, 0xB8 + EDX_enc); 2858 emit_d32( cbuf, (int)$src$$constant ); 2859 // MUL EDX:EAX,EDX 2860 emit_opcode( cbuf, 0xF7 ); 2861 emit_rm( cbuf, 0x3, 0x4, EDX_enc ); 2862 // ADD EDX,ESI 2863 emit_opcode( cbuf, 0x03 ); 2864 emit_rm( cbuf, 0x3, EDX_enc, $tmp$$reg ); 2865 %} 2866 2867 enc_class long_div( eRegL src1, eRegL src2 ) %{ 2868 // PUSH src1.hi 2869 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src1$$reg) ); 2870 // PUSH src1.lo 2871 emit_opcode(cbuf, 0x50+$src1$$reg ); 2872 // PUSH src2.hi 2873 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src2$$reg) ); 2874 // PUSH src2.lo 2875 emit_opcode(cbuf, 0x50+$src2$$reg ); 2876 // CALL directly to the runtime 2877 cbuf.set_insts_mark(); 2878 emit_opcode(cbuf,0xE8); // Call into runtime 2879 emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::ldiv) - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 2880 // Restore stack 2881 emit_opcode(cbuf, 0x83); // add SP, #framesize 2882 emit_rm(cbuf, 0x3, 0x00, ESP_enc); 2883 emit_d8(cbuf, 4*4); 2884 %} 2885 2886 enc_class long_mod( eRegL src1, eRegL src2 ) %{ 2887 // PUSH src1.hi 2888 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src1$$reg) ); 2889 // PUSH src1.lo 2890 emit_opcode(cbuf, 0x50+$src1$$reg ); 2891 // PUSH src2.hi 2892 emit_opcode(cbuf, HIGH_FROM_LOW(0x50+$src2$$reg) ); 2893 // PUSH src2.lo 2894 emit_opcode(cbuf, 0x50+$src2$$reg ); 2895 // CALL directly to the runtime 2896 cbuf.set_insts_mark(); 2897 emit_opcode(cbuf,0xE8); // Call into runtime 2898 emit_d32_reloc(cbuf, (CAST_FROM_FN_PTR(address, SharedRuntime::lrem ) - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 2899 // Restore stack 2900 emit_opcode(cbuf, 0x83); // add SP, #framesize 2901 emit_rm(cbuf, 0x3, 0x00, ESP_enc); 2902 emit_d8(cbuf, 4*4); 2903 %} 2904 2905 enc_class long_cmp_flags0( eRegL src, rRegI tmp ) %{ 2906 // MOV $tmp,$src.lo 2907 emit_opcode(cbuf, 0x8B); 2908 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg); 2909 // OR $tmp,$src.hi 2910 emit_opcode(cbuf, 0x0B); 2911 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg)); 2912 %} 2913 2914 enc_class long_cmp_flags1( eRegL src1, eRegL src2 ) %{ 2915 // CMP $src1.lo,$src2.lo 2916 emit_opcode( cbuf, 0x3B ); 2917 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg ); 2918 // JNE,s skip 2919 emit_cc(cbuf, 0x70, 0x5); 2920 emit_d8(cbuf,2); 2921 // CMP $src1.hi,$src2.hi 2922 emit_opcode( cbuf, 0x3B ); 2923 emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) ); 2924 %} 2925 2926 enc_class long_cmp_flags2( eRegL src1, eRegL src2, rRegI tmp ) %{ 2927 // CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits 2928 emit_opcode( cbuf, 0x3B ); 2929 emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg ); 2930 // MOV $tmp,$src1.hi 2931 emit_opcode( cbuf, 0x8B ); 2932 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src1$$reg) ); 2933 // SBB $tmp,$src2.hi\t! Compute flags for long compare 2934 emit_opcode( cbuf, 0x1B ); 2935 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src2$$reg) ); 2936 %} 2937 2938 enc_class long_cmp_flags3( eRegL src, rRegI tmp ) %{ 2939 // XOR $tmp,$tmp 2940 emit_opcode(cbuf,0x33); // XOR 2941 emit_rm(cbuf,0x3, $tmp$$reg, $tmp$$reg); 2942 // CMP $tmp,$src.lo 2943 emit_opcode( cbuf, 0x3B ); 2944 emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg ); 2945 // SBB $tmp,$src.hi 2946 emit_opcode( cbuf, 0x1B ); 2947 emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src$$reg) ); 2948 %} 2949 2950 // Sniff, sniff... smells like Gnu Superoptimizer 2951 enc_class neg_long( eRegL dst ) %{ 2952 emit_opcode(cbuf,0xF7); // NEG hi 2953 emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg)); 2954 emit_opcode(cbuf,0xF7); // NEG lo 2955 emit_rm (cbuf,0x3, 0x3, $dst$$reg ); 2956 emit_opcode(cbuf,0x83); // SBB hi,0 2957 emit_rm (cbuf,0x3, 0x3, HIGH_FROM_LOW($dst$$reg)); 2958 emit_d8 (cbuf,0 ); 2959 %} 2960 2961 2962 // Because the transitions from emitted code to the runtime 2963 // monitorenter/exit helper stubs are so slow it's critical that 2964 // we inline both the stack-locking fast-path and the inflated fast path. 2965 // 2966 // See also: cmpFastLock and cmpFastUnlock. 2967 // 2968 // What follows is a specialized inline transliteration of the code 2969 // in slow_enter() and slow_exit(). If we're concerned about I$ bloat 2970 // another option would be to emit TrySlowEnter and TrySlowExit methods 2971 // at startup-time. These methods would accept arguments as 2972 // (rax,=Obj, rbx=Self, rcx=box, rdx=Scratch) and return success-failure 2973 // indications in the icc.ZFlag. Fast_Lock and Fast_Unlock would simply 2974 // marshal the arguments and emit calls to TrySlowEnter and TrySlowExit. 2975 // In practice, however, the # of lock sites is bounded and is usually small. 2976 // Besides the call overhead, TrySlowEnter and TrySlowExit might suffer 2977 // if the processor uses simple bimodal branch predictors keyed by EIP 2978 // Since the helper routines would be called from multiple synchronization 2979 // sites. 2980 // 2981 // An even better approach would be write "MonitorEnter()" and "MonitorExit()" 2982 // in java - using j.u.c and unsafe - and just bind the lock and unlock sites 2983 // to those specialized methods. That'd give us a mostly platform-independent 2984 // implementation that the JITs could optimize and inline at their pleasure. 2985 // Done correctly, the only time we'd need to cross to native could would be 2986 // to park() or unpark() threads. We'd also need a few more unsafe operators 2987 // to (a) prevent compiler-JIT reordering of non-volatile accesses, and 2988 // (b) explicit barriers or fence operations. 2989 // 2990 // TODO: 2991 // 2992 // * Arrange for C2 to pass "Self" into Fast_Lock and Fast_Unlock in one of the registers (scr). 2993 // This avoids manifesting the Self pointer in the Fast_Lock and Fast_Unlock terminals. 2994 // Given TLAB allocation, Self is usually manifested in a register, so passing it into 2995 // the lock operators would typically be faster than reifying Self. 2996 // 2997 // * Ideally I'd define the primitives as: 2998 // fast_lock (nax Obj, nax box, EAX tmp, nax scr) where box, tmp and scr are KILLED. 2999 // fast_unlock (nax Obj, EAX box, nax tmp) where box and tmp are KILLED 3000 // Unfortunately ADLC bugs prevent us from expressing the ideal form. 3001 // Instead, we're stuck with a rather awkward and brittle register assignments below. 3002 // Furthermore the register assignments are overconstrained, possibly resulting in 3003 // sub-optimal code near the synchronization site. 3004 // 3005 // * Eliminate the sp-proximity tests and just use "== Self" tests instead. 3006 // Alternately, use a better sp-proximity test. 3007 // 3008 // * Currently ObjectMonitor._Owner can hold either an sp value or a (THREAD *) value. 3009 // Either one is sufficient to uniquely identify a thread. 3010 // TODO: eliminate use of sp in _owner and use get_thread(tr) instead. 3011 // 3012 // * Intrinsify notify() and notifyAll() for the common cases where the 3013 // object is locked by the calling thread but the waitlist is empty. 3014 // avoid the expensive JNI call to JVM_Notify() and JVM_NotifyAll(). 3015 // 3016 // * use jccb and jmpb instead of jcc and jmp to improve code density. 3017 // But beware of excessive branch density on AMD Opterons. 3018 // 3019 // * Both Fast_Lock and Fast_Unlock set the ICC.ZF to indicate success 3020 // or failure of the fast-path. If the fast-path fails then we pass 3021 // control to the slow-path, typically in C. In Fast_Lock and 3022 // Fast_Unlock we often branch to DONE_LABEL, just to find that C2 3023 // will emit a conditional branch immediately after the node. 3024 // So we have branches to branches and lots of ICC.ZF games. 3025 // Instead, it might be better to have C2 pass a "FailureLabel" 3026 // into Fast_Lock and Fast_Unlock. In the case of success, control 3027 // will drop through the node. ICC.ZF is undefined at exit. 3028 // In the case of failure, the node will branch directly to the 3029 // FailureLabel 3030 3031 3032 // obj: object to lock 3033 // box: on-stack box address (displaced header location) - KILLED 3034 // rax,: tmp -- KILLED 3035 // scr: tmp -- KILLED 3036 enc_class Fast_Lock( eRegP obj, eRegP box, eAXRegI tmp, eRegP scr ) %{ 3037 3038 Register objReg = as_Register($obj$$reg); 3039 Register boxReg = as_Register($box$$reg); 3040 Register tmpReg = as_Register($tmp$$reg); 3041 Register scrReg = as_Register($scr$$reg); 3042 3043 // Ensure the register assignents are disjoint 3044 guarantee (objReg != boxReg, "") ; 3045 guarantee (objReg != tmpReg, "") ; 3046 guarantee (objReg != scrReg, "") ; 3047 guarantee (boxReg != tmpReg, "") ; 3048 guarantee (boxReg != scrReg, "") ; 3049 guarantee (tmpReg == as_Register(EAX_enc), "") ; 3050 3051 MacroAssembler masm(&cbuf); 3052 3053 if (_counters != NULL) { 3054 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 3055 } 3056 if (EmitSync & 1) { 3057 // set box->dhw = unused_mark (3) 3058 // Force all sync thru slow-path: slow_enter() and slow_exit() 3059 masm.movptr (Address(boxReg, 0), int32_t(markOopDesc::unused_mark())) ; 3060 masm.cmpptr (rsp, (int32_t)0) ; 3061 } else 3062 if (EmitSync & 2) { 3063 Label DONE_LABEL ; 3064 if (UseBiasedLocking) { 3065 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 3066 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 3067 } 3068 3069 masm.movptr(tmpReg, Address(objReg, 0)) ; // fetch markword 3070 masm.orptr (tmpReg, 0x1); 3071 masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS 3072 if (os::is_MP()) { masm.lock(); } 3073 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3074 masm.jcc(Assembler::equal, DONE_LABEL); 3075 // Recursive locking 3076 masm.subptr(tmpReg, rsp); 3077 masm.andptr(tmpReg, (int32_t) 0xFFFFF003 ); 3078 masm.movptr(Address(boxReg, 0), tmpReg); 3079 masm.bind(DONE_LABEL) ; 3080 } else { 3081 // Possible cases that we'll encounter in fast_lock 3082 // ------------------------------------------------ 3083 // * Inflated 3084 // -- unlocked 3085 // -- Locked 3086 // = by self 3087 // = by other 3088 // * biased 3089 // -- by Self 3090 // -- by other 3091 // * neutral 3092 // * stack-locked 3093 // -- by self 3094 // = sp-proximity test hits 3095 // = sp-proximity test generates false-negative 3096 // -- by other 3097 // 3098 3099 Label IsInflated, DONE_LABEL, PopDone ; 3100 3101 // TODO: optimize away redundant LDs of obj->mark and improve the markword triage 3102 // order to reduce the number of conditional branches in the most common cases. 3103 // Beware -- there's a subtle invariant that fetch of the markword 3104 // at [FETCH], below, will never observe a biased encoding (*101b). 3105 // If this invariant is not held we risk exclusion (safety) failure. 3106 if (UseBiasedLocking && !UseOptoBiasInlining) { 3107 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 3108 } 3109 3110 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 3111 masm.testptr(tmpReg, 0x02) ; // Inflated v (Stack-locked or neutral) 3112 masm.jccb (Assembler::notZero, IsInflated) ; 3113 3114 // Attempt stack-locking ... 3115 masm.orptr (tmpReg, 0x1); 3116 masm.movptr(Address(boxReg, 0), tmpReg); // Anticipate successful CAS 3117 if (os::is_MP()) { masm.lock(); } 3118 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3119 if (_counters != NULL) { 3120 masm.cond_inc32(Assembler::equal, 3121 ExternalAddress((address)_counters->fast_path_entry_count_addr())); 3122 } 3123 masm.jccb (Assembler::equal, DONE_LABEL); 3124 3125 // Recursive locking 3126 masm.subptr(tmpReg, rsp); 3127 masm.andptr(tmpReg, 0xFFFFF003 ); 3128 masm.movptr(Address(boxReg, 0), tmpReg); 3129 if (_counters != NULL) { 3130 masm.cond_inc32(Assembler::equal, 3131 ExternalAddress((address)_counters->fast_path_entry_count_addr())); 3132 } 3133 masm.jmp (DONE_LABEL) ; 3134 3135 masm.bind (IsInflated) ; 3136 3137 // The object is inflated. 3138 // 3139 // TODO-FIXME: eliminate the ugly use of manifest constants: 3140 // Use markOopDesc::monitor_value instead of "2". 3141 // use markOop::unused_mark() instead of "3". 3142 // The tmpReg value is an objectMonitor reference ORed with 3143 // markOopDesc::monitor_value (2). We can either convert tmpReg to an 3144 // objectmonitor pointer by masking off the "2" bit or we can just 3145 // use tmpReg as an objectmonitor pointer but bias the objectmonitor 3146 // field offsets with "-2" to compensate for and annul the low-order tag bit. 3147 // 3148 // I use the latter as it avoids AGI stalls. 3149 // As such, we write "mov r, [tmpReg+OFFSETOF(Owner)-2]" 3150 // instead of "mov r, [tmpReg+OFFSETOF(Owner)]". 3151 // 3152 #define OFFSET_SKEWED(f) ((ObjectMonitor::f ## _offset_in_bytes())-2) 3153 3154 // boxReg refers to the on-stack BasicLock in the current frame. 3155 // We'd like to write: 3156 // set box->_displaced_header = markOop::unused_mark(). Any non-0 value suffices. 3157 // This is convenient but results a ST-before-CAS penalty. The following CAS suffers 3158 // additional latency as we have another ST in the store buffer that must drain. 3159 3160 if (EmitSync & 8192) { 3161 masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty 3162 masm.get_thread (scrReg) ; 3163 masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] 3164 masm.movptr(tmpReg, NULL_WORD); // consider: xor vs mov 3165 if (os::is_MP()) { masm.lock(); } 3166 masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3167 } else 3168 if ((EmitSync & 128) == 0) { // avoid ST-before-CAS 3169 masm.movptr(scrReg, boxReg) ; 3170 masm.movptr(boxReg, tmpReg); // consider: LEA box, [tmp-2] 3171 3172 // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes 3173 if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 3174 // prefetchw [eax + Offset(_owner)-2] 3175 masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); 3176 } 3177 3178 if ((EmitSync & 64) == 0) { 3179 // Optimistic form: consider XORL tmpReg,tmpReg 3180 masm.movptr(tmpReg, NULL_WORD) ; 3181 } else { 3182 // Can suffer RTS->RTO upgrades on shared or cold $ lines 3183 // Test-And-CAS instead of CAS 3184 masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner 3185 masm.testptr(tmpReg, tmpReg) ; // Locked ? 3186 masm.jccb (Assembler::notZero, DONE_LABEL) ; 3187 } 3188 3189 // Appears unlocked - try to swing _owner from null to non-null. 3190 // Ideally, I'd manifest "Self" with get_thread and then attempt 3191 // to CAS the register containing Self into m->Owner. 3192 // But we don't have enough registers, so instead we can either try to CAS 3193 // rsp or the address of the box (in scr) into &m->owner. If the CAS succeeds 3194 // we later store "Self" into m->Owner. Transiently storing a stack address 3195 // (rsp or the address of the box) into m->owner is harmless. 3196 // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. 3197 if (os::is_MP()) { masm.lock(); } 3198 masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3199 masm.movptr(Address(scrReg, 0), 3) ; // box->_displaced_header = 3 3200 masm.jccb (Assembler::notZero, DONE_LABEL) ; 3201 masm.get_thread (scrReg) ; // beware: clobbers ICCs 3202 masm.movptr(Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2), scrReg) ; 3203 masm.xorptr(boxReg, boxReg) ; // set icc.ZFlag = 1 to indicate success 3204 3205 // If the CAS fails we can either retry or pass control to the slow-path. 3206 // We use the latter tactic. 3207 // Pass the CAS result in the icc.ZFlag into DONE_LABEL 3208 // If the CAS was successful ... 3209 // Self has acquired the lock 3210 // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. 3211 // Intentional fall-through into DONE_LABEL ... 3212 } else { 3213 masm.movptr(Address(boxReg, 0), 3) ; // results in ST-before-CAS penalty 3214 masm.movptr(boxReg, tmpReg) ; 3215 3216 // Using a prefetchw helps avoid later RTS->RTO upgrades and cache probes 3217 if ((EmitSync & 2048) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 3218 // prefetchw [eax + Offset(_owner)-2] 3219 masm.prefetchw(Address(rax, ObjectMonitor::owner_offset_in_bytes()-2)); 3220 } 3221 3222 if ((EmitSync & 64) == 0) { 3223 // Optimistic form 3224 masm.xorptr (tmpReg, tmpReg) ; 3225 } else { 3226 // Can suffer RTS->RTO upgrades on shared or cold $ lines 3227 masm.movptr(tmpReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; // rax, = m->_owner 3228 masm.testptr(tmpReg, tmpReg) ; // Locked ? 3229 masm.jccb (Assembler::notZero, DONE_LABEL) ; 3230 } 3231 3232 // Appears unlocked - try to swing _owner from null to non-null. 3233 // Use either "Self" (in scr) or rsp as thread identity in _owner. 3234 // Invariant: tmpReg == 0. tmpReg is EAX which is the implicit cmpxchg comparand. 3235 masm.get_thread (scrReg) ; 3236 if (os::is_MP()) { masm.lock(); } 3237 masm.cmpxchgptr(scrReg, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3238 3239 // If the CAS fails we can either retry or pass control to the slow-path. 3240 // We use the latter tactic. 3241 // Pass the CAS result in the icc.ZFlag into DONE_LABEL 3242 // If the CAS was successful ... 3243 // Self has acquired the lock 3244 // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. 3245 // Intentional fall-through into DONE_LABEL ... 3246 } 3247 3248 // DONE_LABEL is a hot target - we'd really like to place it at the 3249 // start of cache line by padding with NOPs. 3250 // See the AMD and Intel software optimization manuals for the 3251 // most efficient "long" NOP encodings. 3252 // Unfortunately none of our alignment mechanisms suffice. 3253 masm.bind(DONE_LABEL); 3254 3255 // Avoid branch-to-branch on AMD processors 3256 // This appears to be superstition. 3257 if (EmitSync & 32) masm.nop() ; 3258 3259 3260 // At DONE_LABEL the icc ZFlag is set as follows ... 3261 // Fast_Unlock uses the same protocol. 3262 // ZFlag == 1 -> Success 3263 // ZFlag == 0 -> Failure - force control through the slow-path 3264 } 3265 %} 3266 3267 // obj: object to unlock 3268 // box: box address (displaced header location), killed. Must be EAX. 3269 // rbx,: killed tmp; cannot be obj nor box. 3270 // 3271 // Some commentary on balanced locking: 3272 // 3273 // Fast_Lock and Fast_Unlock are emitted only for provably balanced lock sites. 3274 // Methods that don't have provably balanced locking are forced to run in the 3275 // interpreter - such methods won't be compiled to use fast_lock and fast_unlock. 3276 // The interpreter provides two properties: 3277 // I1: At return-time the interpreter automatically and quietly unlocks any 3278 // objects acquired the current activation (frame). Recall that the 3279 // interpreter maintains an on-stack list of locks currently held by 3280 // a frame. 3281 // I2: If a method attempts to unlock an object that is not held by the 3282 // the frame the interpreter throws IMSX. 3283 // 3284 // Lets say A(), which has provably balanced locking, acquires O and then calls B(). 3285 // B() doesn't have provably balanced locking so it runs in the interpreter. 3286 // Control returns to A() and A() unlocks O. By I1 and I2, above, we know that O 3287 // is still locked by A(). 3288 // 3289 // The only other source of unbalanced locking would be JNI. The "Java Native Interface: 3290 // Programmer's Guide and Specification" claims that an object locked by jni_monitorenter 3291 // should not be unlocked by "normal" java-level locking and vice-versa. The specification 3292 // doesn't specify what will occur if a program engages in such mixed-mode locking, however. 3293 3294 enc_class Fast_Unlock( nabxRegP obj, eAXRegP box, eRegP tmp) %{ 3295 3296 Register objReg = as_Register($obj$$reg); 3297 Register boxReg = as_Register($box$$reg); 3298 Register tmpReg = as_Register($tmp$$reg); 3299 3300 guarantee (objReg != boxReg, "") ; 3301 guarantee (objReg != tmpReg, "") ; 3302 guarantee (boxReg != tmpReg, "") ; 3303 guarantee (boxReg == as_Register(EAX_enc), "") ; 3304 MacroAssembler masm(&cbuf); 3305 3306 if (EmitSync & 4) { 3307 // Disable - inhibit all inlining. Force control through the slow-path 3308 masm.cmpptr (rsp, 0) ; 3309 } else 3310 if (EmitSync & 8) { 3311 Label DONE_LABEL ; 3312 if (UseBiasedLocking) { 3313 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3314 } 3315 // classic stack-locking code ... 3316 masm.movptr(tmpReg, Address(boxReg, 0)) ; 3317 masm.testptr(tmpReg, tmpReg) ; 3318 masm.jcc (Assembler::zero, DONE_LABEL) ; 3319 if (os::is_MP()) { masm.lock(); } 3320 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box 3321 masm.bind(DONE_LABEL); 3322 } else { 3323 Label DONE_LABEL, Stacked, CheckSucc, Inflated ; 3324 3325 // Critically, the biased locking test must have precedence over 3326 // and appear before the (box->dhw == 0) recursive stack-lock test. 3327 if (UseBiasedLocking && !UseOptoBiasInlining) { 3328 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3329 } 3330 3331 masm.cmpptr(Address(boxReg, 0), 0) ; // Examine the displaced header 3332 masm.movptr(tmpReg, Address(objReg, 0)) ; // Examine the object's markword 3333 masm.jccb (Assembler::zero, DONE_LABEL) ; // 0 indicates recursive stack-lock 3334 3335 masm.testptr(tmpReg, 0x02) ; // Inflated? 3336 masm.jccb (Assembler::zero, Stacked) ; 3337 3338 masm.bind (Inflated) ; 3339 // It's inflated. 3340 // Despite our balanced locking property we still check that m->_owner == Self 3341 // as java routines or native JNI code called by this thread might 3342 // have released the lock. 3343 // Refer to the comments in synchronizer.cpp for how we might encode extra 3344 // state in _succ so we can avoid fetching EntryList|cxq. 3345 // 3346 // I'd like to add more cases in fast_lock() and fast_unlock() -- 3347 // such as recursive enter and exit -- but we have to be wary of 3348 // I$ bloat, T$ effects and BP$ effects. 3349 // 3350 // If there's no contention try a 1-0 exit. That is, exit without 3351 // a costly MEMBAR or CAS. See synchronizer.cpp for details on how 3352 // we detect and recover from the race that the 1-0 exit admits. 3353 // 3354 // Conceptually Fast_Unlock() must execute a STST|LDST "release" barrier 3355 // before it STs null into _owner, releasing the lock. Updates 3356 // to data protected by the critical section must be visible before 3357 // we drop the lock (and thus before any other thread could acquire 3358 // the lock and observe the fields protected by the lock). 3359 // IA32's memory-model is SPO, so STs are ordered with respect to 3360 // each other and there's no need for an explicit barrier (fence). 3361 // See also http://gee.cs.oswego.edu/dl/jmm/cookbook.html. 3362 3363 masm.get_thread (boxReg) ; 3364 if ((EmitSync & 4096) && VM_Version::supports_3dnow_prefetch() && os::is_MP()) { 3365 // prefetchw [ebx + Offset(_owner)-2] 3366 masm.prefetchw(Address(rbx, ObjectMonitor::owner_offset_in_bytes()-2)); 3367 } 3368 3369 // Note that we could employ various encoding schemes to reduce 3370 // the number of loads below (currently 4) to just 2 or 3. 3371 // Refer to the comments in synchronizer.cpp. 3372 // In practice the chain of fetches doesn't seem to impact performance, however. 3373 if ((EmitSync & 65536) == 0 && (EmitSync & 256)) { 3374 // Attempt to reduce branch density - AMD's branch predictor. 3375 masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3376 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 3377 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 3378 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 3379 masm.jccb (Assembler::notZero, DONE_LABEL) ; 3380 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 3381 masm.jmpb (DONE_LABEL) ; 3382 } else { 3383 masm.xorptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3384 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 3385 masm.jccb (Assembler::notZero, DONE_LABEL) ; 3386 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 3387 masm.orptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 3388 masm.jccb (Assembler::notZero, CheckSucc) ; 3389 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 3390 masm.jmpb (DONE_LABEL) ; 3391 } 3392 3393 // The Following code fragment (EmitSync & 65536) improves the performance of 3394 // contended applications and contended synchronization microbenchmarks. 3395 // Unfortunately the emission of the code - even though not executed - causes regressions 3396 // in scimark and jetstream, evidently because of $ effects. Replacing the code 3397 // with an equal number of never-executed NOPs results in the same regression. 3398 // We leave it off by default. 3399 3400 if ((EmitSync & 65536) != 0) { 3401 Label LSuccess, LGoSlowPath ; 3402 3403 masm.bind (CheckSucc) ; 3404 3405 // Optional pre-test ... it's safe to elide this 3406 if ((EmitSync & 16) == 0) { 3407 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; 3408 masm.jccb (Assembler::zero, LGoSlowPath) ; 3409 } 3410 3411 // We have a classic Dekker-style idiom: 3412 // ST m->_owner = 0 ; MEMBAR; LD m->_succ 3413 // There are a number of ways to implement the barrier: 3414 // (1) lock:andl &m->_owner, 0 3415 // is fast, but mask doesn't currently support the "ANDL M,IMM32" form. 3416 // LOCK: ANDL [ebx+Offset(_Owner)-2], 0 3417 // Encodes as 81 31 OFF32 IMM32 or 83 63 OFF8 IMM8 3418 // (2) If supported, an explicit MFENCE is appealing. 3419 // In older IA32 processors MFENCE is slower than lock:add or xchg 3420 // particularly if the write-buffer is full as might be the case if 3421 // if stores closely precede the fence or fence-equivalent instruction. 3422 // In more modern implementations MFENCE appears faster, however. 3423 // (3) In lieu of an explicit fence, use lock:addl to the top-of-stack 3424 // The $lines underlying the top-of-stack should be in M-state. 3425 // The locked add instruction is serializing, of course. 3426 // (4) Use xchg, which is serializing 3427 // mov boxReg, 0; xchgl boxReg, [tmpReg + Offset(_owner)-2] also works 3428 // (5) ST m->_owner = 0 and then execute lock:orl &m->_succ, 0. 3429 // The integer condition codes will tell us if succ was 0. 3430 // Since _succ and _owner should reside in the same $line and 3431 // we just stored into _owner, it's likely that the $line 3432 // remains in M-state for the lock:orl. 3433 // 3434 // We currently use (3), although it's likely that switching to (2) 3435 // is correct for the future. 3436 3437 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), NULL_WORD) ; 3438 if (os::is_MP()) { 3439 if (VM_Version::supports_sse2() && 1 == FenceInstruction) { 3440 masm.mfence(); 3441 } else { 3442 masm.lock () ; masm.addptr(Address(rsp, 0), 0) ; 3443 } 3444 } 3445 // Ratify _succ remains non-null 3446 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), 0) ; 3447 masm.jccb (Assembler::notZero, LSuccess) ; 3448 3449 masm.xorptr(boxReg, boxReg) ; // box is really EAX 3450 if (os::is_MP()) { masm.lock(); } 3451 masm.cmpxchgptr(rsp, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 3452 masm.jccb (Assembler::notEqual, LSuccess) ; 3453 // Since we're low on registers we installed rsp as a placeholding in _owner. 3454 // Now install Self over rsp. This is safe as we're transitioning from 3455 // non-null to non=null 3456 masm.get_thread (boxReg) ; 3457 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), boxReg) ; 3458 // Intentional fall-through into LGoSlowPath ... 3459 3460 masm.bind (LGoSlowPath) ; 3461 masm.orptr(boxReg, 1) ; // set ICC.ZF=0 to indicate failure 3462 masm.jmpb (DONE_LABEL) ; 3463 3464 masm.bind (LSuccess) ; 3465 masm.xorptr(boxReg, boxReg) ; // set ICC.ZF=1 to indicate success 3466 masm.jmpb (DONE_LABEL) ; 3467 } 3468 3469 masm.bind (Stacked) ; 3470 // It's not inflated and it's not recursively stack-locked and it's not biased. 3471 // It must be stack-locked. 3472 // Try to reset the header to displaced header. 3473 // The "box" value on the stack is stable, so we can reload 3474 // and be assured we observe the same value as above. 3475 masm.movptr(tmpReg, Address(boxReg, 0)) ; 3476 if (os::is_MP()) { masm.lock(); } 3477 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses EAX which is box 3478 // Intention fall-thru into DONE_LABEL 3479 3480 3481 // DONE_LABEL is a hot target - we'd really like to place it at the 3482 // start of cache line by padding with NOPs. 3483 // See the AMD and Intel software optimization manuals for the 3484 // most efficient "long" NOP encodings. 3485 // Unfortunately none of our alignment mechanisms suffice. 3486 if ((EmitSync & 65536) == 0) { 3487 masm.bind (CheckSucc) ; 3488 } 3489 masm.bind(DONE_LABEL); 3490 3491 // Avoid branch to branch on AMD processors 3492 if (EmitSync & 32768) { masm.nop() ; } 3493 } 3494 %} 3495 3496 3497 enc_class enc_pop_rdx() %{ 3498 emit_opcode(cbuf,0x5A); 3499 %} 3500 3501 enc_class enc_rethrow() %{ 3502 cbuf.set_insts_mark(); 3503 emit_opcode(cbuf, 0xE9); // jmp entry 3504 emit_d32_reloc(cbuf, (int)OptoRuntime::rethrow_stub() - ((int)cbuf.insts_end())-4, 3505 runtime_call_Relocation::spec(), RELOC_IMM32 ); 3506 %} 3507 3508 3509 // Convert a double to an int. Java semantics require we do complex 3510 // manglelations in the corner cases. So we set the rounding mode to 3511 // 'zero', store the darned double down as an int, and reset the 3512 // rounding mode to 'nearest'. The hardware throws an exception which 3513 // patches up the correct value directly to the stack. 3514 enc_class DPR2I_encoding( regDPR src ) %{ 3515 // Flip to round-to-zero mode. We attempted to allow invalid-op 3516 // exceptions here, so that a NAN or other corner-case value will 3517 // thrown an exception (but normal values get converted at full speed). 3518 // However, I2C adapters and other float-stack manglers leave pending 3519 // invalid-op exceptions hanging. We would have to clear them before 3520 // enabling them and that is more expensive than just testing for the 3521 // invalid value Intel stores down in the corner cases. 3522 emit_opcode(cbuf,0xD9); // FLDCW trunc 3523 emit_opcode(cbuf,0x2D); 3524 emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc()); 3525 // Allocate a word 3526 emit_opcode(cbuf,0x83); // SUB ESP,4 3527 emit_opcode(cbuf,0xEC); 3528 emit_d8(cbuf,0x04); 3529 // Encoding assumes a double has been pushed into FPR0. 3530 // Store down the double as an int, popping the FPU stack 3531 emit_opcode(cbuf,0xDB); // FISTP [ESP] 3532 emit_opcode(cbuf,0x1C); 3533 emit_d8(cbuf,0x24); 3534 // Restore the rounding mode; mask the exception 3535 emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode 3536 emit_opcode(cbuf,0x2D); 3537 emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode() 3538 ? (int)StubRoutines::addr_fpu_cntrl_wrd_24() 3539 : (int)StubRoutines::addr_fpu_cntrl_wrd_std()); 3540 3541 // Load the converted int; adjust CPU stack 3542 emit_opcode(cbuf,0x58); // POP EAX 3543 emit_opcode(cbuf,0x3D); // CMP EAX,imm 3544 emit_d32 (cbuf,0x80000000); // 0x80000000 3545 emit_opcode(cbuf,0x75); // JNE around_slow_call 3546 emit_d8 (cbuf,0x07); // Size of slow_call 3547 // Push src onto stack slow-path 3548 emit_opcode(cbuf,0xD9 ); // FLD ST(i) 3549 emit_d8 (cbuf,0xC0-1+$src$$reg ); 3550 // CALL directly to the runtime 3551 cbuf.set_insts_mark(); 3552 emit_opcode(cbuf,0xE8); // Call into runtime 3553 emit_d32_reloc(cbuf, (StubRoutines::d2i_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 3554 // Carry on here... 3555 %} 3556 3557 enc_class DPR2L_encoding( regDPR src ) %{ 3558 emit_opcode(cbuf,0xD9); // FLDCW trunc 3559 emit_opcode(cbuf,0x2D); 3560 emit_d32(cbuf,(int)StubRoutines::addr_fpu_cntrl_wrd_trunc()); 3561 // Allocate a word 3562 emit_opcode(cbuf,0x83); // SUB ESP,8 3563 emit_opcode(cbuf,0xEC); 3564 emit_d8(cbuf,0x08); 3565 // Encoding assumes a double has been pushed into FPR0. 3566 // Store down the double as a long, popping the FPU stack 3567 emit_opcode(cbuf,0xDF); // FISTP [ESP] 3568 emit_opcode(cbuf,0x3C); 3569 emit_d8(cbuf,0x24); 3570 // Restore the rounding mode; mask the exception 3571 emit_opcode(cbuf,0xD9); // FLDCW std/24-bit mode 3572 emit_opcode(cbuf,0x2D); 3573 emit_d32( cbuf, Compile::current()->in_24_bit_fp_mode() 3574 ? (int)StubRoutines::addr_fpu_cntrl_wrd_24() 3575 : (int)StubRoutines::addr_fpu_cntrl_wrd_std()); 3576 3577 // Load the converted int; adjust CPU stack 3578 emit_opcode(cbuf,0x58); // POP EAX 3579 emit_opcode(cbuf,0x5A); // POP EDX 3580 emit_opcode(cbuf,0x81); // CMP EDX,imm 3581 emit_d8 (cbuf,0xFA); // rdx 3582 emit_d32 (cbuf,0x80000000); // 0x80000000 3583 emit_opcode(cbuf,0x75); // JNE around_slow_call 3584 emit_d8 (cbuf,0x07+4); // Size of slow_call 3585 emit_opcode(cbuf,0x85); // TEST EAX,EAX 3586 emit_opcode(cbuf,0xC0); // 2/rax,/rax, 3587 emit_opcode(cbuf,0x75); // JNE around_slow_call 3588 emit_d8 (cbuf,0x07); // Size of slow_call 3589 // Push src onto stack slow-path 3590 emit_opcode(cbuf,0xD9 ); // FLD ST(i) 3591 emit_d8 (cbuf,0xC0-1+$src$$reg ); 3592 // CALL directly to the runtime 3593 cbuf.set_insts_mark(); 3594 emit_opcode(cbuf,0xE8); // Call into runtime 3595 emit_d32_reloc(cbuf, (StubRoutines::d2l_wrapper() - cbuf.insts_end()) - 4, runtime_call_Relocation::spec(), RELOC_IMM32 ); 3596 // Carry on here... 3597 %} 3598 3599 enc_class FMul_ST_reg( eRegFPR src1 ) %{ 3600 // Operand was loaded from memory into fp ST (stack top) 3601 // FMUL ST,$src /* D8 C8+i */ 3602 emit_opcode(cbuf, 0xD8); 3603 emit_opcode(cbuf, 0xC8 + $src1$$reg); 3604 %} 3605 3606 enc_class FAdd_ST_reg( eRegFPR src2 ) %{ 3607 // FADDP ST,src2 /* D8 C0+i */ 3608 emit_opcode(cbuf, 0xD8); 3609 emit_opcode(cbuf, 0xC0 + $src2$$reg); 3610 //could use FADDP src2,fpST /* DE C0+i */ 3611 %} 3612 3613 enc_class FAddP_reg_ST( eRegFPR src2 ) %{ 3614 // FADDP src2,ST /* DE C0+i */ 3615 emit_opcode(cbuf, 0xDE); 3616 emit_opcode(cbuf, 0xC0 + $src2$$reg); 3617 %} 3618 3619 enc_class subFPR_divFPR_encode( eRegFPR src1, eRegFPR src2) %{ 3620 // Operand has been loaded into fp ST (stack top) 3621 // FSUB ST,$src1 3622 emit_opcode(cbuf, 0xD8); 3623 emit_opcode(cbuf, 0xE0 + $src1$$reg); 3624 3625 // FDIV 3626 emit_opcode(cbuf, 0xD8); 3627 emit_opcode(cbuf, 0xF0 + $src2$$reg); 3628 %} 3629 3630 enc_class MulFAddF (eRegFPR src1, eRegFPR src2) %{ 3631 // Operand was loaded from memory into fp ST (stack top) 3632 // FADD ST,$src /* D8 C0+i */ 3633 emit_opcode(cbuf, 0xD8); 3634 emit_opcode(cbuf, 0xC0 + $src1$$reg); 3635 3636 // FMUL ST,src2 /* D8 C*+i */ 3637 emit_opcode(cbuf, 0xD8); 3638 emit_opcode(cbuf, 0xC8 + $src2$$reg); 3639 %} 3640 3641 3642 enc_class MulFAddFreverse (eRegFPR src1, eRegFPR src2) %{ 3643 // Operand was loaded from memory into fp ST (stack top) 3644 // FADD ST,$src /* D8 C0+i */ 3645 emit_opcode(cbuf, 0xD8); 3646 emit_opcode(cbuf, 0xC0 + $src1$$reg); 3647 3648 // FMULP src2,ST /* DE C8+i */ 3649 emit_opcode(cbuf, 0xDE); 3650 emit_opcode(cbuf, 0xC8 + $src2$$reg); 3651 %} 3652 3653 // Atomically load the volatile long 3654 enc_class enc_loadL_volatile( memory mem, stackSlotL dst ) %{ 3655 emit_opcode(cbuf,0xDF); 3656 int rm_byte_opcode = 0x05; 3657 int base = $mem$$base; 3658 int index = $mem$$index; 3659 int scale = $mem$$scale; 3660 int displace = $mem$$disp; 3661 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when working with static globals 3662 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_reloc); 3663 store_to_stackslot( cbuf, 0x0DF, 0x07, $dst$$disp ); 3664 %} 3665 3666 // Volatile Store Long. Must be atomic, so move it into 3667 // the FP TOS and then do a 64-bit FIST. Has to probe the 3668 // target address before the store (for null-ptr checks) 3669 // so the memory operand is used twice in the encoding. 3670 enc_class enc_storeL_volatile( memory mem, stackSlotL src ) %{ 3671 store_to_stackslot( cbuf, 0x0DF, 0x05, $src$$disp ); 3672 cbuf.set_insts_mark(); // Mark start of FIST in case $mem has an oop 3673 emit_opcode(cbuf,0xDF); 3674 int rm_byte_opcode = 0x07; 3675 int base = $mem$$base; 3676 int index = $mem$$index; 3677 int scale = $mem$$scale; 3678 int displace = $mem$$disp; 3679 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when working with static globals 3680 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_reloc); 3681 %} 3682 3683 // Safepoint Poll. This polls the safepoint page, and causes an 3684 // exception if it is not readable. Unfortunately, it kills the condition code 3685 // in the process 3686 // We current use TESTL [spp],EDI 3687 // A better choice might be TESTB [spp + pagesize() - CacheLineSize()],0 3688 3689 enc_class Safepoint_Poll() %{ 3690 cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0); 3691 emit_opcode(cbuf,0x85); 3692 emit_rm (cbuf, 0x0, 0x7, 0x5); 3693 emit_d32(cbuf, (intptr_t)os::get_polling_page()); 3694 %} 3695%} 3696 3697 3698//----------FRAME-------------------------------------------------------------- 3699// Definition of frame structure and management information. 3700// 3701// S T A C K L A Y O U T Allocators stack-slot number 3702// | (to get allocators register number 3703// G Owned by | | v add OptoReg::stack0()) 3704// r CALLER | | 3705// o | +--------+ pad to even-align allocators stack-slot 3706// w V | pad0 | numbers; owned by CALLER 3707// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 3708// h ^ | in | 5 3709// | | args | 4 Holes in incoming args owned by SELF 3710// | | | | 3 3711// | | +--------+ 3712// V | | old out| Empty on Intel, window on Sparc 3713// | old |preserve| Must be even aligned. 3714// | SP-+--------+----> Matcher::_old_SP, even aligned 3715// | | in | 3 area for Intel ret address 3716// Owned by |preserve| Empty on Sparc. 3717// SELF +--------+ 3718// | | pad2 | 2 pad to align old SP 3719// | +--------+ 1 3720// | | locks | 0 3721// | +--------+----> OptoReg::stack0(), even aligned 3722// | | pad1 | 11 pad to align new SP 3723// | +--------+ 3724// | | | 10 3725// | | spills | 9 spills 3726// V | | 8 (pad0 slot for callee) 3727// -----------+--------+----> Matcher::_out_arg_limit, unaligned 3728// ^ | out | 7 3729// | | args | 6 Holes in outgoing args owned by CALLEE 3730// Owned by +--------+ 3731// CALLEE | new out| 6 Empty on Intel, window on Sparc 3732// | new |preserve| Must be even-aligned. 3733// | SP-+--------+----> Matcher::_new_SP, even aligned 3734// | | | 3735// 3736// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 3737// known from SELF's arguments and the Java calling convention. 3738// Region 6-7 is determined per call site. 3739// Note 2: If the calling convention leaves holes in the incoming argument 3740// area, those holes are owned by SELF. Holes in the outgoing area 3741// are owned by the CALLEE. Holes should not be nessecary in the 3742// incoming area, as the Java calling convention is completely under 3743// the control of the AD file. Doubles can be sorted and packed to 3744// avoid holes. Holes in the outgoing arguments may be nessecary for 3745// varargs C calling conventions. 3746// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 3747// even aligned with pad0 as needed. 3748// Region 6 is even aligned. Region 6-7 is NOT even aligned; 3749// region 6-11 is even aligned; it may be padded out more so that 3750// the region from SP to FP meets the minimum stack alignment. 3751 3752frame %{ 3753 // What direction does stack grow in (assumed to be same for C & Java) 3754 stack_direction(TOWARDS_LOW); 3755 3756 // These three registers define part of the calling convention 3757 // between compiled code and the interpreter. 3758 inline_cache_reg(EAX); // Inline Cache Register 3759 interpreter_method_oop_reg(EBX); // Method Oop Register when calling interpreter 3760 3761 // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset] 3762 cisc_spilling_operand_name(indOffset32); 3763 3764 // Number of stack slots consumed by locking an object 3765 sync_stack_slots(1); 3766 3767 // Compiled code's Frame Pointer 3768 frame_pointer(ESP); 3769 // Interpreter stores its frame pointer in a register which is 3770 // stored to the stack by I2CAdaptors. 3771 // I2CAdaptors convert from interpreted java to compiled java. 3772 interpreter_frame_pointer(EBP); 3773 3774 // Stack alignment requirement 3775 // Alignment size in bytes (128-bit -> 16 bytes) 3776 stack_alignment(StackAlignmentInBytes); 3777 3778 // Number of stack slots between incoming argument block and the start of 3779 // a new frame. The PROLOG must add this many slots to the stack. The 3780 // EPILOG must remove this many slots. Intel needs one slot for 3781 // return address and one for rbp, (must save rbp) 3782 in_preserve_stack_slots(2+VerifyStackAtCalls); 3783 3784 // Number of outgoing stack slots killed above the out_preserve_stack_slots 3785 // for calls to C. Supports the var-args backing area for register parms. 3786 varargs_C_out_slots_killed(0); 3787 3788 // The after-PROLOG location of the return address. Location of 3789 // return address specifies a type (REG or STACK) and a number 3790 // representing the register number (i.e. - use a register name) or 3791 // stack slot. 3792 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 3793 // Otherwise, it is above the locks and verification slot and alignment word 3794 return_addr(STACK - 1 + 3795 round_to((Compile::current()->in_preserve_stack_slots() + 3796 Compile::current()->fixed_slots()), 3797 stack_alignment_in_slots())); 3798 3799 // Body of function which returns an integer array locating 3800 // arguments either in registers or in stack slots. Passed an array 3801 // of ideal registers called "sig" and a "length" count. Stack-slot 3802 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3803 // arguments for a CALLEE. Incoming stack arguments are 3804 // automatically biased by the preserve_stack_slots field above. 3805 calling_convention %{ 3806 // No difference between ingoing/outgoing just pass false 3807 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 3808 %} 3809 3810 3811 // Body of function which returns an integer array locating 3812 // arguments either in registers or in stack slots. Passed an array 3813 // of ideal registers called "sig" and a "length" count. Stack-slot 3814 // offsets are based on outgoing arguments, i.e. a CALLER setting up 3815 // arguments for a CALLEE. Incoming stack arguments are 3816 // automatically biased by the preserve_stack_slots field above. 3817 c_calling_convention %{ 3818 // This is obviously always outgoing 3819 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); 3820 %} 3821 3822 // Location of C & interpreter return values 3823 c_return_value %{ 3824 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); 3825 static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num, EAX_num, FPR1L_num, FPR1L_num, EAX_num }; 3826 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num }; 3827 3828 // in SSE2+ mode we want to keep the FPU stack clean so pretend 3829 // that C functions return float and double results in XMM0. 3830 if( ideal_reg == Op_RegD && UseSSE>=2 ) 3831 return OptoRegPair(XMM0b_num,XMM0_num); 3832 if( ideal_reg == Op_RegF && UseSSE>=2 ) 3833 return OptoRegPair(OptoReg::Bad,XMM0_num); 3834 3835 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]); 3836 %} 3837 3838 // Location of return values 3839 return_value %{ 3840 assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" ); 3841 static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num, EAX_num, FPR1L_num, FPR1L_num, EAX_num }; 3842 static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num }; 3843 if( ideal_reg == Op_RegD && UseSSE>=2 ) 3844 return OptoRegPair(XMM0b_num,XMM0_num); 3845 if( ideal_reg == Op_RegF && UseSSE>=1 ) 3846 return OptoRegPair(OptoReg::Bad,XMM0_num); 3847 return OptoRegPair(hi[ideal_reg],lo[ideal_reg]); 3848 %} 3849 3850%} 3851 3852//----------ATTRIBUTES--------------------------------------------------------- 3853//----------Operand Attributes------------------------------------------------- 3854op_attrib op_cost(0); // Required cost attribute 3855 3856//----------Instruction Attributes--------------------------------------------- 3857ins_attrib ins_cost(100); // Required cost attribute 3858ins_attrib ins_size(8); // Required size attribute (in bits) 3859ins_attrib ins_short_branch(0); // Required flag: is this instruction a 3860 // non-matching short branch variant of some 3861 // long branch? 3862ins_attrib ins_alignment(1); // Required alignment attribute (must be a power of 2) 3863 // specifies the alignment that some part of the instruction (not 3864 // necessarily the start) requires. If > 1, a compute_padding() 3865 // function must be provided for the instruction 3866 3867//----------OPERANDS----------------------------------------------------------- 3868// Operand definitions must precede instruction definitions for correct parsing 3869// in the ADLC because operands constitute user defined types which are used in 3870// instruction definitions. 3871 3872//----------Simple Operands---------------------------------------------------- 3873// Immediate Operands 3874// Integer Immediate 3875operand immI() %{ 3876 match(ConI); 3877 3878 op_cost(10); 3879 format %{ %} 3880 interface(CONST_INTER); 3881%} 3882 3883// Constant for test vs zero 3884operand immI0() %{ 3885 predicate(n->get_int() == 0); 3886 match(ConI); 3887 3888 op_cost(0); 3889 format %{ %} 3890 interface(CONST_INTER); 3891%} 3892 3893// Constant for increment 3894operand immI1() %{ 3895 predicate(n->get_int() == 1); 3896 match(ConI); 3897 3898 op_cost(0); 3899 format %{ %} 3900 interface(CONST_INTER); 3901%} 3902 3903// Constant for decrement 3904operand immI_M1() %{ 3905 predicate(n->get_int() == -1); 3906 match(ConI); 3907 3908 op_cost(0); 3909 format %{ %} 3910 interface(CONST_INTER); 3911%} 3912 3913// Valid scale values for addressing modes 3914operand immI2() %{ 3915 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3916 match(ConI); 3917 3918 format %{ %} 3919 interface(CONST_INTER); 3920%} 3921 3922operand immI8() %{ 3923 predicate((-128 <= n->get_int()) && (n->get_int() <= 127)); 3924 match(ConI); 3925 3926 op_cost(5); 3927 format %{ %} 3928 interface(CONST_INTER); 3929%} 3930 3931operand immI16() %{ 3932 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 3933 match(ConI); 3934 3935 op_cost(10); 3936 format %{ %} 3937 interface(CONST_INTER); 3938%} 3939 3940// Constant for long shifts 3941operand immI_32() %{ 3942 predicate( n->get_int() == 32 ); 3943 match(ConI); 3944 3945 op_cost(0); 3946 format %{ %} 3947 interface(CONST_INTER); 3948%} 3949 3950operand immI_1_31() %{ 3951 predicate( n->get_int() >= 1 && n->get_int() <= 31 ); 3952 match(ConI); 3953 3954 op_cost(0); 3955 format %{ %} 3956 interface(CONST_INTER); 3957%} 3958 3959operand immI_32_63() %{ 3960 predicate( n->get_int() >= 32 && n->get_int() <= 63 ); 3961 match(ConI); 3962 op_cost(0); 3963 3964 format %{ %} 3965 interface(CONST_INTER); 3966%} 3967 3968operand immI_1() %{ 3969 predicate( n->get_int() == 1 ); 3970 match(ConI); 3971 3972 op_cost(0); 3973 format %{ %} 3974 interface(CONST_INTER); 3975%} 3976 3977operand immI_2() %{ 3978 predicate( n->get_int() == 2 ); 3979 match(ConI); 3980 3981 op_cost(0); 3982 format %{ %} 3983 interface(CONST_INTER); 3984%} 3985 3986operand immI_3() %{ 3987 predicate( n->get_int() == 3 ); 3988 match(ConI); 3989 3990 op_cost(0); 3991 format %{ %} 3992 interface(CONST_INTER); 3993%} 3994 3995// Pointer Immediate 3996operand immP() %{ 3997 match(ConP); 3998 3999 op_cost(10); 4000 format %{ %} 4001 interface(CONST_INTER); 4002%} 4003 4004// NULL Pointer Immediate 4005operand immP0() %{ 4006 predicate( n->get_ptr() == 0 ); 4007 match(ConP); 4008 op_cost(0); 4009 4010 format %{ %} 4011 interface(CONST_INTER); 4012%} 4013 4014// Long Immediate 4015operand immL() %{ 4016 match(ConL); 4017 4018 op_cost(20); 4019 format %{ %} 4020 interface(CONST_INTER); 4021%} 4022 4023// Long Immediate zero 4024operand immL0() %{ 4025 predicate( n->get_long() == 0L ); 4026 match(ConL); 4027 op_cost(0); 4028 4029 format %{ %} 4030 interface(CONST_INTER); 4031%} 4032 4033// Long Immediate zero 4034operand immL_M1() %{ 4035 predicate( n->get_long() == -1L ); 4036 match(ConL); 4037 op_cost(0); 4038 4039 format %{ %} 4040 interface(CONST_INTER); 4041%} 4042 4043// Long immediate from 0 to 127. 4044// Used for a shorter form of long mul by 10. 4045operand immL_127() %{ 4046 predicate((0 <= n->get_long()) && (n->get_long() <= 127)); 4047 match(ConL); 4048 op_cost(0); 4049 4050 format %{ %} 4051 interface(CONST_INTER); 4052%} 4053 4054// Long Immediate: low 32-bit mask 4055operand immL_32bits() %{ 4056 predicate(n->get_long() == 0xFFFFFFFFL); 4057 match(ConL); 4058 op_cost(0); 4059 4060 format %{ %} 4061 interface(CONST_INTER); 4062%} 4063 4064// Long Immediate: low 32-bit mask 4065operand immL32() %{ 4066 predicate(n->get_long() == (int)(n->get_long())); 4067 match(ConL); 4068 op_cost(20); 4069 4070 format %{ %} 4071 interface(CONST_INTER); 4072%} 4073 4074//Double Immediate zero 4075operand immDPR0() %{ 4076 // Do additional (and counter-intuitive) test against NaN to work around VC++ 4077 // bug that generates code such that NaNs compare equal to 0.0 4078 predicate( UseSSE<=1 && n->getd() == 0.0 && !g_isnan(n->getd()) ); 4079 match(ConD); 4080 4081 op_cost(5); 4082 format %{ %} 4083 interface(CONST_INTER); 4084%} 4085 4086// Double Immediate one 4087operand immDPR1() %{ 4088 predicate( UseSSE<=1 && n->getd() == 1.0 ); 4089 match(ConD); 4090 4091 op_cost(5); 4092 format %{ %} 4093 interface(CONST_INTER); 4094%} 4095 4096// Double Immediate 4097operand immDPR() %{ 4098 predicate(UseSSE<=1); 4099 match(ConD); 4100 4101 op_cost(5); 4102 format %{ %} 4103 interface(CONST_INTER); 4104%} 4105 4106operand immD() %{ 4107 predicate(UseSSE>=2); 4108 match(ConD); 4109 4110 op_cost(5); 4111 format %{ %} 4112 interface(CONST_INTER); 4113%} 4114 4115// Double Immediate zero 4116operand immD0() %{ 4117 // Do additional (and counter-intuitive) test against NaN to work around VC++ 4118 // bug that generates code such that NaNs compare equal to 0.0 AND do not 4119 // compare equal to -0.0. 4120 predicate( UseSSE>=2 && jlong_cast(n->getd()) == 0 ); 4121 match(ConD); 4122 4123 format %{ %} 4124 interface(CONST_INTER); 4125%} 4126 4127// Float Immediate zero 4128operand immFPR0() %{ 4129 predicate(UseSSE == 0 && n->getf() == 0.0F); 4130 match(ConF); 4131 4132 op_cost(5); 4133 format %{ %} 4134 interface(CONST_INTER); 4135%} 4136 4137// Float Immediate one 4138operand immFPR1() %{ 4139 predicate(UseSSE == 0 && n->getf() == 1.0F); 4140 match(ConF); 4141 4142 op_cost(5); 4143 format %{ %} 4144 interface(CONST_INTER); 4145%} 4146 4147// Float Immediate 4148operand immFPR() %{ 4149 predicate( UseSSE == 0 ); 4150 match(ConF); 4151 4152 op_cost(5); 4153 format %{ %} 4154 interface(CONST_INTER); 4155%} 4156 4157// Float Immediate 4158operand immF() %{ 4159 predicate(UseSSE >= 1); 4160 match(ConF); 4161 4162 op_cost(5); 4163 format %{ %} 4164 interface(CONST_INTER); 4165%} 4166 4167// Float Immediate zero. Zero and not -0.0 4168operand immF0() %{ 4169 predicate( UseSSE >= 1 && jint_cast(n->getf()) == 0 ); 4170 match(ConF); 4171 4172 op_cost(5); 4173 format %{ %} 4174 interface(CONST_INTER); 4175%} 4176 4177// Immediates for special shifts (sign extend) 4178 4179// Constants for increment 4180operand immI_16() %{ 4181 predicate( n->get_int() == 16 ); 4182 match(ConI); 4183 4184 format %{ %} 4185 interface(CONST_INTER); 4186%} 4187 4188operand immI_24() %{ 4189 predicate( n->get_int() == 24 ); 4190 match(ConI); 4191 4192 format %{ %} 4193 interface(CONST_INTER); 4194%} 4195 4196// Constant for byte-wide masking 4197operand immI_255() %{ 4198 predicate( n->get_int() == 255 ); 4199 match(ConI); 4200 4201 format %{ %} 4202 interface(CONST_INTER); 4203%} 4204 4205// Constant for short-wide masking 4206operand immI_65535() %{ 4207 predicate(n->get_int() == 65535); 4208 match(ConI); 4209 4210 format %{ %} 4211 interface(CONST_INTER); 4212%} 4213 4214// Register Operands 4215// Integer Register 4216operand rRegI() %{ 4217 constraint(ALLOC_IN_RC(int_reg)); 4218 match(RegI); 4219 match(xRegI); 4220 match(eAXRegI); 4221 match(eBXRegI); 4222 match(eCXRegI); 4223 match(eDXRegI); 4224 match(eDIRegI); 4225 match(eSIRegI); 4226 4227 format %{ %} 4228 interface(REG_INTER); 4229%} 4230 4231// Subset of Integer Register 4232operand xRegI(rRegI reg) %{ 4233 constraint(ALLOC_IN_RC(int_x_reg)); 4234 match(reg); 4235 match(eAXRegI); 4236 match(eBXRegI); 4237 match(eCXRegI); 4238 match(eDXRegI); 4239 4240 format %{ %} 4241 interface(REG_INTER); 4242%} 4243 4244// Special Registers 4245operand eAXRegI(xRegI reg) %{ 4246 constraint(ALLOC_IN_RC(eax_reg)); 4247 match(reg); 4248 match(rRegI); 4249 4250 format %{ "EAX" %} 4251 interface(REG_INTER); 4252%} 4253 4254// Special Registers 4255operand eBXRegI(xRegI reg) %{ 4256 constraint(ALLOC_IN_RC(ebx_reg)); 4257 match(reg); 4258 match(rRegI); 4259 4260 format %{ "EBX" %} 4261 interface(REG_INTER); 4262%} 4263 4264operand eCXRegI(xRegI reg) %{ 4265 constraint(ALLOC_IN_RC(ecx_reg)); 4266 match(reg); 4267 match(rRegI); 4268 4269 format %{ "ECX" %} 4270 interface(REG_INTER); 4271%} 4272 4273operand eDXRegI(xRegI reg) %{ 4274 constraint(ALLOC_IN_RC(edx_reg)); 4275 match(reg); 4276 match(rRegI); 4277 4278 format %{ "EDX" %} 4279 interface(REG_INTER); 4280%} 4281 4282operand eDIRegI(xRegI reg) %{ 4283 constraint(ALLOC_IN_RC(edi_reg)); 4284 match(reg); 4285 match(rRegI); 4286 4287 format %{ "EDI" %} 4288 interface(REG_INTER); 4289%} 4290 4291operand naxRegI() %{ 4292 constraint(ALLOC_IN_RC(nax_reg)); 4293 match(RegI); 4294 match(eCXRegI); 4295 match(eDXRegI); 4296 match(eSIRegI); 4297 match(eDIRegI); 4298 4299 format %{ %} 4300 interface(REG_INTER); 4301%} 4302 4303operand nadxRegI() %{ 4304 constraint(ALLOC_IN_RC(nadx_reg)); 4305 match(RegI); 4306 match(eBXRegI); 4307 match(eCXRegI); 4308 match(eSIRegI); 4309 match(eDIRegI); 4310 4311 format %{ %} 4312 interface(REG_INTER); 4313%} 4314 4315operand ncxRegI() %{ 4316 constraint(ALLOC_IN_RC(ncx_reg)); 4317 match(RegI); 4318 match(eAXRegI); 4319 match(eDXRegI); 4320 match(eSIRegI); 4321 match(eDIRegI); 4322 4323 format %{ %} 4324 interface(REG_INTER); 4325%} 4326 4327// // This operand was used by cmpFastUnlock, but conflicted with 'object' reg 4328// // 4329operand eSIRegI(xRegI reg) %{ 4330 constraint(ALLOC_IN_RC(esi_reg)); 4331 match(reg); 4332 match(rRegI); 4333 4334 format %{ "ESI" %} 4335 interface(REG_INTER); 4336%} 4337 4338// Pointer Register 4339operand anyRegP() %{ 4340 constraint(ALLOC_IN_RC(any_reg)); 4341 match(RegP); 4342 match(eAXRegP); 4343 match(eBXRegP); 4344 match(eCXRegP); 4345 match(eDIRegP); 4346 match(eRegP); 4347 4348 format %{ %} 4349 interface(REG_INTER); 4350%} 4351 4352operand eRegP() %{ 4353 constraint(ALLOC_IN_RC(int_reg)); 4354 match(RegP); 4355 match(eAXRegP); 4356 match(eBXRegP); 4357 match(eCXRegP); 4358 match(eDIRegP); 4359 4360 format %{ %} 4361 interface(REG_INTER); 4362%} 4363 4364// On windows95, EBP is not safe to use for implicit null tests. 4365operand eRegP_no_EBP() %{ 4366 constraint(ALLOC_IN_RC(int_reg_no_rbp)); 4367 match(RegP); 4368 match(eAXRegP); 4369 match(eBXRegP); 4370 match(eCXRegP); 4371 match(eDIRegP); 4372 4373 op_cost(100); 4374 format %{ %} 4375 interface(REG_INTER); 4376%} 4377 4378operand naxRegP() %{ 4379 constraint(ALLOC_IN_RC(nax_reg)); 4380 match(RegP); 4381 match(eBXRegP); 4382 match(eDXRegP); 4383 match(eCXRegP); 4384 match(eSIRegP); 4385 match(eDIRegP); 4386 4387 format %{ %} 4388 interface(REG_INTER); 4389%} 4390 4391operand nabxRegP() %{ 4392 constraint(ALLOC_IN_RC(nabx_reg)); 4393 match(RegP); 4394 match(eCXRegP); 4395 match(eDXRegP); 4396 match(eSIRegP); 4397 match(eDIRegP); 4398 4399 format %{ %} 4400 interface(REG_INTER); 4401%} 4402 4403operand pRegP() %{ 4404 constraint(ALLOC_IN_RC(p_reg)); 4405 match(RegP); 4406 match(eBXRegP); 4407 match(eDXRegP); 4408 match(eSIRegP); 4409 match(eDIRegP); 4410 4411 format %{ %} 4412 interface(REG_INTER); 4413%} 4414 4415// Special Registers 4416// Return a pointer value 4417operand eAXRegP(eRegP reg) %{ 4418 constraint(ALLOC_IN_RC(eax_reg)); 4419 match(reg); 4420 format %{ "EAX" %} 4421 interface(REG_INTER); 4422%} 4423 4424// Used in AtomicAdd 4425operand eBXRegP(eRegP reg) %{ 4426 constraint(ALLOC_IN_RC(ebx_reg)); 4427 match(reg); 4428 format %{ "EBX" %} 4429 interface(REG_INTER); 4430%} 4431 4432// Tail-call (interprocedural jump) to interpreter 4433operand eCXRegP(eRegP reg) %{ 4434 constraint(ALLOC_IN_RC(ecx_reg)); 4435 match(reg); 4436 format %{ "ECX" %} 4437 interface(REG_INTER); 4438%} 4439 4440operand eSIRegP(eRegP reg) %{ 4441 constraint(ALLOC_IN_RC(esi_reg)); 4442 match(reg); 4443 format %{ "ESI" %} 4444 interface(REG_INTER); 4445%} 4446 4447// Used in rep stosw 4448operand eDIRegP(eRegP reg) %{ 4449 constraint(ALLOC_IN_RC(edi_reg)); 4450 match(reg); 4451 format %{ "EDI" %} 4452 interface(REG_INTER); 4453%} 4454 4455operand eBPRegP() %{ 4456 constraint(ALLOC_IN_RC(ebp_reg)); 4457 match(RegP); 4458 format %{ "EBP" %} 4459 interface(REG_INTER); 4460%} 4461 4462operand eRegL() %{ 4463 constraint(ALLOC_IN_RC(long_reg)); 4464 match(RegL); 4465 match(eADXRegL); 4466 4467 format %{ %} 4468 interface(REG_INTER); 4469%} 4470 4471operand eADXRegL( eRegL reg ) %{ 4472 constraint(ALLOC_IN_RC(eadx_reg)); 4473 match(reg); 4474 4475 format %{ "EDX:EAX" %} 4476 interface(REG_INTER); 4477%} 4478 4479operand eBCXRegL( eRegL reg ) %{ 4480 constraint(ALLOC_IN_RC(ebcx_reg)); 4481 match(reg); 4482 4483 format %{ "EBX:ECX" %} 4484 interface(REG_INTER); 4485%} 4486 4487// Special case for integer high multiply 4488operand eADXRegL_low_only() %{ 4489 constraint(ALLOC_IN_RC(eadx_reg)); 4490 match(RegL); 4491 4492 format %{ "EAX" %} 4493 interface(REG_INTER); 4494%} 4495 4496// Flags register, used as output of compare instructions 4497operand eFlagsReg() %{ 4498 constraint(ALLOC_IN_RC(int_flags)); 4499 match(RegFlags); 4500 4501 format %{ "EFLAGS" %} 4502 interface(REG_INTER); 4503%} 4504 4505// Flags register, used as output of FLOATING POINT compare instructions 4506operand eFlagsRegU() %{ 4507 constraint(ALLOC_IN_RC(int_flags)); 4508 match(RegFlags); 4509 4510 format %{ "EFLAGS_U" %} 4511 interface(REG_INTER); 4512%} 4513 4514operand eFlagsRegUCF() %{ 4515 constraint(ALLOC_IN_RC(int_flags)); 4516 match(RegFlags); 4517 predicate(false); 4518 4519 format %{ "EFLAGS_U_CF" %} 4520 interface(REG_INTER); 4521%} 4522 4523// Condition Code Register used by long compare 4524operand flagsReg_long_LTGE() %{ 4525 constraint(ALLOC_IN_RC(int_flags)); 4526 match(RegFlags); 4527 format %{ "FLAGS_LTGE" %} 4528 interface(REG_INTER); 4529%} 4530operand flagsReg_long_EQNE() %{ 4531 constraint(ALLOC_IN_RC(int_flags)); 4532 match(RegFlags); 4533 format %{ "FLAGS_EQNE" %} 4534 interface(REG_INTER); 4535%} 4536operand flagsReg_long_LEGT() %{ 4537 constraint(ALLOC_IN_RC(int_flags)); 4538 match(RegFlags); 4539 format %{ "FLAGS_LEGT" %} 4540 interface(REG_INTER); 4541%} 4542 4543// Float register operands 4544operand regDPR() %{ 4545 predicate( UseSSE < 2 ); 4546 constraint(ALLOC_IN_RC(fp_dbl_reg)); 4547 match(RegD); 4548 match(regDPR1); 4549 match(regDPR2); 4550 format %{ %} 4551 interface(REG_INTER); 4552%} 4553 4554operand regDPR1(regDPR reg) %{ 4555 predicate( UseSSE < 2 ); 4556 constraint(ALLOC_IN_RC(fp_dbl_reg0)); 4557 match(reg); 4558 format %{ "FPR1" %} 4559 interface(REG_INTER); 4560%} 4561 4562operand regDPR2(regDPR reg) %{ 4563 predicate( UseSSE < 2 ); 4564 constraint(ALLOC_IN_RC(fp_dbl_reg1)); 4565 match(reg); 4566 format %{ "FPR2" %} 4567 interface(REG_INTER); 4568%} 4569 4570operand regnotDPR1(regDPR reg) %{ 4571 predicate( UseSSE < 2 ); 4572 constraint(ALLOC_IN_RC(fp_dbl_notreg0)); 4573 match(reg); 4574 format %{ %} 4575 interface(REG_INTER); 4576%} 4577 4578// Float register operands 4579operand regFPR() %{ 4580 predicate( UseSSE < 2 ); 4581 constraint(ALLOC_IN_RC(fp_flt_reg)); 4582 match(RegF); 4583 match(regFPR1); 4584 format %{ %} 4585 interface(REG_INTER); 4586%} 4587 4588// Float register operands 4589operand regFPR1(regFPR reg) %{ 4590 predicate( UseSSE < 2 ); 4591 constraint(ALLOC_IN_RC(fp_flt_reg0)); 4592 match(reg); 4593 format %{ "FPR1" %} 4594 interface(REG_INTER); 4595%} 4596 4597// XMM Float register operands 4598operand regF() %{ 4599 predicate( UseSSE>=1 ); 4600 constraint(ALLOC_IN_RC(float_reg)); 4601 match(RegF); 4602 format %{ %} 4603 interface(REG_INTER); 4604%} 4605 4606// XMM Double register operands 4607operand regD() %{ 4608 predicate( UseSSE>=2 ); 4609 constraint(ALLOC_IN_RC(double_reg)); 4610 match(RegD); 4611 format %{ %} 4612 interface(REG_INTER); 4613%} 4614 4615 4616//----------Memory Operands---------------------------------------------------- 4617// Direct Memory Operand 4618operand direct(immP addr) %{ 4619 match(addr); 4620 4621 format %{ "[$addr]" %} 4622 interface(MEMORY_INTER) %{ 4623 base(0xFFFFFFFF); 4624 index(0x4); 4625 scale(0x0); 4626 disp($addr); 4627 %} 4628%} 4629 4630// Indirect Memory Operand 4631operand indirect(eRegP reg) %{ 4632 constraint(ALLOC_IN_RC(int_reg)); 4633 match(reg); 4634 4635 format %{ "[$reg]" %} 4636 interface(MEMORY_INTER) %{ 4637 base($reg); 4638 index(0x4); 4639 scale(0x0); 4640 disp(0x0); 4641 %} 4642%} 4643 4644// Indirect Memory Plus Short Offset Operand 4645operand indOffset8(eRegP reg, immI8 off) %{ 4646 match(AddP reg off); 4647 4648 format %{ "[$reg + $off]" %} 4649 interface(MEMORY_INTER) %{ 4650 base($reg); 4651 index(0x4); 4652 scale(0x0); 4653 disp($off); 4654 %} 4655%} 4656 4657// Indirect Memory Plus Long Offset Operand 4658operand indOffset32(eRegP reg, immI off) %{ 4659 match(AddP reg off); 4660 4661 format %{ "[$reg + $off]" %} 4662 interface(MEMORY_INTER) %{ 4663 base($reg); 4664 index(0x4); 4665 scale(0x0); 4666 disp($off); 4667 %} 4668%} 4669 4670// Indirect Memory Plus Long Offset Operand 4671operand indOffset32X(rRegI reg, immP off) %{ 4672 match(AddP off reg); 4673 4674 format %{ "[$reg + $off]" %} 4675 interface(MEMORY_INTER) %{ 4676 base($reg); 4677 index(0x4); 4678 scale(0x0); 4679 disp($off); 4680 %} 4681%} 4682 4683// Indirect Memory Plus Index Register Plus Offset Operand 4684operand indIndexOffset(eRegP reg, rRegI ireg, immI off) %{ 4685 match(AddP (AddP reg ireg) off); 4686 4687 op_cost(10); 4688 format %{"[$reg + $off + $ireg]" %} 4689 interface(MEMORY_INTER) %{ 4690 base($reg); 4691 index($ireg); 4692 scale(0x0); 4693 disp($off); 4694 %} 4695%} 4696 4697// Indirect Memory Plus Index Register Plus Offset Operand 4698operand indIndex(eRegP reg, rRegI ireg) %{ 4699 match(AddP reg ireg); 4700 4701 op_cost(10); 4702 format %{"[$reg + $ireg]" %} 4703 interface(MEMORY_INTER) %{ 4704 base($reg); 4705 index($ireg); 4706 scale(0x0); 4707 disp(0x0); 4708 %} 4709%} 4710 4711// // ------------------------------------------------------------------------- 4712// // 486 architecture doesn't support "scale * index + offset" with out a base 4713// // ------------------------------------------------------------------------- 4714// // Scaled Memory Operands 4715// // Indirect Memory Times Scale Plus Offset Operand 4716// operand indScaleOffset(immP off, rRegI ireg, immI2 scale) %{ 4717// match(AddP off (LShiftI ireg scale)); 4718// 4719// op_cost(10); 4720// format %{"[$off + $ireg << $scale]" %} 4721// interface(MEMORY_INTER) %{ 4722// base(0x4); 4723// index($ireg); 4724// scale($scale); 4725// disp($off); 4726// %} 4727// %} 4728 4729// Indirect Memory Times Scale Plus Index Register 4730operand indIndexScale(eRegP reg, rRegI ireg, immI2 scale) %{ 4731 match(AddP reg (LShiftI ireg scale)); 4732 4733 op_cost(10); 4734 format %{"[$reg + $ireg << $scale]" %} 4735 interface(MEMORY_INTER) %{ 4736 base($reg); 4737 index($ireg); 4738 scale($scale); 4739 disp(0x0); 4740 %} 4741%} 4742 4743// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4744operand indIndexScaleOffset(eRegP reg, immI off, rRegI ireg, immI2 scale) %{ 4745 match(AddP (AddP reg (LShiftI ireg scale)) off); 4746 4747 op_cost(10); 4748 format %{"[$reg + $off + $ireg << $scale]" %} 4749 interface(MEMORY_INTER) %{ 4750 base($reg); 4751 index($ireg); 4752 scale($scale); 4753 disp($off); 4754 %} 4755%} 4756 4757//----------Load Long Memory Operands------------------------------------------ 4758// The load-long idiom will use it's address expression again after loading 4759// the first word of the long. If the load-long destination overlaps with 4760// registers used in the addressing expression, the 2nd half will be loaded 4761// from a clobbered address. Fix this by requiring that load-long use 4762// address registers that do not overlap with the load-long target. 4763 4764// load-long support 4765operand load_long_RegP() %{ 4766 constraint(ALLOC_IN_RC(esi_reg)); 4767 match(RegP); 4768 match(eSIRegP); 4769 op_cost(100); 4770 format %{ %} 4771 interface(REG_INTER); 4772%} 4773 4774// Indirect Memory Operand Long 4775operand load_long_indirect(load_long_RegP reg) %{ 4776 constraint(ALLOC_IN_RC(esi_reg)); 4777 match(reg); 4778 4779 format %{ "[$reg]" %} 4780 interface(MEMORY_INTER) %{ 4781 base($reg); 4782 index(0x4); 4783 scale(0x0); 4784 disp(0x0); 4785 %} 4786%} 4787 4788// Indirect Memory Plus Long Offset Operand 4789operand load_long_indOffset32(load_long_RegP reg, immI off) %{ 4790 match(AddP reg off); 4791 4792 format %{ "[$reg + $off]" %} 4793 interface(MEMORY_INTER) %{ 4794 base($reg); 4795 index(0x4); 4796 scale(0x0); 4797 disp($off); 4798 %} 4799%} 4800 4801opclass load_long_memory(load_long_indirect, load_long_indOffset32); 4802 4803 4804//----------Special Memory Operands-------------------------------------------- 4805// Stack Slot Operand - This operand is used for loading and storing temporary 4806// values on the stack where a match requires a value to 4807// flow through memory. 4808operand stackSlotP(sRegP reg) %{ 4809 constraint(ALLOC_IN_RC(stack_slots)); 4810 // No match rule because this operand is only generated in matching 4811 format %{ "[$reg]" %} 4812 interface(MEMORY_INTER) %{ 4813 base(0x4); // ESP 4814 index(0x4); // No Index 4815 scale(0x0); // No Scale 4816 disp($reg); // Stack Offset 4817 %} 4818%} 4819 4820operand stackSlotI(sRegI reg) %{ 4821 constraint(ALLOC_IN_RC(stack_slots)); 4822 // No match rule because this operand is only generated in matching 4823 format %{ "[$reg]" %} 4824 interface(MEMORY_INTER) %{ 4825 base(0x4); // ESP 4826 index(0x4); // No Index 4827 scale(0x0); // No Scale 4828 disp($reg); // Stack Offset 4829 %} 4830%} 4831 4832operand stackSlotF(sRegF reg) %{ 4833 constraint(ALLOC_IN_RC(stack_slots)); 4834 // No match rule because this operand is only generated in matching 4835 format %{ "[$reg]" %} 4836 interface(MEMORY_INTER) %{ 4837 base(0x4); // ESP 4838 index(0x4); // No Index 4839 scale(0x0); // No Scale 4840 disp($reg); // Stack Offset 4841 %} 4842%} 4843 4844operand stackSlotD(sRegD reg) %{ 4845 constraint(ALLOC_IN_RC(stack_slots)); 4846 // No match rule because this operand is only generated in matching 4847 format %{ "[$reg]" %} 4848 interface(MEMORY_INTER) %{ 4849 base(0x4); // ESP 4850 index(0x4); // No Index 4851 scale(0x0); // No Scale 4852 disp($reg); // Stack Offset 4853 %} 4854%} 4855 4856operand stackSlotL(sRegL reg) %{ 4857 constraint(ALLOC_IN_RC(stack_slots)); 4858 // No match rule because this operand is only generated in matching 4859 format %{ "[$reg]" %} 4860 interface(MEMORY_INTER) %{ 4861 base(0x4); // ESP 4862 index(0x4); // No Index 4863 scale(0x0); // No Scale 4864 disp($reg); // Stack Offset 4865 %} 4866%} 4867 4868//----------Memory Operands - Win95 Implicit Null Variants---------------- 4869// Indirect Memory Operand 4870operand indirect_win95_safe(eRegP_no_EBP reg) 4871%{ 4872 constraint(ALLOC_IN_RC(int_reg)); 4873 match(reg); 4874 4875 op_cost(100); 4876 format %{ "[$reg]" %} 4877 interface(MEMORY_INTER) %{ 4878 base($reg); 4879 index(0x4); 4880 scale(0x0); 4881 disp(0x0); 4882 %} 4883%} 4884 4885// Indirect Memory Plus Short Offset Operand 4886operand indOffset8_win95_safe(eRegP_no_EBP reg, immI8 off) 4887%{ 4888 match(AddP reg off); 4889 4890 op_cost(100); 4891 format %{ "[$reg + $off]" %} 4892 interface(MEMORY_INTER) %{ 4893 base($reg); 4894 index(0x4); 4895 scale(0x0); 4896 disp($off); 4897 %} 4898%} 4899 4900// Indirect Memory Plus Long Offset Operand 4901operand indOffset32_win95_safe(eRegP_no_EBP reg, immI off) 4902%{ 4903 match(AddP reg off); 4904 4905 op_cost(100); 4906 format %{ "[$reg + $off]" %} 4907 interface(MEMORY_INTER) %{ 4908 base($reg); 4909 index(0x4); 4910 scale(0x0); 4911 disp($off); 4912 %} 4913%} 4914 4915// Indirect Memory Plus Index Register Plus Offset Operand 4916operand indIndexOffset_win95_safe(eRegP_no_EBP reg, rRegI ireg, immI off) 4917%{ 4918 match(AddP (AddP reg ireg) off); 4919 4920 op_cost(100); 4921 format %{"[$reg + $off + $ireg]" %} 4922 interface(MEMORY_INTER) %{ 4923 base($reg); 4924 index($ireg); 4925 scale(0x0); 4926 disp($off); 4927 %} 4928%} 4929 4930// Indirect Memory Times Scale Plus Index Register 4931operand indIndexScale_win95_safe(eRegP_no_EBP reg, rRegI ireg, immI2 scale) 4932%{ 4933 match(AddP reg (LShiftI ireg scale)); 4934 4935 op_cost(100); 4936 format %{"[$reg + $ireg << $scale]" %} 4937 interface(MEMORY_INTER) %{ 4938 base($reg); 4939 index($ireg); 4940 scale($scale); 4941 disp(0x0); 4942 %} 4943%} 4944 4945// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4946operand indIndexScaleOffset_win95_safe(eRegP_no_EBP reg, immI off, rRegI ireg, immI2 scale) 4947%{ 4948 match(AddP (AddP reg (LShiftI ireg scale)) off); 4949 4950 op_cost(100); 4951 format %{"[$reg + $off + $ireg << $scale]" %} 4952 interface(MEMORY_INTER) %{ 4953 base($reg); 4954 index($ireg); 4955 scale($scale); 4956 disp($off); 4957 %} 4958%} 4959 4960//----------Conditional Branch Operands---------------------------------------- 4961// Comparison Op - This is the operation of the comparison, and is limited to 4962// the following set of codes: 4963// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4964// 4965// Other attributes of the comparison, such as unsignedness, are specified 4966// by the comparison instruction that sets a condition code flags register. 4967// That result is represented by a flags operand whose subtype is appropriate 4968// to the unsignedness (etc.) of the comparison. 4969// 4970// Later, the instruction which matches both the Comparison Op (a Bool) and 4971// the flags (produced by the Cmp) specifies the coding of the comparison op 4972// by matching a specific subtype of Bool operand below, such as cmpOpU. 4973 4974// Comparision Code 4975operand cmpOp() %{ 4976 match(Bool); 4977 4978 format %{ "" %} 4979 interface(COND_INTER) %{ 4980 equal(0x4, "e"); 4981 not_equal(0x5, "ne"); 4982 less(0xC, "l"); 4983 greater_equal(0xD, "ge"); 4984 less_equal(0xE, "le"); 4985 greater(0xF, "g"); 4986 %} 4987%} 4988 4989// Comparison Code, unsigned compare. Used by FP also, with 4990// C2 (unordered) turned into GT or LT already. The other bits 4991// C0 and C3 are turned into Carry & Zero flags. 4992operand cmpOpU() %{ 4993 match(Bool); 4994 4995 format %{ "" %} 4996 interface(COND_INTER) %{ 4997 equal(0x4, "e"); 4998 not_equal(0x5, "ne"); 4999 less(0x2, "b"); 5000 greater_equal(0x3, "nb"); 5001 less_equal(0x6, "be"); 5002 greater(0x7, "nbe"); 5003 %} 5004%} 5005 5006// Floating comparisons that don't require any fixup for the unordered case 5007operand cmpOpUCF() %{ 5008 match(Bool); 5009 predicate(n->as_Bool()->_test._test == BoolTest::lt || 5010 n->as_Bool()->_test._test == BoolTest::ge || 5011 n->as_Bool()->_test._test == BoolTest::le || 5012 n->as_Bool()->_test._test == BoolTest::gt); 5013 format %{ "" %} 5014 interface(COND_INTER) %{ 5015 equal(0x4, "e"); 5016 not_equal(0x5, "ne"); 5017 less(0x2, "b"); 5018 greater_equal(0x3, "nb"); 5019 less_equal(0x6, "be"); 5020 greater(0x7, "nbe"); 5021 %} 5022%} 5023 5024 5025// Floating comparisons that can be fixed up with extra conditional jumps 5026operand cmpOpUCF2() %{ 5027 match(Bool); 5028 predicate(n->as_Bool()->_test._test == BoolTest::ne || 5029 n->as_Bool()->_test._test == BoolTest::eq); 5030 format %{ "" %} 5031 interface(COND_INTER) %{ 5032 equal(0x4, "e"); 5033 not_equal(0x5, "ne"); 5034 less(0x2, "b"); 5035 greater_equal(0x3, "nb"); 5036 less_equal(0x6, "be"); 5037 greater(0x7, "nbe"); 5038 %} 5039%} 5040 5041// Comparison Code for FP conditional move 5042operand cmpOp_fcmov() %{ 5043 match(Bool); 5044 5045 format %{ "" %} 5046 interface(COND_INTER) %{ 5047 equal (0x0C8); 5048 not_equal (0x1C8); 5049 less (0x0C0); 5050 greater_equal(0x1C0); 5051 less_equal (0x0D0); 5052 greater (0x1D0); 5053 %} 5054%} 5055 5056// Comparision Code used in long compares 5057operand cmpOp_commute() %{ 5058 match(Bool); 5059 5060 format %{ "" %} 5061 interface(COND_INTER) %{ 5062 equal(0x4, "e"); 5063 not_equal(0x5, "ne"); 5064 less(0xF, "g"); 5065 greater_equal(0xE, "le"); 5066 less_equal(0xD, "ge"); 5067 greater(0xC, "l"); 5068 %} 5069%} 5070 5071//----------OPERAND CLASSES---------------------------------------------------- 5072// Operand Classes are groups of operands that are used as to simplify 5073// instruction definitions by not requiring the AD writer to specify separate 5074// instructions for every form of operand when the instruction accepts 5075// multiple operand types with the same basic encoding and format. The classic 5076// case of this is memory operands. 5077 5078opclass memory(direct, indirect, indOffset8, indOffset32, indOffset32X, indIndexOffset, 5079 indIndex, indIndexScale, indIndexScaleOffset); 5080 5081// Long memory operations are encoded in 2 instructions and a +4 offset. 5082// This means some kind of offset is always required and you cannot use 5083// an oop as the offset (done when working on static globals). 5084opclass long_memory(direct, indirect, indOffset8, indOffset32, indIndexOffset, 5085 indIndex, indIndexScale, indIndexScaleOffset); 5086 5087 5088//----------PIPELINE----------------------------------------------------------- 5089// Rules which define the behavior of the target architectures pipeline. 5090pipeline %{ 5091 5092//----------ATTRIBUTES--------------------------------------------------------- 5093attributes %{ 5094 variable_size_instructions; // Fixed size instructions 5095 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 5096 instruction_unit_size = 1; // An instruction is 1 bytes long 5097 instruction_fetch_unit_size = 16; // The processor fetches one line 5098 instruction_fetch_units = 1; // of 16 bytes 5099 5100 // List of nop instructions 5101 nops( MachNop ); 5102%} 5103 5104//----------RESOURCES---------------------------------------------------------- 5105// Resources are the functional units available to the machine 5106 5107// Generic P2/P3 pipeline 5108// 3 decoders, only D0 handles big operands; a "bundle" is the limit of 5109// 3 instructions decoded per cycle. 5110// 2 load/store ops per cycle, 1 branch, 1 FPU, 5111// 2 ALU op, only ALU0 handles mul/div instructions. 5112resources( D0, D1, D2, DECODE = D0 | D1 | D2, 5113 MS0, MS1, MEM = MS0 | MS1, 5114 BR, FPU, 5115 ALU0, ALU1, ALU = ALU0 | ALU1 ); 5116 5117//----------PIPELINE DESCRIPTION----------------------------------------------- 5118// Pipeline Description specifies the stages in the machine's pipeline 5119 5120// Generic P2/P3 pipeline 5121pipe_desc(S0, S1, S2, S3, S4, S5); 5122 5123//----------PIPELINE CLASSES--------------------------------------------------- 5124// Pipeline Classes describe the stages in which input and output are 5125// referenced by the hardware pipeline. 5126 5127// Naming convention: ialu or fpu 5128// Then: _reg 5129// Then: _reg if there is a 2nd register 5130// Then: _long if it's a pair of instructions implementing a long 5131// Then: _fat if it requires the big decoder 5132// Or: _mem if it requires the big decoder and a memory unit. 5133 5134// Integer ALU reg operation 5135pipe_class ialu_reg(rRegI dst) %{ 5136 single_instruction; 5137 dst : S4(write); 5138 dst : S3(read); 5139 DECODE : S0; // any decoder 5140 ALU : S3; // any alu 5141%} 5142 5143// Long ALU reg operation 5144pipe_class ialu_reg_long(eRegL dst) %{ 5145 instruction_count(2); 5146 dst : S4(write); 5147 dst : S3(read); 5148 DECODE : S0(2); // any 2 decoders 5149 ALU : S3(2); // both alus 5150%} 5151 5152// Integer ALU reg operation using big decoder 5153pipe_class ialu_reg_fat(rRegI dst) %{ 5154 single_instruction; 5155 dst : S4(write); 5156 dst : S3(read); 5157 D0 : S0; // big decoder only 5158 ALU : S3; // any alu 5159%} 5160 5161// Long ALU reg operation using big decoder 5162pipe_class ialu_reg_long_fat(eRegL dst) %{ 5163 instruction_count(2); 5164 dst : S4(write); 5165 dst : S3(read); 5166 D0 : S0(2); // big decoder only; twice 5167 ALU : S3(2); // any 2 alus 5168%} 5169 5170// Integer ALU reg-reg operation 5171pipe_class ialu_reg_reg(rRegI dst, rRegI src) %{ 5172 single_instruction; 5173 dst : S4(write); 5174 src : S3(read); 5175 DECODE : S0; // any decoder 5176 ALU : S3; // any alu 5177%} 5178 5179// Long ALU reg-reg operation 5180pipe_class ialu_reg_reg_long(eRegL dst, eRegL src) %{ 5181 instruction_count(2); 5182 dst : S4(write); 5183 src : S3(read); 5184 DECODE : S0(2); // any 2 decoders 5185 ALU : S3(2); // both alus 5186%} 5187 5188// Integer ALU reg-reg operation 5189pipe_class ialu_reg_reg_fat(rRegI dst, memory src) %{ 5190 single_instruction; 5191 dst : S4(write); 5192 src : S3(read); 5193 D0 : S0; // big decoder only 5194 ALU : S3; // any alu 5195%} 5196 5197// Long ALU reg-reg operation 5198pipe_class ialu_reg_reg_long_fat(eRegL dst, eRegL src) %{ 5199 instruction_count(2); 5200 dst : S4(write); 5201 src : S3(read); 5202 D0 : S0(2); // big decoder only; twice 5203 ALU : S3(2); // both alus 5204%} 5205 5206// Integer ALU reg-mem operation 5207pipe_class ialu_reg_mem(rRegI dst, memory mem) %{ 5208 single_instruction; 5209 dst : S5(write); 5210 mem : S3(read); 5211 D0 : S0; // big decoder only 5212 ALU : S4; // any alu 5213 MEM : S3; // any mem 5214%} 5215 5216// Long ALU reg-mem operation 5217pipe_class ialu_reg_long_mem(eRegL dst, load_long_memory mem) %{ 5218 instruction_count(2); 5219 dst : S5(write); 5220 mem : S3(read); 5221 D0 : S0(2); // big decoder only; twice 5222 ALU : S4(2); // any 2 alus 5223 MEM : S3(2); // both mems 5224%} 5225 5226// Integer mem operation (prefetch) 5227pipe_class ialu_mem(memory mem) 5228%{ 5229 single_instruction; 5230 mem : S3(read); 5231 D0 : S0; // big decoder only 5232 MEM : S3; // any mem 5233%} 5234 5235// Integer Store to Memory 5236pipe_class ialu_mem_reg(memory mem, rRegI src) %{ 5237 single_instruction; 5238 mem : S3(read); 5239 src : S5(read); 5240 D0 : S0; // big decoder only 5241 ALU : S4; // any alu 5242 MEM : S3; 5243%} 5244 5245// Long Store to Memory 5246pipe_class ialu_mem_long_reg(memory mem, eRegL src) %{ 5247 instruction_count(2); 5248 mem : S3(read); 5249 src : S5(read); 5250 D0 : S0(2); // big decoder only; twice 5251 ALU : S4(2); // any 2 alus 5252 MEM : S3(2); // Both mems 5253%} 5254 5255// Integer Store to Memory 5256pipe_class ialu_mem_imm(memory mem) %{ 5257 single_instruction; 5258 mem : S3(read); 5259 D0 : S0; // big decoder only 5260 ALU : S4; // any alu 5261 MEM : S3; 5262%} 5263 5264// Integer ALU0 reg-reg operation 5265pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) %{ 5266 single_instruction; 5267 dst : S4(write); 5268 src : S3(read); 5269 D0 : S0; // Big decoder only 5270 ALU0 : S3; // only alu0 5271%} 5272 5273// Integer ALU0 reg-mem operation 5274pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) %{ 5275 single_instruction; 5276 dst : S5(write); 5277 mem : S3(read); 5278 D0 : S0; // big decoder only 5279 ALU0 : S4; // ALU0 only 5280 MEM : S3; // any mem 5281%} 5282 5283// Integer ALU reg-reg operation 5284pipe_class ialu_cr_reg_reg(eFlagsReg cr, rRegI src1, rRegI src2) %{ 5285 single_instruction; 5286 cr : S4(write); 5287 src1 : S3(read); 5288 src2 : S3(read); 5289 DECODE : S0; // any decoder 5290 ALU : S3; // any alu 5291%} 5292 5293// Integer ALU reg-imm operation 5294pipe_class ialu_cr_reg_imm(eFlagsReg cr, rRegI src1) %{ 5295 single_instruction; 5296 cr : S4(write); 5297 src1 : S3(read); 5298 DECODE : S0; // any decoder 5299 ALU : S3; // any alu 5300%} 5301 5302// Integer ALU reg-mem operation 5303pipe_class ialu_cr_reg_mem(eFlagsReg cr, rRegI src1, memory src2) %{ 5304 single_instruction; 5305 cr : S4(write); 5306 src1 : S3(read); 5307 src2 : S3(read); 5308 D0 : S0; // big decoder only 5309 ALU : S4; // any alu 5310 MEM : S3; 5311%} 5312 5313// Conditional move reg-reg 5314pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y ) %{ 5315 instruction_count(4); 5316 y : S4(read); 5317 q : S3(read); 5318 p : S3(read); 5319 DECODE : S0(4); // any decoder 5320%} 5321 5322// Conditional move reg-reg 5323pipe_class pipe_cmov_reg( rRegI dst, rRegI src, eFlagsReg cr ) %{ 5324 single_instruction; 5325 dst : S4(write); 5326 src : S3(read); 5327 cr : S3(read); 5328 DECODE : S0; // any decoder 5329%} 5330 5331// Conditional move reg-mem 5332pipe_class pipe_cmov_mem( eFlagsReg cr, rRegI dst, memory src) %{ 5333 single_instruction; 5334 dst : S4(write); 5335 src : S3(read); 5336 cr : S3(read); 5337 DECODE : S0; // any decoder 5338 MEM : S3; 5339%} 5340 5341// Conditional move reg-reg long 5342pipe_class pipe_cmov_reg_long( eFlagsReg cr, eRegL dst, eRegL src) %{ 5343 single_instruction; 5344 dst : S4(write); 5345 src : S3(read); 5346 cr : S3(read); 5347 DECODE : S0(2); // any 2 decoders 5348%} 5349 5350// Conditional move double reg-reg 5351pipe_class pipe_cmovDPR_reg( eFlagsReg cr, regDPR1 dst, regDPR src) %{ 5352 single_instruction; 5353 dst : S4(write); 5354 src : S3(read); 5355 cr : S3(read); 5356 DECODE : S0; // any decoder 5357%} 5358 5359// Float reg-reg operation 5360pipe_class fpu_reg(regDPR dst) %{ 5361 instruction_count(2); 5362 dst : S3(read); 5363 DECODE : S0(2); // any 2 decoders 5364 FPU : S3; 5365%} 5366 5367// Float reg-reg operation 5368pipe_class fpu_reg_reg(regDPR dst, regDPR src) %{ 5369 instruction_count(2); 5370 dst : S4(write); 5371 src : S3(read); 5372 DECODE : S0(2); // any 2 decoders 5373 FPU : S3; 5374%} 5375 5376// Float reg-reg operation 5377pipe_class fpu_reg_reg_reg(regDPR dst, regDPR src1, regDPR src2) %{ 5378 instruction_count(3); 5379 dst : S4(write); 5380 src1 : S3(read); 5381 src2 : S3(read); 5382 DECODE : S0(3); // any 3 decoders 5383 FPU : S3(2); 5384%} 5385 5386// Float reg-reg operation 5387pipe_class fpu_reg_reg_reg_reg(regDPR dst, regDPR src1, regDPR src2, regDPR src3) %{ 5388 instruction_count(4); 5389 dst : S4(write); 5390 src1 : S3(read); 5391 src2 : S3(read); 5392 src3 : S3(read); 5393 DECODE : S0(4); // any 3 decoders 5394 FPU : S3(2); 5395%} 5396 5397// Float reg-reg operation 5398pipe_class fpu_reg_mem_reg_reg(regDPR dst, memory src1, regDPR src2, regDPR src3) %{ 5399 instruction_count(4); 5400 dst : S4(write); 5401 src1 : S3(read); 5402 src2 : S3(read); 5403 src3 : S3(read); 5404 DECODE : S1(3); // any 3 decoders 5405 D0 : S0; // Big decoder only 5406 FPU : S3(2); 5407 MEM : S3; 5408%} 5409 5410// Float reg-mem operation 5411pipe_class fpu_reg_mem(regDPR dst, memory mem) %{ 5412 instruction_count(2); 5413 dst : S5(write); 5414 mem : S3(read); 5415 D0 : S0; // big decoder only 5416 DECODE : S1; // any decoder for FPU POP 5417 FPU : S4; 5418 MEM : S3; // any mem 5419%} 5420 5421// Float reg-mem operation 5422pipe_class fpu_reg_reg_mem(regDPR dst, regDPR src1, memory mem) %{ 5423 instruction_count(3); 5424 dst : S5(write); 5425 src1 : S3(read); 5426 mem : S3(read); 5427 D0 : S0; // big decoder only 5428 DECODE : S1(2); // any decoder for FPU POP 5429 FPU : S4; 5430 MEM : S3; // any mem 5431%} 5432 5433// Float mem-reg operation 5434pipe_class fpu_mem_reg(memory mem, regDPR src) %{ 5435 instruction_count(2); 5436 src : S5(read); 5437 mem : S3(read); 5438 DECODE : S0; // any decoder for FPU PUSH 5439 D0 : S1; // big decoder only 5440 FPU : S4; 5441 MEM : S3; // any mem 5442%} 5443 5444pipe_class fpu_mem_reg_reg(memory mem, regDPR src1, regDPR src2) %{ 5445 instruction_count(3); 5446 src1 : S3(read); 5447 src2 : S3(read); 5448 mem : S3(read); 5449 DECODE : S0(2); // any decoder for FPU PUSH 5450 D0 : S1; // big decoder only 5451 FPU : S4; 5452 MEM : S3; // any mem 5453%} 5454 5455pipe_class fpu_mem_reg_mem(memory mem, regDPR src1, memory src2) %{ 5456 instruction_count(3); 5457 src1 : S3(read); 5458 src2 : S3(read); 5459 mem : S4(read); 5460 DECODE : S0; // any decoder for FPU PUSH 5461 D0 : S0(2); // big decoder only 5462 FPU : S4; 5463 MEM : S3(2); // any mem 5464%} 5465 5466pipe_class fpu_mem_mem(memory dst, memory src1) %{ 5467 instruction_count(2); 5468 src1 : S3(read); 5469 dst : S4(read); 5470 D0 : S0(2); // big decoder only 5471 MEM : S3(2); // any mem 5472%} 5473 5474pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) %{ 5475 instruction_count(3); 5476 src1 : S3(read); 5477 src2 : S3(read); 5478 dst : S4(read); 5479 D0 : S0(3); // big decoder only 5480 FPU : S4; 5481 MEM : S3(3); // any mem 5482%} 5483 5484pipe_class fpu_mem_reg_con(memory mem, regDPR src1) %{ 5485 instruction_count(3); 5486 src1 : S4(read); 5487 mem : S4(read); 5488 DECODE : S0; // any decoder for FPU PUSH 5489 D0 : S0(2); // big decoder only 5490 FPU : S4; 5491 MEM : S3(2); // any mem 5492%} 5493 5494// Float load constant 5495pipe_class fpu_reg_con(regDPR dst) %{ 5496 instruction_count(2); 5497 dst : S5(write); 5498 D0 : S0; // big decoder only for the load 5499 DECODE : S1; // any decoder for FPU POP 5500 FPU : S4; 5501 MEM : S3; // any mem 5502%} 5503 5504// Float load constant 5505pipe_class fpu_reg_reg_con(regDPR dst, regDPR src) %{ 5506 instruction_count(3); 5507 dst : S5(write); 5508 src : S3(read); 5509 D0 : S0; // big decoder only for the load 5510 DECODE : S1(2); // any decoder for FPU POP 5511 FPU : S4; 5512 MEM : S3; // any mem 5513%} 5514 5515// UnConditional branch 5516pipe_class pipe_jmp( label labl ) %{ 5517 single_instruction; 5518 BR : S3; 5519%} 5520 5521// Conditional branch 5522pipe_class pipe_jcc( cmpOp cmp, eFlagsReg cr, label labl ) %{ 5523 single_instruction; 5524 cr : S1(read); 5525 BR : S3; 5526%} 5527 5528// Allocation idiom 5529pipe_class pipe_cmpxchg( eRegP dst, eRegP heap_ptr ) %{ 5530 instruction_count(1); force_serialization; 5531 fixed_latency(6); 5532 heap_ptr : S3(read); 5533 DECODE : S0(3); 5534 D0 : S2; 5535 MEM : S3; 5536 ALU : S3(2); 5537 dst : S5(write); 5538 BR : S5; 5539%} 5540 5541// Generic big/slow expanded idiom 5542pipe_class pipe_slow( ) %{ 5543 instruction_count(10); multiple_bundles; force_serialization; 5544 fixed_latency(100); 5545 D0 : S0(2); 5546 MEM : S3(2); 5547%} 5548 5549// The real do-nothing guy 5550pipe_class empty( ) %{ 5551 instruction_count(0); 5552%} 5553 5554// Define the class for the Nop node 5555define %{ 5556 MachNop = empty; 5557%} 5558 5559%} 5560 5561//----------INSTRUCTIONS------------------------------------------------------- 5562// 5563// match -- States which machine-independent subtree may be replaced 5564// by this instruction. 5565// ins_cost -- The estimated cost of this instruction is used by instruction 5566// selection to identify a minimum cost tree of machine 5567// instructions that matches a tree of machine-independent 5568// instructions. 5569// format -- A string providing the disassembly for this instruction. 5570// The value of an instruction's operand may be inserted 5571// by referring to it with a '$' prefix. 5572// opcode -- Three instruction opcodes may be provided. These are referred 5573// to within an encode class as $primary, $secondary, and $tertiary 5574// respectively. The primary opcode is commonly used to 5575// indicate the type of machine instruction, while secondary 5576// and tertiary are often used for prefix options or addressing 5577// modes. 5578// ins_encode -- A list of encode classes with parameters. The encode class 5579// name must have been defined in an 'enc_class' specification 5580// in the encode section of the architecture description. 5581 5582//----------BSWAP-Instruction-------------------------------------------------- 5583instruct bytes_reverse_int(rRegI dst) %{ 5584 match(Set dst (ReverseBytesI dst)); 5585 5586 format %{ "BSWAP $dst" %} 5587 opcode(0x0F, 0xC8); 5588 ins_encode( OpcP, OpcSReg(dst) ); 5589 ins_pipe( ialu_reg ); 5590%} 5591 5592instruct bytes_reverse_long(eRegL dst) %{ 5593 match(Set dst (ReverseBytesL dst)); 5594 5595 format %{ "BSWAP $dst.lo\n\t" 5596 "BSWAP $dst.hi\n\t" 5597 "XCHG $dst.lo $dst.hi" %} 5598 5599 ins_cost(125); 5600 ins_encode( bswap_long_bytes(dst) ); 5601 ins_pipe( ialu_reg_reg); 5602%} 5603 5604instruct bytes_reverse_unsigned_short(rRegI dst, eFlagsReg cr) %{ 5605 match(Set dst (ReverseBytesUS dst)); 5606 effect(KILL cr); 5607 5608 format %{ "BSWAP $dst\n\t" 5609 "SHR $dst,16\n\t" %} 5610 ins_encode %{ 5611 __ bswapl($dst$$Register); 5612 __ shrl($dst$$Register, 16); 5613 %} 5614 ins_pipe( ialu_reg ); 5615%} 5616 5617instruct bytes_reverse_short(rRegI dst, eFlagsReg cr) %{ 5618 match(Set dst (ReverseBytesS dst)); 5619 effect(KILL cr); 5620 5621 format %{ "BSWAP $dst\n\t" 5622 "SAR $dst,16\n\t" %} 5623 ins_encode %{ 5624 __ bswapl($dst$$Register); 5625 __ sarl($dst$$Register, 16); 5626 %} 5627 ins_pipe( ialu_reg ); 5628%} 5629 5630 5631//---------- Zeros Count Instructions ------------------------------------------ 5632 5633instruct countLeadingZerosI(rRegI dst, rRegI src, eFlagsReg cr) %{ 5634 predicate(UseCountLeadingZerosInstruction); 5635 match(Set dst (CountLeadingZerosI src)); 5636 effect(KILL cr); 5637 5638 format %{ "LZCNT $dst, $src\t# count leading zeros (int)" %} 5639 ins_encode %{ 5640 __ lzcntl($dst$$Register, $src$$Register); 5641 %} 5642 ins_pipe(ialu_reg); 5643%} 5644 5645instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, eFlagsReg cr) %{ 5646 predicate(!UseCountLeadingZerosInstruction); 5647 match(Set dst (CountLeadingZerosI src)); 5648 effect(KILL cr); 5649 5650 format %{ "BSR $dst, $src\t# count leading zeros (int)\n\t" 5651 "JNZ skip\n\t" 5652 "MOV $dst, -1\n" 5653 "skip:\n\t" 5654 "NEG $dst\n\t" 5655 "ADD $dst, 31" %} 5656 ins_encode %{ 5657 Register Rdst = $dst$$Register; 5658 Register Rsrc = $src$$Register; 5659 Label skip; 5660 __ bsrl(Rdst, Rsrc); 5661 __ jccb(Assembler::notZero, skip); 5662 __ movl(Rdst, -1); 5663 __ bind(skip); 5664 __ negl(Rdst); 5665 __ addl(Rdst, BitsPerInt - 1); 5666 %} 5667 ins_pipe(ialu_reg); 5668%} 5669 5670instruct countLeadingZerosL(rRegI dst, eRegL src, eFlagsReg cr) %{ 5671 predicate(UseCountLeadingZerosInstruction); 5672 match(Set dst (CountLeadingZerosL src)); 5673 effect(TEMP dst, KILL cr); 5674 5675 format %{ "LZCNT $dst, $src.hi\t# count leading zeros (long)\n\t" 5676 "JNC done\n\t" 5677 "LZCNT $dst, $src.lo\n\t" 5678 "ADD $dst, 32\n" 5679 "done:" %} 5680 ins_encode %{ 5681 Register Rdst = $dst$$Register; 5682 Register Rsrc = $src$$Register; 5683 Label done; 5684 __ lzcntl(Rdst, HIGH_FROM_LOW(Rsrc)); 5685 __ jccb(Assembler::carryClear, done); 5686 __ lzcntl(Rdst, Rsrc); 5687 __ addl(Rdst, BitsPerInt); 5688 __ bind(done); 5689 %} 5690 ins_pipe(ialu_reg); 5691%} 5692 5693instruct countLeadingZerosL_bsr(rRegI dst, eRegL src, eFlagsReg cr) %{ 5694 predicate(!UseCountLeadingZerosInstruction); 5695 match(Set dst (CountLeadingZerosL src)); 5696 effect(TEMP dst, KILL cr); 5697 5698 format %{ "BSR $dst, $src.hi\t# count leading zeros (long)\n\t" 5699 "JZ msw_is_zero\n\t" 5700 "ADD $dst, 32\n\t" 5701 "JMP not_zero\n" 5702 "msw_is_zero:\n\t" 5703 "BSR $dst, $src.lo\n\t" 5704 "JNZ not_zero\n\t" 5705 "MOV $dst, -1\n" 5706 "not_zero:\n\t" 5707 "NEG $dst\n\t" 5708 "ADD $dst, 63\n" %} 5709 ins_encode %{ 5710 Register Rdst = $dst$$Register; 5711 Register Rsrc = $src$$Register; 5712 Label msw_is_zero; 5713 Label not_zero; 5714 __ bsrl(Rdst, HIGH_FROM_LOW(Rsrc)); 5715 __ jccb(Assembler::zero, msw_is_zero); 5716 __ addl(Rdst, BitsPerInt); 5717 __ jmpb(not_zero); 5718 __ bind(msw_is_zero); 5719 __ bsrl(Rdst, Rsrc); 5720 __ jccb(Assembler::notZero, not_zero); 5721 __ movl(Rdst, -1); 5722 __ bind(not_zero); 5723 __ negl(Rdst); 5724 __ addl(Rdst, BitsPerLong - 1); 5725 %} 5726 ins_pipe(ialu_reg); 5727%} 5728 5729instruct countTrailingZerosI(rRegI dst, rRegI src, eFlagsReg cr) %{ 5730 match(Set dst (CountTrailingZerosI src)); 5731 effect(KILL cr); 5732 5733 format %{ "BSF $dst, $src\t# count trailing zeros (int)\n\t" 5734 "JNZ done\n\t" 5735 "MOV $dst, 32\n" 5736 "done:" %} 5737 ins_encode %{ 5738 Register Rdst = $dst$$Register; 5739 Label done; 5740 __ bsfl(Rdst, $src$$Register); 5741 __ jccb(Assembler::notZero, done); 5742 __ movl(Rdst, BitsPerInt); 5743 __ bind(done); 5744 %} 5745 ins_pipe(ialu_reg); 5746%} 5747 5748instruct countTrailingZerosL(rRegI dst, eRegL src, eFlagsReg cr) %{ 5749 match(Set dst (CountTrailingZerosL src)); 5750 effect(TEMP dst, KILL cr); 5751 5752 format %{ "BSF $dst, $src.lo\t# count trailing zeros (long)\n\t" 5753 "JNZ done\n\t" 5754 "BSF $dst, $src.hi\n\t" 5755 "JNZ msw_not_zero\n\t" 5756 "MOV $dst, 32\n" 5757 "msw_not_zero:\n\t" 5758 "ADD $dst, 32\n" 5759 "done:" %} 5760 ins_encode %{ 5761 Register Rdst = $dst$$Register; 5762 Register Rsrc = $src$$Register; 5763 Label msw_not_zero; 5764 Label done; 5765 __ bsfl(Rdst, Rsrc); 5766 __ jccb(Assembler::notZero, done); 5767 __ bsfl(Rdst, HIGH_FROM_LOW(Rsrc)); 5768 __ jccb(Assembler::notZero, msw_not_zero); 5769 __ movl(Rdst, BitsPerInt); 5770 __ bind(msw_not_zero); 5771 __ addl(Rdst, BitsPerInt); 5772 __ bind(done); 5773 %} 5774 ins_pipe(ialu_reg); 5775%} 5776 5777 5778//---------- Population Count Instructions ------------------------------------- 5779 5780instruct popCountI(rRegI dst, rRegI src, eFlagsReg cr) %{ 5781 predicate(UsePopCountInstruction); 5782 match(Set dst (PopCountI src)); 5783 effect(KILL cr); 5784 5785 format %{ "POPCNT $dst, $src" %} 5786 ins_encode %{ 5787 __ popcntl($dst$$Register, $src$$Register); 5788 %} 5789 ins_pipe(ialu_reg); 5790%} 5791 5792instruct popCountI_mem(rRegI dst, memory mem, eFlagsReg cr) %{ 5793 predicate(UsePopCountInstruction); 5794 match(Set dst (PopCountI (LoadI mem))); 5795 effect(KILL cr); 5796 5797 format %{ "POPCNT $dst, $mem" %} 5798 ins_encode %{ 5799 __ popcntl($dst$$Register, $mem$$Address); 5800 %} 5801 ins_pipe(ialu_reg); 5802%} 5803 5804// Note: Long.bitCount(long) returns an int. 5805instruct popCountL(rRegI dst, eRegL src, rRegI tmp, eFlagsReg cr) %{ 5806 predicate(UsePopCountInstruction); 5807 match(Set dst (PopCountL src)); 5808 effect(KILL cr, TEMP tmp, TEMP dst); 5809 5810 format %{ "POPCNT $dst, $src.lo\n\t" 5811 "POPCNT $tmp, $src.hi\n\t" 5812 "ADD $dst, $tmp" %} 5813 ins_encode %{ 5814 __ popcntl($dst$$Register, $src$$Register); 5815 __ popcntl($tmp$$Register, HIGH_FROM_LOW($src$$Register)); 5816 __ addl($dst$$Register, $tmp$$Register); 5817 %} 5818 ins_pipe(ialu_reg); 5819%} 5820 5821// Note: Long.bitCount(long) returns an int. 5822instruct popCountL_mem(rRegI dst, memory mem, rRegI tmp, eFlagsReg cr) %{ 5823 predicate(UsePopCountInstruction); 5824 match(Set dst (PopCountL (LoadL mem))); 5825 effect(KILL cr, TEMP tmp, TEMP dst); 5826 5827 format %{ "POPCNT $dst, $mem\n\t" 5828 "POPCNT $tmp, $mem+4\n\t" 5829 "ADD $dst, $tmp" %} 5830 ins_encode %{ 5831 //__ popcntl($dst$$Register, $mem$$Address$$first); 5832 //__ popcntl($tmp$$Register, $mem$$Address$$second); 5833 __ popcntl($dst$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none)); 5834 __ popcntl($tmp$$Register, Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none)); 5835 __ addl($dst$$Register, $tmp$$Register); 5836 %} 5837 ins_pipe(ialu_reg); 5838%} 5839 5840 5841//----------Load/Store/Move Instructions--------------------------------------- 5842//----------Load Instructions-------------------------------------------------- 5843// Load Byte (8bit signed) 5844instruct loadB(xRegI dst, memory mem) %{ 5845 match(Set dst (LoadB mem)); 5846 5847 ins_cost(125); 5848 format %{ "MOVSX8 $dst,$mem\t# byte" %} 5849 5850 ins_encode %{ 5851 __ movsbl($dst$$Register, $mem$$Address); 5852 %} 5853 5854 ins_pipe(ialu_reg_mem); 5855%} 5856 5857// Load Byte (8bit signed) into Long Register 5858instruct loadB2L(eRegL dst, memory mem, eFlagsReg cr) %{ 5859 match(Set dst (ConvI2L (LoadB mem))); 5860 effect(KILL cr); 5861 5862 ins_cost(375); 5863 format %{ "MOVSX8 $dst.lo,$mem\t# byte -> long\n\t" 5864 "MOV $dst.hi,$dst.lo\n\t" 5865 "SAR $dst.hi,7" %} 5866 5867 ins_encode %{ 5868 __ movsbl($dst$$Register, $mem$$Address); 5869 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register. 5870 __ sarl(HIGH_FROM_LOW($dst$$Register), 7); // 24+1 MSB are already signed extended. 5871 %} 5872 5873 ins_pipe(ialu_reg_mem); 5874%} 5875 5876// Load Unsigned Byte (8bit UNsigned) 5877instruct loadUB(xRegI dst, memory mem) %{ 5878 match(Set dst (LoadUB mem)); 5879 5880 ins_cost(125); 5881 format %{ "MOVZX8 $dst,$mem\t# ubyte -> int" %} 5882 5883 ins_encode %{ 5884 __ movzbl($dst$$Register, $mem$$Address); 5885 %} 5886 5887 ins_pipe(ialu_reg_mem); 5888%} 5889 5890// Load Unsigned Byte (8 bit UNsigned) into Long Register 5891instruct loadUB2L(eRegL dst, memory mem, eFlagsReg cr) %{ 5892 match(Set dst (ConvI2L (LoadUB mem))); 5893 effect(KILL cr); 5894 5895 ins_cost(250); 5896 format %{ "MOVZX8 $dst.lo,$mem\t# ubyte -> long\n\t" 5897 "XOR $dst.hi,$dst.hi" %} 5898 5899 ins_encode %{ 5900 Register Rdst = $dst$$Register; 5901 __ movzbl(Rdst, $mem$$Address); 5902 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 5903 %} 5904 5905 ins_pipe(ialu_reg_mem); 5906%} 5907 5908// Load Unsigned Byte (8 bit UNsigned) with mask into Long Register 5909instruct loadUB2L_immI8(eRegL dst, memory mem, immI8 mask, eFlagsReg cr) %{ 5910 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 5911 effect(KILL cr); 5912 5913 format %{ "MOVZX8 $dst.lo,$mem\t# ubyte & 8-bit mask -> long\n\t" 5914 "XOR $dst.hi,$dst.hi\n\t" 5915 "AND $dst.lo,$mask" %} 5916 ins_encode %{ 5917 Register Rdst = $dst$$Register; 5918 __ movzbl(Rdst, $mem$$Address); 5919 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 5920 __ andl(Rdst, $mask$$constant); 5921 %} 5922 ins_pipe(ialu_reg_mem); 5923%} 5924 5925// Load Short (16bit signed) 5926instruct loadS(rRegI dst, memory mem) %{ 5927 match(Set dst (LoadS mem)); 5928 5929 ins_cost(125); 5930 format %{ "MOVSX $dst,$mem\t# short" %} 5931 5932 ins_encode %{ 5933 __ movswl($dst$$Register, $mem$$Address); 5934 %} 5935 5936 ins_pipe(ialu_reg_mem); 5937%} 5938 5939// Load Short (16 bit signed) to Byte (8 bit signed) 5940instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5941 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 5942 5943 ins_cost(125); 5944 format %{ "MOVSX $dst, $mem\t# short -> byte" %} 5945 ins_encode %{ 5946 __ movsbl($dst$$Register, $mem$$Address); 5947 %} 5948 ins_pipe(ialu_reg_mem); 5949%} 5950 5951// Load Short (16bit signed) into Long Register 5952instruct loadS2L(eRegL dst, memory mem, eFlagsReg cr) %{ 5953 match(Set dst (ConvI2L (LoadS mem))); 5954 effect(KILL cr); 5955 5956 ins_cost(375); 5957 format %{ "MOVSX $dst.lo,$mem\t# short -> long\n\t" 5958 "MOV $dst.hi,$dst.lo\n\t" 5959 "SAR $dst.hi,15" %} 5960 5961 ins_encode %{ 5962 __ movswl($dst$$Register, $mem$$Address); 5963 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register. 5964 __ sarl(HIGH_FROM_LOW($dst$$Register), 15); // 16+1 MSB are already signed extended. 5965 %} 5966 5967 ins_pipe(ialu_reg_mem); 5968%} 5969 5970// Load Unsigned Short/Char (16bit unsigned) 5971instruct loadUS(rRegI dst, memory mem) %{ 5972 match(Set dst (LoadUS mem)); 5973 5974 ins_cost(125); 5975 format %{ "MOVZX $dst,$mem\t# ushort/char -> int" %} 5976 5977 ins_encode %{ 5978 __ movzwl($dst$$Register, $mem$$Address); 5979 %} 5980 5981 ins_pipe(ialu_reg_mem); 5982%} 5983 5984// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 5985instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 5986 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 5987 5988 ins_cost(125); 5989 format %{ "MOVSX $dst, $mem\t# ushort -> byte" %} 5990 ins_encode %{ 5991 __ movsbl($dst$$Register, $mem$$Address); 5992 %} 5993 ins_pipe(ialu_reg_mem); 5994%} 5995 5996// Load Unsigned Short/Char (16 bit UNsigned) into Long Register 5997instruct loadUS2L(eRegL dst, memory mem, eFlagsReg cr) %{ 5998 match(Set dst (ConvI2L (LoadUS mem))); 5999 effect(KILL cr); 6000 6001 ins_cost(250); 6002 format %{ "MOVZX $dst.lo,$mem\t# ushort/char -> long\n\t" 6003 "XOR $dst.hi,$dst.hi" %} 6004 6005 ins_encode %{ 6006 __ movzwl($dst$$Register, $mem$$Address); 6007 __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register)); 6008 %} 6009 6010 ins_pipe(ialu_reg_mem); 6011%} 6012 6013// Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 6014instruct loadUS2L_immI_255(eRegL dst, memory mem, immI_255 mask, eFlagsReg cr) %{ 6015 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 6016 effect(KILL cr); 6017 6018 format %{ "MOVZX8 $dst.lo,$mem\t# ushort/char & 0xFF -> long\n\t" 6019 "XOR $dst.hi,$dst.hi" %} 6020 ins_encode %{ 6021 Register Rdst = $dst$$Register; 6022 __ movzbl(Rdst, $mem$$Address); 6023 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6024 %} 6025 ins_pipe(ialu_reg_mem); 6026%} 6027 6028// Load Unsigned Short/Char (16 bit UNsigned) with a 16-bit mask into Long Register 6029instruct loadUS2L_immI16(eRegL dst, memory mem, immI16 mask, eFlagsReg cr) %{ 6030 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 6031 effect(KILL cr); 6032 6033 format %{ "MOVZX $dst.lo, $mem\t# ushort/char & 16-bit mask -> long\n\t" 6034 "XOR $dst.hi,$dst.hi\n\t" 6035 "AND $dst.lo,$mask" %} 6036 ins_encode %{ 6037 Register Rdst = $dst$$Register; 6038 __ movzwl(Rdst, $mem$$Address); 6039 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6040 __ andl(Rdst, $mask$$constant); 6041 %} 6042 ins_pipe(ialu_reg_mem); 6043%} 6044 6045// Load Integer 6046instruct loadI(rRegI dst, memory mem) %{ 6047 match(Set dst (LoadI mem)); 6048 6049 ins_cost(125); 6050 format %{ "MOV $dst,$mem\t# int" %} 6051 6052 ins_encode %{ 6053 __ movl($dst$$Register, $mem$$Address); 6054 %} 6055 6056 ins_pipe(ialu_reg_mem); 6057%} 6058 6059// Load Integer (32 bit signed) to Byte (8 bit signed) 6060instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 6061 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 6062 6063 ins_cost(125); 6064 format %{ "MOVSX $dst, $mem\t# int -> byte" %} 6065 ins_encode %{ 6066 __ movsbl($dst$$Register, $mem$$Address); 6067 %} 6068 ins_pipe(ialu_reg_mem); 6069%} 6070 6071// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 6072instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 6073 match(Set dst (AndI (LoadI mem) mask)); 6074 6075 ins_cost(125); 6076 format %{ "MOVZX $dst, $mem\t# int -> ubyte" %} 6077 ins_encode %{ 6078 __ movzbl($dst$$Register, $mem$$Address); 6079 %} 6080 ins_pipe(ialu_reg_mem); 6081%} 6082 6083// Load Integer (32 bit signed) to Short (16 bit signed) 6084instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 6085 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 6086 6087 ins_cost(125); 6088 format %{ "MOVSX $dst, $mem\t# int -> short" %} 6089 ins_encode %{ 6090 __ movswl($dst$$Register, $mem$$Address); 6091 %} 6092 ins_pipe(ialu_reg_mem); 6093%} 6094 6095// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 6096instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 6097 match(Set dst (AndI (LoadI mem) mask)); 6098 6099 ins_cost(125); 6100 format %{ "MOVZX $dst, $mem\t# int -> ushort/char" %} 6101 ins_encode %{ 6102 __ movzwl($dst$$Register, $mem$$Address); 6103 %} 6104 ins_pipe(ialu_reg_mem); 6105%} 6106 6107// Load Integer into Long Register 6108instruct loadI2L(eRegL dst, memory mem, eFlagsReg cr) %{ 6109 match(Set dst (ConvI2L (LoadI mem))); 6110 effect(KILL cr); 6111 6112 ins_cost(375); 6113 format %{ "MOV $dst.lo,$mem\t# int -> long\n\t" 6114 "MOV $dst.hi,$dst.lo\n\t" 6115 "SAR $dst.hi,31" %} 6116 6117 ins_encode %{ 6118 __ movl($dst$$Register, $mem$$Address); 6119 __ movl(HIGH_FROM_LOW($dst$$Register), $dst$$Register); // This is always a different register. 6120 __ sarl(HIGH_FROM_LOW($dst$$Register), 31); 6121 %} 6122 6123 ins_pipe(ialu_reg_mem); 6124%} 6125 6126// Load Integer with mask 0xFF into Long Register 6127instruct loadI2L_immI_255(eRegL dst, memory mem, immI_255 mask, eFlagsReg cr) %{ 6128 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6129 effect(KILL cr); 6130 6131 format %{ "MOVZX8 $dst.lo,$mem\t# int & 0xFF -> long\n\t" 6132 "XOR $dst.hi,$dst.hi" %} 6133 ins_encode %{ 6134 Register Rdst = $dst$$Register; 6135 __ movzbl(Rdst, $mem$$Address); 6136 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6137 %} 6138 ins_pipe(ialu_reg_mem); 6139%} 6140 6141// Load Integer with mask 0xFFFF into Long Register 6142instruct loadI2L_immI_65535(eRegL dst, memory mem, immI_65535 mask, eFlagsReg cr) %{ 6143 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6144 effect(KILL cr); 6145 6146 format %{ "MOVZX $dst.lo,$mem\t# int & 0xFFFF -> long\n\t" 6147 "XOR $dst.hi,$dst.hi" %} 6148 ins_encode %{ 6149 Register Rdst = $dst$$Register; 6150 __ movzwl(Rdst, $mem$$Address); 6151 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6152 %} 6153 ins_pipe(ialu_reg_mem); 6154%} 6155 6156// Load Integer with 32-bit mask into Long Register 6157instruct loadI2L_immI(eRegL dst, memory mem, immI mask, eFlagsReg cr) %{ 6158 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 6159 effect(KILL cr); 6160 6161 format %{ "MOV $dst.lo,$mem\t# int & 32-bit mask -> long\n\t" 6162 "XOR $dst.hi,$dst.hi\n\t" 6163 "AND $dst.lo,$mask" %} 6164 ins_encode %{ 6165 Register Rdst = $dst$$Register; 6166 __ movl(Rdst, $mem$$Address); 6167 __ xorl(HIGH_FROM_LOW(Rdst), HIGH_FROM_LOW(Rdst)); 6168 __ andl(Rdst, $mask$$constant); 6169 %} 6170 ins_pipe(ialu_reg_mem); 6171%} 6172 6173// Load Unsigned Integer into Long Register 6174instruct loadUI2L(eRegL dst, memory mem, immL_32bits mask, eFlagsReg cr) %{ 6175 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 6176 effect(KILL cr); 6177 6178 ins_cost(250); 6179 format %{ "MOV $dst.lo,$mem\t# uint -> long\n\t" 6180 "XOR $dst.hi,$dst.hi" %} 6181 6182 ins_encode %{ 6183 __ movl($dst$$Register, $mem$$Address); 6184 __ xorl(HIGH_FROM_LOW($dst$$Register), HIGH_FROM_LOW($dst$$Register)); 6185 %} 6186 6187 ins_pipe(ialu_reg_mem); 6188%} 6189 6190// Load Long. Cannot clobber address while loading, so restrict address 6191// register to ESI 6192instruct loadL(eRegL dst, load_long_memory mem) %{ 6193 predicate(!((LoadLNode*)n)->require_atomic_access()); 6194 match(Set dst (LoadL mem)); 6195 6196 ins_cost(250); 6197 format %{ "MOV $dst.lo,$mem\t# long\n\t" 6198 "MOV $dst.hi,$mem+4" %} 6199 6200 ins_encode %{ 6201 Address Amemlo = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp, relocInfo::none); 6202 Address Amemhi = Address::make_raw($mem$$base, $mem$$index, $mem$$scale, $mem$$disp + 4, relocInfo::none); 6203 __ movl($dst$$Register, Amemlo); 6204 __ movl(HIGH_FROM_LOW($dst$$Register), Amemhi); 6205 %} 6206 6207 ins_pipe(ialu_reg_long_mem); 6208%} 6209 6210// Volatile Load Long. Must be atomic, so do 64-bit FILD 6211// then store it down to the stack and reload on the int 6212// side. 6213instruct loadL_volatile(stackSlotL dst, memory mem) %{ 6214 predicate(UseSSE<=1 && ((LoadLNode*)n)->require_atomic_access()); 6215 match(Set dst (LoadL mem)); 6216 6217 ins_cost(200); 6218 format %{ "FILD $mem\t# Atomic volatile long load\n\t" 6219 "FISTp $dst" %} 6220 ins_encode(enc_loadL_volatile(mem,dst)); 6221 ins_pipe( fpu_reg_mem ); 6222%} 6223 6224instruct loadLX_volatile(stackSlotL dst, memory mem, regD tmp) %{ 6225 predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access()); 6226 match(Set dst (LoadL mem)); 6227 effect(TEMP tmp); 6228 ins_cost(180); 6229 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t" 6230 "MOVSD $dst,$tmp" %} 6231 ins_encode %{ 6232 __ movdbl($tmp$$XMMRegister, $mem$$Address); 6233 __ movdbl(Address(rsp, $dst$$disp), $tmp$$XMMRegister); 6234 %} 6235 ins_pipe( pipe_slow ); 6236%} 6237 6238instruct loadLX_reg_volatile(eRegL dst, memory mem, regD tmp) %{ 6239 predicate(UseSSE>=2 && ((LoadLNode*)n)->require_atomic_access()); 6240 match(Set dst (LoadL mem)); 6241 effect(TEMP tmp); 6242 ins_cost(160); 6243 format %{ "MOVSD $tmp,$mem\t# Atomic volatile long load\n\t" 6244 "MOVD $dst.lo,$tmp\n\t" 6245 "PSRLQ $tmp,32\n\t" 6246 "MOVD $dst.hi,$tmp" %} 6247 ins_encode %{ 6248 __ movdbl($tmp$$XMMRegister, $mem$$Address); 6249 __ movdl($dst$$Register, $tmp$$XMMRegister); 6250 __ psrlq($tmp$$XMMRegister, 32); 6251 __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister); 6252 %} 6253 ins_pipe( pipe_slow ); 6254%} 6255 6256// Load Range 6257instruct loadRange(rRegI dst, memory mem) %{ 6258 match(Set dst (LoadRange mem)); 6259 6260 ins_cost(125); 6261 format %{ "MOV $dst,$mem" %} 6262 opcode(0x8B); 6263 ins_encode( OpcP, RegMem(dst,mem)); 6264 ins_pipe( ialu_reg_mem ); 6265%} 6266 6267 6268// Load Pointer 6269instruct loadP(eRegP dst, memory mem) %{ 6270 match(Set dst (LoadP mem)); 6271 6272 ins_cost(125); 6273 format %{ "MOV $dst,$mem" %} 6274 opcode(0x8B); 6275 ins_encode( OpcP, RegMem(dst,mem)); 6276 ins_pipe( ialu_reg_mem ); 6277%} 6278 6279// Load Klass Pointer 6280instruct loadKlass(eRegP dst, memory mem) %{ 6281 match(Set dst (LoadKlass mem)); 6282 6283 ins_cost(125); 6284 format %{ "MOV $dst,$mem" %} 6285 opcode(0x8B); 6286 ins_encode( OpcP, RegMem(dst,mem)); 6287 ins_pipe( ialu_reg_mem ); 6288%} 6289 6290// Load Double 6291instruct loadDPR(regDPR dst, memory mem) %{ 6292 predicate(UseSSE<=1); 6293 match(Set dst (LoadD mem)); 6294 6295 ins_cost(150); 6296 format %{ "FLD_D ST,$mem\n\t" 6297 "FSTP $dst" %} 6298 opcode(0xDD); /* DD /0 */ 6299 ins_encode( OpcP, RMopc_Mem(0x00,mem), 6300 Pop_Reg_DPR(dst) ); 6301 ins_pipe( fpu_reg_mem ); 6302%} 6303 6304// Load Double to XMM 6305instruct loadD(regD dst, memory mem) %{ 6306 predicate(UseSSE>=2 && UseXmmLoadAndClearUpper); 6307 match(Set dst (LoadD mem)); 6308 ins_cost(145); 6309 format %{ "MOVSD $dst,$mem" %} 6310 ins_encode %{ 6311 __ movdbl ($dst$$XMMRegister, $mem$$Address); 6312 %} 6313 ins_pipe( pipe_slow ); 6314%} 6315 6316instruct loadD_partial(regD dst, memory mem) %{ 6317 predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper); 6318 match(Set dst (LoadD mem)); 6319 ins_cost(145); 6320 format %{ "MOVLPD $dst,$mem" %} 6321 ins_encode %{ 6322 __ movdbl ($dst$$XMMRegister, $mem$$Address); 6323 %} 6324 ins_pipe( pipe_slow ); 6325%} 6326 6327// Load to XMM register (single-precision floating point) 6328// MOVSS instruction 6329instruct loadF(regF dst, memory mem) %{ 6330 predicate(UseSSE>=1); 6331 match(Set dst (LoadF mem)); 6332 ins_cost(145); 6333 format %{ "MOVSS $dst,$mem" %} 6334 ins_encode %{ 6335 __ movflt ($dst$$XMMRegister, $mem$$Address); 6336 %} 6337 ins_pipe( pipe_slow ); 6338%} 6339 6340// Load Float 6341instruct loadFPR(regFPR dst, memory mem) %{ 6342 predicate(UseSSE==0); 6343 match(Set dst (LoadF mem)); 6344 6345 ins_cost(150); 6346 format %{ "FLD_S ST,$mem\n\t" 6347 "FSTP $dst" %} 6348 opcode(0xD9); /* D9 /0 */ 6349 ins_encode( OpcP, RMopc_Mem(0x00,mem), 6350 Pop_Reg_FPR(dst) ); 6351 ins_pipe( fpu_reg_mem ); 6352%} 6353 6354// Load Effective Address 6355instruct leaP8(eRegP dst, indOffset8 mem) %{ 6356 match(Set dst mem); 6357 6358 ins_cost(110); 6359 format %{ "LEA $dst,$mem" %} 6360 opcode(0x8D); 6361 ins_encode( OpcP, RegMem(dst,mem)); 6362 ins_pipe( ialu_reg_reg_fat ); 6363%} 6364 6365instruct leaP32(eRegP dst, indOffset32 mem) %{ 6366 match(Set dst mem); 6367 6368 ins_cost(110); 6369 format %{ "LEA $dst,$mem" %} 6370 opcode(0x8D); 6371 ins_encode( OpcP, RegMem(dst,mem)); 6372 ins_pipe( ialu_reg_reg_fat ); 6373%} 6374 6375instruct leaPIdxOff(eRegP dst, indIndexOffset mem) %{ 6376 match(Set dst mem); 6377 6378 ins_cost(110); 6379 format %{ "LEA $dst,$mem" %} 6380 opcode(0x8D); 6381 ins_encode( OpcP, RegMem(dst,mem)); 6382 ins_pipe( ialu_reg_reg_fat ); 6383%} 6384 6385instruct leaPIdxScale(eRegP dst, indIndexScale mem) %{ 6386 match(Set dst mem); 6387 6388 ins_cost(110); 6389 format %{ "LEA $dst,$mem" %} 6390 opcode(0x8D); 6391 ins_encode( OpcP, RegMem(dst,mem)); 6392 ins_pipe( ialu_reg_reg_fat ); 6393%} 6394 6395instruct leaPIdxScaleOff(eRegP dst, indIndexScaleOffset mem) %{ 6396 match(Set dst mem); 6397 6398 ins_cost(110); 6399 format %{ "LEA $dst,$mem" %} 6400 opcode(0x8D); 6401 ins_encode( OpcP, RegMem(dst,mem)); 6402 ins_pipe( ialu_reg_reg_fat ); 6403%} 6404 6405// Load Constant 6406instruct loadConI(rRegI dst, immI src) %{ 6407 match(Set dst src); 6408 6409 format %{ "MOV $dst,$src" %} 6410 ins_encode( LdImmI(dst, src) ); 6411 ins_pipe( ialu_reg_fat ); 6412%} 6413 6414// Load Constant zero 6415instruct loadConI0(rRegI dst, immI0 src, eFlagsReg cr) %{ 6416 match(Set dst src); 6417 effect(KILL cr); 6418 6419 ins_cost(50); 6420 format %{ "XOR $dst,$dst" %} 6421 opcode(0x33); /* + rd */ 6422 ins_encode( OpcP, RegReg( dst, dst ) ); 6423 ins_pipe( ialu_reg ); 6424%} 6425 6426instruct loadConP(eRegP dst, immP src) %{ 6427 match(Set dst src); 6428 6429 format %{ "MOV $dst,$src" %} 6430 opcode(0xB8); /* + rd */ 6431 ins_encode( LdImmP(dst, src) ); 6432 ins_pipe( ialu_reg_fat ); 6433%} 6434 6435instruct loadConL(eRegL dst, immL src, eFlagsReg cr) %{ 6436 match(Set dst src); 6437 effect(KILL cr); 6438 ins_cost(200); 6439 format %{ "MOV $dst.lo,$src.lo\n\t" 6440 "MOV $dst.hi,$src.hi" %} 6441 opcode(0xB8); 6442 ins_encode( LdImmL_Lo(dst, src), LdImmL_Hi(dst, src) ); 6443 ins_pipe( ialu_reg_long_fat ); 6444%} 6445 6446instruct loadConL0(eRegL dst, immL0 src, eFlagsReg cr) %{ 6447 match(Set dst src); 6448 effect(KILL cr); 6449 ins_cost(150); 6450 format %{ "XOR $dst.lo,$dst.lo\n\t" 6451 "XOR $dst.hi,$dst.hi" %} 6452 opcode(0x33,0x33); 6453 ins_encode( RegReg_Lo(dst,dst), RegReg_Hi(dst, dst) ); 6454 ins_pipe( ialu_reg_long ); 6455%} 6456 6457// The instruction usage is guarded by predicate in operand immFPR(). 6458instruct loadConFPR(regFPR dst, immFPR con) %{ 6459 match(Set dst con); 6460 ins_cost(125); 6461 format %{ "FLD_S ST,[$constantaddress]\t# load from constant table: float=$con\n\t" 6462 "FSTP $dst" %} 6463 ins_encode %{ 6464 __ fld_s($constantaddress($con)); 6465 __ fstp_d($dst$$reg); 6466 %} 6467 ins_pipe(fpu_reg_con); 6468%} 6469 6470// The instruction usage is guarded by predicate in operand immFPR0(). 6471instruct loadConFPR0(regFPR dst, immFPR0 con) %{ 6472 match(Set dst con); 6473 ins_cost(125); 6474 format %{ "FLDZ ST\n\t" 6475 "FSTP $dst" %} 6476 ins_encode %{ 6477 __ fldz(); 6478 __ fstp_d($dst$$reg); 6479 %} 6480 ins_pipe(fpu_reg_con); 6481%} 6482 6483// The instruction usage is guarded by predicate in operand immFPR1(). 6484instruct loadConFPR1(regFPR dst, immFPR1 con) %{ 6485 match(Set dst con); 6486 ins_cost(125); 6487 format %{ "FLD1 ST\n\t" 6488 "FSTP $dst" %} 6489 ins_encode %{ 6490 __ fld1(); 6491 __ fstp_d($dst$$reg); 6492 %} 6493 ins_pipe(fpu_reg_con); 6494%} 6495 6496// The instruction usage is guarded by predicate in operand immF(). 6497instruct loadConF(regF dst, immF con) %{ 6498 match(Set dst con); 6499 ins_cost(125); 6500 format %{ "MOVSS $dst,[$constantaddress]\t# load from constant table: float=$con" %} 6501 ins_encode %{ 6502 __ movflt($dst$$XMMRegister, $constantaddress($con)); 6503 %} 6504 ins_pipe(pipe_slow); 6505%} 6506 6507// The instruction usage is guarded by predicate in operand immF0(). 6508instruct loadConF0(regF dst, immF0 src) %{ 6509 match(Set dst src); 6510 ins_cost(100); 6511 format %{ "XORPS $dst,$dst\t# float 0.0" %} 6512 ins_encode %{ 6513 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 6514 %} 6515 ins_pipe(pipe_slow); 6516%} 6517 6518// The instruction usage is guarded by predicate in operand immDPR(). 6519instruct loadConDPR(regDPR dst, immDPR con) %{ 6520 match(Set dst con); 6521 ins_cost(125); 6522 6523 format %{ "FLD_D ST,[$constantaddress]\t# load from constant table: double=$con\n\t" 6524 "FSTP $dst" %} 6525 ins_encode %{ 6526 __ fld_d($constantaddress($con)); 6527 __ fstp_d($dst$$reg); 6528 %} 6529 ins_pipe(fpu_reg_con); 6530%} 6531 6532// The instruction usage is guarded by predicate in operand immDPR0(). 6533instruct loadConDPR0(regDPR dst, immDPR0 con) %{ 6534 match(Set dst con); 6535 ins_cost(125); 6536 6537 format %{ "FLDZ ST\n\t" 6538 "FSTP $dst" %} 6539 ins_encode %{ 6540 __ fldz(); 6541 __ fstp_d($dst$$reg); 6542 %} 6543 ins_pipe(fpu_reg_con); 6544%} 6545 6546// The instruction usage is guarded by predicate in operand immDPR1(). 6547instruct loadConDPR1(regDPR dst, immDPR1 con) %{ 6548 match(Set dst con); 6549 ins_cost(125); 6550 6551 format %{ "FLD1 ST\n\t" 6552 "FSTP $dst" %} 6553 ins_encode %{ 6554 __ fld1(); 6555 __ fstp_d($dst$$reg); 6556 %} 6557 ins_pipe(fpu_reg_con); 6558%} 6559 6560// The instruction usage is guarded by predicate in operand immD(). 6561instruct loadConD(regD dst, immD con) %{ 6562 match(Set dst con); 6563 ins_cost(125); 6564 format %{ "MOVSD $dst,[$constantaddress]\t# load from constant table: double=$con" %} 6565 ins_encode %{ 6566 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 6567 %} 6568 ins_pipe(pipe_slow); 6569%} 6570 6571// The instruction usage is guarded by predicate in operand immD0(). 6572instruct loadConD0(regD dst, immD0 src) %{ 6573 match(Set dst src); 6574 ins_cost(100); 6575 format %{ "XORPD $dst,$dst\t# double 0.0" %} 6576 ins_encode %{ 6577 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 6578 %} 6579 ins_pipe( pipe_slow ); 6580%} 6581 6582// Load Stack Slot 6583instruct loadSSI(rRegI dst, stackSlotI src) %{ 6584 match(Set dst src); 6585 ins_cost(125); 6586 6587 format %{ "MOV $dst,$src" %} 6588 opcode(0x8B); 6589 ins_encode( OpcP, RegMem(dst,src)); 6590 ins_pipe( ialu_reg_mem ); 6591%} 6592 6593instruct loadSSL(eRegL dst, stackSlotL src) %{ 6594 match(Set dst src); 6595 6596 ins_cost(200); 6597 format %{ "MOV $dst,$src.lo\n\t" 6598 "MOV $dst+4,$src.hi" %} 6599 opcode(0x8B, 0x8B); 6600 ins_encode( OpcP, RegMem( dst, src ), OpcS, RegMem_Hi( dst, src ) ); 6601 ins_pipe( ialu_mem_long_reg ); 6602%} 6603 6604// Load Stack Slot 6605instruct loadSSP(eRegP dst, stackSlotP src) %{ 6606 match(Set dst src); 6607 ins_cost(125); 6608 6609 format %{ "MOV $dst,$src" %} 6610 opcode(0x8B); 6611 ins_encode( OpcP, RegMem(dst,src)); 6612 ins_pipe( ialu_reg_mem ); 6613%} 6614 6615// Load Stack Slot 6616instruct loadSSF(regFPR dst, stackSlotF src) %{ 6617 match(Set dst src); 6618 ins_cost(125); 6619 6620 format %{ "FLD_S $src\n\t" 6621 "FSTP $dst" %} 6622 opcode(0xD9); /* D9 /0, FLD m32real */ 6623 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src), 6624 Pop_Reg_FPR(dst) ); 6625 ins_pipe( fpu_reg_mem ); 6626%} 6627 6628// Load Stack Slot 6629instruct loadSSD(regDPR dst, stackSlotD src) %{ 6630 match(Set dst src); 6631 ins_cost(125); 6632 6633 format %{ "FLD_D $src\n\t" 6634 "FSTP $dst" %} 6635 opcode(0xDD); /* DD /0, FLD m64real */ 6636 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src), 6637 Pop_Reg_DPR(dst) ); 6638 ins_pipe( fpu_reg_mem ); 6639%} 6640 6641// Prefetch instructions. 6642// Must be safe to execute with invalid address (cannot fault). 6643 6644instruct prefetchr0( memory mem ) %{ 6645 predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch()); 6646 match(PrefetchRead mem); 6647 ins_cost(0); 6648 size(0); 6649 format %{ "PREFETCHR (non-SSE is empty encoding)" %} 6650 ins_encode(); 6651 ins_pipe(empty); 6652%} 6653 6654instruct prefetchr( memory mem ) %{ 6655 predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch() || ReadPrefetchInstr==3); 6656 match(PrefetchRead mem); 6657 ins_cost(100); 6658 6659 format %{ "PREFETCHR $mem\t! Prefetch into level 1 cache for read" %} 6660 ins_encode %{ 6661 __ prefetchr($mem$$Address); 6662 %} 6663 ins_pipe(ialu_mem); 6664%} 6665 6666instruct prefetchrNTA( memory mem ) %{ 6667 predicate(UseSSE>=1 && ReadPrefetchInstr==0); 6668 match(PrefetchRead mem); 6669 ins_cost(100); 6670 6671 format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for read" %} 6672 ins_encode %{ 6673 __ prefetchnta($mem$$Address); 6674 %} 6675 ins_pipe(ialu_mem); 6676%} 6677 6678instruct prefetchrT0( memory mem ) %{ 6679 predicate(UseSSE>=1 && ReadPrefetchInstr==1); 6680 match(PrefetchRead mem); 6681 ins_cost(100); 6682 6683 format %{ "PREFETCHT0 $mem\t! Prefetch into L1 and L2 caches for read" %} 6684 ins_encode %{ 6685 __ prefetcht0($mem$$Address); 6686 %} 6687 ins_pipe(ialu_mem); 6688%} 6689 6690instruct prefetchrT2( memory mem ) %{ 6691 predicate(UseSSE>=1 && ReadPrefetchInstr==2); 6692 match(PrefetchRead mem); 6693 ins_cost(100); 6694 6695 format %{ "PREFETCHT2 $mem\t! Prefetch into L2 cache for read" %} 6696 ins_encode %{ 6697 __ prefetcht2($mem$$Address); 6698 %} 6699 ins_pipe(ialu_mem); 6700%} 6701 6702instruct prefetchw0( memory mem ) %{ 6703 predicate(UseSSE==0 && !VM_Version::supports_3dnow_prefetch()); 6704 match(PrefetchWrite mem); 6705 ins_cost(0); 6706 size(0); 6707 format %{ "Prefetch (non-SSE is empty encoding)" %} 6708 ins_encode(); 6709 ins_pipe(empty); 6710%} 6711 6712instruct prefetchw( memory mem ) %{ 6713 predicate(UseSSE==0 && VM_Version::supports_3dnow_prefetch()); 6714 match( PrefetchWrite mem ); 6715 ins_cost(100); 6716 6717 format %{ "PREFETCHW $mem\t! Prefetch into L1 cache and mark modified" %} 6718 ins_encode %{ 6719 __ prefetchw($mem$$Address); 6720 %} 6721 ins_pipe(ialu_mem); 6722%} 6723 6724instruct prefetchwNTA( memory mem ) %{ 6725 predicate(UseSSE>=1); 6726 match(PrefetchWrite mem); 6727 ins_cost(100); 6728 6729 format %{ "PREFETCHNTA $mem\t! Prefetch into non-temporal cache for write" %} 6730 ins_encode %{ 6731 __ prefetchnta($mem$$Address); 6732 %} 6733 ins_pipe(ialu_mem); 6734%} 6735 6736// Prefetch instructions for allocation. 6737 6738instruct prefetchAlloc0( memory mem ) %{ 6739 predicate(UseSSE==0 && AllocatePrefetchInstr!=3); 6740 match(PrefetchAllocation mem); 6741 ins_cost(0); 6742 size(0); 6743 format %{ "Prefetch allocation (non-SSE is empty encoding)" %} 6744 ins_encode(); 6745 ins_pipe(empty); 6746%} 6747 6748instruct prefetchAlloc( memory mem ) %{ 6749 predicate(AllocatePrefetchInstr==3); 6750 match( PrefetchAllocation mem ); 6751 ins_cost(100); 6752 6753 format %{ "PREFETCHW $mem\t! Prefetch allocation into L1 cache and mark modified" %} 6754 ins_encode %{ 6755 __ prefetchw($mem$$Address); 6756 %} 6757 ins_pipe(ialu_mem); 6758%} 6759 6760instruct prefetchAllocNTA( memory mem ) %{ 6761 predicate(UseSSE>=1 && AllocatePrefetchInstr==0); 6762 match(PrefetchAllocation mem); 6763 ins_cost(100); 6764 6765 format %{ "PREFETCHNTA $mem\t! Prefetch allocation into non-temporal cache for write" %} 6766 ins_encode %{ 6767 __ prefetchnta($mem$$Address); 6768 %} 6769 ins_pipe(ialu_mem); 6770%} 6771 6772instruct prefetchAllocT0( memory mem ) %{ 6773 predicate(UseSSE>=1 && AllocatePrefetchInstr==1); 6774 match(PrefetchAllocation mem); 6775 ins_cost(100); 6776 6777 format %{ "PREFETCHT0 $mem\t! Prefetch allocation into L1 and L2 caches for write" %} 6778 ins_encode %{ 6779 __ prefetcht0($mem$$Address); 6780 %} 6781 ins_pipe(ialu_mem); 6782%} 6783 6784instruct prefetchAllocT2( memory mem ) %{ 6785 predicate(UseSSE>=1 && AllocatePrefetchInstr==2); 6786 match(PrefetchAllocation mem); 6787 ins_cost(100); 6788 6789 format %{ "PREFETCHT2 $mem\t! Prefetch allocation into L2 cache for write" %} 6790 ins_encode %{ 6791 __ prefetcht2($mem$$Address); 6792 %} 6793 ins_pipe(ialu_mem); 6794%} 6795 6796//----------Store Instructions------------------------------------------------- 6797 6798// Store Byte 6799instruct storeB(memory mem, xRegI src) %{ 6800 match(Set mem (StoreB mem src)); 6801 6802 ins_cost(125); 6803 format %{ "MOV8 $mem,$src" %} 6804 opcode(0x88); 6805 ins_encode( OpcP, RegMem( src, mem ) ); 6806 ins_pipe( ialu_mem_reg ); 6807%} 6808 6809// Store Char/Short 6810instruct storeC(memory mem, rRegI src) %{ 6811 match(Set mem (StoreC mem src)); 6812 6813 ins_cost(125); 6814 format %{ "MOV16 $mem,$src" %} 6815 opcode(0x89, 0x66); 6816 ins_encode( OpcS, OpcP, RegMem( src, mem ) ); 6817 ins_pipe( ialu_mem_reg ); 6818%} 6819 6820// Store Integer 6821instruct storeI(memory mem, rRegI src) %{ 6822 match(Set mem (StoreI mem src)); 6823 6824 ins_cost(125); 6825 format %{ "MOV $mem,$src" %} 6826 opcode(0x89); 6827 ins_encode( OpcP, RegMem( src, mem ) ); 6828 ins_pipe( ialu_mem_reg ); 6829%} 6830 6831// Store Long 6832instruct storeL(long_memory mem, eRegL src) %{ 6833 predicate(!((StoreLNode*)n)->require_atomic_access()); 6834 match(Set mem (StoreL mem src)); 6835 6836 ins_cost(200); 6837 format %{ "MOV $mem,$src.lo\n\t" 6838 "MOV $mem+4,$src.hi" %} 6839 opcode(0x89, 0x89); 6840 ins_encode( OpcP, RegMem( src, mem ), OpcS, RegMem_Hi( src, mem ) ); 6841 ins_pipe( ialu_mem_long_reg ); 6842%} 6843 6844// Store Long to Integer 6845instruct storeL2I(memory mem, eRegL src) %{ 6846 match(Set mem (StoreI mem (ConvL2I src))); 6847 6848 format %{ "MOV $mem,$src.lo\t# long -> int" %} 6849 ins_encode %{ 6850 __ movl($mem$$Address, $src$$Register); 6851 %} 6852 ins_pipe(ialu_mem_reg); 6853%} 6854 6855// Volatile Store Long. Must be atomic, so move it into 6856// the FP TOS and then do a 64-bit FIST. Has to probe the 6857// target address before the store (for null-ptr checks) 6858// so the memory operand is used twice in the encoding. 6859instruct storeL_volatile(memory mem, stackSlotL src, eFlagsReg cr ) %{ 6860 predicate(UseSSE<=1 && ((StoreLNode*)n)->require_atomic_access()); 6861 match(Set mem (StoreL mem src)); 6862 effect( KILL cr ); 6863 ins_cost(400); 6864 format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t" 6865 "FILD $src\n\t" 6866 "FISTp $mem\t # 64-bit atomic volatile long store" %} 6867 opcode(0x3B); 6868 ins_encode( OpcP, RegMem( EAX, mem ), enc_storeL_volatile(mem,src)); 6869 ins_pipe( fpu_reg_mem ); 6870%} 6871 6872instruct storeLX_volatile(memory mem, stackSlotL src, regD tmp, eFlagsReg cr) %{ 6873 predicate(UseSSE>=2 && ((StoreLNode*)n)->require_atomic_access()); 6874 match(Set mem (StoreL mem src)); 6875 effect( TEMP tmp, KILL cr ); 6876 ins_cost(380); 6877 format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t" 6878 "MOVSD $tmp,$src\n\t" 6879 "MOVSD $mem,$tmp\t # 64-bit atomic volatile long store" %} 6880 ins_encode %{ 6881 __ cmpl(rax, $mem$$Address); 6882 __ movdbl($tmp$$XMMRegister, Address(rsp, $src$$disp)); 6883 __ movdbl($mem$$Address, $tmp$$XMMRegister); 6884 %} 6885 ins_pipe( pipe_slow ); 6886%} 6887 6888instruct storeLX_reg_volatile(memory mem, eRegL src, regD tmp2, regD tmp, eFlagsReg cr) %{ 6889 predicate(UseSSE>=2 && ((StoreLNode*)n)->require_atomic_access()); 6890 match(Set mem (StoreL mem src)); 6891 effect( TEMP tmp2 , TEMP tmp, KILL cr ); 6892 ins_cost(360); 6893 format %{ "CMP $mem,EAX\t# Probe address for implicit null check\n\t" 6894 "MOVD $tmp,$src.lo\n\t" 6895 "MOVD $tmp2,$src.hi\n\t" 6896 "PUNPCKLDQ $tmp,$tmp2\n\t" 6897 "MOVSD $mem,$tmp\t # 64-bit atomic volatile long store" %} 6898 ins_encode %{ 6899 __ cmpl(rax, $mem$$Address); 6900 __ movdl($tmp$$XMMRegister, $src$$Register); 6901 __ movdl($tmp2$$XMMRegister, HIGH_FROM_LOW($src$$Register)); 6902 __ punpckldq($tmp$$XMMRegister, $tmp2$$XMMRegister); 6903 __ movdbl($mem$$Address, $tmp$$XMMRegister); 6904 %} 6905 ins_pipe( pipe_slow ); 6906%} 6907 6908// Store Pointer; for storing unknown oops and raw pointers 6909instruct storeP(memory mem, anyRegP src) %{ 6910 match(Set mem (StoreP mem src)); 6911 6912 ins_cost(125); 6913 format %{ "MOV $mem,$src" %} 6914 opcode(0x89); 6915 ins_encode( OpcP, RegMem( src, mem ) ); 6916 ins_pipe( ialu_mem_reg ); 6917%} 6918 6919// Store Integer Immediate 6920instruct storeImmI(memory mem, immI src) %{ 6921 match(Set mem (StoreI mem src)); 6922 6923 ins_cost(150); 6924 format %{ "MOV $mem,$src" %} 6925 opcode(0xC7); /* C7 /0 */ 6926 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32( src )); 6927 ins_pipe( ialu_mem_imm ); 6928%} 6929 6930// Store Short/Char Immediate 6931instruct storeImmI16(memory mem, immI16 src) %{ 6932 predicate(UseStoreImmI16); 6933 match(Set mem (StoreC mem src)); 6934 6935 ins_cost(150); 6936 format %{ "MOV16 $mem,$src" %} 6937 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 6938 ins_encode( SizePrefix, OpcP, RMopc_Mem(0x00,mem), Con16( src )); 6939 ins_pipe( ialu_mem_imm ); 6940%} 6941 6942// Store Pointer Immediate; null pointers or constant oops that do not 6943// need card-mark barriers. 6944instruct storeImmP(memory mem, immP src) %{ 6945 match(Set mem (StoreP mem src)); 6946 6947 ins_cost(150); 6948 format %{ "MOV $mem,$src" %} 6949 opcode(0xC7); /* C7 /0 */ 6950 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32( src )); 6951 ins_pipe( ialu_mem_imm ); 6952%} 6953 6954// Store Byte Immediate 6955instruct storeImmB(memory mem, immI8 src) %{ 6956 match(Set mem (StoreB mem src)); 6957 6958 ins_cost(150); 6959 format %{ "MOV8 $mem,$src" %} 6960 opcode(0xC6); /* C6 /0 */ 6961 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src )); 6962 ins_pipe( ialu_mem_imm ); 6963%} 6964 6965// Store CMS card-mark Immediate 6966instruct storeImmCM(memory mem, immI8 src) %{ 6967 match(Set mem (StoreCM mem src)); 6968 6969 ins_cost(150); 6970 format %{ "MOV8 $mem,$src\t! CMS card-mark imm0" %} 6971 opcode(0xC6); /* C6 /0 */ 6972 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con8or32( src )); 6973 ins_pipe( ialu_mem_imm ); 6974%} 6975 6976// Store Double 6977instruct storeDPR( memory mem, regDPR1 src) %{ 6978 predicate(UseSSE<=1); 6979 match(Set mem (StoreD mem src)); 6980 6981 ins_cost(100); 6982 format %{ "FST_D $mem,$src" %} 6983 opcode(0xDD); /* DD /2 */ 6984 ins_encode( enc_FPR_store(mem,src) ); 6985 ins_pipe( fpu_mem_reg ); 6986%} 6987 6988// Store double does rounding on x86 6989instruct storeDPR_rounded( memory mem, regDPR1 src) %{ 6990 predicate(UseSSE<=1); 6991 match(Set mem (StoreD mem (RoundDouble src))); 6992 6993 ins_cost(100); 6994 format %{ "FST_D $mem,$src\t# round" %} 6995 opcode(0xDD); /* DD /2 */ 6996 ins_encode( enc_FPR_store(mem,src) ); 6997 ins_pipe( fpu_mem_reg ); 6998%} 6999 7000// Store XMM register to memory (double-precision floating points) 7001// MOVSD instruction 7002instruct storeD(memory mem, regD src) %{ 7003 predicate(UseSSE>=2); 7004 match(Set mem (StoreD mem src)); 7005 ins_cost(95); 7006 format %{ "MOVSD $mem,$src" %} 7007 ins_encode %{ 7008 __ movdbl($mem$$Address, $src$$XMMRegister); 7009 %} 7010 ins_pipe( pipe_slow ); 7011%} 7012 7013// Store XMM register to memory (single-precision floating point) 7014// MOVSS instruction 7015instruct storeF(memory mem, regF src) %{ 7016 predicate(UseSSE>=1); 7017 match(Set mem (StoreF mem src)); 7018 ins_cost(95); 7019 format %{ "MOVSS $mem,$src" %} 7020 ins_encode %{ 7021 __ movflt($mem$$Address, $src$$XMMRegister); 7022 %} 7023 ins_pipe( pipe_slow ); 7024%} 7025 7026// Store Float 7027instruct storeFPR( memory mem, regFPR1 src) %{ 7028 predicate(UseSSE==0); 7029 match(Set mem (StoreF mem src)); 7030 7031 ins_cost(100); 7032 format %{ "FST_S $mem,$src" %} 7033 opcode(0xD9); /* D9 /2 */ 7034 ins_encode( enc_FPR_store(mem,src) ); 7035 ins_pipe( fpu_mem_reg ); 7036%} 7037 7038// Store Float does rounding on x86 7039instruct storeFPR_rounded( memory mem, regFPR1 src) %{ 7040 predicate(UseSSE==0); 7041 match(Set mem (StoreF mem (RoundFloat src))); 7042 7043 ins_cost(100); 7044 format %{ "FST_S $mem,$src\t# round" %} 7045 opcode(0xD9); /* D9 /2 */ 7046 ins_encode( enc_FPR_store(mem,src) ); 7047 ins_pipe( fpu_mem_reg ); 7048%} 7049 7050// Store Float does rounding on x86 7051instruct storeFPR_Drounded( memory mem, regDPR1 src) %{ 7052 predicate(UseSSE<=1); 7053 match(Set mem (StoreF mem (ConvD2F src))); 7054 7055 ins_cost(100); 7056 format %{ "FST_S $mem,$src\t# D-round" %} 7057 opcode(0xD9); /* D9 /2 */ 7058 ins_encode( enc_FPR_store(mem,src) ); 7059 ins_pipe( fpu_mem_reg ); 7060%} 7061 7062// Store immediate Float value (it is faster than store from FPU register) 7063// The instruction usage is guarded by predicate in operand immFPR(). 7064instruct storeFPR_imm( memory mem, immFPR src) %{ 7065 match(Set mem (StoreF mem src)); 7066 7067 ins_cost(50); 7068 format %{ "MOV $mem,$src\t# store float" %} 7069 opcode(0xC7); /* C7 /0 */ 7070 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32FPR_as_bits( src )); 7071 ins_pipe( ialu_mem_imm ); 7072%} 7073 7074// Store immediate Float value (it is faster than store from XMM register) 7075// The instruction usage is guarded by predicate in operand immF(). 7076instruct storeF_imm( memory mem, immF src) %{ 7077 match(Set mem (StoreF mem src)); 7078 7079 ins_cost(50); 7080 format %{ "MOV $mem,$src\t# store float" %} 7081 opcode(0xC7); /* C7 /0 */ 7082 ins_encode( OpcP, RMopc_Mem(0x00,mem), Con32F_as_bits( src )); 7083 ins_pipe( ialu_mem_imm ); 7084%} 7085 7086// Store Integer to stack slot 7087instruct storeSSI(stackSlotI dst, rRegI src) %{ 7088 match(Set dst src); 7089 7090 ins_cost(100); 7091 format %{ "MOV $dst,$src" %} 7092 opcode(0x89); 7093 ins_encode( OpcPRegSS( dst, src ) ); 7094 ins_pipe( ialu_mem_reg ); 7095%} 7096 7097// Store Integer to stack slot 7098instruct storeSSP(stackSlotP dst, eRegP src) %{ 7099 match(Set dst src); 7100 7101 ins_cost(100); 7102 format %{ "MOV $dst,$src" %} 7103 opcode(0x89); 7104 ins_encode( OpcPRegSS( dst, src ) ); 7105 ins_pipe( ialu_mem_reg ); 7106%} 7107 7108// Store Long to stack slot 7109instruct storeSSL(stackSlotL dst, eRegL src) %{ 7110 match(Set dst src); 7111 7112 ins_cost(200); 7113 format %{ "MOV $dst,$src.lo\n\t" 7114 "MOV $dst+4,$src.hi" %} 7115 opcode(0x89, 0x89); 7116 ins_encode( OpcP, RegMem( src, dst ), OpcS, RegMem_Hi( src, dst ) ); 7117 ins_pipe( ialu_mem_long_reg ); 7118%} 7119 7120//----------MemBar Instructions----------------------------------------------- 7121// Memory barrier flavors 7122 7123instruct membar_acquire() %{ 7124 match(MemBarAcquire); 7125 ins_cost(400); 7126 7127 size(0); 7128 format %{ "MEMBAR-acquire ! (empty encoding)" %} 7129 ins_encode(); 7130 ins_pipe(empty); 7131%} 7132 7133instruct membar_acquire_lock() %{ 7134 match(MemBarAcquireLock); 7135 ins_cost(0); 7136 7137 size(0); 7138 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 7139 ins_encode( ); 7140 ins_pipe(empty); 7141%} 7142 7143instruct membar_release() %{ 7144 match(MemBarRelease); 7145 ins_cost(400); 7146 7147 size(0); 7148 format %{ "MEMBAR-release ! (empty encoding)" %} 7149 ins_encode( ); 7150 ins_pipe(empty); 7151%} 7152 7153instruct membar_release_lock() %{ 7154 match(MemBarReleaseLock); 7155 ins_cost(0); 7156 7157 size(0); 7158 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 7159 ins_encode( ); 7160 ins_pipe(empty); 7161%} 7162 7163instruct membar_volatile(eFlagsReg cr) %{ 7164 match(MemBarVolatile); 7165 effect(KILL cr); 7166 ins_cost(400); 7167 7168 format %{ 7169 $$template 7170 if (os::is_MP()) { 7171 $$emit$$"LOCK ADDL [ESP + #0], 0\t! membar_volatile" 7172 } else { 7173 $$emit$$"MEMBAR-volatile ! (empty encoding)" 7174 } 7175 %} 7176 ins_encode %{ 7177 __ membar(Assembler::StoreLoad); 7178 %} 7179 ins_pipe(pipe_slow); 7180%} 7181 7182instruct unnecessary_membar_volatile() %{ 7183 match(MemBarVolatile); 7184 predicate(Matcher::post_store_load_barrier(n)); 7185 ins_cost(0); 7186 7187 size(0); 7188 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 7189 ins_encode( ); 7190 ins_pipe(empty); 7191%} 7192 7193instruct membar_storestore() %{ 7194 match(MemBarStoreStore); 7195 ins_cost(0); 7196 7197 size(0); 7198 format %{ "MEMBAR-storestore (empty encoding)" %} 7199 ins_encode( ); 7200 ins_pipe(empty); 7201%} 7202 7203//----------Move Instructions-------------------------------------------------- 7204instruct castX2P(eAXRegP dst, eAXRegI src) %{ 7205 match(Set dst (CastX2P src)); 7206 format %{ "# X2P $dst, $src" %} 7207 ins_encode( /*empty encoding*/ ); 7208 ins_cost(0); 7209 ins_pipe(empty); 7210%} 7211 7212instruct castP2X(rRegI dst, eRegP src ) %{ 7213 match(Set dst (CastP2X src)); 7214 ins_cost(50); 7215 format %{ "MOV $dst, $src\t# CastP2X" %} 7216 ins_encode( enc_Copy( dst, src) ); 7217 ins_pipe( ialu_reg_reg ); 7218%} 7219 7220//----------Conditional Move--------------------------------------------------- 7221// Conditional move 7222instruct jmovI_reg(cmpOp cop, eFlagsReg cr, rRegI dst, rRegI src) %{ 7223 predicate(!VM_Version::supports_cmov() ); 7224 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7225 ins_cost(200); 7226 format %{ "J$cop,us skip\t# signed cmove\n\t" 7227 "MOV $dst,$src\n" 7228 "skip:" %} 7229 ins_encode %{ 7230 Label Lskip; 7231 // Invert sense of branch from sense of CMOV 7232 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7233 __ movl($dst$$Register, $src$$Register); 7234 __ bind(Lskip); 7235 %} 7236 ins_pipe( pipe_cmov_reg ); 7237%} 7238 7239instruct jmovI_regU(cmpOpU cop, eFlagsRegU cr, rRegI dst, rRegI src) %{ 7240 predicate(!VM_Version::supports_cmov() ); 7241 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7242 ins_cost(200); 7243 format %{ "J$cop,us skip\t# unsigned cmove\n\t" 7244 "MOV $dst,$src\n" 7245 "skip:" %} 7246 ins_encode %{ 7247 Label Lskip; 7248 // Invert sense of branch from sense of CMOV 7249 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 7250 __ movl($dst$$Register, $src$$Register); 7251 __ bind(Lskip); 7252 %} 7253 ins_pipe( pipe_cmov_reg ); 7254%} 7255 7256instruct cmovI_reg(rRegI dst, rRegI src, eFlagsReg cr, cmpOp cop ) %{ 7257 predicate(VM_Version::supports_cmov() ); 7258 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7259 ins_cost(200); 7260 format %{ "CMOV$cop $dst,$src" %} 7261 opcode(0x0F,0x40); 7262 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7263 ins_pipe( pipe_cmov_reg ); 7264%} 7265 7266instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, rRegI dst, rRegI src ) %{ 7267 predicate(VM_Version::supports_cmov() ); 7268 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7269 ins_cost(200); 7270 format %{ "CMOV$cop $dst,$src" %} 7271 opcode(0x0F,0x40); 7272 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7273 ins_pipe( pipe_cmov_reg ); 7274%} 7275 7276instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, rRegI dst, rRegI src ) %{ 7277 predicate(VM_Version::supports_cmov() ); 7278 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 7279 ins_cost(200); 7280 expand %{ 7281 cmovI_regU(cop, cr, dst, src); 7282 %} 7283%} 7284 7285// Conditional move 7286instruct cmovI_mem(cmpOp cop, eFlagsReg cr, rRegI dst, memory src) %{ 7287 predicate(VM_Version::supports_cmov() ); 7288 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7289 ins_cost(250); 7290 format %{ "CMOV$cop $dst,$src" %} 7291 opcode(0x0F,0x40); 7292 ins_encode( enc_cmov(cop), RegMem( dst, src ) ); 7293 ins_pipe( pipe_cmov_mem ); 7294%} 7295 7296// Conditional move 7297instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, rRegI dst, memory src) %{ 7298 predicate(VM_Version::supports_cmov() ); 7299 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7300 ins_cost(250); 7301 format %{ "CMOV$cop $dst,$src" %} 7302 opcode(0x0F,0x40); 7303 ins_encode( enc_cmov(cop), RegMem( dst, src ) ); 7304 ins_pipe( pipe_cmov_mem ); 7305%} 7306 7307instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, rRegI dst, memory src) %{ 7308 predicate(VM_Version::supports_cmov() ); 7309 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 7310 ins_cost(250); 7311 expand %{ 7312 cmovI_memU(cop, cr, dst, src); 7313 %} 7314%} 7315 7316// Conditional move 7317instruct cmovP_reg(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{ 7318 predicate(VM_Version::supports_cmov() ); 7319 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7320 ins_cost(200); 7321 format %{ "CMOV$cop $dst,$src\t# ptr" %} 7322 opcode(0x0F,0x40); 7323 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7324 ins_pipe( pipe_cmov_reg ); 7325%} 7326 7327// Conditional move (non-P6 version) 7328// Note: a CMoveP is generated for stubs and native wrappers 7329// regardless of whether we are on a P6, so we 7330// emulate a cmov here 7331instruct cmovP_reg_nonP6(eRegP dst, eRegP src, eFlagsReg cr, cmpOp cop ) %{ 7332 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7333 ins_cost(300); 7334 format %{ "Jn$cop skip\n\t" 7335 "MOV $dst,$src\t# pointer\n" 7336 "skip:" %} 7337 opcode(0x8b); 7338 ins_encode( enc_cmov_branch(cop, 0x2), OpcP, RegReg(dst, src)); 7339 ins_pipe( pipe_cmov_reg ); 7340%} 7341 7342// Conditional move 7343instruct cmovP_regU(cmpOpU cop, eFlagsRegU cr, eRegP dst, eRegP src ) %{ 7344 predicate(VM_Version::supports_cmov() ); 7345 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7346 ins_cost(200); 7347 format %{ "CMOV$cop $dst,$src\t# ptr" %} 7348 opcode(0x0F,0x40); 7349 ins_encode( enc_cmov(cop), RegReg( dst, src ) ); 7350 ins_pipe( pipe_cmov_reg ); 7351%} 7352 7353instruct cmovP_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegP dst, eRegP src ) %{ 7354 predicate(VM_Version::supports_cmov() ); 7355 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 7356 ins_cost(200); 7357 expand %{ 7358 cmovP_regU(cop, cr, dst, src); 7359 %} 7360%} 7361 7362// DISABLED: Requires the ADLC to emit a bottom_type call that 7363// correctly meets the two pointer arguments; one is an incoming 7364// register but the other is a memory operand. ALSO appears to 7365// be buggy with implicit null checks. 7366// 7367//// Conditional move 7368//instruct cmovP_mem(cmpOp cop, eFlagsReg cr, eRegP dst, memory src) %{ 7369// predicate(VM_Version::supports_cmov() ); 7370// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7371// ins_cost(250); 7372// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7373// opcode(0x0F,0x40); 7374// ins_encode( enc_cmov(cop), RegMem( dst, src ) ); 7375// ins_pipe( pipe_cmov_mem ); 7376//%} 7377// 7378//// Conditional move 7379//instruct cmovP_memU(cmpOpU cop, eFlagsRegU cr, eRegP dst, memory src) %{ 7380// predicate(VM_Version::supports_cmov() ); 7381// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 7382// ins_cost(250); 7383// format %{ "CMOV$cop $dst,$src\t# ptr" %} 7384// opcode(0x0F,0x40); 7385// ins_encode( enc_cmov(cop), RegMem( dst, src ) ); 7386// ins_pipe( pipe_cmov_mem ); 7387//%} 7388 7389// Conditional move 7390instruct fcmovDPR_regU(cmpOp_fcmov cop, eFlagsRegU cr, regDPR1 dst, regDPR src) %{ 7391 predicate(UseSSE<=1); 7392 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7393 ins_cost(200); 7394 format %{ "FCMOV$cop $dst,$src\t# double" %} 7395 opcode(0xDA); 7396 ins_encode( enc_cmov_dpr(cop,src) ); 7397 ins_pipe( pipe_cmovDPR_reg ); 7398%} 7399 7400// Conditional move 7401instruct fcmovFPR_regU(cmpOp_fcmov cop, eFlagsRegU cr, regFPR1 dst, regFPR src) %{ 7402 predicate(UseSSE==0); 7403 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7404 ins_cost(200); 7405 format %{ "FCMOV$cop $dst,$src\t# float" %} 7406 opcode(0xDA); 7407 ins_encode( enc_cmov_dpr(cop,src) ); 7408 ins_pipe( pipe_cmovDPR_reg ); 7409%} 7410 7411// Float CMOV on Intel doesn't handle *signed* compares, only unsigned. 7412instruct fcmovDPR_regS(cmpOp cop, eFlagsReg cr, regDPR dst, regDPR src) %{ 7413 predicate(UseSSE<=1); 7414 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7415 ins_cost(200); 7416 format %{ "Jn$cop skip\n\t" 7417 "MOV $dst,$src\t# double\n" 7418 "skip:" %} 7419 opcode (0xdd, 0x3); /* DD D8+i or DD /3 */ 7420 ins_encode( enc_cmov_branch( cop, 0x4 ), Push_Reg_DPR(src), OpcP, RegOpc(dst) ); 7421 ins_pipe( pipe_cmovDPR_reg ); 7422%} 7423 7424// Float CMOV on Intel doesn't handle *signed* compares, only unsigned. 7425instruct fcmovFPR_regS(cmpOp cop, eFlagsReg cr, regFPR dst, regFPR src) %{ 7426 predicate(UseSSE==0); 7427 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7428 ins_cost(200); 7429 format %{ "Jn$cop skip\n\t" 7430 "MOV $dst,$src\t# float\n" 7431 "skip:" %} 7432 opcode (0xdd, 0x3); /* DD D8+i or DD /3 */ 7433 ins_encode( enc_cmov_branch( cop, 0x4 ), Push_Reg_FPR(src), OpcP, RegOpc(dst) ); 7434 ins_pipe( pipe_cmovDPR_reg ); 7435%} 7436 7437// No CMOVE with SSE/SSE2 7438instruct fcmovF_regS(cmpOp cop, eFlagsReg cr, regF dst, regF src) %{ 7439 predicate (UseSSE>=1); 7440 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7441 ins_cost(200); 7442 format %{ "Jn$cop skip\n\t" 7443 "MOVSS $dst,$src\t# float\n" 7444 "skip:" %} 7445 ins_encode %{ 7446 Label skip; 7447 // Invert sense of branch from sense of CMOV 7448 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip); 7449 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7450 __ bind(skip); 7451 %} 7452 ins_pipe( pipe_slow ); 7453%} 7454 7455// No CMOVE with SSE/SSE2 7456instruct fcmovD_regS(cmpOp cop, eFlagsReg cr, regD dst, regD src) %{ 7457 predicate (UseSSE>=2); 7458 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7459 ins_cost(200); 7460 format %{ "Jn$cop skip\n\t" 7461 "MOVSD $dst,$src\t# float\n" 7462 "skip:" %} 7463 ins_encode %{ 7464 Label skip; 7465 // Invert sense of branch from sense of CMOV 7466 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip); 7467 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7468 __ bind(skip); 7469 %} 7470 ins_pipe( pipe_slow ); 7471%} 7472 7473// unsigned version 7474instruct fcmovF_regU(cmpOpU cop, eFlagsRegU cr, regF dst, regF src) %{ 7475 predicate (UseSSE>=1); 7476 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7477 ins_cost(200); 7478 format %{ "Jn$cop skip\n\t" 7479 "MOVSS $dst,$src\t# float\n" 7480 "skip:" %} 7481 ins_encode %{ 7482 Label skip; 7483 // Invert sense of branch from sense of CMOV 7484 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip); 7485 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 7486 __ bind(skip); 7487 %} 7488 ins_pipe( pipe_slow ); 7489%} 7490 7491instruct fcmovF_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regF dst, regF src) %{ 7492 predicate (UseSSE>=1); 7493 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 7494 ins_cost(200); 7495 expand %{ 7496 fcmovF_regU(cop, cr, dst, src); 7497 %} 7498%} 7499 7500// unsigned version 7501instruct fcmovD_regU(cmpOpU cop, eFlagsRegU cr, regD dst, regD src) %{ 7502 predicate (UseSSE>=2); 7503 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7504 ins_cost(200); 7505 format %{ "Jn$cop skip\n\t" 7506 "MOVSD $dst,$src\t# float\n" 7507 "skip:" %} 7508 ins_encode %{ 7509 Label skip; 7510 // Invert sense of branch from sense of CMOV 7511 __ jccb((Assembler::Condition)($cop$$cmpcode^1), skip); 7512 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 7513 __ bind(skip); 7514 %} 7515 ins_pipe( pipe_slow ); 7516%} 7517 7518instruct fcmovD_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, regD dst, regD src) %{ 7519 predicate (UseSSE>=2); 7520 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 7521 ins_cost(200); 7522 expand %{ 7523 fcmovD_regU(cop, cr, dst, src); 7524 %} 7525%} 7526 7527instruct cmovL_reg(cmpOp cop, eFlagsReg cr, eRegL dst, eRegL src) %{ 7528 predicate(VM_Version::supports_cmov() ); 7529 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7530 ins_cost(200); 7531 format %{ "CMOV$cop $dst.lo,$src.lo\n\t" 7532 "CMOV$cop $dst.hi,$src.hi" %} 7533 opcode(0x0F,0x40); 7534 ins_encode( enc_cmov(cop), RegReg_Lo2( dst, src ), enc_cmov(cop), RegReg_Hi2( dst, src ) ); 7535 ins_pipe( pipe_cmov_reg_long ); 7536%} 7537 7538instruct cmovL_regU(cmpOpU cop, eFlagsRegU cr, eRegL dst, eRegL src) %{ 7539 predicate(VM_Version::supports_cmov() ); 7540 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7541 ins_cost(200); 7542 format %{ "CMOV$cop $dst.lo,$src.lo\n\t" 7543 "CMOV$cop $dst.hi,$src.hi" %} 7544 opcode(0x0F,0x40); 7545 ins_encode( enc_cmov(cop), RegReg_Lo2( dst, src ), enc_cmov(cop), RegReg_Hi2( dst, src ) ); 7546 ins_pipe( pipe_cmov_reg_long ); 7547%} 7548 7549instruct cmovL_regUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegL dst, eRegL src) %{ 7550 predicate(VM_Version::supports_cmov() ); 7551 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 7552 ins_cost(200); 7553 expand %{ 7554 cmovL_regU(cop, cr, dst, src); 7555 %} 7556%} 7557 7558//----------Arithmetic Instructions-------------------------------------------- 7559//----------Addition Instructions---------------------------------------------- 7560// Integer Addition Instructions 7561instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{ 7562 match(Set dst (AddI dst src)); 7563 effect(KILL cr); 7564 7565 size(2); 7566 format %{ "ADD $dst,$src" %} 7567 opcode(0x03); 7568 ins_encode( OpcP, RegReg( dst, src) ); 7569 ins_pipe( ialu_reg_reg ); 7570%} 7571 7572instruct addI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{ 7573 match(Set dst (AddI dst src)); 7574 effect(KILL cr); 7575 7576 format %{ "ADD $dst,$src" %} 7577 opcode(0x81, 0x00); /* /0 id */ 7578 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 7579 ins_pipe( ialu_reg ); 7580%} 7581 7582instruct incI_eReg(rRegI dst, immI1 src, eFlagsReg cr) %{ 7583 predicate(UseIncDec); 7584 match(Set dst (AddI dst src)); 7585 effect(KILL cr); 7586 7587 size(1); 7588 format %{ "INC $dst" %} 7589 opcode(0x40); /* */ 7590 ins_encode( Opc_plus( primary, dst ) ); 7591 ins_pipe( ialu_reg ); 7592%} 7593 7594instruct leaI_eReg_immI(rRegI dst, rRegI src0, immI src1) %{ 7595 match(Set dst (AddI src0 src1)); 7596 ins_cost(110); 7597 7598 format %{ "LEA $dst,[$src0 + $src1]" %} 7599 opcode(0x8D); /* 0x8D /r */ 7600 ins_encode( OpcP, RegLea( dst, src0, src1 ) ); 7601 ins_pipe( ialu_reg_reg ); 7602%} 7603 7604instruct leaP_eReg_immI(eRegP dst, eRegP src0, immI src1) %{ 7605 match(Set dst (AddP src0 src1)); 7606 ins_cost(110); 7607 7608 format %{ "LEA $dst,[$src0 + $src1]\t# ptr" %} 7609 opcode(0x8D); /* 0x8D /r */ 7610 ins_encode( OpcP, RegLea( dst, src0, src1 ) ); 7611 ins_pipe( ialu_reg_reg ); 7612%} 7613 7614instruct decI_eReg(rRegI dst, immI_M1 src, eFlagsReg cr) %{ 7615 predicate(UseIncDec); 7616 match(Set dst (AddI dst src)); 7617 effect(KILL cr); 7618 7619 size(1); 7620 format %{ "DEC $dst" %} 7621 opcode(0x48); /* */ 7622 ins_encode( Opc_plus( primary, dst ) ); 7623 ins_pipe( ialu_reg ); 7624%} 7625 7626instruct addP_eReg(eRegP dst, rRegI src, eFlagsReg cr) %{ 7627 match(Set dst (AddP dst src)); 7628 effect(KILL cr); 7629 7630 size(2); 7631 format %{ "ADD $dst,$src" %} 7632 opcode(0x03); 7633 ins_encode( OpcP, RegReg( dst, src) ); 7634 ins_pipe( ialu_reg_reg ); 7635%} 7636 7637instruct addP_eReg_imm(eRegP dst, immI src, eFlagsReg cr) %{ 7638 match(Set dst (AddP dst src)); 7639 effect(KILL cr); 7640 7641 format %{ "ADD $dst,$src" %} 7642 opcode(0x81,0x00); /* Opcode 81 /0 id */ 7643 // ins_encode( RegImm( dst, src) ); 7644 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 7645 ins_pipe( ialu_reg ); 7646%} 7647 7648instruct addI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{ 7649 match(Set dst (AddI dst (LoadI src))); 7650 effect(KILL cr); 7651 7652 ins_cost(125); 7653 format %{ "ADD $dst,$src" %} 7654 opcode(0x03); 7655 ins_encode( OpcP, RegMem( dst, src) ); 7656 ins_pipe( ialu_reg_mem ); 7657%} 7658 7659instruct addI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{ 7660 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7661 effect(KILL cr); 7662 7663 ins_cost(150); 7664 format %{ "ADD $dst,$src" %} 7665 opcode(0x01); /* Opcode 01 /r */ 7666 ins_encode( OpcP, RegMem( src, dst ) ); 7667 ins_pipe( ialu_mem_reg ); 7668%} 7669 7670// Add Memory with Immediate 7671instruct addI_mem_imm(memory dst, immI src, eFlagsReg cr) %{ 7672 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7673 effect(KILL cr); 7674 7675 ins_cost(125); 7676 format %{ "ADD $dst,$src" %} 7677 opcode(0x81); /* Opcode 81 /0 id */ 7678 ins_encode( OpcSE( src ), RMopc_Mem(0x00,dst), Con8or32( src ) ); 7679 ins_pipe( ialu_mem_imm ); 7680%} 7681 7682instruct incI_mem(memory dst, immI1 src, eFlagsReg cr) %{ 7683 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7684 effect(KILL cr); 7685 7686 ins_cost(125); 7687 format %{ "INC $dst" %} 7688 opcode(0xFF); /* Opcode FF /0 */ 7689 ins_encode( OpcP, RMopc_Mem(0x00,dst)); 7690 ins_pipe( ialu_mem_imm ); 7691%} 7692 7693instruct decI_mem(memory dst, immI_M1 src, eFlagsReg cr) %{ 7694 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7695 effect(KILL cr); 7696 7697 ins_cost(125); 7698 format %{ "DEC $dst" %} 7699 opcode(0xFF); /* Opcode FF /1 */ 7700 ins_encode( OpcP, RMopc_Mem(0x01,dst)); 7701 ins_pipe( ialu_mem_imm ); 7702%} 7703 7704 7705instruct checkCastPP( eRegP dst ) %{ 7706 match(Set dst (CheckCastPP dst)); 7707 7708 size(0); 7709 format %{ "#checkcastPP of $dst" %} 7710 ins_encode( /*empty encoding*/ ); 7711 ins_pipe( empty ); 7712%} 7713 7714instruct castPP( eRegP dst ) %{ 7715 match(Set dst (CastPP dst)); 7716 format %{ "#castPP of $dst" %} 7717 ins_encode( /*empty encoding*/ ); 7718 ins_pipe( empty ); 7719%} 7720 7721instruct castII( rRegI dst ) %{ 7722 match(Set dst (CastII dst)); 7723 format %{ "#castII of $dst" %} 7724 ins_encode( /*empty encoding*/ ); 7725 ins_cost(0); 7726 ins_pipe( empty ); 7727%} 7728 7729 7730// Load-locked - same as a regular pointer load when used with compare-swap 7731instruct loadPLocked(eRegP dst, memory mem) %{ 7732 match(Set dst (LoadPLocked mem)); 7733 7734 ins_cost(125); 7735 format %{ "MOV $dst,$mem\t# Load ptr. locked" %} 7736 opcode(0x8B); 7737 ins_encode( OpcP, RegMem(dst,mem)); 7738 ins_pipe( ialu_reg_mem ); 7739%} 7740 7741// Conditional-store of the updated heap-top. 7742// Used during allocation of the shared heap. 7743// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7744instruct storePConditional( memory heap_top_ptr, eAXRegP oldval, eRegP newval, eFlagsReg cr ) %{ 7745 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7746 // EAX is killed if there is contention, but then it's also unused. 7747 // In the common case of no contention, EAX holds the new oop address. 7748 format %{ "CMPXCHG $heap_top_ptr,$newval\t# If EAX==$heap_top_ptr Then store $newval into $heap_top_ptr" %} 7749 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval,heap_top_ptr) ); 7750 ins_pipe( pipe_cmpxchg ); 7751%} 7752 7753// Conditional-store of an int value. 7754// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG on Intel. 7755instruct storeIConditional( memory mem, eAXRegI oldval, rRegI newval, eFlagsReg cr ) %{ 7756 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7757 effect(KILL oldval); 7758 format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %} 7759 ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) ); 7760 ins_pipe( pipe_cmpxchg ); 7761%} 7762 7763// Conditional-store of a long value. 7764// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG8 on Intel. 7765instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ 7766 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7767 effect(KILL oldval); 7768 format %{ "XCHG EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t" 7769 "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t" 7770 "XCHG EBX,ECX" 7771 %} 7772 ins_encode %{ 7773 // Note: we need to swap rbx, and rcx before and after the 7774 // cmpxchg8 instruction because the instruction uses 7775 // rcx as the high order word of the new value to store but 7776 // our register encoding uses rbx. 7777 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc)); 7778 if( os::is_MP() ) 7779 __ lock(); 7780 __ cmpxchg8($mem$$Address); 7781 __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc)); 7782 %} 7783 ins_pipe( pipe_cmpxchg ); 7784%} 7785 7786// No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7787 7788instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ 7789 predicate(VM_Version::supports_cx8()); 7790 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7791 effect(KILL cr, KILL oldval); 7792 format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 7793 "MOV $res,0\n\t" 7794 "JNE,s fail\n\t" 7795 "MOV $res,1\n" 7796 "fail:" %} 7797 ins_encode( enc_cmpxchg8(mem_ptr), 7798 enc_flags_ne_to_boolean(res) ); 7799 ins_pipe( pipe_cmpxchg ); 7800%} 7801 7802instruct compareAndSwapP( rRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{ 7803 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7804 effect(KILL cr, KILL oldval); 7805 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 7806 "MOV $res,0\n\t" 7807 "JNE,s fail\n\t" 7808 "MOV $res,1\n" 7809 "fail:" %} 7810 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) ); 7811 ins_pipe( pipe_cmpxchg ); 7812%} 7813 7814instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{ 7815 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7816 effect(KILL cr, KILL oldval); 7817 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 7818 "MOV $res,0\n\t" 7819 "JNE,s fail\n\t" 7820 "MOV $res,1\n" 7821 "fail:" %} 7822 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) ); 7823 ins_pipe( pipe_cmpxchg ); 7824%} 7825 7826instruct xaddI_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{ 7827 predicate(n->as_LoadStore()->result_not_used()); 7828 match(Set dummy (GetAndAddI mem add)); 7829 effect(KILL cr); 7830 format %{ "ADDL [$mem],$add" %} 7831 ins_encode %{ 7832 if (os::is_MP()) { __ lock(); } 7833 __ addl($mem$$Address, $add$$constant); 7834 %} 7835 ins_pipe( pipe_cmpxchg ); 7836%} 7837 7838instruct xaddI( memory mem, rRegI newval, eFlagsReg cr) %{ 7839 match(Set newval (GetAndAddI mem newval)); 7840 effect(KILL cr); 7841 format %{ "XADDL [$mem],$newval" %} 7842 ins_encode %{ 7843 if (os::is_MP()) { __ lock(); } 7844 __ xaddl($mem$$Address, $newval$$Register); 7845 %} 7846 ins_pipe( pipe_cmpxchg ); 7847%} 7848 7849instruct xchgI( memory mem, rRegI newval) %{ 7850 match(Set newval (GetAndSetI mem newval)); 7851 format %{ "XCHGL $newval,[$mem]" %} 7852 ins_encode %{ 7853 __ xchgl($newval$$Register, $mem$$Address); 7854 %} 7855 ins_pipe( pipe_cmpxchg ); 7856%} 7857 7858instruct xchgP( memory mem, pRegP newval) %{ 7859 match(Set newval (GetAndSetP mem newval)); 7860 format %{ "XCHGL $newval,[$mem]" %} 7861 ins_encode %{ 7862 __ xchgl($newval$$Register, $mem$$Address); 7863 %} 7864 ins_pipe( pipe_cmpxchg ); 7865%} 7866 7867//----------Subtraction Instructions------------------------------------------- 7868// Integer Subtraction Instructions 7869instruct subI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{ 7870 match(Set dst (SubI dst src)); 7871 effect(KILL cr); 7872 7873 size(2); 7874 format %{ "SUB $dst,$src" %} 7875 opcode(0x2B); 7876 ins_encode( OpcP, RegReg( dst, src) ); 7877 ins_pipe( ialu_reg_reg ); 7878%} 7879 7880instruct subI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{ 7881 match(Set dst (SubI dst src)); 7882 effect(KILL cr); 7883 7884 format %{ "SUB $dst,$src" %} 7885 opcode(0x81,0x05); /* Opcode 81 /5 */ 7886 // ins_encode( RegImm( dst, src) ); 7887 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 7888 ins_pipe( ialu_reg ); 7889%} 7890 7891instruct subI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{ 7892 match(Set dst (SubI dst (LoadI src))); 7893 effect(KILL cr); 7894 7895 ins_cost(125); 7896 format %{ "SUB $dst,$src" %} 7897 opcode(0x2B); 7898 ins_encode( OpcP, RegMem( dst, src) ); 7899 ins_pipe( ialu_reg_mem ); 7900%} 7901 7902instruct subI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{ 7903 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7904 effect(KILL cr); 7905 7906 ins_cost(150); 7907 format %{ "SUB $dst,$src" %} 7908 opcode(0x29); /* Opcode 29 /r */ 7909 ins_encode( OpcP, RegMem( src, dst ) ); 7910 ins_pipe( ialu_mem_reg ); 7911%} 7912 7913// Subtract from a pointer 7914instruct subP_eReg(eRegP dst, rRegI src, immI0 zero, eFlagsReg cr) %{ 7915 match(Set dst (AddP dst (SubI zero src))); 7916 effect(KILL cr); 7917 7918 size(2); 7919 format %{ "SUB $dst,$src" %} 7920 opcode(0x2B); 7921 ins_encode( OpcP, RegReg( dst, src) ); 7922 ins_pipe( ialu_reg_reg ); 7923%} 7924 7925instruct negI_eReg(rRegI dst, immI0 zero, eFlagsReg cr) %{ 7926 match(Set dst (SubI zero dst)); 7927 effect(KILL cr); 7928 7929 size(2); 7930 format %{ "NEG $dst" %} 7931 opcode(0xF7,0x03); // Opcode F7 /3 7932 ins_encode( OpcP, RegOpc( dst ) ); 7933 ins_pipe( ialu_reg ); 7934%} 7935 7936 7937//----------Multiplication/Division Instructions------------------------------- 7938// Integer Multiplication Instructions 7939// Multiply Register 7940instruct mulI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{ 7941 match(Set dst (MulI dst src)); 7942 effect(KILL cr); 7943 7944 size(3); 7945 ins_cost(300); 7946 format %{ "IMUL $dst,$src" %} 7947 opcode(0xAF, 0x0F); 7948 ins_encode( OpcS, OpcP, RegReg( dst, src) ); 7949 ins_pipe( ialu_reg_reg_alu0 ); 7950%} 7951 7952// Multiply 32-bit Immediate 7953instruct mulI_eReg_imm(rRegI dst, rRegI src, immI imm, eFlagsReg cr) %{ 7954 match(Set dst (MulI src imm)); 7955 effect(KILL cr); 7956 7957 ins_cost(300); 7958 format %{ "IMUL $dst,$src,$imm" %} 7959 opcode(0x69); /* 69 /r id */ 7960 ins_encode( OpcSE(imm), RegReg( dst, src ), Con8or32( imm ) ); 7961 ins_pipe( ialu_reg_reg_alu0 ); 7962%} 7963 7964instruct loadConL_low_only(eADXRegL_low_only dst, immL32 src, eFlagsReg cr) %{ 7965 match(Set dst src); 7966 effect(KILL cr); 7967 7968 // Note that this is artificially increased to make it more expensive than loadConL 7969 ins_cost(250); 7970 format %{ "MOV EAX,$src\t// low word only" %} 7971 opcode(0xB8); 7972 ins_encode( LdImmL_Lo(dst, src) ); 7973 ins_pipe( ialu_reg_fat ); 7974%} 7975 7976// Multiply by 32-bit Immediate, taking the shifted high order results 7977// (special case for shift by 32) 7978instruct mulI_imm_high(eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32 cnt, eFlagsReg cr) %{ 7979 match(Set dst (ConvL2I (RShiftL (MulL (ConvI2L src1) src2) cnt))); 7980 predicate( _kids[0]->_kids[0]->_kids[1]->_leaf->Opcode() == Op_ConL && 7981 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() >= min_jint && 7982 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() <= max_jint ); 7983 effect(USE src1, KILL cr); 7984 7985 // Note that this is adjusted by 150 to compensate for the overcosting of loadConL_low_only 7986 ins_cost(0*100 + 1*400 - 150); 7987 format %{ "IMUL EDX:EAX,$src1" %} 7988 ins_encode( multiply_con_and_shift_high( dst, src1, src2, cnt, cr ) ); 7989 ins_pipe( pipe_slow ); 7990%} 7991 7992// Multiply by 32-bit Immediate, taking the shifted high order results 7993instruct mulI_imm_RShift_high(eDXRegI dst, nadxRegI src1, eADXRegL_low_only src2, immI_32_63 cnt, eFlagsReg cr) %{ 7994 match(Set dst (ConvL2I (RShiftL (MulL (ConvI2L src1) src2) cnt))); 7995 predicate( _kids[0]->_kids[0]->_kids[1]->_leaf->Opcode() == Op_ConL && 7996 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() >= min_jint && 7997 _kids[0]->_kids[0]->_kids[1]->_leaf->as_Type()->type()->is_long()->get_con() <= max_jint ); 7998 effect(USE src1, KILL cr); 7999 8000 // Note that this is adjusted by 150 to compensate for the overcosting of loadConL_low_only 8001 ins_cost(1*100 + 1*400 - 150); 8002 format %{ "IMUL EDX:EAX,$src1\n\t" 8003 "SAR EDX,$cnt-32" %} 8004 ins_encode( multiply_con_and_shift_high( dst, src1, src2, cnt, cr ) ); 8005 ins_pipe( pipe_slow ); 8006%} 8007 8008// Multiply Memory 32-bit Immediate 8009instruct mulI_mem_imm(rRegI dst, memory src, immI imm, eFlagsReg cr) %{ 8010 match(Set dst (MulI (LoadI src) imm)); 8011 effect(KILL cr); 8012 8013 ins_cost(300); 8014 format %{ "IMUL $dst,$src,$imm" %} 8015 opcode(0x69); /* 69 /r id */ 8016 ins_encode( OpcSE(imm), RegMem( dst, src ), Con8or32( imm ) ); 8017 ins_pipe( ialu_reg_mem_alu0 ); 8018%} 8019 8020// Multiply Memory 8021instruct mulI(rRegI dst, memory src, eFlagsReg cr) %{ 8022 match(Set dst (MulI dst (LoadI src))); 8023 effect(KILL cr); 8024 8025 ins_cost(350); 8026 format %{ "IMUL $dst,$src" %} 8027 opcode(0xAF, 0x0F); 8028 ins_encode( OpcS, OpcP, RegMem( dst, src) ); 8029 ins_pipe( ialu_reg_mem_alu0 ); 8030%} 8031 8032// Multiply Register Int to Long 8033instruct mulI2L(eADXRegL dst, eAXRegI src, nadxRegI src1, eFlagsReg flags) %{ 8034 // Basic Idea: long = (long)int * (long)int 8035 match(Set dst (MulL (ConvI2L src) (ConvI2L src1))); 8036 effect(DEF dst, USE src, USE src1, KILL flags); 8037 8038 ins_cost(300); 8039 format %{ "IMUL $dst,$src1" %} 8040 8041 ins_encode( long_int_multiply( dst, src1 ) ); 8042 ins_pipe( ialu_reg_reg_alu0 ); 8043%} 8044 8045instruct mulIS_eReg(eADXRegL dst, immL_32bits mask, eFlagsReg flags, eAXRegI src, nadxRegI src1) %{ 8046 // Basic Idea: long = (int & 0xffffffffL) * (int & 0xffffffffL) 8047 match(Set dst (MulL (AndL (ConvI2L src) mask) (AndL (ConvI2L src1) mask))); 8048 effect(KILL flags); 8049 8050 ins_cost(300); 8051 format %{ "MUL $dst,$src1" %} 8052 8053 ins_encode( long_uint_multiply(dst, src1) ); 8054 ins_pipe( ialu_reg_reg_alu0 ); 8055%} 8056 8057// Multiply Register Long 8058instruct mulL_eReg(eADXRegL dst, eRegL src, rRegI tmp, eFlagsReg cr) %{ 8059 match(Set dst (MulL dst src)); 8060 effect(KILL cr, TEMP tmp); 8061 ins_cost(4*100+3*400); 8062// Basic idea: lo(result) = lo(x_lo * y_lo) 8063// hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi) 8064 format %{ "MOV $tmp,$src.lo\n\t" 8065 "IMUL $tmp,EDX\n\t" 8066 "MOV EDX,$src.hi\n\t" 8067 "IMUL EDX,EAX\n\t" 8068 "ADD $tmp,EDX\n\t" 8069 "MUL EDX:EAX,$src.lo\n\t" 8070 "ADD EDX,$tmp" %} 8071 ins_encode( long_multiply( dst, src, tmp ) ); 8072 ins_pipe( pipe_slow ); 8073%} 8074 8075// Multiply Register Long where the left operand's high 32 bits are zero 8076instruct mulL_eReg_lhi0(eADXRegL dst, eRegL src, rRegI tmp, eFlagsReg cr) %{ 8077 predicate(is_operand_hi32_zero(n->in(1))); 8078 match(Set dst (MulL dst src)); 8079 effect(KILL cr, TEMP tmp); 8080 ins_cost(2*100+2*400); 8081// Basic idea: lo(result) = lo(x_lo * y_lo) 8082// hi(result) = hi(x_lo * y_lo) + lo(x_lo * y_hi) where lo(x_hi * y_lo) = 0 because x_hi = 0 8083 format %{ "MOV $tmp,$src.hi\n\t" 8084 "IMUL $tmp,EAX\n\t" 8085 "MUL EDX:EAX,$src.lo\n\t" 8086 "ADD EDX,$tmp" %} 8087 ins_encode %{ 8088 __ movl($tmp$$Register, HIGH_FROM_LOW($src$$Register)); 8089 __ imull($tmp$$Register, rax); 8090 __ mull($src$$Register); 8091 __ addl(rdx, $tmp$$Register); 8092 %} 8093 ins_pipe( pipe_slow ); 8094%} 8095 8096// Multiply Register Long where the right operand's high 32 bits are zero 8097instruct mulL_eReg_rhi0(eADXRegL dst, eRegL src, rRegI tmp, eFlagsReg cr) %{ 8098 predicate(is_operand_hi32_zero(n->in(2))); 8099 match(Set dst (MulL dst src)); 8100 effect(KILL cr, TEMP tmp); 8101 ins_cost(2*100+2*400); 8102// Basic idea: lo(result) = lo(x_lo * y_lo) 8103// hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) where lo(x_lo * y_hi) = 0 because y_hi = 0 8104 format %{ "MOV $tmp,$src.lo\n\t" 8105 "IMUL $tmp,EDX\n\t" 8106 "MUL EDX:EAX,$src.lo\n\t" 8107 "ADD EDX,$tmp" %} 8108 ins_encode %{ 8109 __ movl($tmp$$Register, $src$$Register); 8110 __ imull($tmp$$Register, rdx); 8111 __ mull($src$$Register); 8112 __ addl(rdx, $tmp$$Register); 8113 %} 8114 ins_pipe( pipe_slow ); 8115%} 8116 8117// Multiply Register Long where the left and the right operands' high 32 bits are zero 8118instruct mulL_eReg_hi0(eADXRegL dst, eRegL src, eFlagsReg cr) %{ 8119 predicate(is_operand_hi32_zero(n->in(1)) && is_operand_hi32_zero(n->in(2))); 8120 match(Set dst (MulL dst src)); 8121 effect(KILL cr); 8122 ins_cost(1*400); 8123// Basic idea: lo(result) = lo(x_lo * y_lo) 8124// 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 8125 format %{ "MUL EDX:EAX,$src.lo\n\t" %} 8126 ins_encode %{ 8127 __ mull($src$$Register); 8128 %} 8129 ins_pipe( pipe_slow ); 8130%} 8131 8132// Multiply Register Long by small constant 8133instruct mulL_eReg_con(eADXRegL dst, immL_127 src, rRegI tmp, eFlagsReg cr) %{ 8134 match(Set dst (MulL dst src)); 8135 effect(KILL cr, TEMP tmp); 8136 ins_cost(2*100+2*400); 8137 size(12); 8138// Basic idea: lo(result) = lo(src * EAX) 8139// hi(result) = hi(src * EAX) + lo(src * EDX) 8140 format %{ "IMUL $tmp,EDX,$src\n\t" 8141 "MOV EDX,$src\n\t" 8142 "MUL EDX\t# EDX*EAX -> EDX:EAX\n\t" 8143 "ADD EDX,$tmp" %} 8144 ins_encode( long_multiply_con( dst, src, tmp ) ); 8145 ins_pipe( pipe_slow ); 8146%} 8147 8148// Integer DIV with Register 8149instruct divI_eReg(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{ 8150 match(Set rax (DivI rax div)); 8151 effect(KILL rdx, KILL cr); 8152 size(26); 8153 ins_cost(30*100+10*100); 8154 format %{ "CMP EAX,0x80000000\n\t" 8155 "JNE,s normal\n\t" 8156 "XOR EDX,EDX\n\t" 8157 "CMP ECX,-1\n\t" 8158 "JE,s done\n" 8159 "normal: CDQ\n\t" 8160 "IDIV $div\n\t" 8161 "done:" %} 8162 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8163 ins_encode( cdq_enc, OpcP, RegOpc(div) ); 8164 ins_pipe( ialu_reg_reg_alu0 ); 8165%} 8166 8167// Divide Register Long 8168instruct divL_eReg( eADXRegL dst, eRegL src1, eRegL src2, eFlagsReg cr, eCXRegI cx, eBXRegI bx ) %{ 8169 match(Set dst (DivL src1 src2)); 8170 effect( KILL cr, KILL cx, KILL bx ); 8171 ins_cost(10000); 8172 format %{ "PUSH $src1.hi\n\t" 8173 "PUSH $src1.lo\n\t" 8174 "PUSH $src2.hi\n\t" 8175 "PUSH $src2.lo\n\t" 8176 "CALL SharedRuntime::ldiv\n\t" 8177 "ADD ESP,16" %} 8178 ins_encode( long_div(src1,src2) ); 8179 ins_pipe( pipe_slow ); 8180%} 8181 8182// Integer DIVMOD with Register, both quotient and mod results 8183instruct divModI_eReg_divmod(eAXRegI rax, eDXRegI rdx, eCXRegI div, eFlagsReg cr) %{ 8184 match(DivModI rax div); 8185 effect(KILL cr); 8186 size(26); 8187 ins_cost(30*100+10*100); 8188 format %{ "CMP EAX,0x80000000\n\t" 8189 "JNE,s normal\n\t" 8190 "XOR EDX,EDX\n\t" 8191 "CMP ECX,-1\n\t" 8192 "JE,s done\n" 8193 "normal: CDQ\n\t" 8194 "IDIV $div\n\t" 8195 "done:" %} 8196 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8197 ins_encode( cdq_enc, OpcP, RegOpc(div) ); 8198 ins_pipe( pipe_slow ); 8199%} 8200 8201// Integer MOD with Register 8202instruct modI_eReg(eDXRegI rdx, eAXRegI rax, eCXRegI div, eFlagsReg cr) %{ 8203 match(Set rdx (ModI rax div)); 8204 effect(KILL rax, KILL cr); 8205 8206 size(26); 8207 ins_cost(300); 8208 format %{ "CDQ\n\t" 8209 "IDIV $div" %} 8210 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8211 ins_encode( cdq_enc, OpcP, RegOpc(div) ); 8212 ins_pipe( ialu_reg_reg_alu0 ); 8213%} 8214 8215// Remainder Register Long 8216instruct modL_eReg( eADXRegL dst, eRegL src1, eRegL src2, eFlagsReg cr, eCXRegI cx, eBXRegI bx ) %{ 8217 match(Set dst (ModL src1 src2)); 8218 effect( KILL cr, KILL cx, KILL bx ); 8219 ins_cost(10000); 8220 format %{ "PUSH $src1.hi\n\t" 8221 "PUSH $src1.lo\n\t" 8222 "PUSH $src2.hi\n\t" 8223 "PUSH $src2.lo\n\t" 8224 "CALL SharedRuntime::lrem\n\t" 8225 "ADD ESP,16" %} 8226 ins_encode( long_mod(src1,src2) ); 8227 ins_pipe( pipe_slow ); 8228%} 8229 8230// Divide Register Long (no special case since divisor != -1) 8231instruct divL_eReg_imm32( eADXRegL dst, immL32 imm, rRegI tmp, rRegI tmp2, eFlagsReg cr ) %{ 8232 match(Set dst (DivL dst imm)); 8233 effect( TEMP tmp, TEMP tmp2, KILL cr ); 8234 ins_cost(1000); 8235 format %{ "MOV $tmp,abs($imm) # ldiv EDX:EAX,$imm\n\t" 8236 "XOR $tmp2,$tmp2\n\t" 8237 "CMP $tmp,EDX\n\t" 8238 "JA,s fast\n\t" 8239 "MOV $tmp2,EAX\n\t" 8240 "MOV EAX,EDX\n\t" 8241 "MOV EDX,0\n\t" 8242 "JLE,s pos\n\t" 8243 "LNEG EAX : $tmp2\n\t" 8244 "DIV $tmp # unsigned division\n\t" 8245 "XCHG EAX,$tmp2\n\t" 8246 "DIV $tmp\n\t" 8247 "LNEG $tmp2 : EAX\n\t" 8248 "JMP,s done\n" 8249 "pos:\n\t" 8250 "DIV $tmp\n\t" 8251 "XCHG EAX,$tmp2\n" 8252 "fast:\n\t" 8253 "DIV $tmp\n" 8254 "done:\n\t" 8255 "MOV EDX,$tmp2\n\t" 8256 "NEG EDX:EAX # if $imm < 0" %} 8257 ins_encode %{ 8258 int con = (int)$imm$$constant; 8259 assert(con != 0 && con != -1 && con != min_jint, "wrong divisor"); 8260 int pcon = (con > 0) ? con : -con; 8261 Label Lfast, Lpos, Ldone; 8262 8263 __ movl($tmp$$Register, pcon); 8264 __ xorl($tmp2$$Register,$tmp2$$Register); 8265 __ cmpl($tmp$$Register, HIGH_FROM_LOW($dst$$Register)); 8266 __ jccb(Assembler::above, Lfast); // result fits into 32 bit 8267 8268 __ movl($tmp2$$Register, $dst$$Register); // save 8269 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register)); 8270 __ movl(HIGH_FROM_LOW($dst$$Register),0); // preserve flags 8271 __ jccb(Assembler::lessEqual, Lpos); // result is positive 8272 8273 // Negative dividend. 8274 // convert value to positive to use unsigned division 8275 __ lneg($dst$$Register, $tmp2$$Register); 8276 __ divl($tmp$$Register); 8277 __ xchgl($dst$$Register, $tmp2$$Register); 8278 __ divl($tmp$$Register); 8279 // revert result back to negative 8280 __ lneg($tmp2$$Register, $dst$$Register); 8281 __ jmpb(Ldone); 8282 8283 __ bind(Lpos); 8284 __ divl($tmp$$Register); // Use unsigned division 8285 __ xchgl($dst$$Register, $tmp2$$Register); 8286 // Fallthrow for final divide, tmp2 has 32 bit hi result 8287 8288 __ bind(Lfast); 8289 // fast path: src is positive 8290 __ divl($tmp$$Register); // Use unsigned division 8291 8292 __ bind(Ldone); 8293 __ movl(HIGH_FROM_LOW($dst$$Register),$tmp2$$Register); 8294 if (con < 0) { 8295 __ lneg(HIGH_FROM_LOW($dst$$Register), $dst$$Register); 8296 } 8297 %} 8298 ins_pipe( pipe_slow ); 8299%} 8300 8301// Remainder Register Long (remainder fit into 32 bits) 8302instruct modL_eReg_imm32( eADXRegL dst, immL32 imm, rRegI tmp, rRegI tmp2, eFlagsReg cr ) %{ 8303 match(Set dst (ModL dst imm)); 8304 effect( TEMP tmp, TEMP tmp2, KILL cr ); 8305 ins_cost(1000); 8306 format %{ "MOV $tmp,abs($imm) # lrem EDX:EAX,$imm\n\t" 8307 "CMP $tmp,EDX\n\t" 8308 "JA,s fast\n\t" 8309 "MOV $tmp2,EAX\n\t" 8310 "MOV EAX,EDX\n\t" 8311 "MOV EDX,0\n\t" 8312 "JLE,s pos\n\t" 8313 "LNEG EAX : $tmp2\n\t" 8314 "DIV $tmp # unsigned division\n\t" 8315 "MOV EAX,$tmp2\n\t" 8316 "DIV $tmp\n\t" 8317 "NEG EDX\n\t" 8318 "JMP,s done\n" 8319 "pos:\n\t" 8320 "DIV $tmp\n\t" 8321 "MOV EAX,$tmp2\n" 8322 "fast:\n\t" 8323 "DIV $tmp\n" 8324 "done:\n\t" 8325 "MOV EAX,EDX\n\t" 8326 "SAR EDX,31\n\t" %} 8327 ins_encode %{ 8328 int con = (int)$imm$$constant; 8329 assert(con != 0 && con != -1 && con != min_jint, "wrong divisor"); 8330 int pcon = (con > 0) ? con : -con; 8331 Label Lfast, Lpos, Ldone; 8332 8333 __ movl($tmp$$Register, pcon); 8334 __ cmpl($tmp$$Register, HIGH_FROM_LOW($dst$$Register)); 8335 __ jccb(Assembler::above, Lfast); // src is positive and result fits into 32 bit 8336 8337 __ movl($tmp2$$Register, $dst$$Register); // save 8338 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register)); 8339 __ movl(HIGH_FROM_LOW($dst$$Register),0); // preserve flags 8340 __ jccb(Assembler::lessEqual, Lpos); // result is positive 8341 8342 // Negative dividend. 8343 // convert value to positive to use unsigned division 8344 __ lneg($dst$$Register, $tmp2$$Register); 8345 __ divl($tmp$$Register); 8346 __ movl($dst$$Register, $tmp2$$Register); 8347 __ divl($tmp$$Register); 8348 // revert remainder back to negative 8349 __ negl(HIGH_FROM_LOW($dst$$Register)); 8350 __ jmpb(Ldone); 8351 8352 __ bind(Lpos); 8353 __ divl($tmp$$Register); 8354 __ movl($dst$$Register, $tmp2$$Register); 8355 8356 __ bind(Lfast); 8357 // fast path: src is positive 8358 __ divl($tmp$$Register); 8359 8360 __ bind(Ldone); 8361 __ movl($dst$$Register, HIGH_FROM_LOW($dst$$Register)); 8362 __ sarl(HIGH_FROM_LOW($dst$$Register), 31); // result sign 8363 8364 %} 8365 ins_pipe( pipe_slow ); 8366%} 8367 8368// Integer Shift Instructions 8369// Shift Left by one 8370instruct shlI_eReg_1(rRegI dst, immI1 shift, eFlagsReg cr) %{ 8371 match(Set dst (LShiftI dst shift)); 8372 effect(KILL cr); 8373 8374 size(2); 8375 format %{ "SHL $dst,$shift" %} 8376 opcode(0xD1, 0x4); /* D1 /4 */ 8377 ins_encode( OpcP, RegOpc( dst ) ); 8378 ins_pipe( ialu_reg ); 8379%} 8380 8381// Shift Left by 8-bit immediate 8382instruct salI_eReg_imm(rRegI dst, immI8 shift, eFlagsReg cr) %{ 8383 match(Set dst (LShiftI dst shift)); 8384 effect(KILL cr); 8385 8386 size(3); 8387 format %{ "SHL $dst,$shift" %} 8388 opcode(0xC1, 0x4); /* C1 /4 ib */ 8389 ins_encode( RegOpcImm( dst, shift) ); 8390 ins_pipe( ialu_reg ); 8391%} 8392 8393// Shift Left by variable 8394instruct salI_eReg_CL(rRegI dst, eCXRegI shift, eFlagsReg cr) %{ 8395 match(Set dst (LShiftI dst shift)); 8396 effect(KILL cr); 8397 8398 size(2); 8399 format %{ "SHL $dst,$shift" %} 8400 opcode(0xD3, 0x4); /* D3 /4 */ 8401 ins_encode( OpcP, RegOpc( dst ) ); 8402 ins_pipe( ialu_reg_reg ); 8403%} 8404 8405// Arithmetic shift right by one 8406instruct sarI_eReg_1(rRegI dst, immI1 shift, eFlagsReg cr) %{ 8407 match(Set dst (RShiftI dst shift)); 8408 effect(KILL cr); 8409 8410 size(2); 8411 format %{ "SAR $dst,$shift" %} 8412 opcode(0xD1, 0x7); /* D1 /7 */ 8413 ins_encode( OpcP, RegOpc( dst ) ); 8414 ins_pipe( ialu_reg ); 8415%} 8416 8417// Arithmetic shift right by one 8418instruct sarI_mem_1(memory dst, immI1 shift, eFlagsReg cr) %{ 8419 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8420 effect(KILL cr); 8421 format %{ "SAR $dst,$shift" %} 8422 opcode(0xD1, 0x7); /* D1 /7 */ 8423 ins_encode( OpcP, RMopc_Mem(secondary,dst) ); 8424 ins_pipe( ialu_mem_imm ); 8425%} 8426 8427// Arithmetic Shift Right by 8-bit immediate 8428instruct sarI_eReg_imm(rRegI dst, immI8 shift, eFlagsReg cr) %{ 8429 match(Set dst (RShiftI dst shift)); 8430 effect(KILL cr); 8431 8432 size(3); 8433 format %{ "SAR $dst,$shift" %} 8434 opcode(0xC1, 0x7); /* C1 /7 ib */ 8435 ins_encode( RegOpcImm( dst, shift ) ); 8436 ins_pipe( ialu_mem_imm ); 8437%} 8438 8439// Arithmetic Shift Right by 8-bit immediate 8440instruct sarI_mem_imm(memory dst, immI8 shift, eFlagsReg cr) %{ 8441 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8442 effect(KILL cr); 8443 8444 format %{ "SAR $dst,$shift" %} 8445 opcode(0xC1, 0x7); /* C1 /7 ib */ 8446 ins_encode( OpcP, RMopc_Mem(secondary, dst ), Con8or32( shift ) ); 8447 ins_pipe( ialu_mem_imm ); 8448%} 8449 8450// Arithmetic Shift Right by variable 8451instruct sarI_eReg_CL(rRegI dst, eCXRegI shift, eFlagsReg cr) %{ 8452 match(Set dst (RShiftI dst shift)); 8453 effect(KILL cr); 8454 8455 size(2); 8456 format %{ "SAR $dst,$shift" %} 8457 opcode(0xD3, 0x7); /* D3 /7 */ 8458 ins_encode( OpcP, RegOpc( dst ) ); 8459 ins_pipe( ialu_reg_reg ); 8460%} 8461 8462// Logical shift right by one 8463instruct shrI_eReg_1(rRegI dst, immI1 shift, eFlagsReg cr) %{ 8464 match(Set dst (URShiftI dst shift)); 8465 effect(KILL cr); 8466 8467 size(2); 8468 format %{ "SHR $dst,$shift" %} 8469 opcode(0xD1, 0x5); /* D1 /5 */ 8470 ins_encode( OpcP, RegOpc( dst ) ); 8471 ins_pipe( ialu_reg ); 8472%} 8473 8474// Logical Shift Right by 8-bit immediate 8475instruct shrI_eReg_imm(rRegI dst, immI8 shift, eFlagsReg cr) %{ 8476 match(Set dst (URShiftI dst shift)); 8477 effect(KILL cr); 8478 8479 size(3); 8480 format %{ "SHR $dst,$shift" %} 8481 opcode(0xC1, 0x5); /* C1 /5 ib */ 8482 ins_encode( RegOpcImm( dst, shift) ); 8483 ins_pipe( ialu_reg ); 8484%} 8485 8486 8487// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8488// This idiom is used by the compiler for the i2b bytecode. 8489instruct i2b(rRegI dst, xRegI src, immI_24 twentyfour) %{ 8490 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8491 8492 size(3); 8493 format %{ "MOVSX $dst,$src :8" %} 8494 ins_encode %{ 8495 __ movsbl($dst$$Register, $src$$Register); 8496 %} 8497 ins_pipe(ialu_reg_reg); 8498%} 8499 8500// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8501// This idiom is used by the compiler the i2s bytecode. 8502instruct i2s(rRegI dst, xRegI src, immI_16 sixteen) %{ 8503 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8504 8505 size(3); 8506 format %{ "MOVSX $dst,$src :16" %} 8507 ins_encode %{ 8508 __ movswl($dst$$Register, $src$$Register); 8509 %} 8510 ins_pipe(ialu_reg_reg); 8511%} 8512 8513 8514// Logical Shift Right by variable 8515instruct shrI_eReg_CL(rRegI dst, eCXRegI shift, eFlagsReg cr) %{ 8516 match(Set dst (URShiftI dst shift)); 8517 effect(KILL cr); 8518 8519 size(2); 8520 format %{ "SHR $dst,$shift" %} 8521 opcode(0xD3, 0x5); /* D3 /5 */ 8522 ins_encode( OpcP, RegOpc( dst ) ); 8523 ins_pipe( ialu_reg_reg ); 8524%} 8525 8526 8527//----------Logical Instructions----------------------------------------------- 8528//----------Integer Logical Instructions--------------------------------------- 8529// And Instructions 8530// And Register with Register 8531instruct andI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{ 8532 match(Set dst (AndI dst src)); 8533 effect(KILL cr); 8534 8535 size(2); 8536 format %{ "AND $dst,$src" %} 8537 opcode(0x23); 8538 ins_encode( OpcP, RegReg( dst, src) ); 8539 ins_pipe( ialu_reg_reg ); 8540%} 8541 8542// And Register with Immediate 8543instruct andI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{ 8544 match(Set dst (AndI dst src)); 8545 effect(KILL cr); 8546 8547 format %{ "AND $dst,$src" %} 8548 opcode(0x81,0x04); /* Opcode 81 /4 */ 8549 // ins_encode( RegImm( dst, src) ); 8550 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 8551 ins_pipe( ialu_reg ); 8552%} 8553 8554// And Register with Memory 8555instruct andI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{ 8556 match(Set dst (AndI dst (LoadI src))); 8557 effect(KILL cr); 8558 8559 ins_cost(125); 8560 format %{ "AND $dst,$src" %} 8561 opcode(0x23); 8562 ins_encode( OpcP, RegMem( dst, src) ); 8563 ins_pipe( ialu_reg_mem ); 8564%} 8565 8566// And Memory with Register 8567instruct andI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{ 8568 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8569 effect(KILL cr); 8570 8571 ins_cost(150); 8572 format %{ "AND $dst,$src" %} 8573 opcode(0x21); /* Opcode 21 /r */ 8574 ins_encode( OpcP, RegMem( src, dst ) ); 8575 ins_pipe( ialu_mem_reg ); 8576%} 8577 8578// And Memory with Immediate 8579instruct andI_mem_imm(memory dst, immI src, eFlagsReg cr) %{ 8580 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8581 effect(KILL cr); 8582 8583 ins_cost(125); 8584 format %{ "AND $dst,$src" %} 8585 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8586 // ins_encode( MemImm( dst, src) ); 8587 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) ); 8588 ins_pipe( ialu_mem_imm ); 8589%} 8590 8591// Or Instructions 8592// Or Register with Register 8593instruct orI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{ 8594 match(Set dst (OrI dst src)); 8595 effect(KILL cr); 8596 8597 size(2); 8598 format %{ "OR $dst,$src" %} 8599 opcode(0x0B); 8600 ins_encode( OpcP, RegReg( dst, src) ); 8601 ins_pipe( ialu_reg_reg ); 8602%} 8603 8604instruct orI_eReg_castP2X(rRegI dst, eRegP src, eFlagsReg cr) %{ 8605 match(Set dst (OrI dst (CastP2X src))); 8606 effect(KILL cr); 8607 8608 size(2); 8609 format %{ "OR $dst,$src" %} 8610 opcode(0x0B); 8611 ins_encode( OpcP, RegReg( dst, src) ); 8612 ins_pipe( ialu_reg_reg ); 8613%} 8614 8615 8616// Or Register with Immediate 8617instruct orI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{ 8618 match(Set dst (OrI dst src)); 8619 effect(KILL cr); 8620 8621 format %{ "OR $dst,$src" %} 8622 opcode(0x81,0x01); /* Opcode 81 /1 id */ 8623 // ins_encode( RegImm( dst, src) ); 8624 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 8625 ins_pipe( ialu_reg ); 8626%} 8627 8628// Or Register with Memory 8629instruct orI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{ 8630 match(Set dst (OrI dst (LoadI src))); 8631 effect(KILL cr); 8632 8633 ins_cost(125); 8634 format %{ "OR $dst,$src" %} 8635 opcode(0x0B); 8636 ins_encode( OpcP, RegMem( dst, src) ); 8637 ins_pipe( ialu_reg_mem ); 8638%} 8639 8640// Or Memory with Register 8641instruct orI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{ 8642 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8643 effect(KILL cr); 8644 8645 ins_cost(150); 8646 format %{ "OR $dst,$src" %} 8647 opcode(0x09); /* Opcode 09 /r */ 8648 ins_encode( OpcP, RegMem( src, dst ) ); 8649 ins_pipe( ialu_mem_reg ); 8650%} 8651 8652// Or Memory with Immediate 8653instruct orI_mem_imm(memory dst, immI src, eFlagsReg cr) %{ 8654 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8655 effect(KILL cr); 8656 8657 ins_cost(125); 8658 format %{ "OR $dst,$src" %} 8659 opcode(0x81,0x1); /* Opcode 81 /1 id */ 8660 // ins_encode( MemImm( dst, src) ); 8661 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) ); 8662 ins_pipe( ialu_mem_imm ); 8663%} 8664 8665// ROL/ROR 8666// ROL expand 8667instruct rolI_eReg_imm1(rRegI dst, immI1 shift, eFlagsReg cr) %{ 8668 effect(USE_DEF dst, USE shift, KILL cr); 8669 8670 format %{ "ROL $dst, $shift" %} 8671 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8672 ins_encode( OpcP, RegOpc( dst )); 8673 ins_pipe( ialu_reg ); 8674%} 8675 8676instruct rolI_eReg_imm8(rRegI dst, immI8 shift, eFlagsReg cr) %{ 8677 effect(USE_DEF dst, USE shift, KILL cr); 8678 8679 format %{ "ROL $dst, $shift" %} 8680 opcode(0xC1, 0x0); /*Opcode /C1 /0 */ 8681 ins_encode( RegOpcImm(dst, shift) ); 8682 ins_pipe(ialu_reg); 8683%} 8684 8685instruct rolI_eReg_CL(ncxRegI dst, eCXRegI shift, eFlagsReg cr) %{ 8686 effect(USE_DEF dst, USE shift, KILL cr); 8687 8688 format %{ "ROL $dst, $shift" %} 8689 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8690 ins_encode(OpcP, RegOpc(dst)); 8691 ins_pipe( ialu_reg_reg ); 8692%} 8693// end of ROL expand 8694 8695// ROL 32bit by one once 8696instruct rolI_eReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, eFlagsReg cr) %{ 8697 match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8698 8699 expand %{ 8700 rolI_eReg_imm1(dst, lshift, cr); 8701 %} 8702%} 8703 8704// ROL 32bit var by imm8 once 8705instruct rolI_eReg_i8(rRegI dst, immI8 lshift, immI8 rshift, eFlagsReg cr) %{ 8706 predicate( 0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8707 match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8708 8709 expand %{ 8710 rolI_eReg_imm8(dst, lshift, cr); 8711 %} 8712%} 8713 8714// ROL 32bit var by var once 8715instruct rolI_eReg_Var_C0(ncxRegI dst, eCXRegI shift, immI0 zero, eFlagsReg cr) %{ 8716 match(Set dst ( OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8717 8718 expand %{ 8719 rolI_eReg_CL(dst, shift, cr); 8720 %} 8721%} 8722 8723// ROL 32bit var by var once 8724instruct rolI_eReg_Var_C32(ncxRegI dst, eCXRegI shift, immI_32 c32, eFlagsReg cr) %{ 8725 match(Set dst ( OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8726 8727 expand %{ 8728 rolI_eReg_CL(dst, shift, cr); 8729 %} 8730%} 8731 8732// ROR expand 8733instruct rorI_eReg_imm1(rRegI dst, immI1 shift, eFlagsReg cr) %{ 8734 effect(USE_DEF dst, USE shift, KILL cr); 8735 8736 format %{ "ROR $dst, $shift" %} 8737 opcode(0xD1,0x1); /* Opcode D1 /1 */ 8738 ins_encode( OpcP, RegOpc( dst ) ); 8739 ins_pipe( ialu_reg ); 8740%} 8741 8742instruct rorI_eReg_imm8(rRegI dst, immI8 shift, eFlagsReg cr) %{ 8743 effect (USE_DEF dst, USE shift, KILL cr); 8744 8745 format %{ "ROR $dst, $shift" %} 8746 opcode(0xC1, 0x1); /* Opcode /C1 /1 ib */ 8747 ins_encode( RegOpcImm(dst, shift) ); 8748 ins_pipe( ialu_reg ); 8749%} 8750 8751instruct rorI_eReg_CL(ncxRegI dst, eCXRegI shift, eFlagsReg cr)%{ 8752 effect(USE_DEF dst, USE shift, KILL cr); 8753 8754 format %{ "ROR $dst, $shift" %} 8755 opcode(0xD3, 0x1); /* Opcode D3 /1 */ 8756 ins_encode(OpcP, RegOpc(dst)); 8757 ins_pipe( ialu_reg_reg ); 8758%} 8759// end of ROR expand 8760 8761// ROR right once 8762instruct rorI_eReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, eFlagsReg cr) %{ 8763 match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8764 8765 expand %{ 8766 rorI_eReg_imm1(dst, rshift, cr); 8767 %} 8768%} 8769 8770// ROR 32bit by immI8 once 8771instruct rorI_eReg_i8(rRegI dst, immI8 rshift, immI8 lshift, eFlagsReg cr) %{ 8772 predicate( 0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8773 match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8774 8775 expand %{ 8776 rorI_eReg_imm8(dst, rshift, cr); 8777 %} 8778%} 8779 8780// ROR 32bit var by var once 8781instruct rorI_eReg_Var_C0(ncxRegI dst, eCXRegI shift, immI0 zero, eFlagsReg cr) %{ 8782 match(Set dst ( OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8783 8784 expand %{ 8785 rorI_eReg_CL(dst, shift, cr); 8786 %} 8787%} 8788 8789// ROR 32bit var by var once 8790instruct rorI_eReg_Var_C32(ncxRegI dst, eCXRegI shift, immI_32 c32, eFlagsReg cr) %{ 8791 match(Set dst ( OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8792 8793 expand %{ 8794 rorI_eReg_CL(dst, shift, cr); 8795 %} 8796%} 8797 8798// Xor Instructions 8799// Xor Register with Register 8800instruct xorI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{ 8801 match(Set dst (XorI dst src)); 8802 effect(KILL cr); 8803 8804 size(2); 8805 format %{ "XOR $dst,$src" %} 8806 opcode(0x33); 8807 ins_encode( OpcP, RegReg( dst, src) ); 8808 ins_pipe( ialu_reg_reg ); 8809%} 8810 8811// Xor Register with Immediate -1 8812instruct xorI_eReg_im1(rRegI dst, immI_M1 imm) %{ 8813 match(Set dst (XorI dst imm)); 8814 8815 size(2); 8816 format %{ "NOT $dst" %} 8817 ins_encode %{ 8818 __ notl($dst$$Register); 8819 %} 8820 ins_pipe( ialu_reg ); 8821%} 8822 8823// Xor Register with Immediate 8824instruct xorI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{ 8825 match(Set dst (XorI dst src)); 8826 effect(KILL cr); 8827 8828 format %{ "XOR $dst,$src" %} 8829 opcode(0x81,0x06); /* Opcode 81 /6 id */ 8830 // ins_encode( RegImm( dst, src) ); 8831 ins_encode( OpcSErm( dst, src ), Con8or32( src ) ); 8832 ins_pipe( ialu_reg ); 8833%} 8834 8835// Xor Register with Memory 8836instruct xorI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{ 8837 match(Set dst (XorI dst (LoadI src))); 8838 effect(KILL cr); 8839 8840 ins_cost(125); 8841 format %{ "XOR $dst,$src" %} 8842 opcode(0x33); 8843 ins_encode( OpcP, RegMem(dst, src) ); 8844 ins_pipe( ialu_reg_mem ); 8845%} 8846 8847// Xor Memory with Register 8848instruct xorI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{ 8849 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 8850 effect(KILL cr); 8851 8852 ins_cost(150); 8853 format %{ "XOR $dst,$src" %} 8854 opcode(0x31); /* Opcode 31 /r */ 8855 ins_encode( OpcP, RegMem( src, dst ) ); 8856 ins_pipe( ialu_mem_reg ); 8857%} 8858 8859// Xor Memory with Immediate 8860instruct xorI_mem_imm(memory dst, immI src, eFlagsReg cr) %{ 8861 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 8862 effect(KILL cr); 8863 8864 ins_cost(125); 8865 format %{ "XOR $dst,$src" %} 8866 opcode(0x81,0x6); /* Opcode 81 /6 id */ 8867 ins_encode( OpcSE( src ), RMopc_Mem(secondary, dst ), Con8or32( src ) ); 8868 ins_pipe( ialu_mem_imm ); 8869%} 8870 8871//----------Convert Int to Boolean--------------------------------------------- 8872 8873instruct movI_nocopy(rRegI dst, rRegI src) %{ 8874 effect( DEF dst, USE src ); 8875 format %{ "MOV $dst,$src" %} 8876 ins_encode( enc_Copy( dst, src) ); 8877 ins_pipe( ialu_reg_reg ); 8878%} 8879 8880instruct ci2b( rRegI dst, rRegI src, eFlagsReg cr ) %{ 8881 effect( USE_DEF dst, USE src, KILL cr ); 8882 8883 size(4); 8884 format %{ "NEG $dst\n\t" 8885 "ADC $dst,$src" %} 8886 ins_encode( neg_reg(dst), 8887 OpcRegReg(0x13,dst,src) ); 8888 ins_pipe( ialu_reg_reg_long ); 8889%} 8890 8891instruct convI2B( rRegI dst, rRegI src, eFlagsReg cr ) %{ 8892 match(Set dst (Conv2B src)); 8893 8894 expand %{ 8895 movI_nocopy(dst,src); 8896 ci2b(dst,src,cr); 8897 %} 8898%} 8899 8900instruct movP_nocopy(rRegI dst, eRegP src) %{ 8901 effect( DEF dst, USE src ); 8902 format %{ "MOV $dst,$src" %} 8903 ins_encode( enc_Copy( dst, src) ); 8904 ins_pipe( ialu_reg_reg ); 8905%} 8906 8907instruct cp2b( rRegI dst, eRegP src, eFlagsReg cr ) %{ 8908 effect( USE_DEF dst, USE src, KILL cr ); 8909 format %{ "NEG $dst\n\t" 8910 "ADC $dst,$src" %} 8911 ins_encode( neg_reg(dst), 8912 OpcRegReg(0x13,dst,src) ); 8913 ins_pipe( ialu_reg_reg_long ); 8914%} 8915 8916instruct convP2B( rRegI dst, eRegP src, eFlagsReg cr ) %{ 8917 match(Set dst (Conv2B src)); 8918 8919 expand %{ 8920 movP_nocopy(dst,src); 8921 cp2b(dst,src,cr); 8922 %} 8923%} 8924 8925instruct cmpLTMask( eCXRegI dst, ncxRegI p, ncxRegI q, eFlagsReg cr ) %{ 8926 match(Set dst (CmpLTMask p q)); 8927 effect( KILL cr ); 8928 ins_cost(400); 8929 8930 // SETlt can only use low byte of EAX,EBX, ECX, or EDX as destination 8931 format %{ "XOR $dst,$dst\n\t" 8932 "CMP $p,$q\n\t" 8933 "SETlt $dst\n\t" 8934 "NEG $dst" %} 8935 ins_encode( OpcRegReg(0x33,dst,dst), 8936 OpcRegReg(0x3B,p,q), 8937 setLT_reg(dst), neg_reg(dst) ); 8938 ins_pipe( pipe_slow ); 8939%} 8940 8941instruct cmpLTMask0( rRegI dst, immI0 zero, eFlagsReg cr ) %{ 8942 match(Set dst (CmpLTMask dst zero)); 8943 effect( DEF dst, KILL cr ); 8944 ins_cost(100); 8945 8946 format %{ "SAR $dst,31" %} 8947 opcode(0xC1, 0x7); /* C1 /7 ib */ 8948 ins_encode( RegOpcImm( dst, 0x1F ) ); 8949 ins_pipe( ialu_reg ); 8950%} 8951 8952 8953instruct cadd_cmpLTMask( ncxRegI p, ncxRegI q, ncxRegI y, eCXRegI tmp, eFlagsReg cr ) %{ 8954 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 8955 effect( KILL tmp, KILL cr ); 8956 ins_cost(400); 8957 // annoyingly, $tmp has no edges so you cant ask for it in 8958 // any format or encoding 8959 format %{ "SUB $p,$q\n\t" 8960 "SBB ECX,ECX\n\t" 8961 "AND ECX,$y\n\t" 8962 "ADD $p,ECX" %} 8963 ins_encode( enc_cmpLTP(p,q,y,tmp) ); 8964 ins_pipe( pipe_cmplt ); 8965%} 8966 8967/* If I enable this, I encourage spilling in the inner loop of compress. 8968instruct cadd_cmpLTMask_mem( ncxRegI p, ncxRegI q, memory y, eCXRegI tmp, eFlagsReg cr ) %{ 8969 match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q))); 8970 effect( USE_KILL tmp, KILL cr ); 8971 ins_cost(400); 8972 8973 format %{ "SUB $p,$q\n\t" 8974 "SBB ECX,ECX\n\t" 8975 "AND ECX,$y\n\t" 8976 "ADD $p,ECX" %} 8977 ins_encode( enc_cmpLTP_mem(p,q,y,tmp) ); 8978%} 8979*/ 8980 8981//----------Long Instructions------------------------------------------------ 8982// Add Long Register with Register 8983instruct addL_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 8984 match(Set dst (AddL dst src)); 8985 effect(KILL cr); 8986 ins_cost(200); 8987 format %{ "ADD $dst.lo,$src.lo\n\t" 8988 "ADC $dst.hi,$src.hi" %} 8989 opcode(0x03, 0x13); 8990 ins_encode( RegReg_Lo(dst, src), RegReg_Hi(dst,src) ); 8991 ins_pipe( ialu_reg_reg_long ); 8992%} 8993 8994// Add Long Register with Immediate 8995instruct addL_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{ 8996 match(Set dst (AddL dst src)); 8997 effect(KILL cr); 8998 format %{ "ADD $dst.lo,$src.lo\n\t" 8999 "ADC $dst.hi,$src.hi" %} 9000 opcode(0x81,0x00,0x02); /* Opcode 81 /0, 81 /2 */ 9001 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) ); 9002 ins_pipe( ialu_reg_long ); 9003%} 9004 9005// Add Long Register with Memory 9006instruct addL_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{ 9007 match(Set dst (AddL dst (LoadL mem))); 9008 effect(KILL cr); 9009 ins_cost(125); 9010 format %{ "ADD $dst.lo,$mem\n\t" 9011 "ADC $dst.hi,$mem+4" %} 9012 opcode(0x03, 0x13); 9013 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 9014 ins_pipe( ialu_reg_long_mem ); 9015%} 9016 9017// Subtract Long Register with Register. 9018instruct subL_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 9019 match(Set dst (SubL dst src)); 9020 effect(KILL cr); 9021 ins_cost(200); 9022 format %{ "SUB $dst.lo,$src.lo\n\t" 9023 "SBB $dst.hi,$src.hi" %} 9024 opcode(0x2B, 0x1B); 9025 ins_encode( RegReg_Lo(dst, src), RegReg_Hi(dst,src) ); 9026 ins_pipe( ialu_reg_reg_long ); 9027%} 9028 9029// Subtract Long Register with Immediate 9030instruct subL_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{ 9031 match(Set dst (SubL dst src)); 9032 effect(KILL cr); 9033 format %{ "SUB $dst.lo,$src.lo\n\t" 9034 "SBB $dst.hi,$src.hi" %} 9035 opcode(0x81,0x05,0x03); /* Opcode 81 /5, 81 /3 */ 9036 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) ); 9037 ins_pipe( ialu_reg_long ); 9038%} 9039 9040// Subtract Long Register with Memory 9041instruct subL_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{ 9042 match(Set dst (SubL dst (LoadL mem))); 9043 effect(KILL cr); 9044 ins_cost(125); 9045 format %{ "SUB $dst.lo,$mem\n\t" 9046 "SBB $dst.hi,$mem+4" %} 9047 opcode(0x2B, 0x1B); 9048 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 9049 ins_pipe( ialu_reg_long_mem ); 9050%} 9051 9052instruct negL_eReg(eRegL dst, immL0 zero, eFlagsReg cr) %{ 9053 match(Set dst (SubL zero dst)); 9054 effect(KILL cr); 9055 ins_cost(300); 9056 format %{ "NEG $dst.hi\n\tNEG $dst.lo\n\tSBB $dst.hi,0" %} 9057 ins_encode( neg_long(dst) ); 9058 ins_pipe( ialu_reg_reg_long ); 9059%} 9060 9061// And Long Register with Register 9062instruct andL_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 9063 match(Set dst (AndL dst src)); 9064 effect(KILL cr); 9065 format %{ "AND $dst.lo,$src.lo\n\t" 9066 "AND $dst.hi,$src.hi" %} 9067 opcode(0x23,0x23); 9068 ins_encode( RegReg_Lo( dst, src), RegReg_Hi( dst, src) ); 9069 ins_pipe( ialu_reg_reg_long ); 9070%} 9071 9072// And Long Register with Immediate 9073instruct andL_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{ 9074 match(Set dst (AndL dst src)); 9075 effect(KILL cr); 9076 format %{ "AND $dst.lo,$src.lo\n\t" 9077 "AND $dst.hi,$src.hi" %} 9078 opcode(0x81,0x04,0x04); /* Opcode 81 /4, 81 /4 */ 9079 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) ); 9080 ins_pipe( ialu_reg_long ); 9081%} 9082 9083// And Long Register with Memory 9084instruct andL_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{ 9085 match(Set dst (AndL dst (LoadL mem))); 9086 effect(KILL cr); 9087 ins_cost(125); 9088 format %{ "AND $dst.lo,$mem\n\t" 9089 "AND $dst.hi,$mem+4" %} 9090 opcode(0x23, 0x23); 9091 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 9092 ins_pipe( ialu_reg_long_mem ); 9093%} 9094 9095// Or Long Register with Register 9096instruct orl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 9097 match(Set dst (OrL dst src)); 9098 effect(KILL cr); 9099 format %{ "OR $dst.lo,$src.lo\n\t" 9100 "OR $dst.hi,$src.hi" %} 9101 opcode(0x0B,0x0B); 9102 ins_encode( RegReg_Lo( dst, src), RegReg_Hi( dst, src) ); 9103 ins_pipe( ialu_reg_reg_long ); 9104%} 9105 9106// Or Long Register with Immediate 9107instruct orl_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{ 9108 match(Set dst (OrL dst src)); 9109 effect(KILL cr); 9110 format %{ "OR $dst.lo,$src.lo\n\t" 9111 "OR $dst.hi,$src.hi" %} 9112 opcode(0x81,0x01,0x01); /* Opcode 81 /1, 81 /1 */ 9113 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) ); 9114 ins_pipe( ialu_reg_long ); 9115%} 9116 9117// Or Long Register with Memory 9118instruct orl_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{ 9119 match(Set dst (OrL dst (LoadL mem))); 9120 effect(KILL cr); 9121 ins_cost(125); 9122 format %{ "OR $dst.lo,$mem\n\t" 9123 "OR $dst.hi,$mem+4" %} 9124 opcode(0x0B,0x0B); 9125 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 9126 ins_pipe( ialu_reg_long_mem ); 9127%} 9128 9129// Xor Long Register with Register 9130instruct xorl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{ 9131 match(Set dst (XorL dst src)); 9132 effect(KILL cr); 9133 format %{ "XOR $dst.lo,$src.lo\n\t" 9134 "XOR $dst.hi,$src.hi" %} 9135 opcode(0x33,0x33); 9136 ins_encode( RegReg_Lo( dst, src), RegReg_Hi( dst, src) ); 9137 ins_pipe( ialu_reg_reg_long ); 9138%} 9139 9140// Xor Long Register with Immediate -1 9141instruct xorl_eReg_im1(eRegL dst, immL_M1 imm) %{ 9142 match(Set dst (XorL dst imm)); 9143 format %{ "NOT $dst.lo\n\t" 9144 "NOT $dst.hi" %} 9145 ins_encode %{ 9146 __ notl($dst$$Register); 9147 __ notl(HIGH_FROM_LOW($dst$$Register)); 9148 %} 9149 ins_pipe( ialu_reg_long ); 9150%} 9151 9152// Xor Long Register with Immediate 9153instruct xorl_eReg_imm(eRegL dst, immL src, eFlagsReg cr) %{ 9154 match(Set dst (XorL dst src)); 9155 effect(KILL cr); 9156 format %{ "XOR $dst.lo,$src.lo\n\t" 9157 "XOR $dst.hi,$src.hi" %} 9158 opcode(0x81,0x06,0x06); /* Opcode 81 /6, 81 /6 */ 9159 ins_encode( Long_OpcSErm_Lo( dst, src ), Long_OpcSErm_Hi( dst, src ) ); 9160 ins_pipe( ialu_reg_long ); 9161%} 9162 9163// Xor Long Register with Memory 9164instruct xorl_eReg_mem(eRegL dst, load_long_memory mem, eFlagsReg cr) %{ 9165 match(Set dst (XorL dst (LoadL mem))); 9166 effect(KILL cr); 9167 ins_cost(125); 9168 format %{ "XOR $dst.lo,$mem\n\t" 9169 "XOR $dst.hi,$mem+4" %} 9170 opcode(0x33,0x33); 9171 ins_encode( OpcP, RegMem( dst, mem), OpcS, RegMem_Hi(dst,mem) ); 9172 ins_pipe( ialu_reg_long_mem ); 9173%} 9174 9175// Shift Left Long by 1 9176instruct shlL_eReg_1(eRegL dst, immI_1 cnt, eFlagsReg cr) %{ 9177 predicate(UseNewLongLShift); 9178 match(Set dst (LShiftL dst cnt)); 9179 effect(KILL cr); 9180 ins_cost(100); 9181 format %{ "ADD $dst.lo,$dst.lo\n\t" 9182 "ADC $dst.hi,$dst.hi" %} 9183 ins_encode %{ 9184 __ addl($dst$$Register,$dst$$Register); 9185 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9186 %} 9187 ins_pipe( ialu_reg_long ); 9188%} 9189 9190// Shift Left Long by 2 9191instruct shlL_eReg_2(eRegL dst, immI_2 cnt, eFlagsReg cr) %{ 9192 predicate(UseNewLongLShift); 9193 match(Set dst (LShiftL dst cnt)); 9194 effect(KILL cr); 9195 ins_cost(100); 9196 format %{ "ADD $dst.lo,$dst.lo\n\t" 9197 "ADC $dst.hi,$dst.hi\n\t" 9198 "ADD $dst.lo,$dst.lo\n\t" 9199 "ADC $dst.hi,$dst.hi" %} 9200 ins_encode %{ 9201 __ addl($dst$$Register,$dst$$Register); 9202 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9203 __ addl($dst$$Register,$dst$$Register); 9204 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9205 %} 9206 ins_pipe( ialu_reg_long ); 9207%} 9208 9209// Shift Left Long by 3 9210instruct shlL_eReg_3(eRegL dst, immI_3 cnt, eFlagsReg cr) %{ 9211 predicate(UseNewLongLShift); 9212 match(Set dst (LShiftL dst cnt)); 9213 effect(KILL cr); 9214 ins_cost(100); 9215 format %{ "ADD $dst.lo,$dst.lo\n\t" 9216 "ADC $dst.hi,$dst.hi\n\t" 9217 "ADD $dst.lo,$dst.lo\n\t" 9218 "ADC $dst.hi,$dst.hi\n\t" 9219 "ADD $dst.lo,$dst.lo\n\t" 9220 "ADC $dst.hi,$dst.hi" %} 9221 ins_encode %{ 9222 __ addl($dst$$Register,$dst$$Register); 9223 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9224 __ addl($dst$$Register,$dst$$Register); 9225 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9226 __ addl($dst$$Register,$dst$$Register); 9227 __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register)); 9228 %} 9229 ins_pipe( ialu_reg_long ); 9230%} 9231 9232// Shift Left Long by 1-31 9233instruct shlL_eReg_1_31(eRegL dst, immI_1_31 cnt, eFlagsReg cr) %{ 9234 match(Set dst (LShiftL dst cnt)); 9235 effect(KILL cr); 9236 ins_cost(200); 9237 format %{ "SHLD $dst.hi,$dst.lo,$cnt\n\t" 9238 "SHL $dst.lo,$cnt" %} 9239 opcode(0xC1, 0x4, 0xA4); /* 0F/A4, then C1 /4 ib */ 9240 ins_encode( move_long_small_shift(dst,cnt) ); 9241 ins_pipe( ialu_reg_long ); 9242%} 9243 9244// Shift Left Long by 32-63 9245instruct shlL_eReg_32_63(eRegL dst, immI_32_63 cnt, eFlagsReg cr) %{ 9246 match(Set dst (LShiftL dst cnt)); 9247 effect(KILL cr); 9248 ins_cost(300); 9249 format %{ "MOV $dst.hi,$dst.lo\n" 9250 "\tSHL $dst.hi,$cnt-32\n" 9251 "\tXOR $dst.lo,$dst.lo" %} 9252 opcode(0xC1, 0x4); /* C1 /4 ib */ 9253 ins_encode( move_long_big_shift_clr(dst,cnt) ); 9254 ins_pipe( ialu_reg_long ); 9255%} 9256 9257// Shift Left Long by variable 9258instruct salL_eReg_CL(eRegL dst, eCXRegI shift, eFlagsReg cr) %{ 9259 match(Set dst (LShiftL dst shift)); 9260 effect(KILL cr); 9261 ins_cost(500+200); 9262 size(17); 9263 format %{ "TEST $shift,32\n\t" 9264 "JEQ,s small\n\t" 9265 "MOV $dst.hi,$dst.lo\n\t" 9266 "XOR $dst.lo,$dst.lo\n" 9267 "small:\tSHLD $dst.hi,$dst.lo,$shift\n\t" 9268 "SHL $dst.lo,$shift" %} 9269 ins_encode( shift_left_long( dst, shift ) ); 9270 ins_pipe( pipe_slow ); 9271%} 9272 9273// Shift Right Long by 1-31 9274instruct shrL_eReg_1_31(eRegL dst, immI_1_31 cnt, eFlagsReg cr) %{ 9275 match(Set dst (URShiftL dst cnt)); 9276 effect(KILL cr); 9277 ins_cost(200); 9278 format %{ "SHRD $dst.lo,$dst.hi,$cnt\n\t" 9279 "SHR $dst.hi,$cnt" %} 9280 opcode(0xC1, 0x5, 0xAC); /* 0F/AC, then C1 /5 ib */ 9281 ins_encode( move_long_small_shift(dst,cnt) ); 9282 ins_pipe( ialu_reg_long ); 9283%} 9284 9285// Shift Right Long by 32-63 9286instruct shrL_eReg_32_63(eRegL dst, immI_32_63 cnt, eFlagsReg cr) %{ 9287 match(Set dst (URShiftL dst cnt)); 9288 effect(KILL cr); 9289 ins_cost(300); 9290 format %{ "MOV $dst.lo,$dst.hi\n" 9291 "\tSHR $dst.lo,$cnt-32\n" 9292 "\tXOR $dst.hi,$dst.hi" %} 9293 opcode(0xC1, 0x5); /* C1 /5 ib */ 9294 ins_encode( move_long_big_shift_clr(dst,cnt) ); 9295 ins_pipe( ialu_reg_long ); 9296%} 9297 9298// Shift Right Long by variable 9299instruct shrL_eReg_CL(eRegL dst, eCXRegI shift, eFlagsReg cr) %{ 9300 match(Set dst (URShiftL dst shift)); 9301 effect(KILL cr); 9302 ins_cost(600); 9303 size(17); 9304 format %{ "TEST $shift,32\n\t" 9305 "JEQ,s small\n\t" 9306 "MOV $dst.lo,$dst.hi\n\t" 9307 "XOR $dst.hi,$dst.hi\n" 9308 "small:\tSHRD $dst.lo,$dst.hi,$shift\n\t" 9309 "SHR $dst.hi,$shift" %} 9310 ins_encode( shift_right_long( dst, shift ) ); 9311 ins_pipe( pipe_slow ); 9312%} 9313 9314// Shift Right Long by 1-31 9315instruct sarL_eReg_1_31(eRegL dst, immI_1_31 cnt, eFlagsReg cr) %{ 9316 match(Set dst (RShiftL dst cnt)); 9317 effect(KILL cr); 9318 ins_cost(200); 9319 format %{ "SHRD $dst.lo,$dst.hi,$cnt\n\t" 9320 "SAR $dst.hi,$cnt" %} 9321 opcode(0xC1, 0x7, 0xAC); /* 0F/AC, then C1 /7 ib */ 9322 ins_encode( move_long_small_shift(dst,cnt) ); 9323 ins_pipe( ialu_reg_long ); 9324%} 9325 9326// Shift Right Long by 32-63 9327instruct sarL_eReg_32_63( eRegL dst, immI_32_63 cnt, eFlagsReg cr) %{ 9328 match(Set dst (RShiftL dst cnt)); 9329 effect(KILL cr); 9330 ins_cost(300); 9331 format %{ "MOV $dst.lo,$dst.hi\n" 9332 "\tSAR $dst.lo,$cnt-32\n" 9333 "\tSAR $dst.hi,31" %} 9334 opcode(0xC1, 0x7); /* C1 /7 ib */ 9335 ins_encode( move_long_big_shift_sign(dst,cnt) ); 9336 ins_pipe( ialu_reg_long ); 9337%} 9338 9339// Shift Right arithmetic Long by variable 9340instruct sarL_eReg_CL(eRegL dst, eCXRegI shift, eFlagsReg cr) %{ 9341 match(Set dst (RShiftL dst shift)); 9342 effect(KILL cr); 9343 ins_cost(600); 9344 size(18); 9345 format %{ "TEST $shift,32\n\t" 9346 "JEQ,s small\n\t" 9347 "MOV $dst.lo,$dst.hi\n\t" 9348 "SAR $dst.hi,31\n" 9349 "small:\tSHRD $dst.lo,$dst.hi,$shift\n\t" 9350 "SAR $dst.hi,$shift" %} 9351 ins_encode( shift_right_arith_long( dst, shift ) ); 9352 ins_pipe( pipe_slow ); 9353%} 9354 9355 9356//----------Double Instructions------------------------------------------------ 9357// Double Math 9358 9359// Compare & branch 9360 9361// P6 version of float compare, sets condition codes in EFLAGS 9362instruct cmpDPR_cc_P6(eFlagsRegU cr, regDPR src1, regDPR src2, eAXRegI rax) %{ 9363 predicate(VM_Version::supports_cmov() && UseSSE <=1); 9364 match(Set cr (CmpD src1 src2)); 9365 effect(KILL rax); 9366 ins_cost(150); 9367 format %{ "FLD $src1\n\t" 9368 "FUCOMIP ST,$src2 // P6 instruction\n\t" 9369 "JNP exit\n\t" 9370 "MOV ah,1 // saw a NaN, set CF\n\t" 9371 "SAHF\n" 9372 "exit:\tNOP // avoid branch to branch" %} 9373 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */ 9374 ins_encode( Push_Reg_DPR(src1), 9375 OpcP, RegOpc(src2), 9376 cmpF_P6_fixup ); 9377 ins_pipe( pipe_slow ); 9378%} 9379 9380instruct cmpDPR_cc_P6CF(eFlagsRegUCF cr, regDPR src1, regDPR src2) %{ 9381 predicate(VM_Version::supports_cmov() && UseSSE <=1); 9382 match(Set cr (CmpD src1 src2)); 9383 ins_cost(150); 9384 format %{ "FLD $src1\n\t" 9385 "FUCOMIP ST,$src2 // P6 instruction" %} 9386 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */ 9387 ins_encode( Push_Reg_DPR(src1), 9388 OpcP, RegOpc(src2)); 9389 ins_pipe( pipe_slow ); 9390%} 9391 9392// Compare & branch 9393instruct cmpDPR_cc(eFlagsRegU cr, regDPR src1, regDPR src2, eAXRegI rax) %{ 9394 predicate(UseSSE<=1); 9395 match(Set cr (CmpD src1 src2)); 9396 effect(KILL rax); 9397 ins_cost(200); 9398 format %{ "FLD $src1\n\t" 9399 "FCOMp $src2\n\t" 9400 "FNSTSW AX\n\t" 9401 "TEST AX,0x400\n\t" 9402 "JZ,s flags\n\t" 9403 "MOV AH,1\t# unordered treat as LT\n" 9404 "flags:\tSAHF" %} 9405 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */ 9406 ins_encode( Push_Reg_DPR(src1), 9407 OpcP, RegOpc(src2), 9408 fpu_flags); 9409 ins_pipe( pipe_slow ); 9410%} 9411 9412// Compare vs zero into -1,0,1 9413instruct cmpDPR_0(rRegI dst, regDPR src1, immDPR0 zero, eAXRegI rax, eFlagsReg cr) %{ 9414 predicate(UseSSE<=1); 9415 match(Set dst (CmpD3 src1 zero)); 9416 effect(KILL cr, KILL rax); 9417 ins_cost(280); 9418 format %{ "FTSTD $dst,$src1" %} 9419 opcode(0xE4, 0xD9); 9420 ins_encode( Push_Reg_DPR(src1), 9421 OpcS, OpcP, PopFPU, 9422 CmpF_Result(dst)); 9423 ins_pipe( pipe_slow ); 9424%} 9425 9426// Compare into -1,0,1 9427instruct cmpDPR_reg(rRegI dst, regDPR src1, regDPR src2, eAXRegI rax, eFlagsReg cr) %{ 9428 predicate(UseSSE<=1); 9429 match(Set dst (CmpD3 src1 src2)); 9430 effect(KILL cr, KILL rax); 9431 ins_cost(300); 9432 format %{ "FCMPD $dst,$src1,$src2" %} 9433 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */ 9434 ins_encode( Push_Reg_DPR(src1), 9435 OpcP, RegOpc(src2), 9436 CmpF_Result(dst)); 9437 ins_pipe( pipe_slow ); 9438%} 9439 9440// float compare and set condition codes in EFLAGS by XMM regs 9441instruct cmpD_cc(eFlagsRegU cr, regD src1, regD src2) %{ 9442 predicate(UseSSE>=2); 9443 match(Set cr (CmpD src1 src2)); 9444 ins_cost(145); 9445 format %{ "UCOMISD $src1,$src2\n\t" 9446 "JNP,s exit\n\t" 9447 "PUSHF\t# saw NaN, set CF\n\t" 9448 "AND [rsp], #0xffffff2b\n\t" 9449 "POPF\n" 9450 "exit:" %} 9451 ins_encode %{ 9452 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9453 emit_cmpfp_fixup(_masm); 9454 %} 9455 ins_pipe( pipe_slow ); 9456%} 9457 9458instruct cmpD_ccCF(eFlagsRegUCF cr, regD src1, regD src2) %{ 9459 predicate(UseSSE>=2); 9460 match(Set cr (CmpD src1 src2)); 9461 ins_cost(100); 9462 format %{ "UCOMISD $src1,$src2" %} 9463 ins_encode %{ 9464 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9465 %} 9466 ins_pipe( pipe_slow ); 9467%} 9468 9469// float compare and set condition codes in EFLAGS by XMM regs 9470instruct cmpD_ccmem(eFlagsRegU cr, regD src1, memory src2) %{ 9471 predicate(UseSSE>=2); 9472 match(Set cr (CmpD src1 (LoadD src2))); 9473 ins_cost(145); 9474 format %{ "UCOMISD $src1,$src2\n\t" 9475 "JNP,s exit\n\t" 9476 "PUSHF\t# saw NaN, set CF\n\t" 9477 "AND [rsp], #0xffffff2b\n\t" 9478 "POPF\n" 9479 "exit:" %} 9480 ins_encode %{ 9481 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9482 emit_cmpfp_fixup(_masm); 9483 %} 9484 ins_pipe( pipe_slow ); 9485%} 9486 9487instruct cmpD_ccmemCF(eFlagsRegUCF cr, regD src1, memory src2) %{ 9488 predicate(UseSSE>=2); 9489 match(Set cr (CmpD src1 (LoadD src2))); 9490 ins_cost(100); 9491 format %{ "UCOMISD $src1,$src2" %} 9492 ins_encode %{ 9493 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9494 %} 9495 ins_pipe( pipe_slow ); 9496%} 9497 9498// Compare into -1,0,1 in XMM 9499instruct cmpD_reg(xRegI dst, regD src1, regD src2, eFlagsReg cr) %{ 9500 predicate(UseSSE>=2); 9501 match(Set dst (CmpD3 src1 src2)); 9502 effect(KILL cr); 9503 ins_cost(255); 9504 format %{ "UCOMISD $src1, $src2\n\t" 9505 "MOV $dst, #-1\n\t" 9506 "JP,s done\n\t" 9507 "JB,s done\n\t" 9508 "SETNE $dst\n\t" 9509 "MOVZB $dst, $dst\n" 9510 "done:" %} 9511 ins_encode %{ 9512 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9513 emit_cmpfp3(_masm, $dst$$Register); 9514 %} 9515 ins_pipe( pipe_slow ); 9516%} 9517 9518// Compare into -1,0,1 in XMM and memory 9519instruct cmpD_regmem(xRegI dst, regD src1, memory src2, eFlagsReg cr) %{ 9520 predicate(UseSSE>=2); 9521 match(Set dst (CmpD3 src1 (LoadD src2))); 9522 effect(KILL cr); 9523 ins_cost(275); 9524 format %{ "UCOMISD $src1, $src2\n\t" 9525 "MOV $dst, #-1\n\t" 9526 "JP,s done\n\t" 9527 "JB,s done\n\t" 9528 "SETNE $dst\n\t" 9529 "MOVZB $dst, $dst\n" 9530 "done:" %} 9531 ins_encode %{ 9532 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9533 emit_cmpfp3(_masm, $dst$$Register); 9534 %} 9535 ins_pipe( pipe_slow ); 9536%} 9537 9538 9539instruct subDPR_reg(regDPR dst, regDPR src) %{ 9540 predicate (UseSSE <=1); 9541 match(Set dst (SubD dst src)); 9542 9543 format %{ "FLD $src\n\t" 9544 "DSUBp $dst,ST" %} 9545 opcode(0xDE, 0x5); /* DE E8+i or DE /5 */ 9546 ins_cost(150); 9547 ins_encode( Push_Reg_DPR(src), 9548 OpcP, RegOpc(dst) ); 9549 ins_pipe( fpu_reg_reg ); 9550%} 9551 9552instruct subDPR_reg_round(stackSlotD dst, regDPR src1, regDPR src2) %{ 9553 predicate (UseSSE <=1); 9554 match(Set dst (RoundDouble (SubD src1 src2))); 9555 ins_cost(250); 9556 9557 format %{ "FLD $src2\n\t" 9558 "DSUB ST,$src1\n\t" 9559 "FSTP_D $dst\t# D-round" %} 9560 opcode(0xD8, 0x5); 9561 ins_encode( Push_Reg_DPR(src2), 9562 OpcP, RegOpc(src1), Pop_Mem_DPR(dst) ); 9563 ins_pipe( fpu_mem_reg_reg ); 9564%} 9565 9566 9567instruct subDPR_reg_mem(regDPR dst, memory src) %{ 9568 predicate (UseSSE <=1); 9569 match(Set dst (SubD dst (LoadD src))); 9570 ins_cost(150); 9571 9572 format %{ "FLD $src\n\t" 9573 "DSUBp $dst,ST" %} 9574 opcode(0xDE, 0x5, 0xDD); /* DE C0+i */ /* LoadD DD /0 */ 9575 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src), 9576 OpcP, RegOpc(dst) ); 9577 ins_pipe( fpu_reg_mem ); 9578%} 9579 9580instruct absDPR_reg(regDPR1 dst, regDPR1 src) %{ 9581 predicate (UseSSE<=1); 9582 match(Set dst (AbsD src)); 9583 ins_cost(100); 9584 format %{ "FABS" %} 9585 opcode(0xE1, 0xD9); 9586 ins_encode( OpcS, OpcP ); 9587 ins_pipe( fpu_reg_reg ); 9588%} 9589 9590instruct negDPR_reg(regDPR1 dst, regDPR1 src) %{ 9591 predicate(UseSSE<=1); 9592 match(Set dst (NegD src)); 9593 ins_cost(100); 9594 format %{ "FCHS" %} 9595 opcode(0xE0, 0xD9); 9596 ins_encode( OpcS, OpcP ); 9597 ins_pipe( fpu_reg_reg ); 9598%} 9599 9600instruct addDPR_reg(regDPR dst, regDPR src) %{ 9601 predicate(UseSSE<=1); 9602 match(Set dst (AddD dst src)); 9603 format %{ "FLD $src\n\t" 9604 "DADD $dst,ST" %} 9605 size(4); 9606 ins_cost(150); 9607 opcode(0xDE, 0x0); /* DE C0+i or DE /0*/ 9608 ins_encode( Push_Reg_DPR(src), 9609 OpcP, RegOpc(dst) ); 9610 ins_pipe( fpu_reg_reg ); 9611%} 9612 9613 9614instruct addDPR_reg_round(stackSlotD dst, regDPR src1, regDPR src2) %{ 9615 predicate(UseSSE<=1); 9616 match(Set dst (RoundDouble (AddD src1 src2))); 9617 ins_cost(250); 9618 9619 format %{ "FLD $src2\n\t" 9620 "DADD ST,$src1\n\t" 9621 "FSTP_D $dst\t# D-round" %} 9622 opcode(0xD8, 0x0); /* D8 C0+i or D8 /0*/ 9623 ins_encode( Push_Reg_DPR(src2), 9624 OpcP, RegOpc(src1), Pop_Mem_DPR(dst) ); 9625 ins_pipe( fpu_mem_reg_reg ); 9626%} 9627 9628 9629instruct addDPR_reg_mem(regDPR dst, memory src) %{ 9630 predicate(UseSSE<=1); 9631 match(Set dst (AddD dst (LoadD src))); 9632 ins_cost(150); 9633 9634 format %{ "FLD $src\n\t" 9635 "DADDp $dst,ST" %} 9636 opcode(0xDE, 0x0, 0xDD); /* DE C0+i */ /* LoadD DD /0 */ 9637 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src), 9638 OpcP, RegOpc(dst) ); 9639 ins_pipe( fpu_reg_mem ); 9640%} 9641 9642// add-to-memory 9643instruct addDPR_mem_reg(memory dst, regDPR src) %{ 9644 predicate(UseSSE<=1); 9645 match(Set dst (StoreD dst (RoundDouble (AddD (LoadD dst) src)))); 9646 ins_cost(150); 9647 9648 format %{ "FLD_D $dst\n\t" 9649 "DADD ST,$src\n\t" 9650 "FST_D $dst" %} 9651 opcode(0xDD, 0x0); 9652 ins_encode( Opcode(0xDD), RMopc_Mem(0x00,dst), 9653 Opcode(0xD8), RegOpc(src), 9654 set_instruction_start, 9655 Opcode(0xDD), RMopc_Mem(0x03,dst) ); 9656 ins_pipe( fpu_reg_mem ); 9657%} 9658 9659instruct addDPR_reg_imm1(regDPR dst, immDPR1 con) %{ 9660 predicate(UseSSE<=1); 9661 match(Set dst (AddD dst con)); 9662 ins_cost(125); 9663 format %{ "FLD1\n\t" 9664 "DADDp $dst,ST" %} 9665 ins_encode %{ 9666 __ fld1(); 9667 __ faddp($dst$$reg); 9668 %} 9669 ins_pipe(fpu_reg); 9670%} 9671 9672instruct addDPR_reg_imm(regDPR dst, immDPR con) %{ 9673 predicate(UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 ); 9674 match(Set dst (AddD dst con)); 9675 ins_cost(200); 9676 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t" 9677 "DADDp $dst,ST" %} 9678 ins_encode %{ 9679 __ fld_d($constantaddress($con)); 9680 __ faddp($dst$$reg); 9681 %} 9682 ins_pipe(fpu_reg_mem); 9683%} 9684 9685instruct addDPR_reg_imm_round(stackSlotD dst, regDPR src, immDPR con) %{ 9686 predicate(UseSSE<=1 && _kids[0]->_kids[1]->_leaf->getd() != 0.0 && _kids[0]->_kids[1]->_leaf->getd() != 1.0 ); 9687 match(Set dst (RoundDouble (AddD src con))); 9688 ins_cost(200); 9689 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t" 9690 "DADD ST,$src\n\t" 9691 "FSTP_D $dst\t# D-round" %} 9692 ins_encode %{ 9693 __ fld_d($constantaddress($con)); 9694 __ fadd($src$$reg); 9695 __ fstp_d(Address(rsp, $dst$$disp)); 9696 %} 9697 ins_pipe(fpu_mem_reg_con); 9698%} 9699 9700instruct mulDPR_reg(regDPR dst, regDPR src) %{ 9701 predicate(UseSSE<=1); 9702 match(Set dst (MulD dst src)); 9703 format %{ "FLD $src\n\t" 9704 "DMULp $dst,ST" %} 9705 opcode(0xDE, 0x1); /* DE C8+i or DE /1*/ 9706 ins_cost(150); 9707 ins_encode( Push_Reg_DPR(src), 9708 OpcP, RegOpc(dst) ); 9709 ins_pipe( fpu_reg_reg ); 9710%} 9711 9712// Strict FP instruction biases argument before multiply then 9713// biases result to avoid double rounding of subnormals. 9714// 9715// scale arg1 by multiplying arg1 by 2^(-15360) 9716// load arg2 9717// multiply scaled arg1 by arg2 9718// rescale product by 2^(15360) 9719// 9720instruct strictfp_mulDPR_reg(regDPR1 dst, regnotDPR1 src) %{ 9721 predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() ); 9722 match(Set dst (MulD dst src)); 9723 ins_cost(1); // Select this instruction for all strict FP double multiplies 9724 9725 format %{ "FLD StubRoutines::_fpu_subnormal_bias1\n\t" 9726 "DMULp $dst,ST\n\t" 9727 "FLD $src\n\t" 9728 "DMULp $dst,ST\n\t" 9729 "FLD StubRoutines::_fpu_subnormal_bias2\n\t" 9730 "DMULp $dst,ST\n\t" %} 9731 opcode(0xDE, 0x1); /* DE C8+i or DE /1*/ 9732 ins_encode( strictfp_bias1(dst), 9733 Push_Reg_DPR(src), 9734 OpcP, RegOpc(dst), 9735 strictfp_bias2(dst) ); 9736 ins_pipe( fpu_reg_reg ); 9737%} 9738 9739instruct mulDPR_reg_imm(regDPR dst, immDPR con) %{ 9740 predicate( UseSSE<=1 && _kids[1]->_leaf->getd() != 0.0 && _kids[1]->_leaf->getd() != 1.0 ); 9741 match(Set dst (MulD dst con)); 9742 ins_cost(200); 9743 format %{ "FLD_D [$constantaddress]\t# load from constant table: double=$con\n\t" 9744 "DMULp $dst,ST" %} 9745 ins_encode %{ 9746 __ fld_d($constantaddress($con)); 9747 __ fmulp($dst$$reg); 9748 %} 9749 ins_pipe(fpu_reg_mem); 9750%} 9751 9752 9753instruct mulDPR_reg_mem(regDPR dst, memory src) %{ 9754 predicate( UseSSE<=1 ); 9755 match(Set dst (MulD dst (LoadD src))); 9756 ins_cost(200); 9757 format %{ "FLD_D $src\n\t" 9758 "DMULp $dst,ST" %} 9759 opcode(0xDE, 0x1, 0xDD); /* DE C8+i or DE /1*/ /* LoadD DD /0 */ 9760 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src), 9761 OpcP, RegOpc(dst) ); 9762 ins_pipe( fpu_reg_mem ); 9763%} 9764 9765// 9766// Cisc-alternate to reg-reg multiply 9767instruct mulDPR_reg_mem_cisc(regDPR dst, regDPR src, memory mem) %{ 9768 predicate( UseSSE<=1 ); 9769 match(Set dst (MulD src (LoadD mem))); 9770 ins_cost(250); 9771 format %{ "FLD_D $mem\n\t" 9772 "DMUL ST,$src\n\t" 9773 "FSTP_D $dst" %} 9774 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i */ /* LoadD D9 /0 */ 9775 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,mem), 9776 OpcReg_FPR(src), 9777 Pop_Reg_DPR(dst) ); 9778 ins_pipe( fpu_reg_reg_mem ); 9779%} 9780 9781 9782// MACRO3 -- addDPR a mulDPR 9783// This instruction is a '2-address' instruction in that the result goes 9784// back to src2. This eliminates a move from the macro; possibly the 9785// register allocator will have to add it back (and maybe not). 9786instruct addDPR_mulDPR_reg(regDPR src2, regDPR src1, regDPR src0) %{ 9787 predicate( UseSSE<=1 ); 9788 match(Set src2 (AddD (MulD src0 src1) src2)); 9789 format %{ "FLD $src0\t# ===MACRO3d===\n\t" 9790 "DMUL ST,$src1\n\t" 9791 "DADDp $src2,ST" %} 9792 ins_cost(250); 9793 opcode(0xDD); /* LoadD DD /0 */ 9794 ins_encode( Push_Reg_FPR(src0), 9795 FMul_ST_reg(src1), 9796 FAddP_reg_ST(src2) ); 9797 ins_pipe( fpu_reg_reg_reg ); 9798%} 9799 9800 9801// MACRO3 -- subDPR a mulDPR 9802instruct subDPR_mulDPR_reg(regDPR src2, regDPR src1, regDPR src0) %{ 9803 predicate( UseSSE<=1 ); 9804 match(Set src2 (SubD (MulD src0 src1) src2)); 9805 format %{ "FLD $src0\t# ===MACRO3d===\n\t" 9806 "DMUL ST,$src1\n\t" 9807 "DSUBRp $src2,ST" %} 9808 ins_cost(250); 9809 ins_encode( Push_Reg_FPR(src0), 9810 FMul_ST_reg(src1), 9811 Opcode(0xDE), Opc_plus(0xE0,src2)); 9812 ins_pipe( fpu_reg_reg_reg ); 9813%} 9814 9815 9816instruct divDPR_reg(regDPR dst, regDPR src) %{ 9817 predicate( UseSSE<=1 ); 9818 match(Set dst (DivD dst src)); 9819 9820 format %{ "FLD $src\n\t" 9821 "FDIVp $dst,ST" %} 9822 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/ 9823 ins_cost(150); 9824 ins_encode( Push_Reg_DPR(src), 9825 OpcP, RegOpc(dst) ); 9826 ins_pipe( fpu_reg_reg ); 9827%} 9828 9829// Strict FP instruction biases argument before division then 9830// biases result, to avoid double rounding of subnormals. 9831// 9832// scale dividend by multiplying dividend by 2^(-15360) 9833// load divisor 9834// divide scaled dividend by divisor 9835// rescale quotient by 2^(15360) 9836// 9837instruct strictfp_divDPR_reg(regDPR1 dst, regnotDPR1 src) %{ 9838 predicate (UseSSE<=1); 9839 match(Set dst (DivD dst src)); 9840 predicate( UseSSE<=1 && Compile::current()->has_method() && Compile::current()->method()->is_strict() ); 9841 ins_cost(01); 9842 9843 format %{ "FLD StubRoutines::_fpu_subnormal_bias1\n\t" 9844 "DMULp $dst,ST\n\t" 9845 "FLD $src\n\t" 9846 "FDIVp $dst,ST\n\t" 9847 "FLD StubRoutines::_fpu_subnormal_bias2\n\t" 9848 "DMULp $dst,ST\n\t" %} 9849 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/ 9850 ins_encode( strictfp_bias1(dst), 9851 Push_Reg_DPR(src), 9852 OpcP, RegOpc(dst), 9853 strictfp_bias2(dst) ); 9854 ins_pipe( fpu_reg_reg ); 9855%} 9856 9857instruct divDPR_reg_round(stackSlotD dst, regDPR src1, regDPR src2) %{ 9858 predicate( UseSSE<=1 && !(Compile::current()->has_method() && Compile::current()->method()->is_strict()) ); 9859 match(Set dst (RoundDouble (DivD src1 src2))); 9860 9861 format %{ "FLD $src1\n\t" 9862 "FDIV ST,$src2\n\t" 9863 "FSTP_D $dst\t# D-round" %} 9864 opcode(0xD8, 0x6); /* D8 F0+i or D8 /6 */ 9865 ins_encode( Push_Reg_DPR(src1), 9866 OpcP, RegOpc(src2), Pop_Mem_DPR(dst) ); 9867 ins_pipe( fpu_mem_reg_reg ); 9868%} 9869 9870 9871instruct modDPR_reg(regDPR dst, regDPR src, eAXRegI rax, eFlagsReg cr) %{ 9872 predicate(UseSSE<=1); 9873 match(Set dst (ModD dst src)); 9874 effect(KILL rax, KILL cr); // emitModDPR() uses EAX and EFLAGS 9875 9876 format %{ "DMOD $dst,$src" %} 9877 ins_cost(250); 9878 ins_encode(Push_Reg_Mod_DPR(dst, src), 9879 emitModDPR(), 9880 Push_Result_Mod_DPR(src), 9881 Pop_Reg_DPR(dst)); 9882 ins_pipe( pipe_slow ); 9883%} 9884 9885instruct modD_reg(regD dst, regD src0, regD src1, eAXRegI rax, eFlagsReg cr) %{ 9886 predicate(UseSSE>=2); 9887 match(Set dst (ModD src0 src1)); 9888 effect(KILL rax, KILL cr); 9889 9890 format %{ "SUB ESP,8\t # DMOD\n" 9891 "\tMOVSD [ESP+0],$src1\n" 9892 "\tFLD_D [ESP+0]\n" 9893 "\tMOVSD [ESP+0],$src0\n" 9894 "\tFLD_D [ESP+0]\n" 9895 "loop:\tFPREM\n" 9896 "\tFWAIT\n" 9897 "\tFNSTSW AX\n" 9898 "\tSAHF\n" 9899 "\tJP loop\n" 9900 "\tFSTP_D [ESP+0]\n" 9901 "\tMOVSD $dst,[ESP+0]\n" 9902 "\tADD ESP,8\n" 9903 "\tFSTP ST0\t # Restore FPU Stack" 9904 %} 9905 ins_cost(250); 9906 ins_encode( Push_ModD_encoding(src0, src1), emitModDPR(), Push_ResultD(dst), PopFPU); 9907 ins_pipe( pipe_slow ); 9908%} 9909 9910instruct sinDPR_reg(regDPR1 dst, regDPR1 src) %{ 9911 predicate (UseSSE<=1); 9912 match(Set dst (SinD src)); 9913 ins_cost(1800); 9914 format %{ "DSIN $dst" %} 9915 opcode(0xD9, 0xFE); 9916 ins_encode( OpcP, OpcS ); 9917 ins_pipe( pipe_slow ); 9918%} 9919 9920instruct sinD_reg(regD dst, eFlagsReg cr) %{ 9921 predicate (UseSSE>=2); 9922 match(Set dst (SinD dst)); 9923 effect(KILL cr); // Push_{Src|Result}D() uses "{SUB|ADD} ESP,8" 9924 ins_cost(1800); 9925 format %{ "DSIN $dst" %} 9926 opcode(0xD9, 0xFE); 9927 ins_encode( Push_SrcD(dst), OpcP, OpcS, Push_ResultD(dst) ); 9928 ins_pipe( pipe_slow ); 9929%} 9930 9931instruct cosDPR_reg(regDPR1 dst, regDPR1 src) %{ 9932 predicate (UseSSE<=1); 9933 match(Set dst (CosD src)); 9934 ins_cost(1800); 9935 format %{ "DCOS $dst" %} 9936 opcode(0xD9, 0xFF); 9937 ins_encode( OpcP, OpcS ); 9938 ins_pipe( pipe_slow ); 9939%} 9940 9941instruct cosD_reg(regD dst, eFlagsReg cr) %{ 9942 predicate (UseSSE>=2); 9943 match(Set dst (CosD dst)); 9944 effect(KILL cr); // Push_{Src|Result}D() uses "{SUB|ADD} ESP,8" 9945 ins_cost(1800); 9946 format %{ "DCOS $dst" %} 9947 opcode(0xD9, 0xFF); 9948 ins_encode( Push_SrcD(dst), OpcP, OpcS, Push_ResultD(dst) ); 9949 ins_pipe( pipe_slow ); 9950%} 9951 9952instruct tanDPR_reg(regDPR1 dst, regDPR1 src) %{ 9953 predicate (UseSSE<=1); 9954 match(Set dst(TanD src)); 9955 format %{ "DTAN $dst" %} 9956 ins_encode( Opcode(0xD9), Opcode(0xF2), // fptan 9957 Opcode(0xDD), Opcode(0xD8)); // fstp st 9958 ins_pipe( pipe_slow ); 9959%} 9960 9961instruct tanD_reg(regD dst, eFlagsReg cr) %{ 9962 predicate (UseSSE>=2); 9963 match(Set dst(TanD dst)); 9964 effect(KILL cr); // Push_{Src|Result}D() uses "{SUB|ADD} ESP,8" 9965 format %{ "DTAN $dst" %} 9966 ins_encode( Push_SrcD(dst), 9967 Opcode(0xD9), Opcode(0xF2), // fptan 9968 Opcode(0xDD), Opcode(0xD8), // fstp st 9969 Push_ResultD(dst) ); 9970 ins_pipe( pipe_slow ); 9971%} 9972 9973instruct atanDPR_reg(regDPR dst, regDPR src) %{ 9974 predicate (UseSSE<=1); 9975 match(Set dst(AtanD dst src)); 9976 format %{ "DATA $dst,$src" %} 9977 opcode(0xD9, 0xF3); 9978 ins_encode( Push_Reg_DPR(src), 9979 OpcP, OpcS, RegOpc(dst) ); 9980 ins_pipe( pipe_slow ); 9981%} 9982 9983instruct atanD_reg(regD dst, regD src, eFlagsReg cr) %{ 9984 predicate (UseSSE>=2); 9985 match(Set dst(AtanD dst src)); 9986 effect(KILL cr); // Push_{Src|Result}D() uses "{SUB|ADD} ESP,8" 9987 format %{ "DATA $dst,$src" %} 9988 opcode(0xD9, 0xF3); 9989 ins_encode( Push_SrcD(src), 9990 OpcP, OpcS, Push_ResultD(dst) ); 9991 ins_pipe( pipe_slow ); 9992%} 9993 9994instruct sqrtDPR_reg(regDPR dst, regDPR src) %{ 9995 predicate (UseSSE<=1); 9996 match(Set dst (SqrtD src)); 9997 format %{ "DSQRT $dst,$src" %} 9998 opcode(0xFA, 0xD9); 9999 ins_encode( Push_Reg_DPR(src), 10000 OpcS, OpcP, Pop_Reg_DPR(dst) ); 10001 ins_pipe( pipe_slow ); 10002%} 10003 10004instruct powDPR_reg(regDPR X, regDPR1 Y, eAXRegI rax, eDXRegI rdx, eCXRegI rcx, eFlagsReg cr) %{ 10005 predicate (UseSSE<=1); 10006 match(Set Y (PowD X Y)); // Raise X to the Yth power 10007 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 10008 format %{ "fast_pow $X $Y -> $Y // KILL $rax, $rcx, $rdx" %} 10009 ins_encode %{ 10010 __ subptr(rsp, 8); 10011 __ fld_s($X$$reg - 1); 10012 __ fast_pow(); 10013 __ addptr(rsp, 8); 10014 %} 10015 ins_pipe( pipe_slow ); 10016%} 10017 10018instruct powD_reg(regD dst, regD src0, regD src1, eAXRegI rax, eDXRegI rdx, eCXRegI rcx, eFlagsReg cr) %{ 10019 predicate (UseSSE>=2); 10020 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 10021 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 10022 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} 10023 ins_encode %{ 10024 __ subptr(rsp, 8); 10025 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 10026 __ fld_d(Address(rsp, 0)); 10027 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 10028 __ fld_d(Address(rsp, 0)); 10029 __ fast_pow(); 10030 __ fstp_d(Address(rsp, 0)); 10031 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 10032 __ addptr(rsp, 8); 10033 %} 10034 ins_pipe( pipe_slow ); 10035%} 10036 10037 10038instruct expDPR_reg(regDPR1 dpr1, eAXRegI rax, eDXRegI rdx, eCXRegI rcx, eFlagsReg cr) %{ 10039 predicate (UseSSE<=1); 10040 match(Set dpr1 (ExpD dpr1)); 10041 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); 10042 format %{ "fast_exp $dpr1 -> $dpr1 // KILL $rax, $rcx, $rdx" %} 10043 ins_encode %{ 10044 __ fast_exp(); 10045 %} 10046 ins_pipe( pipe_slow ); 10047%} 10048 10049instruct expD_reg(regD dst, regD src, eAXRegI rax, eDXRegI rdx, eCXRegI rcx, eFlagsReg cr) %{ 10050 predicate (UseSSE>=2); 10051 match(Set dst (ExpD src)); 10052 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); 10053 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %} 10054 ins_encode %{ 10055 __ subptr(rsp, 8); 10056 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10057 __ fld_d(Address(rsp, 0)); 10058 __ fast_exp(); 10059 __ fstp_d(Address(rsp, 0)); 10060 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 10061 __ addptr(rsp, 8); 10062 %} 10063 ins_pipe( pipe_slow ); 10064%} 10065 10066instruct log10DPR_reg(regDPR1 dst, regDPR1 src) %{ 10067 predicate (UseSSE<=1); 10068 // The source Double operand on FPU stack 10069 match(Set dst (Log10D src)); 10070 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 10071 // fxch ; swap ST(0) with ST(1) 10072 // fyl2x ; compute log_10(2) * log_2(x) 10073 format %{ "FLDLG2 \t\t\t#Log10\n\t" 10074 "FXCH \n\t" 10075 "FYL2X \t\t\t# Q=Log10*Log_2(x)" 10076 %} 10077 ins_encode( Opcode(0xD9), Opcode(0xEC), // fldlg2 10078 Opcode(0xD9), Opcode(0xC9), // fxch 10079 Opcode(0xD9), Opcode(0xF1)); // fyl2x 10080 10081 ins_pipe( pipe_slow ); 10082%} 10083 10084instruct log10D_reg(regD dst, regD src, eFlagsReg cr) %{ 10085 predicate (UseSSE>=2); 10086 effect(KILL cr); 10087 match(Set dst (Log10D src)); 10088 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 10089 // fyl2x ; compute log_10(2) * log_2(x) 10090 format %{ "FLDLG2 \t\t\t#Log10\n\t" 10091 "FYL2X \t\t\t# Q=Log10*Log_2(x)" 10092 %} 10093 ins_encode( Opcode(0xD9), Opcode(0xEC), // fldlg2 10094 Push_SrcD(src), 10095 Opcode(0xD9), Opcode(0xF1), // fyl2x 10096 Push_ResultD(dst)); 10097 10098 ins_pipe( pipe_slow ); 10099%} 10100 10101instruct logDPR_reg(regDPR1 dst, regDPR1 src) %{ 10102 predicate (UseSSE<=1); 10103 // The source Double operand on FPU stack 10104 match(Set dst (LogD src)); 10105 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 10106 // fxch ; swap ST(0) with ST(1) 10107 // fyl2x ; compute log_e(2) * log_2(x) 10108 format %{ "FLDLN2 \t\t\t#Log_e\n\t" 10109 "FXCH \n\t" 10110 "FYL2X \t\t\t# Q=Log_e*Log_2(x)" 10111 %} 10112 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 10113 Opcode(0xD9), Opcode(0xC9), // fxch 10114 Opcode(0xD9), Opcode(0xF1)); // fyl2x 10115 10116 ins_pipe( pipe_slow ); 10117%} 10118 10119instruct logD_reg(regD dst, regD src, eFlagsReg cr) %{ 10120 predicate (UseSSE>=2); 10121 effect(KILL cr); 10122 // The source and result Double operands in XMM registers 10123 match(Set dst (LogD src)); 10124 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 10125 // fyl2x ; compute log_e(2) * log_2(x) 10126 format %{ "FLDLN2 \t\t\t#Log_e\n\t" 10127 "FYL2X \t\t\t# Q=Log_e*Log_2(x)" 10128 %} 10129 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 10130 Push_SrcD(src), 10131 Opcode(0xD9), Opcode(0xF1), // fyl2x 10132 Push_ResultD(dst)); 10133 ins_pipe( pipe_slow ); 10134%} 10135 10136//-------------Float Instructions------------------------------- 10137// Float Math 10138 10139// Code for float compare: 10140// fcompp(); 10141// fwait(); fnstsw_ax(); 10142// sahf(); 10143// movl(dst, unordered_result); 10144// jcc(Assembler::parity, exit); 10145// movl(dst, less_result); 10146// jcc(Assembler::below, exit); 10147// movl(dst, equal_result); 10148// jcc(Assembler::equal, exit); 10149// movl(dst, greater_result); 10150// exit: 10151 10152// P6 version of float compare, sets condition codes in EFLAGS 10153instruct cmpFPR_cc_P6(eFlagsRegU cr, regFPR src1, regFPR src2, eAXRegI rax) %{ 10154 predicate(VM_Version::supports_cmov() && UseSSE == 0); 10155 match(Set cr (CmpF src1 src2)); 10156 effect(KILL rax); 10157 ins_cost(150); 10158 format %{ "FLD $src1\n\t" 10159 "FUCOMIP ST,$src2 // P6 instruction\n\t" 10160 "JNP exit\n\t" 10161 "MOV ah,1 // saw a NaN, set CF (treat as LT)\n\t" 10162 "SAHF\n" 10163 "exit:\tNOP // avoid branch to branch" %} 10164 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */ 10165 ins_encode( Push_Reg_DPR(src1), 10166 OpcP, RegOpc(src2), 10167 cmpF_P6_fixup ); 10168 ins_pipe( pipe_slow ); 10169%} 10170 10171instruct cmpFPR_cc_P6CF(eFlagsRegUCF cr, regFPR src1, regFPR src2) %{ 10172 predicate(VM_Version::supports_cmov() && UseSSE == 0); 10173 match(Set cr (CmpF src1 src2)); 10174 ins_cost(100); 10175 format %{ "FLD $src1\n\t" 10176 "FUCOMIP ST,$src2 // P6 instruction" %} 10177 opcode(0xDF, 0x05); /* DF E8+i or DF /5 */ 10178 ins_encode( Push_Reg_DPR(src1), 10179 OpcP, RegOpc(src2)); 10180 ins_pipe( pipe_slow ); 10181%} 10182 10183 10184// Compare & branch 10185instruct cmpFPR_cc(eFlagsRegU cr, regFPR src1, regFPR src2, eAXRegI rax) %{ 10186 predicate(UseSSE == 0); 10187 match(Set cr (CmpF src1 src2)); 10188 effect(KILL rax); 10189 ins_cost(200); 10190 format %{ "FLD $src1\n\t" 10191 "FCOMp $src2\n\t" 10192 "FNSTSW AX\n\t" 10193 "TEST AX,0x400\n\t" 10194 "JZ,s flags\n\t" 10195 "MOV AH,1\t# unordered treat as LT\n" 10196 "flags:\tSAHF" %} 10197 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */ 10198 ins_encode( Push_Reg_DPR(src1), 10199 OpcP, RegOpc(src2), 10200 fpu_flags); 10201 ins_pipe( pipe_slow ); 10202%} 10203 10204// Compare vs zero into -1,0,1 10205instruct cmpFPR_0(rRegI dst, regFPR src1, immFPR0 zero, eAXRegI rax, eFlagsReg cr) %{ 10206 predicate(UseSSE == 0); 10207 match(Set dst (CmpF3 src1 zero)); 10208 effect(KILL cr, KILL rax); 10209 ins_cost(280); 10210 format %{ "FTSTF $dst,$src1" %} 10211 opcode(0xE4, 0xD9); 10212 ins_encode( Push_Reg_DPR(src1), 10213 OpcS, OpcP, PopFPU, 10214 CmpF_Result(dst)); 10215 ins_pipe( pipe_slow ); 10216%} 10217 10218// Compare into -1,0,1 10219instruct cmpFPR_reg(rRegI dst, regFPR src1, regFPR src2, eAXRegI rax, eFlagsReg cr) %{ 10220 predicate(UseSSE == 0); 10221 match(Set dst (CmpF3 src1 src2)); 10222 effect(KILL cr, KILL rax); 10223 ins_cost(300); 10224 format %{ "FCMPF $dst,$src1,$src2" %} 10225 opcode(0xD8, 0x3); /* D8 D8+i or D8 /3 */ 10226 ins_encode( Push_Reg_DPR(src1), 10227 OpcP, RegOpc(src2), 10228 CmpF_Result(dst)); 10229 ins_pipe( pipe_slow ); 10230%} 10231 10232// float compare and set condition codes in EFLAGS by XMM regs 10233instruct cmpF_cc(eFlagsRegU cr, regF src1, regF src2) %{ 10234 predicate(UseSSE>=1); 10235 match(Set cr (CmpF src1 src2)); 10236 ins_cost(145); 10237 format %{ "UCOMISS $src1,$src2\n\t" 10238 "JNP,s exit\n\t" 10239 "PUSHF\t# saw NaN, set CF\n\t" 10240 "AND [rsp], #0xffffff2b\n\t" 10241 "POPF\n" 10242 "exit:" %} 10243 ins_encode %{ 10244 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10245 emit_cmpfp_fixup(_masm); 10246 %} 10247 ins_pipe( pipe_slow ); 10248%} 10249 10250instruct cmpF_ccCF(eFlagsRegUCF cr, regF src1, regF src2) %{ 10251 predicate(UseSSE>=1); 10252 match(Set cr (CmpF src1 src2)); 10253 ins_cost(100); 10254 format %{ "UCOMISS $src1,$src2" %} 10255 ins_encode %{ 10256 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10257 %} 10258 ins_pipe( pipe_slow ); 10259%} 10260 10261// float compare and set condition codes in EFLAGS by XMM regs 10262instruct cmpF_ccmem(eFlagsRegU cr, regF src1, memory src2) %{ 10263 predicate(UseSSE>=1); 10264 match(Set cr (CmpF src1 (LoadF src2))); 10265 ins_cost(165); 10266 format %{ "UCOMISS $src1,$src2\n\t" 10267 "JNP,s exit\n\t" 10268 "PUSHF\t# saw NaN, set CF\n\t" 10269 "AND [rsp], #0xffffff2b\n\t" 10270 "POPF\n" 10271 "exit:" %} 10272 ins_encode %{ 10273 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10274 emit_cmpfp_fixup(_masm); 10275 %} 10276 ins_pipe( pipe_slow ); 10277%} 10278 10279instruct cmpF_ccmemCF(eFlagsRegUCF cr, regF src1, memory src2) %{ 10280 predicate(UseSSE>=1); 10281 match(Set cr (CmpF src1 (LoadF src2))); 10282 ins_cost(100); 10283 format %{ "UCOMISS $src1,$src2" %} 10284 ins_encode %{ 10285 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10286 %} 10287 ins_pipe( pipe_slow ); 10288%} 10289 10290// Compare into -1,0,1 in XMM 10291instruct cmpF_reg(xRegI dst, regF src1, regF src2, eFlagsReg cr) %{ 10292 predicate(UseSSE>=1); 10293 match(Set dst (CmpF3 src1 src2)); 10294 effect(KILL cr); 10295 ins_cost(255); 10296 format %{ "UCOMISS $src1, $src2\n\t" 10297 "MOV $dst, #-1\n\t" 10298 "JP,s done\n\t" 10299 "JB,s done\n\t" 10300 "SETNE $dst\n\t" 10301 "MOVZB $dst, $dst\n" 10302 "done:" %} 10303 ins_encode %{ 10304 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 10305 emit_cmpfp3(_masm, $dst$$Register); 10306 %} 10307 ins_pipe( pipe_slow ); 10308%} 10309 10310// Compare into -1,0,1 in XMM and memory 10311instruct cmpF_regmem(xRegI dst, regF src1, memory src2, eFlagsReg cr) %{ 10312 predicate(UseSSE>=1); 10313 match(Set dst (CmpF3 src1 (LoadF src2))); 10314 effect(KILL cr); 10315 ins_cost(275); 10316 format %{ "UCOMISS $src1, $src2\n\t" 10317 "MOV $dst, #-1\n\t" 10318 "JP,s done\n\t" 10319 "JB,s done\n\t" 10320 "SETNE $dst\n\t" 10321 "MOVZB $dst, $dst\n" 10322 "done:" %} 10323 ins_encode %{ 10324 __ ucomiss($src1$$XMMRegister, $src2$$Address); 10325 emit_cmpfp3(_masm, $dst$$Register); 10326 %} 10327 ins_pipe( pipe_slow ); 10328%} 10329 10330// Spill to obtain 24-bit precision 10331instruct subFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2) %{ 10332 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10333 match(Set dst (SubF src1 src2)); 10334 10335 format %{ "FSUB $dst,$src1 - $src2" %} 10336 opcode(0xD8, 0x4); /* D8 E0+i or D8 /4 mod==0x3 ;; result in TOS */ 10337 ins_encode( Push_Reg_FPR(src1), 10338 OpcReg_FPR(src2), 10339 Pop_Mem_FPR(dst) ); 10340 ins_pipe( fpu_mem_reg_reg ); 10341%} 10342// 10343// This instruction does not round to 24-bits 10344instruct subFPR_reg(regFPR dst, regFPR src) %{ 10345 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10346 match(Set dst (SubF dst src)); 10347 10348 format %{ "FSUB $dst,$src" %} 10349 opcode(0xDE, 0x5); /* DE E8+i or DE /5 */ 10350 ins_encode( Push_Reg_FPR(src), 10351 OpcP, RegOpc(dst) ); 10352 ins_pipe( fpu_reg_reg ); 10353%} 10354 10355// Spill to obtain 24-bit precision 10356instruct addFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2) %{ 10357 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10358 match(Set dst (AddF src1 src2)); 10359 10360 format %{ "FADD $dst,$src1,$src2" %} 10361 opcode(0xD8, 0x0); /* D8 C0+i */ 10362 ins_encode( Push_Reg_FPR(src2), 10363 OpcReg_FPR(src1), 10364 Pop_Mem_FPR(dst) ); 10365 ins_pipe( fpu_mem_reg_reg ); 10366%} 10367// 10368// This instruction does not round to 24-bits 10369instruct addFPR_reg(regFPR dst, regFPR src) %{ 10370 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10371 match(Set dst (AddF dst src)); 10372 10373 format %{ "FLD $src\n\t" 10374 "FADDp $dst,ST" %} 10375 opcode(0xDE, 0x0); /* DE C0+i or DE /0*/ 10376 ins_encode( Push_Reg_FPR(src), 10377 OpcP, RegOpc(dst) ); 10378 ins_pipe( fpu_reg_reg ); 10379%} 10380 10381instruct absFPR_reg(regFPR1 dst, regFPR1 src) %{ 10382 predicate(UseSSE==0); 10383 match(Set dst (AbsF src)); 10384 ins_cost(100); 10385 format %{ "FABS" %} 10386 opcode(0xE1, 0xD9); 10387 ins_encode( OpcS, OpcP ); 10388 ins_pipe( fpu_reg_reg ); 10389%} 10390 10391instruct negFPR_reg(regFPR1 dst, regFPR1 src) %{ 10392 predicate(UseSSE==0); 10393 match(Set dst (NegF src)); 10394 ins_cost(100); 10395 format %{ "FCHS" %} 10396 opcode(0xE0, 0xD9); 10397 ins_encode( OpcS, OpcP ); 10398 ins_pipe( fpu_reg_reg ); 10399%} 10400 10401// Cisc-alternate to addFPR_reg 10402// Spill to obtain 24-bit precision 10403instruct addFPR24_reg_mem(stackSlotF dst, regFPR src1, memory src2) %{ 10404 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10405 match(Set dst (AddF src1 (LoadF src2))); 10406 10407 format %{ "FLD $src2\n\t" 10408 "FADD ST,$src1\n\t" 10409 "FSTP_S $dst" %} 10410 opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */ 10411 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 10412 OpcReg_FPR(src1), 10413 Pop_Mem_FPR(dst) ); 10414 ins_pipe( fpu_mem_reg_mem ); 10415%} 10416// 10417// Cisc-alternate to addFPR_reg 10418// This instruction does not round to 24-bits 10419instruct addFPR_reg_mem(regFPR dst, memory src) %{ 10420 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10421 match(Set dst (AddF dst (LoadF src))); 10422 10423 format %{ "FADD $dst,$src" %} 10424 opcode(0xDE, 0x0, 0xD9); /* DE C0+i or DE /0*/ /* LoadF D9 /0 */ 10425 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src), 10426 OpcP, RegOpc(dst) ); 10427 ins_pipe( fpu_reg_mem ); 10428%} 10429 10430// // Following two instructions for _222_mpegaudio 10431// Spill to obtain 24-bit precision 10432instruct addFPR24_mem_reg(stackSlotF dst, regFPR src2, memory src1 ) %{ 10433 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10434 match(Set dst (AddF src1 src2)); 10435 10436 format %{ "FADD $dst,$src1,$src2" %} 10437 opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */ 10438 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src1), 10439 OpcReg_FPR(src2), 10440 Pop_Mem_FPR(dst) ); 10441 ins_pipe( fpu_mem_reg_mem ); 10442%} 10443 10444// Cisc-spill variant 10445// Spill to obtain 24-bit precision 10446instruct addFPR24_mem_cisc(stackSlotF dst, memory src1, memory src2) %{ 10447 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10448 match(Set dst (AddF src1 (LoadF src2))); 10449 10450 format %{ "FADD $dst,$src1,$src2 cisc" %} 10451 opcode(0xD8, 0x0, 0xD9); /* D8 C0+i */ /* LoadF D9 /0 */ 10452 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 10453 set_instruction_start, 10454 OpcP, RMopc_Mem(secondary,src1), 10455 Pop_Mem_FPR(dst) ); 10456 ins_pipe( fpu_mem_mem_mem ); 10457%} 10458 10459// Spill to obtain 24-bit precision 10460instruct addFPR24_mem_mem(stackSlotF dst, memory src1, memory src2) %{ 10461 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10462 match(Set dst (AddF src1 src2)); 10463 10464 format %{ "FADD $dst,$src1,$src2" %} 10465 opcode(0xD8, 0x0, 0xD9); /* D8 /0 */ /* LoadF D9 /0 */ 10466 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 10467 set_instruction_start, 10468 OpcP, RMopc_Mem(secondary,src1), 10469 Pop_Mem_FPR(dst) ); 10470 ins_pipe( fpu_mem_mem_mem ); 10471%} 10472 10473 10474// Spill to obtain 24-bit precision 10475instruct addFPR24_reg_imm(stackSlotF dst, regFPR src, immFPR con) %{ 10476 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10477 match(Set dst (AddF src con)); 10478 format %{ "FLD $src\n\t" 10479 "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t" 10480 "FSTP_S $dst" %} 10481 ins_encode %{ 10482 __ fld_s($src$$reg - 1); // FLD ST(i-1) 10483 __ fadd_s($constantaddress($con)); 10484 __ fstp_s(Address(rsp, $dst$$disp)); 10485 %} 10486 ins_pipe(fpu_mem_reg_con); 10487%} 10488// 10489// This instruction does not round to 24-bits 10490instruct addFPR_reg_imm(regFPR dst, regFPR src, immFPR con) %{ 10491 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10492 match(Set dst (AddF src con)); 10493 format %{ "FLD $src\n\t" 10494 "FADD_S [$constantaddress]\t# load from constant table: float=$con\n\t" 10495 "FSTP $dst" %} 10496 ins_encode %{ 10497 __ fld_s($src$$reg - 1); // FLD ST(i-1) 10498 __ fadd_s($constantaddress($con)); 10499 __ fstp_d($dst$$reg); 10500 %} 10501 ins_pipe(fpu_reg_reg_con); 10502%} 10503 10504// Spill to obtain 24-bit precision 10505instruct mulFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2) %{ 10506 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10507 match(Set dst (MulF src1 src2)); 10508 10509 format %{ "FLD $src1\n\t" 10510 "FMUL $src2\n\t" 10511 "FSTP_S $dst" %} 10512 opcode(0xD8, 0x1); /* D8 C8+i or D8 /1 ;; result in TOS */ 10513 ins_encode( Push_Reg_FPR(src1), 10514 OpcReg_FPR(src2), 10515 Pop_Mem_FPR(dst) ); 10516 ins_pipe( fpu_mem_reg_reg ); 10517%} 10518// 10519// This instruction does not round to 24-bits 10520instruct mulFPR_reg(regFPR dst, regFPR src1, regFPR src2) %{ 10521 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10522 match(Set dst (MulF src1 src2)); 10523 10524 format %{ "FLD $src1\n\t" 10525 "FMUL $src2\n\t" 10526 "FSTP_S $dst" %} 10527 opcode(0xD8, 0x1); /* D8 C8+i */ 10528 ins_encode( Push_Reg_FPR(src2), 10529 OpcReg_FPR(src1), 10530 Pop_Reg_FPR(dst) ); 10531 ins_pipe( fpu_reg_reg_reg ); 10532%} 10533 10534 10535// Spill to obtain 24-bit precision 10536// Cisc-alternate to reg-reg multiply 10537instruct mulFPR24_reg_mem(stackSlotF dst, regFPR src1, memory src2) %{ 10538 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10539 match(Set dst (MulF src1 (LoadF src2))); 10540 10541 format %{ "FLD_S $src2\n\t" 10542 "FMUL $src1\n\t" 10543 "FSTP_S $dst" %} 10544 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i or DE /1*/ /* LoadF D9 /0 */ 10545 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 10546 OpcReg_FPR(src1), 10547 Pop_Mem_FPR(dst) ); 10548 ins_pipe( fpu_mem_reg_mem ); 10549%} 10550// 10551// This instruction does not round to 24-bits 10552// Cisc-alternate to reg-reg multiply 10553instruct mulFPR_reg_mem(regFPR dst, regFPR src1, memory src2) %{ 10554 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10555 match(Set dst (MulF src1 (LoadF src2))); 10556 10557 format %{ "FMUL $dst,$src1,$src2" %} 10558 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i */ /* LoadF D9 /0 */ 10559 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 10560 OpcReg_FPR(src1), 10561 Pop_Reg_FPR(dst) ); 10562 ins_pipe( fpu_reg_reg_mem ); 10563%} 10564 10565// Spill to obtain 24-bit precision 10566instruct mulFPR24_mem_mem(stackSlotF dst, memory src1, memory src2) %{ 10567 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10568 match(Set dst (MulF src1 src2)); 10569 10570 format %{ "FMUL $dst,$src1,$src2" %} 10571 opcode(0xD8, 0x1, 0xD9); /* D8 /1 */ /* LoadF D9 /0 */ 10572 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,src2), 10573 set_instruction_start, 10574 OpcP, RMopc_Mem(secondary,src1), 10575 Pop_Mem_FPR(dst) ); 10576 ins_pipe( fpu_mem_mem_mem ); 10577%} 10578 10579// Spill to obtain 24-bit precision 10580instruct mulFPR24_reg_imm(stackSlotF dst, regFPR src, immFPR con) %{ 10581 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10582 match(Set dst (MulF src con)); 10583 10584 format %{ "FLD $src\n\t" 10585 "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t" 10586 "FSTP_S $dst" %} 10587 ins_encode %{ 10588 __ fld_s($src$$reg - 1); // FLD ST(i-1) 10589 __ fmul_s($constantaddress($con)); 10590 __ fstp_s(Address(rsp, $dst$$disp)); 10591 %} 10592 ins_pipe(fpu_mem_reg_con); 10593%} 10594// 10595// This instruction does not round to 24-bits 10596instruct mulFPR_reg_imm(regFPR dst, regFPR src, immFPR con) %{ 10597 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10598 match(Set dst (MulF src con)); 10599 10600 format %{ "FLD $src\n\t" 10601 "FMUL_S [$constantaddress]\t# load from constant table: float=$con\n\t" 10602 "FSTP $dst" %} 10603 ins_encode %{ 10604 __ fld_s($src$$reg - 1); // FLD ST(i-1) 10605 __ fmul_s($constantaddress($con)); 10606 __ fstp_d($dst$$reg); 10607 %} 10608 ins_pipe(fpu_reg_reg_con); 10609%} 10610 10611 10612// 10613// MACRO1 -- subsume unshared load into mulFPR 10614// This instruction does not round to 24-bits 10615instruct mulFPR_reg_load1(regFPR dst, regFPR src, memory mem1 ) %{ 10616 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10617 match(Set dst (MulF (LoadF mem1) src)); 10618 10619 format %{ "FLD $mem1 ===MACRO1===\n\t" 10620 "FMUL ST,$src\n\t" 10621 "FSTP $dst" %} 10622 opcode(0xD8, 0x1, 0xD9); /* D8 C8+i or D8 /1 */ /* LoadF D9 /0 */ 10623 ins_encode( Opcode(tertiary), RMopc_Mem(0x00,mem1), 10624 OpcReg_FPR(src), 10625 Pop_Reg_FPR(dst) ); 10626 ins_pipe( fpu_reg_reg_mem ); 10627%} 10628// 10629// MACRO2 -- addFPR a mulFPR which subsumed an unshared load 10630// This instruction does not round to 24-bits 10631instruct addFPR_mulFPR_reg_load1(regFPR dst, memory mem1, regFPR src1, regFPR src2) %{ 10632 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10633 match(Set dst (AddF (MulF (LoadF mem1) src1) src2)); 10634 ins_cost(95); 10635 10636 format %{ "FLD $mem1 ===MACRO2===\n\t" 10637 "FMUL ST,$src1 subsume mulFPR left load\n\t" 10638 "FADD ST,$src2\n\t" 10639 "FSTP $dst" %} 10640 opcode(0xD9); /* LoadF D9 /0 */ 10641 ins_encode( OpcP, RMopc_Mem(0x00,mem1), 10642 FMul_ST_reg(src1), 10643 FAdd_ST_reg(src2), 10644 Pop_Reg_FPR(dst) ); 10645 ins_pipe( fpu_reg_mem_reg_reg ); 10646%} 10647 10648// MACRO3 -- addFPR a mulFPR 10649// This instruction does not round to 24-bits. It is a '2-address' 10650// instruction in that the result goes back to src2. This eliminates 10651// a move from the macro; possibly the register allocator will have 10652// to add it back (and maybe not). 10653instruct addFPR_mulFPR_reg(regFPR src2, regFPR src1, regFPR src0) %{ 10654 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10655 match(Set src2 (AddF (MulF src0 src1) src2)); 10656 10657 format %{ "FLD $src0 ===MACRO3===\n\t" 10658 "FMUL ST,$src1\n\t" 10659 "FADDP $src2,ST" %} 10660 opcode(0xD9); /* LoadF D9 /0 */ 10661 ins_encode( Push_Reg_FPR(src0), 10662 FMul_ST_reg(src1), 10663 FAddP_reg_ST(src2) ); 10664 ins_pipe( fpu_reg_reg_reg ); 10665%} 10666 10667// MACRO4 -- divFPR subFPR 10668// This instruction does not round to 24-bits 10669instruct subFPR_divFPR_reg(regFPR dst, regFPR src1, regFPR src2, regFPR src3) %{ 10670 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10671 match(Set dst (DivF (SubF src2 src1) src3)); 10672 10673 format %{ "FLD $src2 ===MACRO4===\n\t" 10674 "FSUB ST,$src1\n\t" 10675 "FDIV ST,$src3\n\t" 10676 "FSTP $dst" %} 10677 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/ 10678 ins_encode( Push_Reg_FPR(src2), 10679 subFPR_divFPR_encode(src1,src3), 10680 Pop_Reg_FPR(dst) ); 10681 ins_pipe( fpu_reg_reg_reg_reg ); 10682%} 10683 10684// Spill to obtain 24-bit precision 10685instruct divFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2) %{ 10686 predicate(UseSSE==0 && Compile::current()->select_24_bit_instr()); 10687 match(Set dst (DivF src1 src2)); 10688 10689 format %{ "FDIV $dst,$src1,$src2" %} 10690 opcode(0xD8, 0x6); /* D8 F0+i or DE /6*/ 10691 ins_encode( Push_Reg_FPR(src1), 10692 OpcReg_FPR(src2), 10693 Pop_Mem_FPR(dst) ); 10694 ins_pipe( fpu_mem_reg_reg ); 10695%} 10696// 10697// This instruction does not round to 24-bits 10698instruct divFPR_reg(regFPR dst, regFPR src) %{ 10699 predicate(UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10700 match(Set dst (DivF dst src)); 10701 10702 format %{ "FDIV $dst,$src" %} 10703 opcode(0xDE, 0x7); /* DE F8+i or DE /7*/ 10704 ins_encode( Push_Reg_FPR(src), 10705 OpcP, RegOpc(dst) ); 10706 ins_pipe( fpu_reg_reg ); 10707%} 10708 10709 10710// Spill to obtain 24-bit precision 10711instruct modFPR24_reg(stackSlotF dst, regFPR src1, regFPR src2, eAXRegI rax, eFlagsReg cr) %{ 10712 predicate( UseSSE==0 && Compile::current()->select_24_bit_instr()); 10713 match(Set dst (ModF src1 src2)); 10714 effect(KILL rax, KILL cr); // emitModDPR() uses EAX and EFLAGS 10715 10716 format %{ "FMOD $dst,$src1,$src2" %} 10717 ins_encode( Push_Reg_Mod_DPR(src1, src2), 10718 emitModDPR(), 10719 Push_Result_Mod_DPR(src2), 10720 Pop_Mem_FPR(dst)); 10721 ins_pipe( pipe_slow ); 10722%} 10723// 10724// This instruction does not round to 24-bits 10725instruct modFPR_reg(regFPR dst, regFPR src, eAXRegI rax, eFlagsReg cr) %{ 10726 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr()); 10727 match(Set dst (ModF dst src)); 10728 effect(KILL rax, KILL cr); // emitModDPR() uses EAX and EFLAGS 10729 10730 format %{ "FMOD $dst,$src" %} 10731 ins_encode(Push_Reg_Mod_DPR(dst, src), 10732 emitModDPR(), 10733 Push_Result_Mod_DPR(src), 10734 Pop_Reg_FPR(dst)); 10735 ins_pipe( pipe_slow ); 10736%} 10737 10738instruct modF_reg(regF dst, regF src0, regF src1, eAXRegI rax, eFlagsReg cr) %{ 10739 predicate(UseSSE>=1); 10740 match(Set dst (ModF src0 src1)); 10741 effect(KILL rax, KILL cr); 10742 format %{ "SUB ESP,4\t # FMOD\n" 10743 "\tMOVSS [ESP+0],$src1\n" 10744 "\tFLD_S [ESP+0]\n" 10745 "\tMOVSS [ESP+0],$src0\n" 10746 "\tFLD_S [ESP+0]\n" 10747 "loop:\tFPREM\n" 10748 "\tFWAIT\n" 10749 "\tFNSTSW AX\n" 10750 "\tSAHF\n" 10751 "\tJP loop\n" 10752 "\tFSTP_S [ESP+0]\n" 10753 "\tMOVSS $dst,[ESP+0]\n" 10754 "\tADD ESP,4\n" 10755 "\tFSTP ST0\t # Restore FPU Stack" 10756 %} 10757 ins_cost(250); 10758 ins_encode( Push_ModF_encoding(src0, src1), emitModDPR(), Push_ResultF(dst,0x4), PopFPU); 10759 ins_pipe( pipe_slow ); 10760%} 10761 10762 10763//----------Arithmetic Conversion Instructions--------------------------------- 10764// The conversions operations are all Alpha sorted. Please keep it that way! 10765 10766instruct roundFloat_mem_reg(stackSlotF dst, regFPR src) %{ 10767 predicate(UseSSE==0); 10768 match(Set dst (RoundFloat src)); 10769 ins_cost(125); 10770 format %{ "FST_S $dst,$src\t# F-round" %} 10771 ins_encode( Pop_Mem_Reg_FPR(dst, src) ); 10772 ins_pipe( fpu_mem_reg ); 10773%} 10774 10775instruct roundDouble_mem_reg(stackSlotD dst, regDPR src) %{ 10776 predicate(UseSSE<=1); 10777 match(Set dst (RoundDouble src)); 10778 ins_cost(125); 10779 format %{ "FST_D $dst,$src\t# D-round" %} 10780 ins_encode( Pop_Mem_Reg_DPR(dst, src) ); 10781 ins_pipe( fpu_mem_reg ); 10782%} 10783 10784// Force rounding to 24-bit precision and 6-bit exponent 10785instruct convDPR2FPR_reg(stackSlotF dst, regDPR src) %{ 10786 predicate(UseSSE==0); 10787 match(Set dst (ConvD2F src)); 10788 format %{ "FST_S $dst,$src\t# F-round" %} 10789 expand %{ 10790 roundFloat_mem_reg(dst,src); 10791 %} 10792%} 10793 10794// Force rounding to 24-bit precision and 6-bit exponent 10795instruct convDPR2F_reg(regF dst, regDPR src, eFlagsReg cr) %{ 10796 predicate(UseSSE==1); 10797 match(Set dst (ConvD2F src)); 10798 effect( KILL cr ); 10799 format %{ "SUB ESP,4\n\t" 10800 "FST_S [ESP],$src\t# F-round\n\t" 10801 "MOVSS $dst,[ESP]\n\t" 10802 "ADD ESP,4" %} 10803 ins_encode %{ 10804 __ subptr(rsp, 4); 10805 if ($src$$reg != FPR1L_enc) { 10806 __ fld_s($src$$reg-1); 10807 __ fstp_s(Address(rsp, 0)); 10808 } else { 10809 __ fst_s(Address(rsp, 0)); 10810 } 10811 __ movflt($dst$$XMMRegister, Address(rsp, 0)); 10812 __ addptr(rsp, 4); 10813 %} 10814 ins_pipe( pipe_slow ); 10815%} 10816 10817// Force rounding double precision to single precision 10818instruct convD2F_reg(regF dst, regD src) %{ 10819 predicate(UseSSE>=2); 10820 match(Set dst (ConvD2F src)); 10821 format %{ "CVTSD2SS $dst,$src\t# F-round" %} 10822 ins_encode %{ 10823 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10824 %} 10825 ins_pipe( pipe_slow ); 10826%} 10827 10828instruct convFPR2DPR_reg_reg(regDPR dst, regFPR src) %{ 10829 predicate(UseSSE==0); 10830 match(Set dst (ConvF2D src)); 10831 format %{ "FST_S $dst,$src\t# D-round" %} 10832 ins_encode( Pop_Reg_Reg_DPR(dst, src)); 10833 ins_pipe( fpu_reg_reg ); 10834%} 10835 10836instruct convFPR2D_reg(stackSlotD dst, regFPR src) %{ 10837 predicate(UseSSE==1); 10838 match(Set dst (ConvF2D src)); 10839 format %{ "FST_D $dst,$src\t# D-round" %} 10840 expand %{ 10841 roundDouble_mem_reg(dst,src); 10842 %} 10843%} 10844 10845instruct convF2DPR_reg(regDPR dst, regF src, eFlagsReg cr) %{ 10846 predicate(UseSSE==1); 10847 match(Set dst (ConvF2D src)); 10848 effect( KILL cr ); 10849 format %{ "SUB ESP,4\n\t" 10850 "MOVSS [ESP] $src\n\t" 10851 "FLD_S [ESP]\n\t" 10852 "ADD ESP,4\n\t" 10853 "FSTP $dst\t# D-round" %} 10854 ins_encode %{ 10855 __ subptr(rsp, 4); 10856 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10857 __ fld_s(Address(rsp, 0)); 10858 __ addptr(rsp, 4); 10859 __ fstp_d($dst$$reg); 10860 %} 10861 ins_pipe( pipe_slow ); 10862%} 10863 10864instruct convF2D_reg(regD dst, regF src) %{ 10865 predicate(UseSSE>=2); 10866 match(Set dst (ConvF2D src)); 10867 format %{ "CVTSS2SD $dst,$src\t# D-round" %} 10868 ins_encode %{ 10869 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10870 %} 10871 ins_pipe( pipe_slow ); 10872%} 10873 10874// Convert a double to an int. If the double is a NAN, stuff a zero in instead. 10875instruct convDPR2I_reg_reg( eAXRegI dst, eDXRegI tmp, regDPR src, eFlagsReg cr ) %{ 10876 predicate(UseSSE<=1); 10877 match(Set dst (ConvD2I src)); 10878 effect( KILL tmp, KILL cr ); 10879 format %{ "FLD $src\t# Convert double to int \n\t" 10880 "FLDCW trunc mode\n\t" 10881 "SUB ESP,4\n\t" 10882 "FISTp [ESP + #0]\n\t" 10883 "FLDCW std/24-bit mode\n\t" 10884 "POP EAX\n\t" 10885 "CMP EAX,0x80000000\n\t" 10886 "JNE,s fast\n\t" 10887 "FLD_D $src\n\t" 10888 "CALL d2i_wrapper\n" 10889 "fast:" %} 10890 ins_encode( Push_Reg_DPR(src), DPR2I_encoding(src) ); 10891 ins_pipe( pipe_slow ); 10892%} 10893 10894// Convert a double to an int. If the double is a NAN, stuff a zero in instead. 10895instruct convD2I_reg_reg( eAXRegI dst, eDXRegI tmp, regD src, eFlagsReg cr ) %{ 10896 predicate(UseSSE>=2); 10897 match(Set dst (ConvD2I src)); 10898 effect( KILL tmp, KILL cr ); 10899 format %{ "CVTTSD2SI $dst, $src\n\t" 10900 "CMP $dst,0x80000000\n\t" 10901 "JNE,s fast\n\t" 10902 "SUB ESP, 8\n\t" 10903 "MOVSD [ESP], $src\n\t" 10904 "FLD_D [ESP]\n\t" 10905 "ADD ESP, 8\n\t" 10906 "CALL d2i_wrapper\n" 10907 "fast:" %} 10908 ins_encode %{ 10909 Label fast; 10910 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10911 __ cmpl($dst$$Register, 0x80000000); 10912 __ jccb(Assembler::notEqual, fast); 10913 __ subptr(rsp, 8); 10914 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10915 __ fld_d(Address(rsp, 0)); 10916 __ addptr(rsp, 8); 10917 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::d2i_wrapper()))); 10918 __ bind(fast); 10919 %} 10920 ins_pipe( pipe_slow ); 10921%} 10922 10923instruct convDPR2L_reg_reg( eADXRegL dst, regDPR src, eFlagsReg cr ) %{ 10924 predicate(UseSSE<=1); 10925 match(Set dst (ConvD2L src)); 10926 effect( KILL cr ); 10927 format %{ "FLD $src\t# Convert double to long\n\t" 10928 "FLDCW trunc mode\n\t" 10929 "SUB ESP,8\n\t" 10930 "FISTp [ESP + #0]\n\t" 10931 "FLDCW std/24-bit mode\n\t" 10932 "POP EAX\n\t" 10933 "POP EDX\n\t" 10934 "CMP EDX,0x80000000\n\t" 10935 "JNE,s fast\n\t" 10936 "TEST EAX,EAX\n\t" 10937 "JNE,s fast\n\t" 10938 "FLD $src\n\t" 10939 "CALL d2l_wrapper\n" 10940 "fast:" %} 10941 ins_encode( Push_Reg_DPR(src), DPR2L_encoding(src) ); 10942 ins_pipe( pipe_slow ); 10943%} 10944 10945// XMM lacks a float/double->long conversion, so use the old FPU stack. 10946instruct convD2L_reg_reg( eADXRegL dst, regD src, eFlagsReg cr ) %{ 10947 predicate (UseSSE>=2); 10948 match(Set dst (ConvD2L src)); 10949 effect( KILL cr ); 10950 format %{ "SUB ESP,8\t# Convert double to long\n\t" 10951 "MOVSD [ESP],$src\n\t" 10952 "FLD_D [ESP]\n\t" 10953 "FLDCW trunc mode\n\t" 10954 "FISTp [ESP + #0]\n\t" 10955 "FLDCW std/24-bit mode\n\t" 10956 "POP EAX\n\t" 10957 "POP EDX\n\t" 10958 "CMP EDX,0x80000000\n\t" 10959 "JNE,s fast\n\t" 10960 "TEST EAX,EAX\n\t" 10961 "JNE,s fast\n\t" 10962 "SUB ESP,8\n\t" 10963 "MOVSD [ESP],$src\n\t" 10964 "FLD_D [ESP]\n\t" 10965 "ADD ESP,8\n\t" 10966 "CALL d2l_wrapper\n" 10967 "fast:" %} 10968 ins_encode %{ 10969 Label fast; 10970 __ subptr(rsp, 8); 10971 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10972 __ fld_d(Address(rsp, 0)); 10973 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_trunc())); 10974 __ fistp_d(Address(rsp, 0)); 10975 // Restore the rounding mode, mask the exception 10976 if (Compile::current()->in_24_bit_fp_mode()) { 10977 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24())); 10978 } else { 10979 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); 10980 } 10981 // Load the converted long, adjust CPU stack 10982 __ pop(rax); 10983 __ pop(rdx); 10984 __ cmpl(rdx, 0x80000000); 10985 __ jccb(Assembler::notEqual, fast); 10986 __ testl(rax, rax); 10987 __ jccb(Assembler::notEqual, fast); 10988 __ subptr(rsp, 8); 10989 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10990 __ fld_d(Address(rsp, 0)); 10991 __ addptr(rsp, 8); 10992 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::d2l_wrapper()))); 10993 __ bind(fast); 10994 %} 10995 ins_pipe( pipe_slow ); 10996%} 10997 10998// Convert a double to an int. Java semantics require we do complex 10999// manglations in the corner cases. So we set the rounding mode to 11000// 'zero', store the darned double down as an int, and reset the 11001// rounding mode to 'nearest'. The hardware stores a flag value down 11002// if we would overflow or converted a NAN; we check for this and 11003// and go the slow path if needed. 11004instruct convFPR2I_reg_reg(eAXRegI dst, eDXRegI tmp, regFPR src, eFlagsReg cr ) %{ 11005 predicate(UseSSE==0); 11006 match(Set dst (ConvF2I src)); 11007 effect( KILL tmp, KILL cr ); 11008 format %{ "FLD $src\t# Convert float to int \n\t" 11009 "FLDCW trunc mode\n\t" 11010 "SUB ESP,4\n\t" 11011 "FISTp [ESP + #0]\n\t" 11012 "FLDCW std/24-bit mode\n\t" 11013 "POP EAX\n\t" 11014 "CMP EAX,0x80000000\n\t" 11015 "JNE,s fast\n\t" 11016 "FLD $src\n\t" 11017 "CALL d2i_wrapper\n" 11018 "fast:" %} 11019 // DPR2I_encoding works for FPR2I 11020 ins_encode( Push_Reg_FPR(src), DPR2I_encoding(src) ); 11021 ins_pipe( pipe_slow ); 11022%} 11023 11024// Convert a float in xmm to an int reg. 11025instruct convF2I_reg(eAXRegI dst, eDXRegI tmp, regF src, eFlagsReg cr ) %{ 11026 predicate(UseSSE>=1); 11027 match(Set dst (ConvF2I src)); 11028 effect( KILL tmp, KILL cr ); 11029 format %{ "CVTTSS2SI $dst, $src\n\t" 11030 "CMP $dst,0x80000000\n\t" 11031 "JNE,s fast\n\t" 11032 "SUB ESP, 4\n\t" 11033 "MOVSS [ESP], $src\n\t" 11034 "FLD [ESP]\n\t" 11035 "ADD ESP, 4\n\t" 11036 "CALL d2i_wrapper\n" 11037 "fast:" %} 11038 ins_encode %{ 11039 Label fast; 11040 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 11041 __ cmpl($dst$$Register, 0x80000000); 11042 __ jccb(Assembler::notEqual, fast); 11043 __ subptr(rsp, 4); 11044 __ movflt(Address(rsp, 0), $src$$XMMRegister); 11045 __ fld_s(Address(rsp, 0)); 11046 __ addptr(rsp, 4); 11047 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::d2i_wrapper()))); 11048 __ bind(fast); 11049 %} 11050 ins_pipe( pipe_slow ); 11051%} 11052 11053instruct convFPR2L_reg_reg( eADXRegL dst, regFPR src, eFlagsReg cr ) %{ 11054 predicate(UseSSE==0); 11055 match(Set dst (ConvF2L src)); 11056 effect( KILL cr ); 11057 format %{ "FLD $src\t# Convert float to long\n\t" 11058 "FLDCW trunc mode\n\t" 11059 "SUB ESP,8\n\t" 11060 "FISTp [ESP + #0]\n\t" 11061 "FLDCW std/24-bit mode\n\t" 11062 "POP EAX\n\t" 11063 "POP EDX\n\t" 11064 "CMP EDX,0x80000000\n\t" 11065 "JNE,s fast\n\t" 11066 "TEST EAX,EAX\n\t" 11067 "JNE,s fast\n\t" 11068 "FLD $src\n\t" 11069 "CALL d2l_wrapper\n" 11070 "fast:" %} 11071 // DPR2L_encoding works for FPR2L 11072 ins_encode( Push_Reg_FPR(src), DPR2L_encoding(src) ); 11073 ins_pipe( pipe_slow ); 11074%} 11075 11076// XMM lacks a float/double->long conversion, so use the old FPU stack. 11077instruct convF2L_reg_reg( eADXRegL dst, regF src, eFlagsReg cr ) %{ 11078 predicate (UseSSE>=1); 11079 match(Set dst (ConvF2L src)); 11080 effect( KILL cr ); 11081 format %{ "SUB ESP,8\t# Convert float to long\n\t" 11082 "MOVSS [ESP],$src\n\t" 11083 "FLD_S [ESP]\n\t" 11084 "FLDCW trunc mode\n\t" 11085 "FISTp [ESP + #0]\n\t" 11086 "FLDCW std/24-bit mode\n\t" 11087 "POP EAX\n\t" 11088 "POP EDX\n\t" 11089 "CMP EDX,0x80000000\n\t" 11090 "JNE,s fast\n\t" 11091 "TEST EAX,EAX\n\t" 11092 "JNE,s fast\n\t" 11093 "SUB ESP,4\t# Convert float to long\n\t" 11094 "MOVSS [ESP],$src\n\t" 11095 "FLD_S [ESP]\n\t" 11096 "ADD ESP,4\n\t" 11097 "CALL d2l_wrapper\n" 11098 "fast:" %} 11099 ins_encode %{ 11100 Label fast; 11101 __ subptr(rsp, 8); 11102 __ movflt(Address(rsp, 0), $src$$XMMRegister); 11103 __ fld_s(Address(rsp, 0)); 11104 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_trunc())); 11105 __ fistp_d(Address(rsp, 0)); 11106 // Restore the rounding mode, mask the exception 11107 if (Compile::current()->in_24_bit_fp_mode()) { 11108 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_24())); 11109 } else { 11110 __ fldcw(ExternalAddress(StubRoutines::addr_fpu_cntrl_wrd_std())); 11111 } 11112 // Load the converted long, adjust CPU stack 11113 __ pop(rax); 11114 __ pop(rdx); 11115 __ cmpl(rdx, 0x80000000); 11116 __ jccb(Assembler::notEqual, fast); 11117 __ testl(rax, rax); 11118 __ jccb(Assembler::notEqual, fast); 11119 __ subptr(rsp, 4); 11120 __ movflt(Address(rsp, 0), $src$$XMMRegister); 11121 __ fld_s(Address(rsp, 0)); 11122 __ addptr(rsp, 4); 11123 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::d2l_wrapper()))); 11124 __ bind(fast); 11125 %} 11126 ins_pipe( pipe_slow ); 11127%} 11128 11129instruct convI2DPR_reg(regDPR dst, stackSlotI src) %{ 11130 predicate( UseSSE<=1 ); 11131 match(Set dst (ConvI2D src)); 11132 format %{ "FILD $src\n\t" 11133 "FSTP $dst" %} 11134 opcode(0xDB, 0x0); /* DB /0 */ 11135 ins_encode(Push_Mem_I(src), Pop_Reg_DPR(dst)); 11136 ins_pipe( fpu_reg_mem ); 11137%} 11138 11139instruct convI2D_reg(regD dst, rRegI src) %{ 11140 predicate( UseSSE>=2 && !UseXmmI2D ); 11141 match(Set dst (ConvI2D src)); 11142 format %{ "CVTSI2SD $dst,$src" %} 11143 ins_encode %{ 11144 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 11145 %} 11146 ins_pipe( pipe_slow ); 11147%} 11148 11149instruct convI2D_mem(regD dst, memory mem) %{ 11150 predicate( UseSSE>=2 ); 11151 match(Set dst (ConvI2D (LoadI mem))); 11152 format %{ "CVTSI2SD $dst,$mem" %} 11153 ins_encode %{ 11154 __ cvtsi2sdl ($dst$$XMMRegister, $mem$$Address); 11155 %} 11156 ins_pipe( pipe_slow ); 11157%} 11158 11159instruct convXI2D_reg(regD dst, rRegI src) 11160%{ 11161 predicate( UseSSE>=2 && UseXmmI2D ); 11162 match(Set dst (ConvI2D src)); 11163 11164 format %{ "MOVD $dst,$src\n\t" 11165 "CVTDQ2PD $dst,$dst\t# i2d" %} 11166 ins_encode %{ 11167 __ movdl($dst$$XMMRegister, $src$$Register); 11168 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 11169 %} 11170 ins_pipe(pipe_slow); // XXX 11171%} 11172 11173instruct convI2DPR_mem(regDPR dst, memory mem) %{ 11174 predicate( UseSSE<=1 && !Compile::current()->select_24_bit_instr()); 11175 match(Set dst (ConvI2D (LoadI mem))); 11176 format %{ "FILD $mem\n\t" 11177 "FSTP $dst" %} 11178 opcode(0xDB); /* DB /0 */ 11179 ins_encode( OpcP, RMopc_Mem(0x00,mem), 11180 Pop_Reg_DPR(dst)); 11181 ins_pipe( fpu_reg_mem ); 11182%} 11183 11184// Convert a byte to a float; no rounding step needed. 11185instruct conv24I2FPR_reg(regFPR dst, stackSlotI src) %{ 11186 predicate( UseSSE==0 && n->in(1)->Opcode() == Op_AndI && n->in(1)->in(2)->is_Con() && n->in(1)->in(2)->get_int() == 255 ); 11187 match(Set dst (ConvI2F src)); 11188 format %{ "FILD $src\n\t" 11189 "FSTP $dst" %} 11190 11191 opcode(0xDB, 0x0); /* DB /0 */ 11192 ins_encode(Push_Mem_I(src), Pop_Reg_FPR(dst)); 11193 ins_pipe( fpu_reg_mem ); 11194%} 11195 11196// In 24-bit mode, force exponent rounding by storing back out 11197instruct convI2FPR_SSF(stackSlotF dst, stackSlotI src) %{ 11198 predicate( UseSSE==0 && Compile::current()->select_24_bit_instr()); 11199 match(Set dst (ConvI2F src)); 11200 ins_cost(200); 11201 format %{ "FILD $src\n\t" 11202 "FSTP_S $dst" %} 11203 opcode(0xDB, 0x0); /* DB /0 */ 11204 ins_encode( Push_Mem_I(src), 11205 Pop_Mem_FPR(dst)); 11206 ins_pipe( fpu_mem_mem ); 11207%} 11208 11209// In 24-bit mode, force exponent rounding by storing back out 11210instruct convI2FPR_SSF_mem(stackSlotF dst, memory mem) %{ 11211 predicate( UseSSE==0 && Compile::current()->select_24_bit_instr()); 11212 match(Set dst (ConvI2F (LoadI mem))); 11213 ins_cost(200); 11214 format %{ "FILD $mem\n\t" 11215 "FSTP_S $dst" %} 11216 opcode(0xDB); /* DB /0 */ 11217 ins_encode( OpcP, RMopc_Mem(0x00,mem), 11218 Pop_Mem_FPR(dst)); 11219 ins_pipe( fpu_mem_mem ); 11220%} 11221 11222// This instruction does not round to 24-bits 11223instruct convI2FPR_reg(regFPR dst, stackSlotI src) %{ 11224 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11225 match(Set dst (ConvI2F src)); 11226 format %{ "FILD $src\n\t" 11227 "FSTP $dst" %} 11228 opcode(0xDB, 0x0); /* DB /0 */ 11229 ins_encode( Push_Mem_I(src), 11230 Pop_Reg_FPR(dst)); 11231 ins_pipe( fpu_reg_mem ); 11232%} 11233 11234// This instruction does not round to 24-bits 11235instruct convI2FPR_mem(regFPR dst, memory mem) %{ 11236 predicate( UseSSE==0 && !Compile::current()->select_24_bit_instr()); 11237 match(Set dst (ConvI2F (LoadI mem))); 11238 format %{ "FILD $mem\n\t" 11239 "FSTP $dst" %} 11240 opcode(0xDB); /* DB /0 */ 11241 ins_encode( OpcP, RMopc_Mem(0x00,mem), 11242 Pop_Reg_FPR(dst)); 11243 ins_pipe( fpu_reg_mem ); 11244%} 11245 11246// Convert an int to a float in xmm; no rounding step needed. 11247instruct convI2F_reg(regF dst, rRegI src) %{ 11248 predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F ); 11249 match(Set dst (ConvI2F src)); 11250 format %{ "CVTSI2SS $dst, $src" %} 11251 ins_encode %{ 11252 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 11253 %} 11254 ins_pipe( pipe_slow ); 11255%} 11256 11257 instruct convXI2F_reg(regF dst, rRegI src) 11258%{ 11259 predicate( UseSSE>=2 && UseXmmI2F ); 11260 match(Set dst (ConvI2F src)); 11261 11262 format %{ "MOVD $dst,$src\n\t" 11263 "CVTDQ2PS $dst,$dst\t# i2f" %} 11264 ins_encode %{ 11265 __ movdl($dst$$XMMRegister, $src$$Register); 11266 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 11267 %} 11268 ins_pipe(pipe_slow); // XXX 11269%} 11270 11271instruct convI2L_reg( eRegL dst, rRegI src, eFlagsReg cr) %{ 11272 match(Set dst (ConvI2L src)); 11273 effect(KILL cr); 11274 ins_cost(375); 11275 format %{ "MOV $dst.lo,$src\n\t" 11276 "MOV $dst.hi,$src\n\t" 11277 "SAR $dst.hi,31" %} 11278 ins_encode(convert_int_long(dst,src)); 11279 ins_pipe( ialu_reg_reg_long ); 11280%} 11281 11282// Zero-extend convert int to long 11283instruct convI2L_reg_zex(eRegL dst, rRegI src, immL_32bits mask, eFlagsReg flags ) %{ 11284 match(Set dst (AndL (ConvI2L src) mask) ); 11285 effect( KILL flags ); 11286 ins_cost(250); 11287 format %{ "MOV $dst.lo,$src\n\t" 11288 "XOR $dst.hi,$dst.hi" %} 11289 opcode(0x33); // XOR 11290 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) ); 11291 ins_pipe( ialu_reg_reg_long ); 11292%} 11293 11294// Zero-extend long 11295instruct zerox_long(eRegL dst, eRegL src, immL_32bits mask, eFlagsReg flags ) %{ 11296 match(Set dst (AndL src mask) ); 11297 effect( KILL flags ); 11298 ins_cost(250); 11299 format %{ "MOV $dst.lo,$src.lo\n\t" 11300 "XOR $dst.hi,$dst.hi\n\t" %} 11301 opcode(0x33); // XOR 11302 ins_encode(enc_Copy(dst,src), OpcP, RegReg_Hi2(dst,dst) ); 11303 ins_pipe( ialu_reg_reg_long ); 11304%} 11305 11306instruct convL2DPR_reg( stackSlotD dst, eRegL src, eFlagsReg cr) %{ 11307 predicate (UseSSE<=1); 11308 match(Set dst (ConvL2D src)); 11309 effect( KILL cr ); 11310 format %{ "PUSH $src.hi\t# Convert long to double\n\t" 11311 "PUSH $src.lo\n\t" 11312 "FILD ST,[ESP + #0]\n\t" 11313 "ADD ESP,8\n\t" 11314 "FSTP_D $dst\t# D-round" %} 11315 opcode(0xDF, 0x5); /* DF /5 */ 11316 ins_encode(convert_long_double(src), Pop_Mem_DPR(dst)); 11317 ins_pipe( pipe_slow ); 11318%} 11319 11320instruct convL2D_reg( regD dst, eRegL src, eFlagsReg cr) %{ 11321 predicate (UseSSE>=2); 11322 match(Set dst (ConvL2D src)); 11323 effect( KILL cr ); 11324 format %{ "PUSH $src.hi\t# Convert long to double\n\t" 11325 "PUSH $src.lo\n\t" 11326 "FILD_D [ESP]\n\t" 11327 "FSTP_D [ESP]\n\t" 11328 "MOVSD $dst,[ESP]\n\t" 11329 "ADD ESP,8" %} 11330 opcode(0xDF, 0x5); /* DF /5 */ 11331 ins_encode(convert_long_double2(src), Push_ResultD(dst)); 11332 ins_pipe( pipe_slow ); 11333%} 11334 11335instruct convL2F_reg( regF dst, eRegL src, eFlagsReg cr) %{ 11336 predicate (UseSSE>=1); 11337 match(Set dst (ConvL2F src)); 11338 effect( KILL cr ); 11339 format %{ "PUSH $src.hi\t# Convert long to single float\n\t" 11340 "PUSH $src.lo\n\t" 11341 "FILD_D [ESP]\n\t" 11342 "FSTP_S [ESP]\n\t" 11343 "MOVSS $dst,[ESP]\n\t" 11344 "ADD ESP,8" %} 11345 opcode(0xDF, 0x5); /* DF /5 */ 11346 ins_encode(convert_long_double2(src), Push_ResultF(dst,0x8)); 11347 ins_pipe( pipe_slow ); 11348%} 11349 11350instruct convL2FPR_reg( stackSlotF dst, eRegL src, eFlagsReg cr) %{ 11351 match(Set dst (ConvL2F src)); 11352 effect( KILL cr ); 11353 format %{ "PUSH $src.hi\t# Convert long to single float\n\t" 11354 "PUSH $src.lo\n\t" 11355 "FILD ST,[ESP + #0]\n\t" 11356 "ADD ESP,8\n\t" 11357 "FSTP_S $dst\t# F-round" %} 11358 opcode(0xDF, 0x5); /* DF /5 */ 11359 ins_encode(convert_long_double(src), Pop_Mem_FPR(dst)); 11360 ins_pipe( pipe_slow ); 11361%} 11362 11363instruct convL2I_reg( rRegI dst, eRegL src ) %{ 11364 match(Set dst (ConvL2I src)); 11365 effect( DEF dst, USE src ); 11366 format %{ "MOV $dst,$src.lo" %} 11367 ins_encode(enc_CopyL_Lo(dst,src)); 11368 ins_pipe( ialu_reg_reg ); 11369%} 11370 11371 11372instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 11373 match(Set dst (MoveF2I src)); 11374 effect( DEF dst, USE src ); 11375 ins_cost(100); 11376 format %{ "MOV $dst,$src\t# MoveF2I_stack_reg" %} 11377 ins_encode %{ 11378 __ movl($dst$$Register, Address(rsp, $src$$disp)); 11379 %} 11380 ins_pipe( ialu_reg_mem ); 11381%} 11382 11383instruct MoveFPR2I_reg_stack(stackSlotI dst, regFPR src) %{ 11384 predicate(UseSSE==0); 11385 match(Set dst (MoveF2I src)); 11386 effect( DEF dst, USE src ); 11387 11388 ins_cost(125); 11389 format %{ "FST_S $dst,$src\t# MoveF2I_reg_stack" %} 11390 ins_encode( Pop_Mem_Reg_FPR(dst, src) ); 11391 ins_pipe( fpu_mem_reg ); 11392%} 11393 11394instruct MoveF2I_reg_stack_sse(stackSlotI dst, regF src) %{ 11395 predicate(UseSSE>=1); 11396 match(Set dst (MoveF2I src)); 11397 effect( DEF dst, USE src ); 11398 11399 ins_cost(95); 11400 format %{ "MOVSS $dst,$src\t# MoveF2I_reg_stack_sse" %} 11401 ins_encode %{ 11402 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 11403 %} 11404 ins_pipe( pipe_slow ); 11405%} 11406 11407instruct MoveF2I_reg_reg_sse(rRegI dst, regF src) %{ 11408 predicate(UseSSE>=2); 11409 match(Set dst (MoveF2I src)); 11410 effect( DEF dst, USE src ); 11411 ins_cost(85); 11412 format %{ "MOVD $dst,$src\t# MoveF2I_reg_reg_sse" %} 11413 ins_encode %{ 11414 __ movdl($dst$$Register, $src$$XMMRegister); 11415 %} 11416 ins_pipe( pipe_slow ); 11417%} 11418 11419instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 11420 match(Set dst (MoveI2F src)); 11421 effect( DEF dst, USE src ); 11422 11423 ins_cost(100); 11424 format %{ "MOV $dst,$src\t# MoveI2F_reg_stack" %} 11425 ins_encode %{ 11426 __ movl(Address(rsp, $dst$$disp), $src$$Register); 11427 %} 11428 ins_pipe( ialu_mem_reg ); 11429%} 11430 11431 11432instruct MoveI2FPR_stack_reg(regFPR dst, stackSlotI src) %{ 11433 predicate(UseSSE==0); 11434 match(Set dst (MoveI2F src)); 11435 effect(DEF dst, USE src); 11436 11437 ins_cost(125); 11438 format %{ "FLD_S $src\n\t" 11439 "FSTP $dst\t# MoveI2F_stack_reg" %} 11440 opcode(0xD9); /* D9 /0, FLD m32real */ 11441 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src), 11442 Pop_Reg_FPR(dst) ); 11443 ins_pipe( fpu_reg_mem ); 11444%} 11445 11446instruct MoveI2F_stack_reg_sse(regF dst, stackSlotI src) %{ 11447 predicate(UseSSE>=1); 11448 match(Set dst (MoveI2F src)); 11449 effect( DEF dst, USE src ); 11450 11451 ins_cost(95); 11452 format %{ "MOVSS $dst,$src\t# MoveI2F_stack_reg_sse" %} 11453 ins_encode %{ 11454 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 11455 %} 11456 ins_pipe( pipe_slow ); 11457%} 11458 11459instruct MoveI2F_reg_reg_sse(regF dst, rRegI src) %{ 11460 predicate(UseSSE>=2); 11461 match(Set dst (MoveI2F src)); 11462 effect( DEF dst, USE src ); 11463 11464 ins_cost(85); 11465 format %{ "MOVD $dst,$src\t# MoveI2F_reg_reg_sse" %} 11466 ins_encode %{ 11467 __ movdl($dst$$XMMRegister, $src$$Register); 11468 %} 11469 ins_pipe( pipe_slow ); 11470%} 11471 11472instruct MoveD2L_stack_reg(eRegL dst, stackSlotD src) %{ 11473 match(Set dst (MoveD2L src)); 11474 effect(DEF dst, USE src); 11475 11476 ins_cost(250); 11477 format %{ "MOV $dst.lo,$src\n\t" 11478 "MOV $dst.hi,$src+4\t# MoveD2L_stack_reg" %} 11479 opcode(0x8B, 0x8B); 11480 ins_encode( OpcP, RegMem(dst,src), OpcS, RegMem_Hi(dst,src)); 11481 ins_pipe( ialu_mem_long_reg ); 11482%} 11483 11484instruct MoveDPR2L_reg_stack(stackSlotL dst, regDPR src) %{ 11485 predicate(UseSSE<=1); 11486 match(Set dst (MoveD2L src)); 11487 effect(DEF dst, USE src); 11488 11489 ins_cost(125); 11490 format %{ "FST_D $dst,$src\t# MoveD2L_reg_stack" %} 11491 ins_encode( Pop_Mem_Reg_DPR(dst, src) ); 11492 ins_pipe( fpu_mem_reg ); 11493%} 11494 11495instruct MoveD2L_reg_stack_sse(stackSlotL dst, regD src) %{ 11496 predicate(UseSSE>=2); 11497 match(Set dst (MoveD2L src)); 11498 effect(DEF dst, USE src); 11499 ins_cost(95); 11500 format %{ "MOVSD $dst,$src\t# MoveD2L_reg_stack_sse" %} 11501 ins_encode %{ 11502 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 11503 %} 11504 ins_pipe( pipe_slow ); 11505%} 11506 11507instruct MoveD2L_reg_reg_sse(eRegL dst, regD src, regD tmp) %{ 11508 predicate(UseSSE>=2); 11509 match(Set dst (MoveD2L src)); 11510 effect(DEF dst, USE src, TEMP tmp); 11511 ins_cost(85); 11512 format %{ "MOVD $dst.lo,$src\n\t" 11513 "PSHUFLW $tmp,$src,0x4E\n\t" 11514 "MOVD $dst.hi,$tmp\t# MoveD2L_reg_reg_sse" %} 11515 ins_encode %{ 11516 __ movdl($dst$$Register, $src$$XMMRegister); 11517 __ pshuflw($tmp$$XMMRegister, $src$$XMMRegister, 0x4e); 11518 __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister); 11519 %} 11520 ins_pipe( pipe_slow ); 11521%} 11522 11523instruct MoveL2D_reg_stack(stackSlotD dst, eRegL src) %{ 11524 match(Set dst (MoveL2D src)); 11525 effect(DEF dst, USE src); 11526 11527 ins_cost(200); 11528 format %{ "MOV $dst,$src.lo\n\t" 11529 "MOV $dst+4,$src.hi\t# MoveL2D_reg_stack" %} 11530 opcode(0x89, 0x89); 11531 ins_encode( OpcP, RegMem( src, dst ), OpcS, RegMem_Hi( src, dst ) ); 11532 ins_pipe( ialu_mem_long_reg ); 11533%} 11534 11535 11536instruct MoveL2DPR_stack_reg(regDPR dst, stackSlotL src) %{ 11537 predicate(UseSSE<=1); 11538 match(Set dst (MoveL2D src)); 11539 effect(DEF dst, USE src); 11540 ins_cost(125); 11541 11542 format %{ "FLD_D $src\n\t" 11543 "FSTP $dst\t# MoveL2D_stack_reg" %} 11544 opcode(0xDD); /* DD /0, FLD m64real */ 11545 ins_encode( OpcP, RMopc_Mem_no_oop(0x00,src), 11546 Pop_Reg_DPR(dst) ); 11547 ins_pipe( fpu_reg_mem ); 11548%} 11549 11550 11551instruct MoveL2D_stack_reg_sse(regD dst, stackSlotL src) %{ 11552 predicate(UseSSE>=2 && UseXmmLoadAndClearUpper); 11553 match(Set dst (MoveL2D src)); 11554 effect(DEF dst, USE src); 11555 11556 ins_cost(95); 11557 format %{ "MOVSD $dst,$src\t# MoveL2D_stack_reg_sse" %} 11558 ins_encode %{ 11559 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11560 %} 11561 ins_pipe( pipe_slow ); 11562%} 11563 11564instruct MoveL2D_stack_reg_sse_partial(regD dst, stackSlotL src) %{ 11565 predicate(UseSSE>=2 && !UseXmmLoadAndClearUpper); 11566 match(Set dst (MoveL2D src)); 11567 effect(DEF dst, USE src); 11568 11569 ins_cost(95); 11570 format %{ "MOVLPD $dst,$src\t# MoveL2D_stack_reg_sse" %} 11571 ins_encode %{ 11572 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 11573 %} 11574 ins_pipe( pipe_slow ); 11575%} 11576 11577instruct MoveL2D_reg_reg_sse(regD dst, eRegL src, regD tmp) %{ 11578 predicate(UseSSE>=2); 11579 match(Set dst (MoveL2D src)); 11580 effect(TEMP dst, USE src, TEMP tmp); 11581 ins_cost(85); 11582 format %{ "MOVD $dst,$src.lo\n\t" 11583 "MOVD $tmp,$src.hi\n\t" 11584 "PUNPCKLDQ $dst,$tmp\t# MoveL2D_reg_reg_sse" %} 11585 ins_encode %{ 11586 __ movdl($dst$$XMMRegister, $src$$Register); 11587 __ movdl($tmp$$XMMRegister, HIGH_FROM_LOW($src$$Register)); 11588 __ punpckldq($dst$$XMMRegister, $tmp$$XMMRegister); 11589 %} 11590 ins_pipe( pipe_slow ); 11591%} 11592 11593 11594// ======================================================================= 11595// fast clearing of an array 11596instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ 11597 predicate(!UseFastStosb); 11598 match(Set dummy (ClearArray cnt base)); 11599 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 11600 format %{ "XOR EAX,EAX\t# ClearArray:\n\t" 11601 "SHL ECX,1\t# Convert doublewords to words\n\t" 11602 "REP STOS\t# store EAX into [EDI++] while ECX--" %} 11603 ins_encode %{ 11604 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 11605 %} 11606 ins_pipe( pipe_slow ); 11607%} 11608 11609instruct rep_fast_stosb(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlagsReg cr) %{ 11610 predicate(UseFastStosb); 11611 match(Set dummy (ClearArray cnt base)); 11612 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 11613 format %{ "XOR EAX,EAX\t# ClearArray:\n\t" 11614 "SHL ECX,3\t# Convert doublewords to bytes\n\t" 11615 "REP STOSB\t# store EAX into [EDI++] while ECX--" %} 11616 ins_encode %{ 11617 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 11618 %} 11619 ins_pipe( pipe_slow ); 11620%} 11621 11622instruct string_compare(eDIRegP str1, eCXRegI cnt1, eSIRegP str2, eDXRegI cnt2, 11623 eAXRegI result, regD tmp1, eFlagsReg cr) %{ 11624 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 11625 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 11626 11627 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 11628 ins_encode %{ 11629 __ string_compare($str1$$Register, $str2$$Register, 11630 $cnt1$$Register, $cnt2$$Register, $result$$Register, 11631 $tmp1$$XMMRegister); 11632 %} 11633 ins_pipe( pipe_slow ); 11634%} 11635 11636// fast string equals 11637instruct string_equals(eDIRegP str1, eSIRegP str2, eCXRegI cnt, eAXRegI result, 11638 regD tmp1, regD tmp2, eBXRegI tmp3, eFlagsReg cr) %{ 11639 match(Set result (StrEquals (Binary str1 str2) cnt)); 11640 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 11641 11642 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 11643 ins_encode %{ 11644 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 11645 $cnt$$Register, $result$$Register, $tmp3$$Register, 11646 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11647 %} 11648 ins_pipe( pipe_slow ); 11649%} 11650 11651// fast search of substring with known size. 11652instruct string_indexof_con(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, immI int_cnt2, 11653 eBXRegI result, regD vec, eAXRegI cnt2, eCXRegI tmp, eFlagsReg cr) %{ 11654 predicate(UseSSE42Intrinsics); 11655 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 11656 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 11657 11658 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 11659 ins_encode %{ 11660 int icnt2 = (int)$int_cnt2$$constant; 11661 if (icnt2 >= 8) { 11662 // IndexOf for constant substrings with size >= 8 elements 11663 // which don't need to be loaded through stack. 11664 __ string_indexofC8($str1$$Register, $str2$$Register, 11665 $cnt1$$Register, $cnt2$$Register, 11666 icnt2, $result$$Register, 11667 $vec$$XMMRegister, $tmp$$Register); 11668 } else { 11669 // Small strings are loaded through stack if they cross page boundary. 11670 __ string_indexof($str1$$Register, $str2$$Register, 11671 $cnt1$$Register, $cnt2$$Register, 11672 icnt2, $result$$Register, 11673 $vec$$XMMRegister, $tmp$$Register); 11674 } 11675 %} 11676 ins_pipe( pipe_slow ); 11677%} 11678 11679instruct string_indexof(eDIRegP str1, eDXRegI cnt1, eSIRegP str2, eAXRegI cnt2, 11680 eBXRegI result, regD vec, eCXRegI tmp, eFlagsReg cr) %{ 11681 predicate(UseSSE42Intrinsics); 11682 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 11683 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 11684 11685 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 11686 ins_encode %{ 11687 __ string_indexof($str1$$Register, $str2$$Register, 11688 $cnt1$$Register, $cnt2$$Register, 11689 (-1), $result$$Register, 11690 $vec$$XMMRegister, $tmp$$Register); 11691 %} 11692 ins_pipe( pipe_slow ); 11693%} 11694 11695// fast array equals 11696instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI result, 11697 regD tmp1, regD tmp2, eCXRegI tmp3, eBXRegI tmp4, eFlagsReg cr) 11698%{ 11699 match(Set result (AryEq ary1 ary2)); 11700 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 11701 //ins_cost(300); 11702 11703 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 11704 ins_encode %{ 11705 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 11706 $tmp3$$Register, $result$$Register, $tmp4$$Register, 11707 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 11708 %} 11709 ins_pipe( pipe_slow ); 11710%} 11711 11712// encode char[] to byte[] in ISO_8859_1 11713instruct encode_iso_array(eSIRegP src, eDIRegP dst, eDXRegI len, 11714 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 11715 eCXRegI tmp5, eAXRegI result, eFlagsReg cr) %{ 11716 match(Set result (EncodeISOArray src (Binary dst len))); 11717 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 11718 11719 format %{ "Encode array $src,$dst,$len -> $result // KILL ECX, EDX, $tmp1, $tmp2, $tmp3, $tmp4, ESI, EDI " %} 11720 ins_encode %{ 11721 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 11722 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 11723 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 11724 %} 11725 ins_pipe( pipe_slow ); 11726%} 11727 11728 11729//----------Control Flow Instructions------------------------------------------ 11730// Signed compare Instructions 11731instruct compI_eReg(eFlagsReg cr, rRegI op1, rRegI op2) %{ 11732 match(Set cr (CmpI op1 op2)); 11733 effect( DEF cr, USE op1, USE op2 ); 11734 format %{ "CMP $op1,$op2" %} 11735 opcode(0x3B); /* Opcode 3B /r */ 11736 ins_encode( OpcP, RegReg( op1, op2) ); 11737 ins_pipe( ialu_cr_reg_reg ); 11738%} 11739 11740instruct compI_eReg_imm(eFlagsReg cr, rRegI op1, immI op2) %{ 11741 match(Set cr (CmpI op1 op2)); 11742 effect( DEF cr, USE op1 ); 11743 format %{ "CMP $op1,$op2" %} 11744 opcode(0x81,0x07); /* Opcode 81 /7 */ 11745 // ins_encode( RegImm( op1, op2) ); /* Was CmpImm */ 11746 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) ); 11747 ins_pipe( ialu_cr_reg_imm ); 11748%} 11749 11750// Cisc-spilled version of cmpI_eReg 11751instruct compI_eReg_mem(eFlagsReg cr, rRegI op1, memory op2) %{ 11752 match(Set cr (CmpI op1 (LoadI op2))); 11753 11754 format %{ "CMP $op1,$op2" %} 11755 ins_cost(500); 11756 opcode(0x3B); /* Opcode 3B /r */ 11757 ins_encode( OpcP, RegMem( op1, op2) ); 11758 ins_pipe( ialu_cr_reg_mem ); 11759%} 11760 11761instruct testI_reg( eFlagsReg cr, rRegI src, immI0 zero ) %{ 11762 match(Set cr (CmpI src zero)); 11763 effect( DEF cr, USE src ); 11764 11765 format %{ "TEST $src,$src" %} 11766 opcode(0x85); 11767 ins_encode( OpcP, RegReg( src, src ) ); 11768 ins_pipe( ialu_cr_reg_imm ); 11769%} 11770 11771instruct testI_reg_imm( eFlagsReg cr, rRegI src, immI con, immI0 zero ) %{ 11772 match(Set cr (CmpI (AndI src con) zero)); 11773 11774 format %{ "TEST $src,$con" %} 11775 opcode(0xF7,0x00); 11776 ins_encode( OpcP, RegOpc(src), Con32(con) ); 11777 ins_pipe( ialu_cr_reg_imm ); 11778%} 11779 11780instruct testI_reg_mem( eFlagsReg cr, rRegI src, memory mem, immI0 zero ) %{ 11781 match(Set cr (CmpI (AndI src mem) zero)); 11782 11783 format %{ "TEST $src,$mem" %} 11784 opcode(0x85); 11785 ins_encode( OpcP, RegMem( src, mem ) ); 11786 ins_pipe( ialu_cr_reg_mem ); 11787%} 11788 11789// Unsigned compare Instructions; really, same as signed except they 11790// produce an eFlagsRegU instead of eFlagsReg. 11791instruct compU_eReg(eFlagsRegU cr, rRegI op1, rRegI op2) %{ 11792 match(Set cr (CmpU op1 op2)); 11793 11794 format %{ "CMPu $op1,$op2" %} 11795 opcode(0x3B); /* Opcode 3B /r */ 11796 ins_encode( OpcP, RegReg( op1, op2) ); 11797 ins_pipe( ialu_cr_reg_reg ); 11798%} 11799 11800instruct compU_eReg_imm(eFlagsRegU cr, rRegI op1, immI op2) %{ 11801 match(Set cr (CmpU op1 op2)); 11802 11803 format %{ "CMPu $op1,$op2" %} 11804 opcode(0x81,0x07); /* Opcode 81 /7 */ 11805 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) ); 11806 ins_pipe( ialu_cr_reg_imm ); 11807%} 11808 11809// // Cisc-spilled version of cmpU_eReg 11810instruct compU_eReg_mem(eFlagsRegU cr, rRegI op1, memory op2) %{ 11811 match(Set cr (CmpU op1 (LoadI op2))); 11812 11813 format %{ "CMPu $op1,$op2" %} 11814 ins_cost(500); 11815 opcode(0x3B); /* Opcode 3B /r */ 11816 ins_encode( OpcP, RegMem( op1, op2) ); 11817 ins_pipe( ialu_cr_reg_mem ); 11818%} 11819 11820// // Cisc-spilled version of cmpU_eReg 11821//instruct compU_mem_eReg(eFlagsRegU cr, memory op1, rRegI op2) %{ 11822// match(Set cr (CmpU (LoadI op1) op2)); 11823// 11824// format %{ "CMPu $op1,$op2" %} 11825// ins_cost(500); 11826// opcode(0x39); /* Opcode 39 /r */ 11827// ins_encode( OpcP, RegMem( op1, op2) ); 11828//%} 11829 11830instruct testU_reg( eFlagsRegU cr, rRegI src, immI0 zero ) %{ 11831 match(Set cr (CmpU src zero)); 11832 11833 format %{ "TESTu $src,$src" %} 11834 opcode(0x85); 11835 ins_encode( OpcP, RegReg( src, src ) ); 11836 ins_pipe( ialu_cr_reg_imm ); 11837%} 11838 11839// Unsigned pointer compare Instructions 11840instruct compP_eReg(eFlagsRegU cr, eRegP op1, eRegP op2) %{ 11841 match(Set cr (CmpP op1 op2)); 11842 11843 format %{ "CMPu $op1,$op2" %} 11844 opcode(0x3B); /* Opcode 3B /r */ 11845 ins_encode( OpcP, RegReg( op1, op2) ); 11846 ins_pipe( ialu_cr_reg_reg ); 11847%} 11848 11849instruct compP_eReg_imm(eFlagsRegU cr, eRegP op1, immP op2) %{ 11850 match(Set cr (CmpP op1 op2)); 11851 11852 format %{ "CMPu $op1,$op2" %} 11853 opcode(0x81,0x07); /* Opcode 81 /7 */ 11854 ins_encode( OpcSErm( op1, op2 ), Con8or32( op2 ) ); 11855 ins_pipe( ialu_cr_reg_imm ); 11856%} 11857 11858// // Cisc-spilled version of cmpP_eReg 11859instruct compP_eReg_mem(eFlagsRegU cr, eRegP op1, memory op2) %{ 11860 match(Set cr (CmpP op1 (LoadP op2))); 11861 11862 format %{ "CMPu $op1,$op2" %} 11863 ins_cost(500); 11864 opcode(0x3B); /* Opcode 3B /r */ 11865 ins_encode( OpcP, RegMem( op1, op2) ); 11866 ins_pipe( ialu_cr_reg_mem ); 11867%} 11868 11869// // Cisc-spilled version of cmpP_eReg 11870//instruct compP_mem_eReg(eFlagsRegU cr, memory op1, eRegP op2) %{ 11871// match(Set cr (CmpP (LoadP op1) op2)); 11872// 11873// format %{ "CMPu $op1,$op2" %} 11874// ins_cost(500); 11875// opcode(0x39); /* Opcode 39 /r */ 11876// ins_encode( OpcP, RegMem( op1, op2) ); 11877//%} 11878 11879// Compare raw pointer (used in out-of-heap check). 11880// Only works because non-oop pointers must be raw pointers 11881// and raw pointers have no anti-dependencies. 11882instruct compP_mem_eReg( eFlagsRegU cr, eRegP op1, memory op2 ) %{ 11883 predicate( n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none ); 11884 match(Set cr (CmpP op1 (LoadP op2))); 11885 11886 format %{ "CMPu $op1,$op2" %} 11887 opcode(0x3B); /* Opcode 3B /r */ 11888 ins_encode( OpcP, RegMem( op1, op2) ); 11889 ins_pipe( ialu_cr_reg_mem ); 11890%} 11891 11892// 11893// This will generate a signed flags result. This should be ok 11894// since any compare to a zero should be eq/neq. 11895instruct testP_reg( eFlagsReg cr, eRegP src, immP0 zero ) %{ 11896 match(Set cr (CmpP src zero)); 11897 11898 format %{ "TEST $src,$src" %} 11899 opcode(0x85); 11900 ins_encode( OpcP, RegReg( src, src ) ); 11901 ins_pipe( ialu_cr_reg_imm ); 11902%} 11903 11904// Cisc-spilled version of testP_reg 11905// This will generate a signed flags result. This should be ok 11906// since any compare to a zero should be eq/neq. 11907instruct testP_Reg_mem( eFlagsReg cr, memory op, immI0 zero ) %{ 11908 match(Set cr (CmpP (LoadP op) zero)); 11909 11910 format %{ "TEST $op,0xFFFFFFFF" %} 11911 ins_cost(500); 11912 opcode(0xF7); /* Opcode F7 /0 */ 11913 ins_encode( OpcP, RMopc_Mem(0x00,op), Con_d32(0xFFFFFFFF) ); 11914 ins_pipe( ialu_cr_reg_imm ); 11915%} 11916 11917// Yanked all unsigned pointer compare operations. 11918// Pointer compares are done with CmpP which is already unsigned. 11919 11920//----------Max and Min-------------------------------------------------------- 11921// Min Instructions 11922//// 11923// *** Min and Max using the conditional move are slower than the 11924// *** branch version on a Pentium III. 11925// // Conditional move for min 11926//instruct cmovI_reg_lt( rRegI op2, rRegI op1, eFlagsReg cr ) %{ 11927// effect( USE_DEF op2, USE op1, USE cr ); 11928// format %{ "CMOVlt $op2,$op1\t! min" %} 11929// opcode(0x4C,0x0F); 11930// ins_encode( OpcS, OpcP, RegReg( op2, op1 ) ); 11931// ins_pipe( pipe_cmov_reg ); 11932//%} 11933// 11934//// Min Register with Register (P6 version) 11935//instruct minI_eReg_p6( rRegI op1, rRegI op2 ) %{ 11936// predicate(VM_Version::supports_cmov() ); 11937// match(Set op2 (MinI op1 op2)); 11938// ins_cost(200); 11939// expand %{ 11940// eFlagsReg cr; 11941// compI_eReg(cr,op1,op2); 11942// cmovI_reg_lt(op2,op1,cr); 11943// %} 11944//%} 11945 11946// Min Register with Register (generic version) 11947instruct minI_eReg(rRegI dst, rRegI src, eFlagsReg flags) %{ 11948 match(Set dst (MinI dst src)); 11949 effect(KILL flags); 11950 ins_cost(300); 11951 11952 format %{ "MIN $dst,$src" %} 11953 opcode(0xCC); 11954 ins_encode( min_enc(dst,src) ); 11955 ins_pipe( pipe_slow ); 11956%} 11957 11958// Max Register with Register 11959// *** Min and Max using the conditional move are slower than the 11960// *** branch version on a Pentium III. 11961// // Conditional move for max 11962//instruct cmovI_reg_gt( rRegI op2, rRegI op1, eFlagsReg cr ) %{ 11963// effect( USE_DEF op2, USE op1, USE cr ); 11964// format %{ "CMOVgt $op2,$op1\t! max" %} 11965// opcode(0x4F,0x0F); 11966// ins_encode( OpcS, OpcP, RegReg( op2, op1 ) ); 11967// ins_pipe( pipe_cmov_reg ); 11968//%} 11969// 11970// // Max Register with Register (P6 version) 11971//instruct maxI_eReg_p6( rRegI op1, rRegI op2 ) %{ 11972// predicate(VM_Version::supports_cmov() ); 11973// match(Set op2 (MaxI op1 op2)); 11974// ins_cost(200); 11975// expand %{ 11976// eFlagsReg cr; 11977// compI_eReg(cr,op1,op2); 11978// cmovI_reg_gt(op2,op1,cr); 11979// %} 11980//%} 11981 11982// Max Register with Register (generic version) 11983instruct maxI_eReg(rRegI dst, rRegI src, eFlagsReg flags) %{ 11984 match(Set dst (MaxI dst src)); 11985 effect(KILL flags); 11986 ins_cost(300); 11987 11988 format %{ "MAX $dst,$src" %} 11989 opcode(0xCC); 11990 ins_encode( max_enc(dst,src) ); 11991 ins_pipe( pipe_slow ); 11992%} 11993 11994// ============================================================================ 11995// Counted Loop limit node which represents exact final iterator value. 11996// Note: the resulting value should fit into integer range since 11997// counted loops have limit check on overflow. 11998instruct loopLimit_eReg(eAXRegI limit, nadxRegI init, immI stride, eDXRegI limit_hi, nadxRegI tmp, eFlagsReg flags) %{ 11999 match(Set limit (LoopLimit (Binary init limit) stride)); 12000 effect(TEMP limit_hi, TEMP tmp, KILL flags); 12001 ins_cost(300); 12002 12003 format %{ "loopLimit $init,$limit,$stride # $limit = $init + $stride *( $limit - $init + $stride -1)/ $stride, kills $limit_hi" %} 12004 ins_encode %{ 12005 int strd = (int)$stride$$constant; 12006 assert(strd != 1 && strd != -1, "sanity"); 12007 int m1 = (strd > 0) ? 1 : -1; 12008 // Convert limit to long (EAX:EDX) 12009 __ cdql(); 12010 // Convert init to long (init:tmp) 12011 __ movl($tmp$$Register, $init$$Register); 12012 __ sarl($tmp$$Register, 31); 12013 // $limit - $init 12014 __ subl($limit$$Register, $init$$Register); 12015 __ sbbl($limit_hi$$Register, $tmp$$Register); 12016 // + ($stride - 1) 12017 if (strd > 0) { 12018 __ addl($limit$$Register, (strd - 1)); 12019 __ adcl($limit_hi$$Register, 0); 12020 __ movl($tmp$$Register, strd); 12021 } else { 12022 __ addl($limit$$Register, (strd + 1)); 12023 __ adcl($limit_hi$$Register, -1); 12024 __ lneg($limit_hi$$Register, $limit$$Register); 12025 __ movl($tmp$$Register, -strd); 12026 } 12027 // signed devision: (EAX:EDX) / pos_stride 12028 __ idivl($tmp$$Register); 12029 if (strd < 0) { 12030 // restore sign 12031 __ negl($tmp$$Register); 12032 } 12033 // (EAX) * stride 12034 __ mull($tmp$$Register); 12035 // + init (ignore upper bits) 12036 __ addl($limit$$Register, $init$$Register); 12037 %} 12038 ins_pipe( pipe_slow ); 12039%} 12040 12041// ============================================================================ 12042// Branch Instructions 12043// Jump Table 12044instruct jumpXtnd(rRegI switch_val) %{ 12045 match(Jump switch_val); 12046 ins_cost(350); 12047 format %{ "JMP [$constantaddress](,$switch_val,1)\n\t" %} 12048 ins_encode %{ 12049 // Jump to Address(table_base + switch_reg) 12050 Address index(noreg, $switch_val$$Register, Address::times_1); 12051 __ jump(ArrayAddress($constantaddress, index)); 12052 %} 12053 ins_pipe(pipe_jmp); 12054%} 12055 12056// Jump Direct - Label defines a relative address from JMP+1 12057instruct jmpDir(label labl) %{ 12058 match(Goto); 12059 effect(USE labl); 12060 12061 ins_cost(300); 12062 format %{ "JMP $labl" %} 12063 size(5); 12064 ins_encode %{ 12065 Label* L = $labl$$label; 12066 __ jmp(*L, false); // Always long jump 12067 %} 12068 ins_pipe( pipe_jmp ); 12069%} 12070 12071// Jump Direct Conditional - Label defines a relative address from Jcc+1 12072instruct jmpCon(cmpOp cop, eFlagsReg cr, label labl) %{ 12073 match(If cop cr); 12074 effect(USE labl); 12075 12076 ins_cost(300); 12077 format %{ "J$cop $labl" %} 12078 size(6); 12079 ins_encode %{ 12080 Label* L = $labl$$label; 12081 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12082 %} 12083 ins_pipe( pipe_jcc ); 12084%} 12085 12086// Jump Direct Conditional - Label defines a relative address from Jcc+1 12087instruct jmpLoopEnd(cmpOp cop, eFlagsReg cr, label labl) %{ 12088 match(CountedLoopEnd cop cr); 12089 effect(USE labl); 12090 12091 ins_cost(300); 12092 format %{ "J$cop $labl\t# Loop end" %} 12093 size(6); 12094 ins_encode %{ 12095 Label* L = $labl$$label; 12096 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12097 %} 12098 ins_pipe( pipe_jcc ); 12099%} 12100 12101// Jump Direct Conditional - Label defines a relative address from Jcc+1 12102instruct jmpLoopEndU(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 12103 match(CountedLoopEnd cop cmp); 12104 effect(USE labl); 12105 12106 ins_cost(300); 12107 format %{ "J$cop,u $labl\t# Loop end" %} 12108 size(6); 12109 ins_encode %{ 12110 Label* L = $labl$$label; 12111 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12112 %} 12113 ins_pipe( pipe_jcc ); 12114%} 12115 12116instruct jmpLoopEndUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 12117 match(CountedLoopEnd cop cmp); 12118 effect(USE labl); 12119 12120 ins_cost(200); 12121 format %{ "J$cop,u $labl\t# Loop end" %} 12122 size(6); 12123 ins_encode %{ 12124 Label* L = $labl$$label; 12125 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12126 %} 12127 ins_pipe( pipe_jcc ); 12128%} 12129 12130// Jump Direct Conditional - using unsigned comparison 12131instruct jmpConU(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 12132 match(If cop cmp); 12133 effect(USE labl); 12134 12135 ins_cost(300); 12136 format %{ "J$cop,u $labl" %} 12137 size(6); 12138 ins_encode %{ 12139 Label* L = $labl$$label; 12140 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12141 %} 12142 ins_pipe(pipe_jcc); 12143%} 12144 12145instruct jmpConUCF(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 12146 match(If cop cmp); 12147 effect(USE labl); 12148 12149 ins_cost(200); 12150 format %{ "J$cop,u $labl" %} 12151 size(6); 12152 ins_encode %{ 12153 Label* L = $labl$$label; 12154 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 12155 %} 12156 ins_pipe(pipe_jcc); 12157%} 12158 12159instruct jmpConUCF2(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{ 12160 match(If cop cmp); 12161 effect(USE labl); 12162 12163 ins_cost(200); 12164 format %{ $$template 12165 if ($cop$$cmpcode == Assembler::notEqual) { 12166 $$emit$$"JP,u $labl\n\t" 12167 $$emit$$"J$cop,u $labl" 12168 } else { 12169 $$emit$$"JP,u done\n\t" 12170 $$emit$$"J$cop,u $labl\n\t" 12171 $$emit$$"done:" 12172 } 12173 %} 12174 ins_encode %{ 12175 Label* l = $labl$$label; 12176 if ($cop$$cmpcode == Assembler::notEqual) { 12177 __ jcc(Assembler::parity, *l, false); 12178 __ jcc(Assembler::notEqual, *l, false); 12179 } else if ($cop$$cmpcode == Assembler::equal) { 12180 Label done; 12181 __ jccb(Assembler::parity, done); 12182 __ jcc(Assembler::equal, *l, false); 12183 __ bind(done); 12184 } else { 12185 ShouldNotReachHere(); 12186 } 12187 %} 12188 ins_pipe(pipe_jcc); 12189%} 12190 12191// ============================================================================ 12192// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary superklass 12193// array for an instance of the superklass. Set a hidden internal cache on a 12194// hit (cache is checked with exposed code in gen_subtype_check()). Return 12195// NZ for a miss or zero for a hit. The encoding ALSO sets flags. 12196instruct partialSubtypeCheck( eDIRegP result, eSIRegP sub, eAXRegP super, eCXRegI rcx, eFlagsReg cr ) %{ 12197 match(Set result (PartialSubtypeCheck sub super)); 12198 effect( KILL rcx, KILL cr ); 12199 12200 ins_cost(1100); // slightly larger than the next version 12201 format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t" 12202 "MOV ECX,[EDI+ArrayKlass::length]\t# length to scan\n\t" 12203 "ADD EDI,ArrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" 12204 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" 12205 "JNE,s miss\t\t# Missed: EDI not-zero\n\t" 12206 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache\n\t" 12207 "XOR $result,$result\t\t Hit: EDI zero\n\t" 12208 "miss:\t" %} 12209 12210 opcode(0x1); // Force a XOR of EDI 12211 ins_encode( enc_PartialSubtypeCheck() ); 12212 ins_pipe( pipe_slow ); 12213%} 12214 12215instruct partialSubtypeCheck_vs_Zero( eFlagsReg cr, eSIRegP sub, eAXRegP super, eCXRegI rcx, eDIRegP result, immP0 zero ) %{ 12216 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 12217 effect( KILL rcx, KILL result ); 12218 12219 ins_cost(1000); 12220 format %{ "MOV EDI,[$sub+Klass::secondary_supers]\n\t" 12221 "MOV ECX,[EDI+ArrayKlass::length]\t# length to scan\n\t" 12222 "ADD EDI,ArrayKlass::base_offset\t# Skip to start of data; set NZ in case count is zero\n\t" 12223 "REPNE SCASD\t# Scan *EDI++ for a match with EAX while CX-- != 0\n\t" 12224 "JNE,s miss\t\t# Missed: flags NZ\n\t" 12225 "MOV [$sub+Klass::secondary_super_cache],$super\t# Hit: update cache, flags Z\n\t" 12226 "miss:\t" %} 12227 12228 opcode(0x0); // No need to XOR EDI 12229 ins_encode( enc_PartialSubtypeCheck() ); 12230 ins_pipe( pipe_slow ); 12231%} 12232 12233// ============================================================================ 12234// Branch Instructions -- short offset versions 12235// 12236// These instructions are used to replace jumps of a long offset (the default 12237// match) with jumps of a shorter offset. These instructions are all tagged 12238// with the ins_short_branch attribute, which causes the ADLC to suppress the 12239// match rules in general matching. Instead, the ADLC generates a conversion 12240// method in the MachNode which can be used to do in-place replacement of the 12241// long variant with the shorter variant. The compiler will determine if a 12242// branch can be taken by the is_short_branch_offset() predicate in the machine 12243// specific code section of the file. 12244 12245// Jump Direct - Label defines a relative address from JMP+1 12246instruct jmpDir_short(label labl) %{ 12247 match(Goto); 12248 effect(USE labl); 12249 12250 ins_cost(300); 12251 format %{ "JMP,s $labl" %} 12252 size(2); 12253 ins_encode %{ 12254 Label* L = $labl$$label; 12255 __ jmpb(*L); 12256 %} 12257 ins_pipe( pipe_jmp ); 12258 ins_short_branch(1); 12259%} 12260 12261// Jump Direct Conditional - Label defines a relative address from Jcc+1 12262instruct jmpCon_short(cmpOp cop, eFlagsReg cr, label labl) %{ 12263 match(If cop cr); 12264 effect(USE labl); 12265 12266 ins_cost(300); 12267 format %{ "J$cop,s $labl" %} 12268 size(2); 12269 ins_encode %{ 12270 Label* L = $labl$$label; 12271 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12272 %} 12273 ins_pipe( pipe_jcc ); 12274 ins_short_branch(1); 12275%} 12276 12277// Jump Direct Conditional - Label defines a relative address from Jcc+1 12278instruct jmpLoopEnd_short(cmpOp cop, eFlagsReg cr, label labl) %{ 12279 match(CountedLoopEnd cop cr); 12280 effect(USE labl); 12281 12282 ins_cost(300); 12283 format %{ "J$cop,s $labl\t# Loop end" %} 12284 size(2); 12285 ins_encode %{ 12286 Label* L = $labl$$label; 12287 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12288 %} 12289 ins_pipe( pipe_jcc ); 12290 ins_short_branch(1); 12291%} 12292 12293// Jump Direct Conditional - Label defines a relative address from Jcc+1 12294instruct jmpLoopEndU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 12295 match(CountedLoopEnd cop cmp); 12296 effect(USE labl); 12297 12298 ins_cost(300); 12299 format %{ "J$cop,us $labl\t# Loop end" %} 12300 size(2); 12301 ins_encode %{ 12302 Label* L = $labl$$label; 12303 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12304 %} 12305 ins_pipe( pipe_jcc ); 12306 ins_short_branch(1); 12307%} 12308 12309instruct jmpLoopEndUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 12310 match(CountedLoopEnd cop cmp); 12311 effect(USE labl); 12312 12313 ins_cost(300); 12314 format %{ "J$cop,us $labl\t# Loop end" %} 12315 size(2); 12316 ins_encode %{ 12317 Label* L = $labl$$label; 12318 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12319 %} 12320 ins_pipe( pipe_jcc ); 12321 ins_short_branch(1); 12322%} 12323 12324// Jump Direct Conditional - using unsigned comparison 12325instruct jmpConU_short(cmpOpU cop, eFlagsRegU cmp, label labl) %{ 12326 match(If cop cmp); 12327 effect(USE labl); 12328 12329 ins_cost(300); 12330 format %{ "J$cop,us $labl" %} 12331 size(2); 12332 ins_encode %{ 12333 Label* L = $labl$$label; 12334 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12335 %} 12336 ins_pipe( pipe_jcc ); 12337 ins_short_branch(1); 12338%} 12339 12340instruct jmpConUCF_short(cmpOpUCF cop, eFlagsRegUCF cmp, label labl) %{ 12341 match(If cop cmp); 12342 effect(USE labl); 12343 12344 ins_cost(300); 12345 format %{ "J$cop,us $labl" %} 12346 size(2); 12347 ins_encode %{ 12348 Label* L = $labl$$label; 12349 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 12350 %} 12351 ins_pipe( pipe_jcc ); 12352 ins_short_branch(1); 12353%} 12354 12355instruct jmpConUCF2_short(cmpOpUCF2 cop, eFlagsRegUCF cmp, label labl) %{ 12356 match(If cop cmp); 12357 effect(USE labl); 12358 12359 ins_cost(300); 12360 format %{ $$template 12361 if ($cop$$cmpcode == Assembler::notEqual) { 12362 $$emit$$"JP,u,s $labl\n\t" 12363 $$emit$$"J$cop,u,s $labl" 12364 } else { 12365 $$emit$$"JP,u,s done\n\t" 12366 $$emit$$"J$cop,u,s $labl\n\t" 12367 $$emit$$"done:" 12368 } 12369 %} 12370 size(4); 12371 ins_encode %{ 12372 Label* l = $labl$$label; 12373 if ($cop$$cmpcode == Assembler::notEqual) { 12374 __ jccb(Assembler::parity, *l); 12375 __ jccb(Assembler::notEqual, *l); 12376 } else if ($cop$$cmpcode == Assembler::equal) { 12377 Label done; 12378 __ jccb(Assembler::parity, done); 12379 __ jccb(Assembler::equal, *l); 12380 __ bind(done); 12381 } else { 12382 ShouldNotReachHere(); 12383 } 12384 %} 12385 ins_pipe(pipe_jcc); 12386 ins_short_branch(1); 12387%} 12388 12389// ============================================================================ 12390// Long Compare 12391// 12392// Currently we hold longs in 2 registers. Comparing such values efficiently 12393// is tricky. The flavor of compare used depends on whether we are testing 12394// for LT, LE, or EQ. For a simple LT test we can check just the sign bit. 12395// The GE test is the negated LT test. The LE test can be had by commuting 12396// the operands (yielding a GE test) and then negating; negate again for the 12397// GT test. The EQ test is done by ORcc'ing the high and low halves, and the 12398// NE test is negated from that. 12399 12400// Due to a shortcoming in the ADLC, it mixes up expressions like: 12401// (foo (CmpI (CmpL X Y) 0)) and (bar (CmpI (CmpL X 0L) 0)). Note the 12402// difference between 'Y' and '0L'. The tree-matches for the CmpI sections 12403// are collapsed internally in the ADLC's dfa-gen code. The match for 12404// (CmpI (CmpL X Y) 0) is silently replaced with (CmpI (CmpL X 0L) 0) and the 12405// foo match ends up with the wrong leaf. One fix is to not match both 12406// reg-reg and reg-zero forms of long-compare. This is unfortunate because 12407// both forms beat the trinary form of long-compare and both are very useful 12408// on Intel which has so few registers. 12409 12410// Manifest a CmpL result in an integer register. Very painful. 12411// This is the test to avoid. 12412instruct cmpL3_reg_reg(eSIRegI dst, eRegL src1, eRegL src2, eFlagsReg flags ) %{ 12413 match(Set dst (CmpL3 src1 src2)); 12414 effect( KILL flags ); 12415 ins_cost(1000); 12416 format %{ "XOR $dst,$dst\n\t" 12417 "CMP $src1.hi,$src2.hi\n\t" 12418 "JLT,s m_one\n\t" 12419 "JGT,s p_one\n\t" 12420 "CMP $src1.lo,$src2.lo\n\t" 12421 "JB,s m_one\n\t" 12422 "JEQ,s done\n" 12423 "p_one:\tINC $dst\n\t" 12424 "JMP,s done\n" 12425 "m_one:\tDEC $dst\n" 12426 "done:" %} 12427 ins_encode %{ 12428 Label p_one, m_one, done; 12429 __ xorptr($dst$$Register, $dst$$Register); 12430 __ cmpl(HIGH_FROM_LOW($src1$$Register), HIGH_FROM_LOW($src2$$Register)); 12431 __ jccb(Assembler::less, m_one); 12432 __ jccb(Assembler::greater, p_one); 12433 __ cmpl($src1$$Register, $src2$$Register); 12434 __ jccb(Assembler::below, m_one); 12435 __ jccb(Assembler::equal, done); 12436 __ bind(p_one); 12437 __ incrementl($dst$$Register); 12438 __ jmpb(done); 12439 __ bind(m_one); 12440 __ decrementl($dst$$Register); 12441 __ bind(done); 12442 %} 12443 ins_pipe( pipe_slow ); 12444%} 12445 12446//====== 12447// Manifest a CmpL result in the normal flags. Only good for LT or GE 12448// compares. Can be used for LE or GT compares by reversing arguments. 12449// NOT GOOD FOR EQ/NE tests. 12450instruct cmpL_zero_flags_LTGE( flagsReg_long_LTGE flags, eRegL src, immL0 zero ) %{ 12451 match( Set flags (CmpL src zero )); 12452 ins_cost(100); 12453 format %{ "TEST $src.hi,$src.hi" %} 12454 opcode(0x85); 12455 ins_encode( OpcP, RegReg_Hi2( src, src ) ); 12456 ins_pipe( ialu_cr_reg_reg ); 12457%} 12458 12459// Manifest a CmpL result in the normal flags. Only good for LT or GE 12460// compares. Can be used for LE or GT compares by reversing arguments. 12461// NOT GOOD FOR EQ/NE tests. 12462instruct cmpL_reg_flags_LTGE( flagsReg_long_LTGE flags, eRegL src1, eRegL src2, rRegI tmp ) %{ 12463 match( Set flags (CmpL src1 src2 )); 12464 effect( TEMP tmp ); 12465 ins_cost(300); 12466 format %{ "CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t" 12467 "MOV $tmp,$src1.hi\n\t" 12468 "SBB $tmp,$src2.hi\t! Compute flags for long compare" %} 12469 ins_encode( long_cmp_flags2( src1, src2, tmp ) ); 12470 ins_pipe( ialu_cr_reg_reg ); 12471%} 12472 12473// Long compares reg < zero/req OR reg >= zero/req. 12474// Just a wrapper for a normal branch, plus the predicate test. 12475instruct cmpL_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, label labl) %{ 12476 match(If cmp flags); 12477 effect(USE labl); 12478 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ); 12479 expand %{ 12480 jmpCon(cmp,flags,labl); // JLT or JGE... 12481 %} 12482%} 12483 12484// Compare 2 longs and CMOVE longs. 12485instruct cmovLL_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, eRegL src) %{ 12486 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); 12487 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 )); 12488 ins_cost(400); 12489 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 12490 "CMOV$cmp $dst.hi,$src.hi" %} 12491 opcode(0x0F,0x40); 12492 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) ); 12493 ins_pipe( pipe_cmov_reg_long ); 12494%} 12495 12496instruct cmovLL_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegL dst, load_long_memory src) %{ 12497 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src)))); 12498 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 )); 12499 ins_cost(500); 12500 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 12501 "CMOV$cmp $dst.hi,$src.hi" %} 12502 opcode(0x0F,0x40); 12503 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) ); 12504 ins_pipe( pipe_cmov_reg_long ); 12505%} 12506 12507// Compare 2 longs and CMOVE ints. 12508instruct cmovII_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, rRegI dst, rRegI src) %{ 12509 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 )); 12510 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src))); 12511 ins_cost(200); 12512 format %{ "CMOV$cmp $dst,$src" %} 12513 opcode(0x0F,0x40); 12514 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 12515 ins_pipe( pipe_cmov_reg ); 12516%} 12517 12518instruct cmovII_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, rRegI dst, memory src) %{ 12519 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 )); 12520 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src)))); 12521 ins_cost(250); 12522 format %{ "CMOV$cmp $dst,$src" %} 12523 opcode(0x0F,0x40); 12524 ins_encode( enc_cmov(cmp), RegMem( dst, src ) ); 12525 ins_pipe( pipe_cmov_mem ); 12526%} 12527 12528// Compare 2 longs and CMOVE ints. 12529instruct cmovPP_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegP dst, eRegP src) %{ 12530 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 )); 12531 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src))); 12532 ins_cost(200); 12533 format %{ "CMOV$cmp $dst,$src" %} 12534 opcode(0x0F,0x40); 12535 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 12536 ins_pipe( pipe_cmov_reg ); 12537%} 12538 12539// Compare 2 longs and CMOVE doubles 12540instruct cmovDDPR_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regDPR dst, regDPR src) %{ 12541 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 ); 12542 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 12543 ins_cost(200); 12544 expand %{ 12545 fcmovDPR_regS(cmp,flags,dst,src); 12546 %} 12547%} 12548 12549// Compare 2 longs and CMOVE doubles 12550instruct cmovDD_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regD dst, regD src) %{ 12551 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 ); 12552 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 12553 ins_cost(200); 12554 expand %{ 12555 fcmovD_regS(cmp,flags,dst,src); 12556 %} 12557%} 12558 12559instruct cmovFFPR_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regFPR dst, regFPR src) %{ 12560 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 ); 12561 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 12562 ins_cost(200); 12563 expand %{ 12564 fcmovFPR_regS(cmp,flags,dst,src); 12565 %} 12566%} 12567 12568instruct cmovFF_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, regF dst, regF src) %{ 12569 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 ); 12570 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 12571 ins_cost(200); 12572 expand %{ 12573 fcmovF_regS(cmp,flags,dst,src); 12574 %} 12575%} 12576 12577//====== 12578// Manifest a CmpL result in the normal flags. Only good for EQ/NE compares. 12579instruct cmpL_zero_flags_EQNE( flagsReg_long_EQNE flags, eRegL src, immL0 zero, rRegI tmp ) %{ 12580 match( Set flags (CmpL src zero )); 12581 effect(TEMP tmp); 12582 ins_cost(200); 12583 format %{ "MOV $tmp,$src.lo\n\t" 12584 "OR $tmp,$src.hi\t! Long is EQ/NE 0?" %} 12585 ins_encode( long_cmp_flags0( src, tmp ) ); 12586 ins_pipe( ialu_reg_reg_long ); 12587%} 12588 12589// Manifest a CmpL result in the normal flags. Only good for EQ/NE compares. 12590instruct cmpL_reg_flags_EQNE( flagsReg_long_EQNE flags, eRegL src1, eRegL src2 ) %{ 12591 match( Set flags (CmpL src1 src2 )); 12592 ins_cost(200+300); 12593 format %{ "CMP $src1.lo,$src2.lo\t! Long compare; set flags for low bits\n\t" 12594 "JNE,s skip\n\t" 12595 "CMP $src1.hi,$src2.hi\n\t" 12596 "skip:\t" %} 12597 ins_encode( long_cmp_flags1( src1, src2 ) ); 12598 ins_pipe( ialu_cr_reg_reg ); 12599%} 12600 12601// Long compare reg == zero/reg OR reg != zero/reg 12602// Just a wrapper for a normal branch, plus the predicate test. 12603instruct cmpL_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, label labl) %{ 12604 match(If cmp flags); 12605 effect(USE labl); 12606 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ); 12607 expand %{ 12608 jmpCon(cmp,flags,labl); // JEQ or JNE... 12609 %} 12610%} 12611 12612// Compare 2 longs and CMOVE longs. 12613instruct cmovLL_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, eRegL src) %{ 12614 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); 12615 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 )); 12616 ins_cost(400); 12617 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 12618 "CMOV$cmp $dst.hi,$src.hi" %} 12619 opcode(0x0F,0x40); 12620 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) ); 12621 ins_pipe( pipe_cmov_reg_long ); 12622%} 12623 12624instruct cmovLL_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegL dst, load_long_memory src) %{ 12625 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src)))); 12626 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 )); 12627 ins_cost(500); 12628 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 12629 "CMOV$cmp $dst.hi,$src.hi" %} 12630 opcode(0x0F,0x40); 12631 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) ); 12632 ins_pipe( pipe_cmov_reg_long ); 12633%} 12634 12635// Compare 2 longs and CMOVE ints. 12636instruct cmovII_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, rRegI dst, rRegI src) %{ 12637 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 )); 12638 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src))); 12639 ins_cost(200); 12640 format %{ "CMOV$cmp $dst,$src" %} 12641 opcode(0x0F,0x40); 12642 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 12643 ins_pipe( pipe_cmov_reg ); 12644%} 12645 12646instruct cmovII_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, rRegI dst, memory src) %{ 12647 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 )); 12648 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src)))); 12649 ins_cost(250); 12650 format %{ "CMOV$cmp $dst,$src" %} 12651 opcode(0x0F,0x40); 12652 ins_encode( enc_cmov(cmp), RegMem( dst, src ) ); 12653 ins_pipe( pipe_cmov_mem ); 12654%} 12655 12656// Compare 2 longs and CMOVE ints. 12657instruct cmovPP_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegP dst, eRegP src) %{ 12658 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 )); 12659 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src))); 12660 ins_cost(200); 12661 format %{ "CMOV$cmp $dst,$src" %} 12662 opcode(0x0F,0x40); 12663 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 12664 ins_pipe( pipe_cmov_reg ); 12665%} 12666 12667// Compare 2 longs and CMOVE doubles 12668instruct cmovDDPR_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regDPR dst, regDPR src) %{ 12669 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 ); 12670 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 12671 ins_cost(200); 12672 expand %{ 12673 fcmovDPR_regS(cmp,flags,dst,src); 12674 %} 12675%} 12676 12677// Compare 2 longs and CMOVE doubles 12678instruct cmovDD_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regD dst, regD src) %{ 12679 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 ); 12680 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 12681 ins_cost(200); 12682 expand %{ 12683 fcmovD_regS(cmp,flags,dst,src); 12684 %} 12685%} 12686 12687instruct cmovFFPR_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regFPR dst, regFPR src) %{ 12688 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 ); 12689 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 12690 ins_cost(200); 12691 expand %{ 12692 fcmovFPR_regS(cmp,flags,dst,src); 12693 %} 12694%} 12695 12696instruct cmovFF_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, regF dst, regF src) %{ 12697 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 ); 12698 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 12699 ins_cost(200); 12700 expand %{ 12701 fcmovF_regS(cmp,flags,dst,src); 12702 %} 12703%} 12704 12705//====== 12706// Manifest a CmpL result in the normal flags. Only good for LE or GT compares. 12707// Same as cmpL_reg_flags_LEGT except must negate src 12708instruct cmpL_zero_flags_LEGT( flagsReg_long_LEGT flags, eRegL src, immL0 zero, rRegI tmp ) %{ 12709 match( Set flags (CmpL src zero )); 12710 effect( TEMP tmp ); 12711 ins_cost(300); 12712 format %{ "XOR $tmp,$tmp\t# Long compare for -$src < 0, use commuted test\n\t" 12713 "CMP $tmp,$src.lo\n\t" 12714 "SBB $tmp,$src.hi\n\t" %} 12715 ins_encode( long_cmp_flags3(src, tmp) ); 12716 ins_pipe( ialu_reg_reg_long ); 12717%} 12718 12719// Manifest a CmpL result in the normal flags. Only good for LE or GT compares. 12720// Same as cmpL_reg_flags_LTGE except operands swapped. Swapping operands 12721// requires a commuted test to get the same result. 12722instruct cmpL_reg_flags_LEGT( flagsReg_long_LEGT flags, eRegL src1, eRegL src2, rRegI tmp ) %{ 12723 match( Set flags (CmpL src1 src2 )); 12724 effect( TEMP tmp ); 12725 ins_cost(300); 12726 format %{ "CMP $src2.lo,$src1.lo\t! Long compare, swapped operands, use with commuted test\n\t" 12727 "MOV $tmp,$src2.hi\n\t" 12728 "SBB $tmp,$src1.hi\t! Compute flags for long compare" %} 12729 ins_encode( long_cmp_flags2( src2, src1, tmp ) ); 12730 ins_pipe( ialu_cr_reg_reg ); 12731%} 12732 12733// Long compares reg < zero/req OR reg >= zero/req. 12734// Just a wrapper for a normal branch, plus the predicate test 12735instruct cmpL_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, label labl) %{ 12736 match(If cmp flags); 12737 effect(USE labl); 12738 predicate( _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt || _kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le ); 12739 ins_cost(300); 12740 expand %{ 12741 jmpCon(cmp,flags,labl); // JGT or JLE... 12742 %} 12743%} 12744 12745// Compare 2 longs and CMOVE longs. 12746instruct cmovLL_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, eRegL src) %{ 12747 match(Set dst (CMoveL (Binary cmp flags) (Binary dst src))); 12748 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 )); 12749 ins_cost(400); 12750 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 12751 "CMOV$cmp $dst.hi,$src.hi" %} 12752 opcode(0x0F,0x40); 12753 ins_encode( enc_cmov(cmp), RegReg_Lo2( dst, src ), enc_cmov(cmp), RegReg_Hi2( dst, src ) ); 12754 ins_pipe( pipe_cmov_reg_long ); 12755%} 12756 12757instruct cmovLL_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegL dst, load_long_memory src) %{ 12758 match(Set dst (CMoveL (Binary cmp flags) (Binary dst (LoadL src)))); 12759 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 )); 12760 ins_cost(500); 12761 format %{ "CMOV$cmp $dst.lo,$src.lo\n\t" 12762 "CMOV$cmp $dst.hi,$src.hi+4" %} 12763 opcode(0x0F,0x40); 12764 ins_encode( enc_cmov(cmp), RegMem(dst, src), enc_cmov(cmp), RegMem_Hi(dst, src) ); 12765 ins_pipe( pipe_cmov_reg_long ); 12766%} 12767 12768// Compare 2 longs and CMOVE ints. 12769instruct cmovII_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, rRegI dst, rRegI src) %{ 12770 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 )); 12771 match(Set dst (CMoveI (Binary cmp flags) (Binary dst src))); 12772 ins_cost(200); 12773 format %{ "CMOV$cmp $dst,$src" %} 12774 opcode(0x0F,0x40); 12775 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 12776 ins_pipe( pipe_cmov_reg ); 12777%} 12778 12779instruct cmovII_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, rRegI dst, memory src) %{ 12780 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 )); 12781 match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src)))); 12782 ins_cost(250); 12783 format %{ "CMOV$cmp $dst,$src" %} 12784 opcode(0x0F,0x40); 12785 ins_encode( enc_cmov(cmp), RegMem( dst, src ) ); 12786 ins_pipe( pipe_cmov_mem ); 12787%} 12788 12789// Compare 2 longs and CMOVE ptrs. 12790instruct cmovPP_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegP dst, eRegP src) %{ 12791 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 )); 12792 match(Set dst (CMoveP (Binary cmp flags) (Binary dst src))); 12793 ins_cost(200); 12794 format %{ "CMOV$cmp $dst,$src" %} 12795 opcode(0x0F,0x40); 12796 ins_encode( enc_cmov(cmp), RegReg( dst, src ) ); 12797 ins_pipe( pipe_cmov_reg ); 12798%} 12799 12800// Compare 2 longs and CMOVE doubles 12801instruct cmovDDPR_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regDPR dst, regDPR src) %{ 12802 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 ); 12803 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 12804 ins_cost(200); 12805 expand %{ 12806 fcmovDPR_regS(cmp,flags,dst,src); 12807 %} 12808%} 12809 12810// Compare 2 longs and CMOVE doubles 12811instruct cmovDD_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regD dst, regD src) %{ 12812 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 ); 12813 match(Set dst (CMoveD (Binary cmp flags) (Binary dst src))); 12814 ins_cost(200); 12815 expand %{ 12816 fcmovD_regS(cmp,flags,dst,src); 12817 %} 12818%} 12819 12820instruct cmovFFPR_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regFPR dst, regFPR src) %{ 12821 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 ); 12822 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 12823 ins_cost(200); 12824 expand %{ 12825 fcmovFPR_regS(cmp,flags,dst,src); 12826 %} 12827%} 12828 12829 12830instruct cmovFF_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, regF dst, regF src) %{ 12831 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 ); 12832 match(Set dst (CMoveF (Binary cmp flags) (Binary dst src))); 12833 ins_cost(200); 12834 expand %{ 12835 fcmovF_regS(cmp,flags,dst,src); 12836 %} 12837%} 12838 12839 12840// ============================================================================ 12841// Procedure Call/Return Instructions 12842// Call Java Static Instruction 12843// Note: If this code changes, the corresponding ret_addr_offset() and 12844// compute_padding() functions will have to be adjusted. 12845instruct CallStaticJavaDirect(method meth) %{ 12846 match(CallStaticJava); 12847 predicate(! ((CallStaticJavaNode*)n)->is_method_handle_invoke()); 12848 effect(USE meth); 12849 12850 ins_cost(300); 12851 format %{ "CALL,static " %} 12852 opcode(0xE8); /* E8 cd */ 12853 ins_encode( pre_call_resets, 12854 Java_Static_Call( meth ), 12855 call_epilog, 12856 post_call_FPU ); 12857 ins_pipe( pipe_slow ); 12858 ins_alignment(4); 12859%} 12860 12861// Call Java Static Instruction (method handle version) 12862// Note: If this code changes, the corresponding ret_addr_offset() and 12863// compute_padding() functions will have to be adjusted. 12864instruct CallStaticJavaHandle(method meth, eBPRegP ebp_mh_SP_save) %{ 12865 match(CallStaticJava); 12866 predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke()); 12867 effect(USE meth); 12868 // EBP is saved by all callees (for interpreter stack correction). 12869 // We use it here for a similar purpose, in {preserve,restore}_SP. 12870 12871 ins_cost(300); 12872 format %{ "CALL,static/MethodHandle " %} 12873 opcode(0xE8); /* E8 cd */ 12874 ins_encode( pre_call_resets, 12875 preserve_SP, 12876 Java_Static_Call( meth ), 12877 restore_SP, 12878 call_epilog, 12879 post_call_FPU ); 12880 ins_pipe( pipe_slow ); 12881 ins_alignment(4); 12882%} 12883 12884// Call Java Dynamic Instruction 12885// Note: If this code changes, the corresponding ret_addr_offset() and 12886// compute_padding() functions will have to be adjusted. 12887instruct CallDynamicJavaDirect(method meth) %{ 12888 match(CallDynamicJava); 12889 effect(USE meth); 12890 12891 ins_cost(300); 12892 format %{ "MOV EAX,(oop)-1\n\t" 12893 "CALL,dynamic" %} 12894 opcode(0xE8); /* E8 cd */ 12895 ins_encode( pre_call_resets, 12896 Java_Dynamic_Call( meth ), 12897 call_epilog, 12898 post_call_FPU ); 12899 ins_pipe( pipe_slow ); 12900 ins_alignment(4); 12901%} 12902 12903// Call Runtime Instruction 12904instruct CallRuntimeDirect(method meth) %{ 12905 match(CallRuntime ); 12906 effect(USE meth); 12907 12908 ins_cost(300); 12909 format %{ "CALL,runtime " %} 12910 opcode(0xE8); /* E8 cd */ 12911 // Use FFREEs to clear entries in float stack 12912 ins_encode( pre_call_resets, 12913 FFree_Float_Stack_All, 12914 Java_To_Runtime( meth ), 12915 post_call_FPU ); 12916 ins_pipe( pipe_slow ); 12917%} 12918 12919// Call runtime without safepoint 12920instruct CallLeafDirect(method meth) %{ 12921 match(CallLeaf); 12922 effect(USE meth); 12923 12924 ins_cost(300); 12925 format %{ "CALL_LEAF,runtime " %} 12926 opcode(0xE8); /* E8 cd */ 12927 ins_encode( pre_call_resets, 12928 FFree_Float_Stack_All, 12929 Java_To_Runtime( meth ), 12930 Verify_FPU_For_Leaf, post_call_FPU ); 12931 ins_pipe( pipe_slow ); 12932%} 12933 12934instruct CallLeafNoFPDirect(method meth) %{ 12935 match(CallLeafNoFP); 12936 effect(USE meth); 12937 12938 ins_cost(300); 12939 format %{ "CALL_LEAF_NOFP,runtime " %} 12940 opcode(0xE8); /* E8 cd */ 12941 ins_encode(Java_To_Runtime(meth)); 12942 ins_pipe( pipe_slow ); 12943%} 12944 12945 12946// Return Instruction 12947// Remove the return address & jump to it. 12948instruct Ret() %{ 12949 match(Return); 12950 format %{ "RET" %} 12951 opcode(0xC3); 12952 ins_encode(OpcP); 12953 ins_pipe( pipe_jmp ); 12954%} 12955 12956// Tail Call; Jump from runtime stub to Java code. 12957// Also known as an 'interprocedural jump'. 12958// Target of jump will eventually return to caller. 12959// TailJump below removes the return address. 12960instruct TailCalljmpInd(eRegP_no_EBP jump_target, eBXRegP method_oop) %{ 12961 match(TailCall jump_target method_oop ); 12962 ins_cost(300); 12963 format %{ "JMP $jump_target \t# EBX holds method oop" %} 12964 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12965 ins_encode( OpcP, RegOpc(jump_target) ); 12966 ins_pipe( pipe_jmp ); 12967%} 12968 12969 12970// Tail Jump; remove the return address; jump to target. 12971// TailCall above leaves the return address around. 12972instruct tailjmpInd(eRegP_no_EBP jump_target, eAXRegP ex_oop) %{ 12973 match( TailJump jump_target ex_oop ); 12974 ins_cost(300); 12975 format %{ "POP EDX\t# pop return address into dummy\n\t" 12976 "JMP $jump_target " %} 12977 opcode(0xFF, 0x4); /* Opcode FF /4 */ 12978 ins_encode( enc_pop_rdx, 12979 OpcP, RegOpc(jump_target) ); 12980 ins_pipe( pipe_jmp ); 12981%} 12982 12983// Create exception oop: created by stack-crawling runtime code. 12984// Created exception is now available to this handler, and is setup 12985// just prior to jumping to this handler. No code emitted. 12986instruct CreateException( eAXRegP ex_oop ) 12987%{ 12988 match(Set ex_oop (CreateEx)); 12989 12990 size(0); 12991 // use the following format syntax 12992 format %{ "# exception oop is in EAX; no code emitted" %} 12993 ins_encode(); 12994 ins_pipe( empty ); 12995%} 12996 12997 12998// Rethrow exception: 12999// The exception oop will come in the first argument position. 13000// Then JUMP (not call) to the rethrow stub code. 13001instruct RethrowException() 13002%{ 13003 match(Rethrow); 13004 13005 // use the following format syntax 13006 format %{ "JMP rethrow_stub" %} 13007 ins_encode(enc_rethrow); 13008 ins_pipe( pipe_jmp ); 13009%} 13010 13011// inlined locking and unlocking 13012 13013 13014instruct cmpFastLock( eFlagsReg cr, eRegP object, eBXRegP box, eAXRegI tmp, eRegP scr) %{ 13015 match( Set cr (FastLock object box) ); 13016 effect( TEMP tmp, TEMP scr, USE_KILL box ); 13017 ins_cost(300); 13018 format %{ "FASTLOCK $object,$box\t! kills $box,$tmp,$scr" %} 13019 ins_encode( Fast_Lock(object,box,tmp,scr) ); 13020 ins_pipe( pipe_slow ); 13021%} 13022 13023instruct cmpFastUnlock( eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{ 13024 match( Set cr (FastUnlock object box) ); 13025 effect( TEMP tmp, USE_KILL box ); 13026 ins_cost(300); 13027 format %{ "FASTUNLOCK $object,$box\t! kills $box,$tmp" %} 13028 ins_encode( Fast_Unlock(object,box,tmp) ); 13029 ins_pipe( pipe_slow ); 13030%} 13031 13032 13033 13034// ============================================================================ 13035// Safepoint Instruction 13036instruct safePoint_poll(eFlagsReg cr) %{ 13037 match(SafePoint); 13038 effect(KILL cr); 13039 13040 // TODO-FIXME: we currently poll at offset 0 of the safepoint polling page. 13041 // On SPARC that might be acceptable as we can generate the address with 13042 // just a sethi, saving an or. By polling at offset 0 we can end up 13043 // putting additional pressure on the index-0 in the D$. Because of 13044 // alignment (just like the situation at hand) the lower indices tend 13045 // to see more traffic. It'd be better to change the polling address 13046 // to offset 0 of the last $line in the polling page. 13047 13048 format %{ "TSTL #polladdr,EAX\t! Safepoint: poll for GC" %} 13049 ins_cost(125); 13050 size(6) ; 13051 ins_encode( Safepoint_Poll() ); 13052 ins_pipe( ialu_reg_mem ); 13053%} 13054 13055 13056// ============================================================================ 13057// This name is KNOWN by the ADLC and cannot be changed. 13058// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 13059// for this guy. 13060instruct tlsLoadP(eRegP dst, eFlagsReg cr) %{ 13061 match(Set dst (ThreadLocal)); 13062 effect(DEF dst, KILL cr); 13063 13064 format %{ "MOV $dst, Thread::current()" %} 13065 ins_encode %{ 13066 Register dstReg = as_Register($dst$$reg); 13067 __ get_thread(dstReg); 13068 %} 13069 ins_pipe( ialu_reg_fat ); 13070%} 13071 13072 13073 13074//----------PEEPHOLE RULES----------------------------------------------------- 13075// These must follow all instruction definitions as they use the names 13076// defined in the instructions definitions. 13077// 13078// peepmatch ( root_instr_name [preceding_instruction]* ); 13079// 13080// peepconstraint %{ 13081// (instruction_number.operand_name relational_op instruction_number.operand_name 13082// [, ...] ); 13083// // instruction numbers are zero-based using left to right order in peepmatch 13084// 13085// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 13086// // provide an instruction_number.operand_name for each operand that appears 13087// // in the replacement instruction's match rule 13088// 13089// ---------VM FLAGS--------------------------------------------------------- 13090// 13091// All peephole optimizations can be turned off using -XX:-OptoPeephole 13092// 13093// Each peephole rule is given an identifying number starting with zero and 13094// increasing by one in the order seen by the parser. An individual peephole 13095// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 13096// on the command-line. 13097// 13098// ---------CURRENT LIMITATIONS---------------------------------------------- 13099// 13100// Only match adjacent instructions in same basic block 13101// Only equality constraints 13102// Only constraints between operands, not (0.dest_reg == EAX_enc) 13103// Only one replacement instruction 13104// 13105// ---------EXAMPLE---------------------------------------------------------- 13106// 13107// // pertinent parts of existing instructions in architecture description 13108// instruct movI(rRegI dst, rRegI src) %{ 13109// match(Set dst (CopyI src)); 13110// %} 13111// 13112// instruct incI_eReg(rRegI dst, immI1 src, eFlagsReg cr) %{ 13113// match(Set dst (AddI dst src)); 13114// effect(KILL cr); 13115// %} 13116// 13117// // Change (inc mov) to lea 13118// peephole %{ 13119// // increment preceeded by register-register move 13120// peepmatch ( incI_eReg movI ); 13121// // require that the destination register of the increment 13122// // match the destination register of the move 13123// peepconstraint ( 0.dst == 1.dst ); 13124// // construct a replacement instruction that sets 13125// // the destination to ( move's source register + one ) 13126// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13127// %} 13128// 13129// Implementation no longer uses movX instructions since 13130// machine-independent system no longer uses CopyX nodes. 13131// 13132// peephole %{ 13133// peepmatch ( incI_eReg movI ); 13134// peepconstraint ( 0.dst == 1.dst ); 13135// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13136// %} 13137// 13138// peephole %{ 13139// peepmatch ( decI_eReg movI ); 13140// peepconstraint ( 0.dst == 1.dst ); 13141// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13142// %} 13143// 13144// peephole %{ 13145// peepmatch ( addI_eReg_imm movI ); 13146// peepconstraint ( 0.dst == 1.dst ); 13147// peepreplace ( leaI_eReg_immI( 0.dst 1.src 0.src ) ); 13148// %} 13149// 13150// peephole %{ 13151// peepmatch ( addP_eReg_imm movP ); 13152// peepconstraint ( 0.dst == 1.dst ); 13153// peepreplace ( leaP_eReg_immI( 0.dst 1.src 0.src ) ); 13154// %} 13155 13156// // Change load of spilled value to only a spill 13157// instruct storeI(memory mem, rRegI src) %{ 13158// match(Set mem (StoreI mem src)); 13159// %} 13160// 13161// instruct loadI(rRegI dst, memory mem) %{ 13162// match(Set dst (LoadI mem)); 13163// %} 13164// 13165peephole %{ 13166 peepmatch ( loadI storeI ); 13167 peepconstraint ( 1.src == 0.dst, 1.mem == 0.mem ); 13168 peepreplace ( storeI( 1.mem 1.mem 1.src ) ); 13169%} 13170 13171//----------SMARTSPILL RULES--------------------------------------------------- 13172// These must follow all instruction definitions as they use the names 13173// defined in the instructions definitions. 13174