x86_64.ad revision 5976:2b8e28fdf503
1// 2// Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4// 5// This code is free software; you can redistribute it and/or modify it 6// under the terms of the GNU General Public License version 2 only, as 7// published by the Free Software Foundation. 8// 9// This code is distributed in the hope that it will be useful, but WITHOUT 10// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12// version 2 for more details (a copy is included in the LICENSE file that 13// accompanied this code). 14// 15// You should have received a copy of the GNU General Public License version 16// 2 along with this work; if not, write to the Free Software Foundation, 17// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18// 19// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20// or visit www.oracle.com if you need additional information or have any 21// questions. 22// 23// 24 25// AMD64 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// R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64// used as byte registers) 65 66// Previously set RBX, RSI, and RDI as save-on-entry for java code 67// Turn off SOE in java-code due to frequent use of uncommon-traps. 68// Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85// now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89#ifdef _WIN64 90 91reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97#else 98 99reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105#endif 106 107reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132// Floating Point Registers 133 134// Specify priority of register selection within phases of register 135// allocation. Highest priority is first. A useful heuristic is to 136// give registers a low priority when they are required by machine 137// instructions, like EAX and EDX on I486, and choose no-save registers 138// before save-on-call, & save-on-call before save-on-entry. Registers 139// which participate in fixed calling sequences should come last. 140// Registers which are used as pairs must fall on an even boundary. 141 142alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160//----------Architecture Description Register Classes-------------------------- 161// Several register classes are automatically defined based upon information in 162// this architecture description. 163// 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164// 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166// 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167// 168 169// Class for all pointer registers (including RSP) 170reg_class any_reg(RAX, RAX_H, 171 RDX, RDX_H, 172 RBP, RBP_H, 173 RDI, RDI_H, 174 RSI, RSI_H, 175 RCX, RCX_H, 176 RBX, RBX_H, 177 RSP, RSP_H, 178 R8, R8_H, 179 R9, R9_H, 180 R10, R10_H, 181 R11, R11_H, 182 R12, R12_H, 183 R13, R13_H, 184 R14, R14_H, 185 R15, R15_H); 186 187// Class for all pointer registers except RSP 188reg_class ptr_reg(RAX, RAX_H, 189 RDX, RDX_H, 190 RBP, RBP_H, 191 RDI, RDI_H, 192 RSI, RSI_H, 193 RCX, RCX_H, 194 RBX, RBX_H, 195 R8, R8_H, 196 R9, R9_H, 197 R10, R10_H, 198 R11, R11_H, 199 R13, R13_H, 200 R14, R14_H); 201 202// Class for all pointer registers except RAX and RSP 203reg_class ptr_no_rax_reg(RDX, RDX_H, 204 RBP, RBP_H, 205 RDI, RDI_H, 206 RSI, RSI_H, 207 RCX, RCX_H, 208 RBX, RBX_H, 209 R8, R8_H, 210 R9, R9_H, 211 R10, R10_H, 212 R11, R11_H, 213 R13, R13_H, 214 R14, R14_H); 215 216reg_class ptr_no_rbp_reg(RDX, RDX_H, 217 RAX, RAX_H, 218 RDI, RDI_H, 219 RSI, RSI_H, 220 RCX, RCX_H, 221 RBX, RBX_H, 222 R8, R8_H, 223 R9, R9_H, 224 R10, R10_H, 225 R11, R11_H, 226 R13, R13_H, 227 R14, R14_H); 228 229// Class for all pointer registers except RAX, RBX and RSP 230reg_class ptr_no_rax_rbx_reg(RDX, RDX_H, 231 RBP, RBP_H, 232 RDI, RDI_H, 233 RSI, RSI_H, 234 RCX, RCX_H, 235 R8, R8_H, 236 R9, R9_H, 237 R10, R10_H, 238 R11, R11_H, 239 R13, R13_H, 240 R14, R14_H); 241 242// Singleton class for RAX pointer register 243reg_class ptr_rax_reg(RAX, RAX_H); 244 245// Singleton class for RBX pointer register 246reg_class ptr_rbx_reg(RBX, RBX_H); 247 248// Singleton class for RSI pointer register 249reg_class ptr_rsi_reg(RSI, RSI_H); 250 251// Singleton class for RDI pointer register 252reg_class ptr_rdi_reg(RDI, RDI_H); 253 254// Singleton class for RBP pointer register 255reg_class ptr_rbp_reg(RBP, RBP_H); 256 257// Singleton class for stack pointer 258reg_class ptr_rsp_reg(RSP, RSP_H); 259 260// Singleton class for TLS pointer 261reg_class ptr_r15_reg(R15, R15_H); 262 263// Class for all long registers (except RSP) 264reg_class long_reg(RAX, RAX_H, 265 RDX, RDX_H, 266 RBP, RBP_H, 267 RDI, RDI_H, 268 RSI, RSI_H, 269 RCX, RCX_H, 270 RBX, RBX_H, 271 R8, R8_H, 272 R9, R9_H, 273 R10, R10_H, 274 R11, R11_H, 275 R13, R13_H, 276 R14, R14_H); 277 278// Class for all long registers except RAX, RDX (and RSP) 279reg_class long_no_rax_rdx_reg(RBP, RBP_H, 280 RDI, RDI_H, 281 RSI, RSI_H, 282 RCX, RCX_H, 283 RBX, RBX_H, 284 R8, R8_H, 285 R9, R9_H, 286 R10, R10_H, 287 R11, R11_H, 288 R13, R13_H, 289 R14, R14_H); 290 291// Class for all long registers except RCX (and RSP) 292reg_class long_no_rcx_reg(RBP, RBP_H, 293 RDI, RDI_H, 294 RSI, RSI_H, 295 RAX, RAX_H, 296 RDX, RDX_H, 297 RBX, RBX_H, 298 R8, R8_H, 299 R9, R9_H, 300 R10, R10_H, 301 R11, R11_H, 302 R13, R13_H, 303 R14, R14_H); 304 305// Class for all long registers except RAX (and RSP) 306reg_class long_no_rax_reg(RBP, RBP_H, 307 RDX, RDX_H, 308 RDI, RDI_H, 309 RSI, RSI_H, 310 RCX, RCX_H, 311 RBX, RBX_H, 312 R8, R8_H, 313 R9, R9_H, 314 R10, R10_H, 315 R11, R11_H, 316 R13, R13_H, 317 R14, R14_H); 318 319// Singleton class for RAX long register 320reg_class long_rax_reg(RAX, RAX_H); 321 322// Singleton class for RCX long register 323reg_class long_rcx_reg(RCX, RCX_H); 324 325// Singleton class for RDX long register 326reg_class long_rdx_reg(RDX, RDX_H); 327 328// Class for all int registers (except RSP) 329reg_class int_reg(RAX, 330 RDX, 331 RBP, 332 RDI, 333 RSI, 334 RCX, 335 RBX, 336 R8, 337 R9, 338 R10, 339 R11, 340 R13, 341 R14); 342 343// Class for all int registers except RCX (and RSP) 344reg_class int_no_rcx_reg(RAX, 345 RDX, 346 RBP, 347 RDI, 348 RSI, 349 RBX, 350 R8, 351 R9, 352 R10, 353 R11, 354 R13, 355 R14); 356 357// Class for all int registers except RAX, RDX (and RSP) 358reg_class int_no_rax_rdx_reg(RBP, 359 RDI, 360 RSI, 361 RCX, 362 RBX, 363 R8, 364 R9, 365 R10, 366 R11, 367 R13, 368 R14); 369 370// Singleton class for RAX int register 371reg_class int_rax_reg(RAX); 372 373// Singleton class for RBX int register 374reg_class int_rbx_reg(RBX); 375 376// Singleton class for RCX int register 377reg_class int_rcx_reg(RCX); 378 379// Singleton class for RCX int register 380reg_class int_rdx_reg(RDX); 381 382// Singleton class for RCX int register 383reg_class int_rdi_reg(RDI); 384 385// Singleton class for instruction pointer 386// reg_class ip_reg(RIP); 387 388%} 389 390//----------SOURCE BLOCK------------------------------------------------------- 391// This is a block of C++ code which provides values, functions, and 392// definitions necessary in the rest of the architecture description 393source %{ 394#define RELOC_IMM64 Assembler::imm_operand 395#define RELOC_DISP32 Assembler::disp32_operand 396 397#define __ _masm. 398 399static int preserve_SP_size() { 400 return 3; // rex.w, op, rm(reg/reg) 401} 402static int clear_avx_size() { 403 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper 404} 405 406// !!!!! Special hack to get all types of calls to specify the byte offset 407// from the start of the call to the point where the return address 408// will point. 409int MachCallStaticJavaNode::ret_addr_offset() 410{ 411 int offset = 5; // 5 bytes from start of call to where return address points 412 offset += clear_avx_size(); 413 if (_method_handle_invoke) 414 offset += preserve_SP_size(); 415 return offset; 416} 417 418int MachCallDynamicJavaNode::ret_addr_offset() 419{ 420 int offset = 15; // 15 bytes from start of call to where return address points 421 offset += clear_avx_size(); 422 return offset; 423} 424 425int MachCallRuntimeNode::ret_addr_offset() { 426 int offset = 13; // movq r10,#addr; callq (r10) 427 offset += clear_avx_size(); 428 return offset; 429} 430 431// Indicate if the safepoint node needs the polling page as an input, 432// it does if the polling page is more than disp32 away. 433bool SafePointNode::needs_polling_address_input() 434{ 435 return Assembler::is_polling_page_far(); 436} 437 438// 439// Compute padding required for nodes which need alignment 440// 441 442// The address of the call instruction needs to be 4-byte aligned to 443// ensure that it does not span a cache line so that it can be patched. 444int CallStaticJavaDirectNode::compute_padding(int current_offset) const 445{ 446 current_offset += clear_avx_size(); // skip vzeroupper 447 current_offset += 1; // skip call opcode byte 448 return round_to(current_offset, alignment_required()) - current_offset; 449} 450 451// The address of the call instruction needs to be 4-byte aligned to 452// ensure that it does not span a cache line so that it can be patched. 453int CallStaticJavaHandleNode::compute_padding(int current_offset) const 454{ 455 current_offset += preserve_SP_size(); // skip mov rbp, rsp 456 current_offset += clear_avx_size(); // skip vzeroupper 457 current_offset += 1; // skip call opcode byte 458 return round_to(current_offset, alignment_required()) - current_offset; 459} 460 461// The address of the call instruction needs to be 4-byte aligned to 462// ensure that it does not span a cache line so that it can be patched. 463int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 464{ 465 current_offset += clear_avx_size(); // skip vzeroupper 466 current_offset += 11; // skip movq instruction + call opcode byte 467 return round_to(current_offset, alignment_required()) - current_offset; 468} 469 470// EMIT_RM() 471void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 472 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 473 cbuf.insts()->emit_int8(c); 474} 475 476// EMIT_CC() 477void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 478 unsigned char c = (unsigned char) (f1 | f2); 479 cbuf.insts()->emit_int8(c); 480} 481 482// EMIT_OPCODE() 483void emit_opcode(CodeBuffer &cbuf, int code) { 484 cbuf.insts()->emit_int8((unsigned char) code); 485} 486 487// EMIT_OPCODE() w/ relocation information 488void emit_opcode(CodeBuffer &cbuf, 489 int code, relocInfo::relocType reloc, int offset, int format) 490{ 491 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 492 emit_opcode(cbuf, code); 493} 494 495// EMIT_D8() 496void emit_d8(CodeBuffer &cbuf, int d8) { 497 cbuf.insts()->emit_int8((unsigned char) d8); 498} 499 500// EMIT_D16() 501void emit_d16(CodeBuffer &cbuf, int d16) { 502 cbuf.insts()->emit_int16(d16); 503} 504 505// EMIT_D32() 506void emit_d32(CodeBuffer &cbuf, int d32) { 507 cbuf.insts()->emit_int32(d32); 508} 509 510// EMIT_D64() 511void emit_d64(CodeBuffer &cbuf, int64_t d64) { 512 cbuf.insts()->emit_int64(d64); 513} 514 515// emit 32 bit value and construct relocation entry from relocInfo::relocType 516void emit_d32_reloc(CodeBuffer& cbuf, 517 int d32, 518 relocInfo::relocType reloc, 519 int format) 520{ 521 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 522 cbuf.relocate(cbuf.insts_mark(), reloc, format); 523 cbuf.insts()->emit_int32(d32); 524} 525 526// emit 32 bit value and construct relocation entry from RelocationHolder 527void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 528#ifdef ASSERT 529 if (rspec.reloc()->type() == relocInfo::oop_type && 530 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 531 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 532 assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 533 } 534#endif 535 cbuf.relocate(cbuf.insts_mark(), rspec, format); 536 cbuf.insts()->emit_int32(d32); 537} 538 539void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 540 address next_ip = cbuf.insts_end() + 4; 541 emit_d32_reloc(cbuf, (int) (addr - next_ip), 542 external_word_Relocation::spec(addr), 543 RELOC_DISP32); 544} 545 546 547// emit 64 bit value and construct relocation entry from relocInfo::relocType 548void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 549 cbuf.relocate(cbuf.insts_mark(), reloc, format); 550 cbuf.insts()->emit_int64(d64); 551} 552 553// emit 64 bit value and construct relocation entry from RelocationHolder 554void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 555#ifdef ASSERT 556 if (rspec.reloc()->type() == relocInfo::oop_type && 557 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 558 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 559 assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()), 560 "cannot embed scavengable oops in code"); 561 } 562#endif 563 cbuf.relocate(cbuf.insts_mark(), rspec, format); 564 cbuf.insts()->emit_int64(d64); 565} 566 567// Access stack slot for load or store 568void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 569{ 570 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 571 if (-0x80 <= disp && disp < 0x80) { 572 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 573 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 574 emit_d8(cbuf, disp); // Displacement // R/M byte 575 } else { 576 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 577 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 578 emit_d32(cbuf, disp); // Displacement // R/M byte 579 } 580} 581 582 // rRegI ereg, memory mem) %{ // emit_reg_mem 583void encode_RegMem(CodeBuffer &cbuf, 584 int reg, 585 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 586{ 587 assert(disp_reloc == relocInfo::none, "cannot have disp"); 588 int regenc = reg & 7; 589 int baseenc = base & 7; 590 int indexenc = index & 7; 591 592 // There is no index & no scale, use form without SIB byte 593 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 594 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 595 if (disp == 0 && base != RBP_enc && base != R13_enc) { 596 emit_rm(cbuf, 0x0, regenc, baseenc); // * 597 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 598 // If 8-bit displacement, mode 0x1 599 emit_rm(cbuf, 0x1, regenc, baseenc); // * 600 emit_d8(cbuf, disp); 601 } else { 602 // If 32-bit displacement 603 if (base == -1) { // Special flag for absolute address 604 emit_rm(cbuf, 0x0, regenc, 0x5); // * 605 if (disp_reloc != relocInfo::none) { 606 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 607 } else { 608 emit_d32(cbuf, disp); 609 } 610 } else { 611 // Normal base + offset 612 emit_rm(cbuf, 0x2, regenc, baseenc); // * 613 if (disp_reloc != relocInfo::none) { 614 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 615 } else { 616 emit_d32(cbuf, disp); 617 } 618 } 619 } 620 } else { 621 // Else, encode with the SIB byte 622 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 623 if (disp == 0 && base != RBP_enc && base != R13_enc) { 624 // If no displacement 625 emit_rm(cbuf, 0x0, regenc, 0x4); // * 626 emit_rm(cbuf, scale, indexenc, baseenc); 627 } else { 628 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 629 // If 8-bit displacement, mode 0x1 630 emit_rm(cbuf, 0x1, regenc, 0x4); // * 631 emit_rm(cbuf, scale, indexenc, baseenc); 632 emit_d8(cbuf, disp); 633 } else { 634 // If 32-bit displacement 635 if (base == 0x04 ) { 636 emit_rm(cbuf, 0x2, regenc, 0x4); 637 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 638 } else { 639 emit_rm(cbuf, 0x2, regenc, 0x4); 640 emit_rm(cbuf, scale, indexenc, baseenc); // * 641 } 642 if (disp_reloc != relocInfo::none) { 643 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 644 } else { 645 emit_d32(cbuf, disp); 646 } 647 } 648 } 649 } 650} 651 652// This could be in MacroAssembler but it's fairly C2 specific 653void emit_cmpfp_fixup(MacroAssembler& _masm) { 654 Label exit; 655 __ jccb(Assembler::noParity, exit); 656 __ pushf(); 657 // 658 // comiss/ucomiss instructions set ZF,PF,CF flags and 659 // zero OF,AF,SF for NaN values. 660 // Fixup flags by zeroing ZF,PF so that compare of NaN 661 // values returns 'less than' result (CF is set). 662 // Leave the rest of flags unchanged. 663 // 664 // 7 6 5 4 3 2 1 0 665 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 666 // 0 0 1 0 1 0 1 1 (0x2B) 667 // 668 __ andq(Address(rsp, 0), 0xffffff2b); 669 __ popf(); 670 __ bind(exit); 671} 672 673void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 674 Label done; 675 __ movl(dst, -1); 676 __ jcc(Assembler::parity, done); 677 __ jcc(Assembler::below, done); 678 __ setb(Assembler::notEqual, dst); 679 __ movzbl(dst, dst); 680 __ bind(done); 681} 682 683 684//============================================================================= 685const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 686 687int Compile::ConstantTable::calculate_table_base_offset() const { 688 return 0; // absolute addressing, no offset 689} 690 691void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 692 // Empty encoding 693} 694 695uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 696 return 0; 697} 698 699#ifndef PRODUCT 700void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 701 st->print("# MachConstantBaseNode (empty encoding)"); 702} 703#endif 704 705 706//============================================================================= 707#ifndef PRODUCT 708void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 709 Compile* C = ra_->C; 710 711 int framesize = C->frame_slots() << LogBytesPerInt; 712 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 713 // Remove wordSize for return addr which is already pushed. 714 framesize -= wordSize; 715 716 if (C->need_stack_bang(framesize)) { 717 framesize -= wordSize; 718 st->print("# stack bang"); 719 st->print("\n\t"); 720 st->print("pushq rbp\t# Save rbp"); 721 if (framesize) { 722 st->print("\n\t"); 723 st->print("subq rsp, #%d\t# Create frame",framesize); 724 } 725 } else { 726 st->print("subq rsp, #%d\t# Create frame",framesize); 727 st->print("\n\t"); 728 framesize -= wordSize; 729 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 730 } 731 732 if (VerifyStackAtCalls) { 733 st->print("\n\t"); 734 framesize -= wordSize; 735 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 736#ifdef ASSERT 737 st->print("\n\t"); 738 st->print("# stack alignment check"); 739#endif 740 } 741 st->cr(); 742} 743#endif 744 745void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 746 Compile* C = ra_->C; 747 MacroAssembler _masm(&cbuf); 748 749 int framesize = C->frame_slots() << LogBytesPerInt; 750 751 __ verified_entry(framesize, C->need_stack_bang(framesize), false); 752 753 C->set_frame_complete(cbuf.insts_size()); 754 755 if (C->has_mach_constant_base_node()) { 756 // NOTE: We set the table base offset here because users might be 757 // emitted before MachConstantBaseNode. 758 Compile::ConstantTable& constant_table = C->constant_table(); 759 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 760 } 761} 762 763uint MachPrologNode::size(PhaseRegAlloc* ra_) const 764{ 765 return MachNode::size(ra_); // too many variables; just compute it 766 // the hard way 767} 768 769int MachPrologNode::reloc() const 770{ 771 return 0; // a large enough number 772} 773 774//============================================================================= 775#ifndef PRODUCT 776void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 777{ 778 Compile* C = ra_->C; 779 if (C->max_vector_size() > 16) { 780 st->print("vzeroupper"); 781 st->cr(); st->print("\t"); 782 } 783 784 int framesize = C->frame_slots() << LogBytesPerInt; 785 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 786 // Remove word for return adr already pushed 787 // and RBP 788 framesize -= 2*wordSize; 789 790 if (framesize) { 791 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 792 st->print("\t"); 793 } 794 795 st->print_cr("popq rbp"); 796 if (do_polling() && C->is_method_compilation()) { 797 st->print("\t"); 798 if (Assembler::is_polling_page_far()) { 799 st->print_cr("movq rscratch1, #polling_page_address\n\t" 800 "testl rax, [rscratch1]\t" 801 "# Safepoint: poll for GC"); 802 } else { 803 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 804 "# Safepoint: poll for GC"); 805 } 806 } 807} 808#endif 809 810void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 811{ 812 Compile* C = ra_->C; 813 if (C->max_vector_size() > 16) { 814 // Clear upper bits of YMM registers when current compiled code uses 815 // wide vectors to avoid AVX <-> SSE transition penalty during call. 816 MacroAssembler _masm(&cbuf); 817 __ vzeroupper(); 818 } 819 820 int framesize = C->frame_slots() << LogBytesPerInt; 821 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 822 // Remove word for return adr already pushed 823 // and RBP 824 framesize -= 2*wordSize; 825 826 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 827 828 if (framesize) { 829 emit_opcode(cbuf, Assembler::REX_W); 830 if (framesize < 0x80) { 831 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 832 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 833 emit_d8(cbuf, framesize); 834 } else { 835 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 836 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 837 emit_d32(cbuf, framesize); 838 } 839 } 840 841 // popq rbp 842 emit_opcode(cbuf, 0x58 | RBP_enc); 843 844 if (do_polling() && C->is_method_compilation()) { 845 MacroAssembler _masm(&cbuf); 846 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 847 if (Assembler::is_polling_page_far()) { 848 __ lea(rscratch1, polling_page); 849 __ relocate(relocInfo::poll_return_type); 850 __ testl(rax, Address(rscratch1, 0)); 851 } else { 852 __ testl(rax, polling_page); 853 } 854 } 855} 856 857uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 858{ 859 return MachNode::size(ra_); // too many variables; just compute it 860 // the hard way 861} 862 863int MachEpilogNode::reloc() const 864{ 865 return 2; // a large enough number 866} 867 868const Pipeline* MachEpilogNode::pipeline() const 869{ 870 return MachNode::pipeline_class(); 871} 872 873int MachEpilogNode::safepoint_offset() const 874{ 875 return 0; 876} 877 878//============================================================================= 879 880enum RC { 881 rc_bad, 882 rc_int, 883 rc_float, 884 rc_stack 885}; 886 887static enum RC rc_class(OptoReg::Name reg) 888{ 889 if( !OptoReg::is_valid(reg) ) return rc_bad; 890 891 if (OptoReg::is_stack(reg)) return rc_stack; 892 893 VMReg r = OptoReg::as_VMReg(reg); 894 895 if (r->is_Register()) return rc_int; 896 897 assert(r->is_XMMRegister(), "must be"); 898 return rc_float; 899} 900 901// Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 902static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 903 int src_hi, int dst_hi, uint ireg, outputStream* st); 904 905static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 906 int stack_offset, int reg, uint ireg, outputStream* st); 907 908static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 909 int dst_offset, uint ireg, outputStream* st) { 910 if (cbuf) { 911 MacroAssembler _masm(cbuf); 912 switch (ireg) { 913 case Op_VecS: 914 __ movq(Address(rsp, -8), rax); 915 __ movl(rax, Address(rsp, src_offset)); 916 __ movl(Address(rsp, dst_offset), rax); 917 __ movq(rax, Address(rsp, -8)); 918 break; 919 case Op_VecD: 920 __ pushq(Address(rsp, src_offset)); 921 __ popq (Address(rsp, dst_offset)); 922 break; 923 case Op_VecX: 924 __ pushq(Address(rsp, src_offset)); 925 __ popq (Address(rsp, dst_offset)); 926 __ pushq(Address(rsp, src_offset+8)); 927 __ popq (Address(rsp, dst_offset+8)); 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#ifndef PRODUCT 939 } else { 940 switch (ireg) { 941 case Op_VecS: 942 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 943 "movl rax, [rsp + #%d]\n\t" 944 "movl [rsp + #%d], rax\n\t" 945 "movq rax, [rsp - #8]", 946 src_offset, dst_offset); 947 break; 948 case Op_VecD: 949 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 950 "popq [rsp + #%d]", 951 src_offset, dst_offset); 952 break; 953 case Op_VecX: 954 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 955 "popq [rsp + #%d]\n\t" 956 "pushq [rsp + #%d]\n\t" 957 "popq [rsp + #%d]", 958 src_offset, dst_offset, src_offset+8, dst_offset+8); 959 break; 960 case Op_VecY: 961 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 962 "vmovdqu xmm0, [rsp + #%d]\n\t" 963 "vmovdqu [rsp + #%d], xmm0\n\t" 964 "vmovdqu xmm0, [rsp - #32]", 965 src_offset, dst_offset); 966 break; 967 default: 968 ShouldNotReachHere(); 969 } 970#endif 971 } 972} 973 974uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 975 PhaseRegAlloc* ra_, 976 bool do_size, 977 outputStream* st) const { 978 assert(cbuf != NULL || st != NULL, "sanity"); 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), 991 "must move at least 1 register" ); 992 993 if (src_first == dst_first && src_second == dst_second) { 994 // Self copy, no move 995 return 0; 996 } 997 if (bottom_type()->isa_vect() != NULL) { 998 uint ireg = ideal_reg(); 999 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1000 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity"); 1001 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1002 // mem -> mem 1003 int src_offset = ra_->reg2offset(src_first); 1004 int dst_offset = ra_->reg2offset(dst_first); 1005 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1006 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1007 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1008 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1009 int stack_offset = ra_->reg2offset(dst_first); 1010 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1011 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1012 int stack_offset = ra_->reg2offset(src_first); 1013 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1014 } else { 1015 ShouldNotReachHere(); 1016 } 1017 return 0; 1018 } 1019 if (src_first_rc == rc_stack) { 1020 // mem -> 1021 if (dst_first_rc == rc_stack) { 1022 // mem -> mem 1023 assert(src_second != dst_first, "overlap"); 1024 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1025 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1026 // 64-bit 1027 int src_offset = ra_->reg2offset(src_first); 1028 int dst_offset = ra_->reg2offset(dst_first); 1029 if (cbuf) { 1030 MacroAssembler _masm(cbuf); 1031 __ pushq(Address(rsp, src_offset)); 1032 __ popq (Address(rsp, dst_offset)); 1033#ifndef PRODUCT 1034 } else { 1035 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1036 "popq [rsp + #%d]", 1037 src_offset, dst_offset); 1038#endif 1039 } 1040 } else { 1041 // 32-bit 1042 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1043 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1044 // No pushl/popl, so: 1045 int src_offset = ra_->reg2offset(src_first); 1046 int dst_offset = ra_->reg2offset(dst_first); 1047 if (cbuf) { 1048 MacroAssembler _masm(cbuf); 1049 __ movq(Address(rsp, -8), rax); 1050 __ movl(rax, Address(rsp, src_offset)); 1051 __ movl(Address(rsp, dst_offset), rax); 1052 __ movq(rax, Address(rsp, -8)); 1053#ifndef PRODUCT 1054 } else { 1055 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1056 "movl rax, [rsp + #%d]\n\t" 1057 "movl [rsp + #%d], rax\n\t" 1058 "movq rax, [rsp - #8]", 1059 src_offset, dst_offset); 1060#endif 1061 } 1062 } 1063 return 0; 1064 } else if (dst_first_rc == rc_int) { 1065 // mem -> gpr 1066 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1067 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1068 // 64-bit 1069 int offset = ra_->reg2offset(src_first); 1070 if (cbuf) { 1071 MacroAssembler _masm(cbuf); 1072 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1073#ifndef PRODUCT 1074 } else { 1075 st->print("movq %s, [rsp + #%d]\t# spill", 1076 Matcher::regName[dst_first], 1077 offset); 1078#endif 1079 } 1080 } else { 1081 // 32-bit 1082 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1083 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1084 int offset = ra_->reg2offset(src_first); 1085 if (cbuf) { 1086 MacroAssembler _masm(cbuf); 1087 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1088#ifndef PRODUCT 1089 } else { 1090 st->print("movl %s, [rsp + #%d]\t# spill", 1091 Matcher::regName[dst_first], 1092 offset); 1093#endif 1094 } 1095 } 1096 return 0; 1097 } else if (dst_first_rc == rc_float) { 1098 // mem-> xmm 1099 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1100 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1101 // 64-bit 1102 int offset = ra_->reg2offset(src_first); 1103 if (cbuf) { 1104 MacroAssembler _masm(cbuf); 1105 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1106#ifndef PRODUCT 1107 } else { 1108 st->print("%s %s, [rsp + #%d]\t# spill", 1109 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1110 Matcher::regName[dst_first], 1111 offset); 1112#endif 1113 } 1114 } else { 1115 // 32-bit 1116 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1117 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1118 int offset = ra_->reg2offset(src_first); 1119 if (cbuf) { 1120 MacroAssembler _masm(cbuf); 1121 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1122#ifndef PRODUCT 1123 } else { 1124 st->print("movss %s, [rsp + #%d]\t# spill", 1125 Matcher::regName[dst_first], 1126 offset); 1127#endif 1128 } 1129 } 1130 return 0; 1131 } 1132 } else if (src_first_rc == rc_int) { 1133 // gpr -> 1134 if (dst_first_rc == rc_stack) { 1135 // gpr -> mem 1136 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1137 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1138 // 64-bit 1139 int offset = ra_->reg2offset(dst_first); 1140 if (cbuf) { 1141 MacroAssembler _masm(cbuf); 1142 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1143#ifndef PRODUCT 1144 } else { 1145 st->print("movq [rsp + #%d], %s\t# spill", 1146 offset, 1147 Matcher::regName[src_first]); 1148#endif 1149 } 1150 } else { 1151 // 32-bit 1152 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1153 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1154 int offset = ra_->reg2offset(dst_first); 1155 if (cbuf) { 1156 MacroAssembler _masm(cbuf); 1157 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1158#ifndef PRODUCT 1159 } else { 1160 st->print("movl [rsp + #%d], %s\t# spill", 1161 offset, 1162 Matcher::regName[src_first]); 1163#endif 1164 } 1165 } 1166 return 0; 1167 } else if (dst_first_rc == rc_int) { 1168 // gpr -> gpr 1169 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1170 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1171 // 64-bit 1172 if (cbuf) { 1173 MacroAssembler _masm(cbuf); 1174 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1175 as_Register(Matcher::_regEncode[src_first])); 1176#ifndef PRODUCT 1177 } else { 1178 st->print("movq %s, %s\t# spill", 1179 Matcher::regName[dst_first], 1180 Matcher::regName[src_first]); 1181#endif 1182 } 1183 return 0; 1184 } else { 1185 // 32-bit 1186 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1187 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1188 if (cbuf) { 1189 MacroAssembler _masm(cbuf); 1190 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1191 as_Register(Matcher::_regEncode[src_first])); 1192#ifndef PRODUCT 1193 } else { 1194 st->print("movl %s, %s\t# spill", 1195 Matcher::regName[dst_first], 1196 Matcher::regName[src_first]); 1197#endif 1198 } 1199 return 0; 1200 } 1201 } else if (dst_first_rc == rc_float) { 1202 // gpr -> xmm 1203 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1204 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1205 // 64-bit 1206 if (cbuf) { 1207 MacroAssembler _masm(cbuf); 1208 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1209#ifndef PRODUCT 1210 } else { 1211 st->print("movdq %s, %s\t# spill", 1212 Matcher::regName[dst_first], 1213 Matcher::regName[src_first]); 1214#endif 1215 } 1216 } else { 1217 // 32-bit 1218 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1219 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1220 if (cbuf) { 1221 MacroAssembler _masm(cbuf); 1222 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1223#ifndef PRODUCT 1224 } else { 1225 st->print("movdl %s, %s\t# spill", 1226 Matcher::regName[dst_first], 1227 Matcher::regName[src_first]); 1228#endif 1229 } 1230 } 1231 return 0; 1232 } 1233 } else if (src_first_rc == rc_float) { 1234 // xmm -> 1235 if (dst_first_rc == rc_stack) { 1236 // xmm -> mem 1237 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1238 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1239 // 64-bit 1240 int offset = ra_->reg2offset(dst_first); 1241 if (cbuf) { 1242 MacroAssembler _masm(cbuf); 1243 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1244#ifndef PRODUCT 1245 } else { 1246 st->print("movsd [rsp + #%d], %s\t# spill", 1247 offset, 1248 Matcher::regName[src_first]); 1249#endif 1250 } 1251 } else { 1252 // 32-bit 1253 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1254 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1255 int offset = ra_->reg2offset(dst_first); 1256 if (cbuf) { 1257 MacroAssembler _masm(cbuf); 1258 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1259#ifndef PRODUCT 1260 } else { 1261 st->print("movss [rsp + #%d], %s\t# spill", 1262 offset, 1263 Matcher::regName[src_first]); 1264#endif 1265 } 1266 } 1267 return 0; 1268 } else if (dst_first_rc == rc_int) { 1269 // xmm -> gpr 1270 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1271 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1272 // 64-bit 1273 if (cbuf) { 1274 MacroAssembler _masm(cbuf); 1275 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1276#ifndef PRODUCT 1277 } else { 1278 st->print("movdq %s, %s\t# spill", 1279 Matcher::regName[dst_first], 1280 Matcher::regName[src_first]); 1281#endif 1282 } 1283 } else { 1284 // 32-bit 1285 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1286 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1287 if (cbuf) { 1288 MacroAssembler _masm(cbuf); 1289 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1290#ifndef PRODUCT 1291 } else { 1292 st->print("movdl %s, %s\t# spill", 1293 Matcher::regName[dst_first], 1294 Matcher::regName[src_first]); 1295#endif 1296 } 1297 } 1298 return 0; 1299 } else if (dst_first_rc == rc_float) { 1300 // xmm -> xmm 1301 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1302 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1303 // 64-bit 1304 if (cbuf) { 1305 MacroAssembler _masm(cbuf); 1306 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1307#ifndef PRODUCT 1308 } else { 1309 st->print("%s %s, %s\t# spill", 1310 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1311 Matcher::regName[dst_first], 1312 Matcher::regName[src_first]); 1313#endif 1314 } 1315 } else { 1316 // 32-bit 1317 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1318 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1319 if (cbuf) { 1320 MacroAssembler _masm(cbuf); 1321 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1322#ifndef PRODUCT 1323 } else { 1324 st->print("%s %s, %s\t# spill", 1325 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1326 Matcher::regName[dst_first], 1327 Matcher::regName[src_first]); 1328#endif 1329 } 1330 } 1331 return 0; 1332 } 1333 } 1334 1335 assert(0," foo "); 1336 Unimplemented(); 1337 return 0; 1338} 1339 1340#ifndef PRODUCT 1341void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1342 implementation(NULL, ra_, false, st); 1343} 1344#endif 1345 1346void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1347 implementation(&cbuf, ra_, false, NULL); 1348} 1349 1350uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1351 return MachNode::size(ra_); 1352} 1353 1354//============================================================================= 1355#ifndef PRODUCT 1356void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1357{ 1358 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1359 int reg = ra_->get_reg_first(this); 1360 st->print("leaq %s, [rsp + #%d]\t# box lock", 1361 Matcher::regName[reg], offset); 1362} 1363#endif 1364 1365void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1366{ 1367 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1368 int reg = ra_->get_encode(this); 1369 if (offset >= 0x80) { 1370 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1371 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1372 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1373 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1374 emit_d32(cbuf, offset); 1375 } else { 1376 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1377 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1378 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1379 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1380 emit_d8(cbuf, offset); 1381 } 1382} 1383 1384uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1385{ 1386 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1387 return (offset < 0x80) ? 5 : 8; // REX 1388} 1389 1390//============================================================================= 1391#ifndef PRODUCT 1392void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1393{ 1394 if (UseCompressedClassPointers) { 1395 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1396 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1397 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1398 } else { 1399 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1400 "# Inline cache check"); 1401 } 1402 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1403 st->print_cr("\tnop\t# nops to align entry point"); 1404} 1405#endif 1406 1407void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1408{ 1409 MacroAssembler masm(&cbuf); 1410 uint insts_size = cbuf.insts_size(); 1411 if (UseCompressedClassPointers) { 1412 masm.load_klass(rscratch1, j_rarg0); 1413 masm.cmpptr(rax, rscratch1); 1414 } else { 1415 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1416 } 1417 1418 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1419 1420 /* WARNING these NOPs are critical so that verified entry point is properly 1421 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1422 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1423 if (OptoBreakpoint) { 1424 // Leave space for int3 1425 nops_cnt -= 1; 1426 } 1427 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1428 if (nops_cnt > 0) 1429 masm.nop(nops_cnt); 1430} 1431 1432uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1433{ 1434 return MachNode::size(ra_); // too many variables; just compute it 1435 // the hard way 1436} 1437 1438 1439//============================================================================= 1440uint size_exception_handler() 1441{ 1442 // NativeCall instruction size is the same as NativeJump. 1443 // Note that this value is also credited (in output.cpp) to 1444 // the size of the code section. 1445 return NativeJump::instruction_size; 1446} 1447 1448// Emit exception handler code. 1449int emit_exception_handler(CodeBuffer& cbuf) 1450{ 1451 1452 // Note that the code buffer's insts_mark is always relative to insts. 1453 // That's why we must use the macroassembler to generate a handler. 1454 MacroAssembler _masm(&cbuf); 1455 address base = 1456 __ start_a_stub(size_exception_handler()); 1457 if (base == NULL) return 0; // CodeBuffer::expand failed 1458 int offset = __ offset(); 1459 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1460 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1461 __ end_a_stub(); 1462 return offset; 1463} 1464 1465uint size_deopt_handler() 1466{ 1467 // three 5 byte instructions 1468 return 15; 1469} 1470 1471// Emit deopt handler code. 1472int emit_deopt_handler(CodeBuffer& cbuf) 1473{ 1474 1475 // Note that the code buffer's insts_mark is always relative to insts. 1476 // That's why we must use the macroassembler to generate a handler. 1477 MacroAssembler _masm(&cbuf); 1478 address base = 1479 __ start_a_stub(size_deopt_handler()); 1480 if (base == NULL) return 0; // CodeBuffer::expand failed 1481 int offset = __ offset(); 1482 address the_pc = (address) __ pc(); 1483 Label next; 1484 // push a "the_pc" on the stack without destroying any registers 1485 // as they all may be live. 1486 1487 // push address of "next" 1488 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 1489 __ bind(next); 1490 // adjust it so it matches "the_pc" 1491 __ subptr(Address(rsp, 0), __ offset() - offset); 1492 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1493 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1494 __ end_a_stub(); 1495 return offset; 1496} 1497 1498int Matcher::regnum_to_fpu_offset(int regnum) 1499{ 1500 return regnum - 32; // The FP registers are in the second chunk 1501} 1502 1503// This is UltraSparc specific, true just means we have fast l2f conversion 1504const bool Matcher::convL2FSupported(void) { 1505 return true; 1506} 1507 1508// Is this branch offset short enough that a short branch can be used? 1509// 1510// NOTE: If the platform does not provide any short branch variants, then 1511// this method should return false for offset 0. 1512bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1513 // The passed offset is relative to address of the branch. 1514 // On 86 a branch displacement is calculated relative to address 1515 // of a next instruction. 1516 offset -= br_size; 1517 1518 // the short version of jmpConUCF2 contains multiple branches, 1519 // making the reach slightly less 1520 if (rule == jmpConUCF2_rule) 1521 return (-126 <= offset && offset <= 125); 1522 return (-128 <= offset && offset <= 127); 1523} 1524 1525const bool Matcher::isSimpleConstant64(jlong value) { 1526 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1527 //return value == (int) value; // Cf. storeImmL and immL32. 1528 1529 // Probably always true, even if a temp register is required. 1530 return true; 1531} 1532 1533// The ecx parameter to rep stosq for the ClearArray node is in words. 1534const bool Matcher::init_array_count_is_in_bytes = false; 1535 1536// Threshold size for cleararray. 1537const int Matcher::init_array_short_size = 8 * BytesPerLong; 1538 1539// No additional cost for CMOVL. 1540const int Matcher::long_cmove_cost() { return 0; } 1541 1542// No CMOVF/CMOVD with SSE2 1543const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1544 1545// Should the Matcher clone shifts on addressing modes, expecting them 1546// to be subsumed into complex addressing expressions or compute them 1547// into registers? True for Intel but false for most RISCs 1548const bool Matcher::clone_shift_expressions = true; 1549 1550// Do we need to mask the count passed to shift instructions or does 1551// the cpu only look at the lower 5/6 bits anyway? 1552const bool Matcher::need_masked_shift_count = false; 1553 1554bool Matcher::narrow_oop_use_complex_address() { 1555 assert(UseCompressedOops, "only for compressed oops code"); 1556 return (LogMinObjAlignmentInBytes <= 3); 1557} 1558 1559bool Matcher::narrow_klass_use_complex_address() { 1560 assert(UseCompressedClassPointers, "only for compressed klass code"); 1561 return (LogKlassAlignmentInBytes <= 3); 1562} 1563 1564// Is it better to copy float constants, or load them directly from 1565// memory? Intel can load a float constant from a direct address, 1566// requiring no extra registers. Most RISCs will have to materialize 1567// an address into a register first, so they would do better to copy 1568// the constant from stack. 1569const bool Matcher::rematerialize_float_constants = true; // XXX 1570 1571// If CPU can load and store mis-aligned doubles directly then no 1572// fixup is needed. Else we split the double into 2 integer pieces 1573// and move it piece-by-piece. Only happens when passing doubles into 1574// C code as the Java calling convention forces doubles to be aligned. 1575const bool Matcher::misaligned_doubles_ok = true; 1576 1577// No-op on amd64 1578void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1579 1580// Advertise here if the CPU requires explicit rounding operations to 1581// implement the UseStrictFP mode. 1582const bool Matcher::strict_fp_requires_explicit_rounding = true; 1583 1584// Are floats conerted to double when stored to stack during deoptimization? 1585// On x64 it is stored without convertion so we can use normal access. 1586bool Matcher::float_in_double() { return false; } 1587 1588// Do ints take an entire long register or just half? 1589const bool Matcher::int_in_long = true; 1590 1591// Return whether or not this register is ever used as an argument. 1592// This function is used on startup to build the trampoline stubs in 1593// generateOptoStub. Registers not mentioned will be killed by the VM 1594// call in the trampoline, and arguments in those registers not be 1595// available to the callee. 1596bool Matcher::can_be_java_arg(int reg) 1597{ 1598 return 1599 reg == RDI_num || reg == RDI_H_num || 1600 reg == RSI_num || reg == RSI_H_num || 1601 reg == RDX_num || reg == RDX_H_num || 1602 reg == RCX_num || reg == RCX_H_num || 1603 reg == R8_num || reg == R8_H_num || 1604 reg == R9_num || reg == R9_H_num || 1605 reg == R12_num || reg == R12_H_num || 1606 reg == XMM0_num || reg == XMM0b_num || 1607 reg == XMM1_num || reg == XMM1b_num || 1608 reg == XMM2_num || reg == XMM2b_num || 1609 reg == XMM3_num || reg == XMM3b_num || 1610 reg == XMM4_num || reg == XMM4b_num || 1611 reg == XMM5_num || reg == XMM5b_num || 1612 reg == XMM6_num || reg == XMM6b_num || 1613 reg == XMM7_num || reg == XMM7b_num; 1614} 1615 1616bool Matcher::is_spillable_arg(int reg) 1617{ 1618 return can_be_java_arg(reg); 1619} 1620 1621bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1622 // In 64 bit mode a code which use multiply when 1623 // devisor is constant is faster than hardware 1624 // DIV instruction (it uses MulHiL). 1625 return false; 1626} 1627 1628// Register for DIVI projection of divmodI 1629RegMask Matcher::divI_proj_mask() { 1630 return INT_RAX_REG_mask(); 1631} 1632 1633// Register for MODI projection of divmodI 1634RegMask Matcher::modI_proj_mask() { 1635 return INT_RDX_REG_mask(); 1636} 1637 1638// Register for DIVL projection of divmodL 1639RegMask Matcher::divL_proj_mask() { 1640 return LONG_RAX_REG_mask(); 1641} 1642 1643// Register for MODL projection of divmodL 1644RegMask Matcher::modL_proj_mask() { 1645 return LONG_RDX_REG_mask(); 1646} 1647 1648const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1649 return PTR_RBP_REG_mask(); 1650} 1651 1652const RegMask Matcher::mathExactI_result_proj_mask() { 1653 return INT_RAX_REG_mask(); 1654} 1655 1656const RegMask Matcher::mathExactL_result_proj_mask() { 1657 return LONG_RAX_REG_mask(); 1658} 1659 1660const RegMask Matcher::mathExactI_flags_proj_mask() { 1661 return INT_FLAGS_mask(); 1662} 1663 1664%} 1665 1666//----------ENCODING BLOCK----------------------------------------------------- 1667// This block specifies the encoding classes used by the compiler to 1668// output byte streams. Encoding classes are parameterized macros 1669// used by Machine Instruction Nodes in order to generate the bit 1670// encoding of the instruction. Operands specify their base encoding 1671// interface with the interface keyword. There are currently 1672// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1673// COND_INTER. REG_INTER causes an operand to generate a function 1674// which returns its register number when queried. CONST_INTER causes 1675// an operand to generate a function which returns the value of the 1676// constant when queried. MEMORY_INTER causes an operand to generate 1677// four functions which return the Base Register, the Index Register, 1678// the Scale Value, and the Offset Value of the operand when queried. 1679// COND_INTER causes an operand to generate six functions which return 1680// the encoding code (ie - encoding bits for the instruction) 1681// associated with each basic boolean condition for a conditional 1682// instruction. 1683// 1684// Instructions specify two basic values for encoding. Again, a 1685// function is available to check if the constant displacement is an 1686// oop. They use the ins_encode keyword to specify their encoding 1687// classes (which must be a sequence of enc_class names, and their 1688// parameters, specified in the encoding block), and they use the 1689// opcode keyword to specify, in order, their primary, secondary, and 1690// tertiary opcode. Only the opcode sections which a particular 1691// instruction needs for encoding need to be specified. 1692encode %{ 1693 // Build emit functions for each basic byte or larger field in the 1694 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1695 // from C++ code in the enc_class source block. Emit functions will 1696 // live in the main source block for now. In future, we can 1697 // generalize this by adding a syntax that specifies the sizes of 1698 // fields in an order, so that the adlc can build the emit functions 1699 // automagically 1700 1701 // Emit primary opcode 1702 enc_class OpcP 1703 %{ 1704 emit_opcode(cbuf, $primary); 1705 %} 1706 1707 // Emit secondary opcode 1708 enc_class OpcS 1709 %{ 1710 emit_opcode(cbuf, $secondary); 1711 %} 1712 1713 // Emit tertiary opcode 1714 enc_class OpcT 1715 %{ 1716 emit_opcode(cbuf, $tertiary); 1717 %} 1718 1719 // Emit opcode directly 1720 enc_class Opcode(immI d8) 1721 %{ 1722 emit_opcode(cbuf, $d8$$constant); 1723 %} 1724 1725 // Emit size prefix 1726 enc_class SizePrefix 1727 %{ 1728 emit_opcode(cbuf, 0x66); 1729 %} 1730 1731 enc_class reg(rRegI reg) 1732 %{ 1733 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1734 %} 1735 1736 enc_class reg_reg(rRegI dst, rRegI src) 1737 %{ 1738 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1739 %} 1740 1741 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1742 %{ 1743 emit_opcode(cbuf, $opcode$$constant); 1744 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1745 %} 1746 1747 enc_class cdql_enc(no_rax_rdx_RegI div) 1748 %{ 1749 // Full implementation of Java idiv and irem; checks for 1750 // special case as described in JVM spec., p.243 & p.271. 1751 // 1752 // normal case special case 1753 // 1754 // input : rax: dividend min_int 1755 // reg: divisor -1 1756 // 1757 // output: rax: quotient (= rax idiv reg) min_int 1758 // rdx: remainder (= rax irem reg) 0 1759 // 1760 // Code sequnce: 1761 // 1762 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1763 // 5: 75 07/08 jne e <normal> 1764 // 7: 33 d2 xor %edx,%edx 1765 // [div >= 8 -> offset + 1] 1766 // [REX_B] 1767 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1768 // c: 74 03/04 je 11 <done> 1769 // 000000000000000e <normal>: 1770 // e: 99 cltd 1771 // [div >= 8 -> offset + 1] 1772 // [REX_B] 1773 // f: f7 f9 idiv $div 1774 // 0000000000000011 <done>: 1775 1776 // cmp $0x80000000,%eax 1777 emit_opcode(cbuf, 0x3d); 1778 emit_d8(cbuf, 0x00); 1779 emit_d8(cbuf, 0x00); 1780 emit_d8(cbuf, 0x00); 1781 emit_d8(cbuf, 0x80); 1782 1783 // jne e <normal> 1784 emit_opcode(cbuf, 0x75); 1785 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1786 1787 // xor %edx,%edx 1788 emit_opcode(cbuf, 0x33); 1789 emit_d8(cbuf, 0xD2); 1790 1791 // cmp $0xffffffffffffffff,%ecx 1792 if ($div$$reg >= 8) { 1793 emit_opcode(cbuf, Assembler::REX_B); 1794 } 1795 emit_opcode(cbuf, 0x83); 1796 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1797 emit_d8(cbuf, 0xFF); 1798 1799 // je 11 <done> 1800 emit_opcode(cbuf, 0x74); 1801 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1802 1803 // <normal> 1804 // cltd 1805 emit_opcode(cbuf, 0x99); 1806 1807 // idivl (note: must be emitted by the user of this rule) 1808 // <done> 1809 %} 1810 1811 enc_class cdqq_enc(no_rax_rdx_RegL div) 1812 %{ 1813 // Full implementation of Java ldiv and lrem; checks for 1814 // special case as described in JVM spec., p.243 & p.271. 1815 // 1816 // normal case special case 1817 // 1818 // input : rax: dividend min_long 1819 // reg: divisor -1 1820 // 1821 // output: rax: quotient (= rax idiv reg) min_long 1822 // rdx: remainder (= rax irem reg) 0 1823 // 1824 // Code sequnce: 1825 // 1826 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1827 // 7: 00 00 80 1828 // a: 48 39 d0 cmp %rdx,%rax 1829 // d: 75 08 jne 17 <normal> 1830 // f: 33 d2 xor %edx,%edx 1831 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1832 // 15: 74 05 je 1c <done> 1833 // 0000000000000017 <normal>: 1834 // 17: 48 99 cqto 1835 // 19: 48 f7 f9 idiv $div 1836 // 000000000000001c <done>: 1837 1838 // mov $0x8000000000000000,%rdx 1839 emit_opcode(cbuf, Assembler::REX_W); 1840 emit_opcode(cbuf, 0xBA); 1841 emit_d8(cbuf, 0x00); 1842 emit_d8(cbuf, 0x00); 1843 emit_d8(cbuf, 0x00); 1844 emit_d8(cbuf, 0x00); 1845 emit_d8(cbuf, 0x00); 1846 emit_d8(cbuf, 0x00); 1847 emit_d8(cbuf, 0x00); 1848 emit_d8(cbuf, 0x80); 1849 1850 // cmp %rdx,%rax 1851 emit_opcode(cbuf, Assembler::REX_W); 1852 emit_opcode(cbuf, 0x39); 1853 emit_d8(cbuf, 0xD0); 1854 1855 // jne 17 <normal> 1856 emit_opcode(cbuf, 0x75); 1857 emit_d8(cbuf, 0x08); 1858 1859 // xor %edx,%edx 1860 emit_opcode(cbuf, 0x33); 1861 emit_d8(cbuf, 0xD2); 1862 1863 // cmp $0xffffffffffffffff,$div 1864 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1865 emit_opcode(cbuf, 0x83); 1866 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1867 emit_d8(cbuf, 0xFF); 1868 1869 // je 1e <done> 1870 emit_opcode(cbuf, 0x74); 1871 emit_d8(cbuf, 0x05); 1872 1873 // <normal> 1874 // cqto 1875 emit_opcode(cbuf, Assembler::REX_W); 1876 emit_opcode(cbuf, 0x99); 1877 1878 // idivq (note: must be emitted by the user of this rule) 1879 // <done> 1880 %} 1881 1882 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1883 enc_class OpcSE(immI imm) 1884 %{ 1885 // Emit primary opcode and set sign-extend bit 1886 // Check for 8-bit immediate, and set sign extend bit in opcode 1887 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1888 emit_opcode(cbuf, $primary | 0x02); 1889 } else { 1890 // 32-bit immediate 1891 emit_opcode(cbuf, $primary); 1892 } 1893 %} 1894 1895 enc_class OpcSErm(rRegI dst, immI imm) 1896 %{ 1897 // OpcSEr/m 1898 int dstenc = $dst$$reg; 1899 if (dstenc >= 8) { 1900 emit_opcode(cbuf, Assembler::REX_B); 1901 dstenc -= 8; 1902 } 1903 // Emit primary opcode and set sign-extend bit 1904 // Check for 8-bit immediate, and set sign extend bit in opcode 1905 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1906 emit_opcode(cbuf, $primary | 0x02); 1907 } else { 1908 // 32-bit immediate 1909 emit_opcode(cbuf, $primary); 1910 } 1911 // Emit r/m byte with secondary opcode, after primary opcode. 1912 emit_rm(cbuf, 0x3, $secondary, dstenc); 1913 %} 1914 1915 enc_class OpcSErm_wide(rRegL dst, immI imm) 1916 %{ 1917 // OpcSEr/m 1918 int dstenc = $dst$$reg; 1919 if (dstenc < 8) { 1920 emit_opcode(cbuf, Assembler::REX_W); 1921 } else { 1922 emit_opcode(cbuf, Assembler::REX_WB); 1923 dstenc -= 8; 1924 } 1925 // Emit primary opcode and set sign-extend bit 1926 // Check for 8-bit immediate, and set sign extend bit in opcode 1927 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1928 emit_opcode(cbuf, $primary | 0x02); 1929 } else { 1930 // 32-bit immediate 1931 emit_opcode(cbuf, $primary); 1932 } 1933 // Emit r/m byte with secondary opcode, after primary opcode. 1934 emit_rm(cbuf, 0x3, $secondary, dstenc); 1935 %} 1936 1937 enc_class Con8or32(immI imm) 1938 %{ 1939 // Check for 8-bit immediate, and set sign extend bit in opcode 1940 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1941 $$$emit8$imm$$constant; 1942 } else { 1943 // 32-bit immediate 1944 $$$emit32$imm$$constant; 1945 } 1946 %} 1947 1948 enc_class opc2_reg(rRegI dst) 1949 %{ 1950 // BSWAP 1951 emit_cc(cbuf, $secondary, $dst$$reg); 1952 %} 1953 1954 enc_class opc3_reg(rRegI dst) 1955 %{ 1956 // BSWAP 1957 emit_cc(cbuf, $tertiary, $dst$$reg); 1958 %} 1959 1960 enc_class reg_opc(rRegI div) 1961 %{ 1962 // INC, DEC, IDIV, IMOD, JMP indirect, ... 1963 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 1964 %} 1965 1966 enc_class enc_cmov(cmpOp cop) 1967 %{ 1968 // CMOV 1969 $$$emit8$primary; 1970 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1971 %} 1972 1973 enc_class enc_PartialSubtypeCheck() 1974 %{ 1975 Register Rrdi = as_Register(RDI_enc); // result register 1976 Register Rrax = as_Register(RAX_enc); // super class 1977 Register Rrcx = as_Register(RCX_enc); // killed 1978 Register Rrsi = as_Register(RSI_enc); // sub class 1979 Label miss; 1980 const bool set_cond_codes = true; 1981 1982 MacroAssembler _masm(&cbuf); 1983 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 1984 NULL, &miss, 1985 /*set_cond_codes:*/ true); 1986 if ($primary) { 1987 __ xorptr(Rrdi, Rrdi); 1988 } 1989 __ bind(miss); 1990 %} 1991 1992 enc_class clear_avx %{ 1993 debug_only(int off0 = cbuf.insts_size()); 1994 if (ra_->C->max_vector_size() > 16) { 1995 // Clear upper bits of YMM registers when current compiled code uses 1996 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1997 MacroAssembler _masm(&cbuf); 1998 __ vzeroupper(); 1999 } 2000 debug_only(int off1 = cbuf.insts_size()); 2001 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2002 %} 2003 2004 enc_class Java_To_Runtime(method meth) %{ 2005 // No relocation needed 2006 MacroAssembler _masm(&cbuf); 2007 __ mov64(r10, (int64_t) $meth$$method); 2008 __ call(r10); 2009 %} 2010 2011 enc_class Java_To_Interpreter(method meth) 2012 %{ 2013 // CALL Java_To_Interpreter 2014 // This is the instruction starting address for relocation info. 2015 cbuf.set_insts_mark(); 2016 $$$emit8$primary; 2017 // CALL directly to the runtime 2018 emit_d32_reloc(cbuf, 2019 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2020 runtime_call_Relocation::spec(), 2021 RELOC_DISP32); 2022 %} 2023 2024 enc_class Java_Static_Call(method meth) 2025 %{ 2026 // JAVA STATIC CALL 2027 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2028 // determine who we intended to call. 2029 cbuf.set_insts_mark(); 2030 $$$emit8$primary; 2031 2032 if (!_method) { 2033 emit_d32_reloc(cbuf, 2034 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2035 runtime_call_Relocation::spec(), 2036 RELOC_DISP32); 2037 } else if (_optimized_virtual) { 2038 emit_d32_reloc(cbuf, 2039 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2040 opt_virtual_call_Relocation::spec(), 2041 RELOC_DISP32); 2042 } else { 2043 emit_d32_reloc(cbuf, 2044 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2045 static_call_Relocation::spec(), 2046 RELOC_DISP32); 2047 } 2048 if (_method) { 2049 // Emit stub for static call. 2050 CompiledStaticCall::emit_to_interp_stub(cbuf); 2051 } 2052 %} 2053 2054 enc_class Java_Dynamic_Call(method meth) %{ 2055 MacroAssembler _masm(&cbuf); 2056 __ ic_call((address)$meth$$method); 2057 %} 2058 2059 enc_class Java_Compiled_Call(method meth) 2060 %{ 2061 // JAVA COMPILED CALL 2062 int disp = in_bytes(Method:: from_compiled_offset()); 2063 2064 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2065 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2066 2067 // callq *disp(%rax) 2068 cbuf.set_insts_mark(); 2069 $$$emit8$primary; 2070 if (disp < 0x80) { 2071 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2072 emit_d8(cbuf, disp); // Displacement 2073 } else { 2074 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2075 emit_d32(cbuf, disp); // Displacement 2076 } 2077 %} 2078 2079 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2080 %{ 2081 // SAL, SAR, SHR 2082 int dstenc = $dst$$reg; 2083 if (dstenc >= 8) { 2084 emit_opcode(cbuf, Assembler::REX_B); 2085 dstenc -= 8; 2086 } 2087 $$$emit8$primary; 2088 emit_rm(cbuf, 0x3, $secondary, dstenc); 2089 $$$emit8$shift$$constant; 2090 %} 2091 2092 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2093 %{ 2094 // SAL, SAR, SHR 2095 int dstenc = $dst$$reg; 2096 if (dstenc < 8) { 2097 emit_opcode(cbuf, Assembler::REX_W); 2098 } else { 2099 emit_opcode(cbuf, Assembler::REX_WB); 2100 dstenc -= 8; 2101 } 2102 $$$emit8$primary; 2103 emit_rm(cbuf, 0x3, $secondary, dstenc); 2104 $$$emit8$shift$$constant; 2105 %} 2106 2107 enc_class load_immI(rRegI dst, immI src) 2108 %{ 2109 int dstenc = $dst$$reg; 2110 if (dstenc >= 8) { 2111 emit_opcode(cbuf, Assembler::REX_B); 2112 dstenc -= 8; 2113 } 2114 emit_opcode(cbuf, 0xB8 | dstenc); 2115 $$$emit32$src$$constant; 2116 %} 2117 2118 enc_class load_immL(rRegL dst, immL src) 2119 %{ 2120 int dstenc = $dst$$reg; 2121 if (dstenc < 8) { 2122 emit_opcode(cbuf, Assembler::REX_W); 2123 } else { 2124 emit_opcode(cbuf, Assembler::REX_WB); 2125 dstenc -= 8; 2126 } 2127 emit_opcode(cbuf, 0xB8 | dstenc); 2128 emit_d64(cbuf, $src$$constant); 2129 %} 2130 2131 enc_class load_immUL32(rRegL dst, immUL32 src) 2132 %{ 2133 // same as load_immI, but this time we care about zeroes in the high word 2134 int dstenc = $dst$$reg; 2135 if (dstenc >= 8) { 2136 emit_opcode(cbuf, Assembler::REX_B); 2137 dstenc -= 8; 2138 } 2139 emit_opcode(cbuf, 0xB8 | dstenc); 2140 $$$emit32$src$$constant; 2141 %} 2142 2143 enc_class load_immL32(rRegL dst, immL32 src) 2144 %{ 2145 int dstenc = $dst$$reg; 2146 if (dstenc < 8) { 2147 emit_opcode(cbuf, Assembler::REX_W); 2148 } else { 2149 emit_opcode(cbuf, Assembler::REX_WB); 2150 dstenc -= 8; 2151 } 2152 emit_opcode(cbuf, 0xC7); 2153 emit_rm(cbuf, 0x03, 0x00, dstenc); 2154 $$$emit32$src$$constant; 2155 %} 2156 2157 enc_class load_immP31(rRegP dst, immP32 src) 2158 %{ 2159 // same as load_immI, but this time we care about zeroes in the high word 2160 int dstenc = $dst$$reg; 2161 if (dstenc >= 8) { 2162 emit_opcode(cbuf, Assembler::REX_B); 2163 dstenc -= 8; 2164 } 2165 emit_opcode(cbuf, 0xB8 | dstenc); 2166 $$$emit32$src$$constant; 2167 %} 2168 2169 enc_class load_immP(rRegP dst, immP src) 2170 %{ 2171 int dstenc = $dst$$reg; 2172 if (dstenc < 8) { 2173 emit_opcode(cbuf, Assembler::REX_W); 2174 } else { 2175 emit_opcode(cbuf, Assembler::REX_WB); 2176 dstenc -= 8; 2177 } 2178 emit_opcode(cbuf, 0xB8 | dstenc); 2179 // This next line should be generated from ADLC 2180 if ($src->constant_reloc() != relocInfo::none) { 2181 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2182 } else { 2183 emit_d64(cbuf, $src$$constant); 2184 } 2185 %} 2186 2187 enc_class Con32(immI src) 2188 %{ 2189 // Output immediate 2190 $$$emit32$src$$constant; 2191 %} 2192 2193 enc_class Con32F_as_bits(immF src) 2194 %{ 2195 // Output Float immediate bits 2196 jfloat jf = $src$$constant; 2197 jint jf_as_bits = jint_cast(jf); 2198 emit_d32(cbuf, jf_as_bits); 2199 %} 2200 2201 enc_class Con16(immI src) 2202 %{ 2203 // Output immediate 2204 $$$emit16$src$$constant; 2205 %} 2206 2207 // How is this different from Con32??? XXX 2208 enc_class Con_d32(immI src) 2209 %{ 2210 emit_d32(cbuf,$src$$constant); 2211 %} 2212 2213 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2214 // Output immediate memory reference 2215 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2216 emit_d32(cbuf, 0x00); 2217 %} 2218 2219 enc_class lock_prefix() 2220 %{ 2221 if (os::is_MP()) { 2222 emit_opcode(cbuf, 0xF0); // lock 2223 } 2224 %} 2225 2226 enc_class REX_mem(memory mem) 2227 %{ 2228 if ($mem$$base >= 8) { 2229 if ($mem$$index < 8) { 2230 emit_opcode(cbuf, Assembler::REX_B); 2231 } else { 2232 emit_opcode(cbuf, Assembler::REX_XB); 2233 } 2234 } else { 2235 if ($mem$$index >= 8) { 2236 emit_opcode(cbuf, Assembler::REX_X); 2237 } 2238 } 2239 %} 2240 2241 enc_class REX_mem_wide(memory mem) 2242 %{ 2243 if ($mem$$base >= 8) { 2244 if ($mem$$index < 8) { 2245 emit_opcode(cbuf, Assembler::REX_WB); 2246 } else { 2247 emit_opcode(cbuf, Assembler::REX_WXB); 2248 } 2249 } else { 2250 if ($mem$$index < 8) { 2251 emit_opcode(cbuf, Assembler::REX_W); 2252 } else { 2253 emit_opcode(cbuf, Assembler::REX_WX); 2254 } 2255 } 2256 %} 2257 2258 // for byte regs 2259 enc_class REX_breg(rRegI reg) 2260 %{ 2261 if ($reg$$reg >= 4) { 2262 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2263 } 2264 %} 2265 2266 // for byte regs 2267 enc_class REX_reg_breg(rRegI dst, rRegI src) 2268 %{ 2269 if ($dst$$reg < 8) { 2270 if ($src$$reg >= 4) { 2271 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2272 } 2273 } else { 2274 if ($src$$reg < 8) { 2275 emit_opcode(cbuf, Assembler::REX_R); 2276 } else { 2277 emit_opcode(cbuf, Assembler::REX_RB); 2278 } 2279 } 2280 %} 2281 2282 // for byte regs 2283 enc_class REX_breg_mem(rRegI reg, memory mem) 2284 %{ 2285 if ($reg$$reg < 8) { 2286 if ($mem$$base < 8) { 2287 if ($mem$$index >= 8) { 2288 emit_opcode(cbuf, Assembler::REX_X); 2289 } else if ($reg$$reg >= 4) { 2290 emit_opcode(cbuf, Assembler::REX); 2291 } 2292 } else { 2293 if ($mem$$index < 8) { 2294 emit_opcode(cbuf, Assembler::REX_B); 2295 } else { 2296 emit_opcode(cbuf, Assembler::REX_XB); 2297 } 2298 } 2299 } else { 2300 if ($mem$$base < 8) { 2301 if ($mem$$index < 8) { 2302 emit_opcode(cbuf, Assembler::REX_R); 2303 } else { 2304 emit_opcode(cbuf, Assembler::REX_RX); 2305 } 2306 } else { 2307 if ($mem$$index < 8) { 2308 emit_opcode(cbuf, Assembler::REX_RB); 2309 } else { 2310 emit_opcode(cbuf, Assembler::REX_RXB); 2311 } 2312 } 2313 } 2314 %} 2315 2316 enc_class REX_reg(rRegI reg) 2317 %{ 2318 if ($reg$$reg >= 8) { 2319 emit_opcode(cbuf, Assembler::REX_B); 2320 } 2321 %} 2322 2323 enc_class REX_reg_wide(rRegI reg) 2324 %{ 2325 if ($reg$$reg < 8) { 2326 emit_opcode(cbuf, Assembler::REX_W); 2327 } else { 2328 emit_opcode(cbuf, Assembler::REX_WB); 2329 } 2330 %} 2331 2332 enc_class REX_reg_reg(rRegI dst, rRegI src) 2333 %{ 2334 if ($dst$$reg < 8) { 2335 if ($src$$reg >= 8) { 2336 emit_opcode(cbuf, Assembler::REX_B); 2337 } 2338 } else { 2339 if ($src$$reg < 8) { 2340 emit_opcode(cbuf, Assembler::REX_R); 2341 } else { 2342 emit_opcode(cbuf, Assembler::REX_RB); 2343 } 2344 } 2345 %} 2346 2347 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2348 %{ 2349 if ($dst$$reg < 8) { 2350 if ($src$$reg < 8) { 2351 emit_opcode(cbuf, Assembler::REX_W); 2352 } else { 2353 emit_opcode(cbuf, Assembler::REX_WB); 2354 } 2355 } else { 2356 if ($src$$reg < 8) { 2357 emit_opcode(cbuf, Assembler::REX_WR); 2358 } else { 2359 emit_opcode(cbuf, Assembler::REX_WRB); 2360 } 2361 } 2362 %} 2363 2364 enc_class REX_reg_mem(rRegI reg, memory mem) 2365 %{ 2366 if ($reg$$reg < 8) { 2367 if ($mem$$base < 8) { 2368 if ($mem$$index >= 8) { 2369 emit_opcode(cbuf, Assembler::REX_X); 2370 } 2371 } else { 2372 if ($mem$$index < 8) { 2373 emit_opcode(cbuf, Assembler::REX_B); 2374 } else { 2375 emit_opcode(cbuf, Assembler::REX_XB); 2376 } 2377 } 2378 } else { 2379 if ($mem$$base < 8) { 2380 if ($mem$$index < 8) { 2381 emit_opcode(cbuf, Assembler::REX_R); 2382 } else { 2383 emit_opcode(cbuf, Assembler::REX_RX); 2384 } 2385 } else { 2386 if ($mem$$index < 8) { 2387 emit_opcode(cbuf, Assembler::REX_RB); 2388 } else { 2389 emit_opcode(cbuf, Assembler::REX_RXB); 2390 } 2391 } 2392 } 2393 %} 2394 2395 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2396 %{ 2397 if ($reg$$reg < 8) { 2398 if ($mem$$base < 8) { 2399 if ($mem$$index < 8) { 2400 emit_opcode(cbuf, Assembler::REX_W); 2401 } else { 2402 emit_opcode(cbuf, Assembler::REX_WX); 2403 } 2404 } else { 2405 if ($mem$$index < 8) { 2406 emit_opcode(cbuf, Assembler::REX_WB); 2407 } else { 2408 emit_opcode(cbuf, Assembler::REX_WXB); 2409 } 2410 } 2411 } else { 2412 if ($mem$$base < 8) { 2413 if ($mem$$index < 8) { 2414 emit_opcode(cbuf, Assembler::REX_WR); 2415 } else { 2416 emit_opcode(cbuf, Assembler::REX_WRX); 2417 } 2418 } else { 2419 if ($mem$$index < 8) { 2420 emit_opcode(cbuf, Assembler::REX_WRB); 2421 } else { 2422 emit_opcode(cbuf, Assembler::REX_WRXB); 2423 } 2424 } 2425 } 2426 %} 2427 2428 enc_class reg_mem(rRegI ereg, memory mem) 2429 %{ 2430 // High registers handle in encode_RegMem 2431 int reg = $ereg$$reg; 2432 int base = $mem$$base; 2433 int index = $mem$$index; 2434 int scale = $mem$$scale; 2435 int disp = $mem$$disp; 2436 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2437 2438 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2439 %} 2440 2441 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2442 %{ 2443 int rm_byte_opcode = $rm_opcode$$constant; 2444 2445 // High registers handle in encode_RegMem 2446 int base = $mem$$base; 2447 int index = $mem$$index; 2448 int scale = $mem$$scale; 2449 int displace = $mem$$disp; 2450 2451 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2452 // working with static 2453 // globals 2454 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2455 disp_reloc); 2456 %} 2457 2458 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2459 %{ 2460 int reg_encoding = $dst$$reg; 2461 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2462 int index = 0x04; // 0x04 indicates no index 2463 int scale = 0x00; // 0x00 indicates no scale 2464 int displace = $src1$$constant; // 0x00 indicates no displacement 2465 relocInfo::relocType disp_reloc = relocInfo::none; 2466 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2467 disp_reloc); 2468 %} 2469 2470 enc_class neg_reg(rRegI dst) 2471 %{ 2472 int dstenc = $dst$$reg; 2473 if (dstenc >= 8) { 2474 emit_opcode(cbuf, Assembler::REX_B); 2475 dstenc -= 8; 2476 } 2477 // NEG $dst 2478 emit_opcode(cbuf, 0xF7); 2479 emit_rm(cbuf, 0x3, 0x03, dstenc); 2480 %} 2481 2482 enc_class neg_reg_wide(rRegI dst) 2483 %{ 2484 int dstenc = $dst$$reg; 2485 if (dstenc < 8) { 2486 emit_opcode(cbuf, Assembler::REX_W); 2487 } else { 2488 emit_opcode(cbuf, Assembler::REX_WB); 2489 dstenc -= 8; 2490 } 2491 // NEG $dst 2492 emit_opcode(cbuf, 0xF7); 2493 emit_rm(cbuf, 0x3, 0x03, dstenc); 2494 %} 2495 2496 enc_class setLT_reg(rRegI dst) 2497 %{ 2498 int dstenc = $dst$$reg; 2499 if (dstenc >= 8) { 2500 emit_opcode(cbuf, Assembler::REX_B); 2501 dstenc -= 8; 2502 } else if (dstenc >= 4) { 2503 emit_opcode(cbuf, Assembler::REX); 2504 } 2505 // SETLT $dst 2506 emit_opcode(cbuf, 0x0F); 2507 emit_opcode(cbuf, 0x9C); 2508 emit_rm(cbuf, 0x3, 0x0, dstenc); 2509 %} 2510 2511 enc_class setNZ_reg(rRegI dst) 2512 %{ 2513 int dstenc = $dst$$reg; 2514 if (dstenc >= 8) { 2515 emit_opcode(cbuf, Assembler::REX_B); 2516 dstenc -= 8; 2517 } else if (dstenc >= 4) { 2518 emit_opcode(cbuf, Assembler::REX); 2519 } 2520 // SETNZ $dst 2521 emit_opcode(cbuf, 0x0F); 2522 emit_opcode(cbuf, 0x95); 2523 emit_rm(cbuf, 0x3, 0x0, dstenc); 2524 %} 2525 2526 2527 // Compare the lonogs and set -1, 0, or 1 into dst 2528 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2529 %{ 2530 int src1enc = $src1$$reg; 2531 int src2enc = $src2$$reg; 2532 int dstenc = $dst$$reg; 2533 2534 // cmpq $src1, $src2 2535 if (src1enc < 8) { 2536 if (src2enc < 8) { 2537 emit_opcode(cbuf, Assembler::REX_W); 2538 } else { 2539 emit_opcode(cbuf, Assembler::REX_WB); 2540 } 2541 } else { 2542 if (src2enc < 8) { 2543 emit_opcode(cbuf, Assembler::REX_WR); 2544 } else { 2545 emit_opcode(cbuf, Assembler::REX_WRB); 2546 } 2547 } 2548 emit_opcode(cbuf, 0x3B); 2549 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2550 2551 // movl $dst, -1 2552 if (dstenc >= 8) { 2553 emit_opcode(cbuf, Assembler::REX_B); 2554 } 2555 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2556 emit_d32(cbuf, -1); 2557 2558 // jl,s done 2559 emit_opcode(cbuf, 0x7C); 2560 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2561 2562 // setne $dst 2563 if (dstenc >= 4) { 2564 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2565 } 2566 emit_opcode(cbuf, 0x0F); 2567 emit_opcode(cbuf, 0x95); 2568 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2569 2570 // movzbl $dst, $dst 2571 if (dstenc >= 4) { 2572 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2573 } 2574 emit_opcode(cbuf, 0x0F); 2575 emit_opcode(cbuf, 0xB6); 2576 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2577 %} 2578 2579 enc_class Push_ResultXD(regD dst) %{ 2580 MacroAssembler _masm(&cbuf); 2581 __ fstp_d(Address(rsp, 0)); 2582 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2583 __ addptr(rsp, 8); 2584 %} 2585 2586 enc_class Push_SrcXD(regD src) %{ 2587 MacroAssembler _masm(&cbuf); 2588 __ subptr(rsp, 8); 2589 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2590 __ fld_d(Address(rsp, 0)); 2591 %} 2592 2593 2594 // obj: object to lock 2595 // box: box address (header location) -- killed 2596 // tmp: rax -- killed 2597 // scr: rbx -- killed 2598 // 2599 // What follows is a direct transliteration of fast_lock() and fast_unlock() 2600 // from i486.ad. See that file for comments. 2601 // TODO: where possible switch from movq (r, 0) to movl(r,0) and 2602 // use the shorter encoding. (Movl clears the high-order 32-bits). 2603 2604 2605 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) 2606 %{ 2607 Register objReg = as_Register((int)$obj$$reg); 2608 Register boxReg = as_Register((int)$box$$reg); 2609 Register tmpReg = as_Register($tmp$$reg); 2610 Register scrReg = as_Register($scr$$reg); 2611 MacroAssembler masm(&cbuf); 2612 2613 // Verify uniqueness of register assignments -- necessary but not sufficient 2614 assert (objReg != boxReg && objReg != tmpReg && 2615 objReg != scrReg && tmpReg != scrReg, "invariant") ; 2616 2617 if (_counters != NULL) { 2618 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 2619 } 2620 if (EmitSync & 1) { 2621 // Without cast to int32_t a movptr will destroy r10 which is typically obj 2622 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 2623 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 2624 } else 2625 if (EmitSync & 2) { 2626 Label DONE_LABEL; 2627 if (UseBiasedLocking) { 2628 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 2629 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); 2630 } 2631 // QQQ was movl... 2632 masm.movptr(tmpReg, 0x1); 2633 masm.orptr(tmpReg, Address(objReg, 0)); 2634 masm.movptr(Address(boxReg, 0), tmpReg); 2635 if (os::is_MP()) { 2636 masm.lock(); 2637 } 2638 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 2639 masm.jcc(Assembler::equal, DONE_LABEL); 2640 2641 // Recursive locking 2642 masm.subptr(tmpReg, rsp); 2643 masm.andptr(tmpReg, 7 - os::vm_page_size()); 2644 masm.movptr(Address(boxReg, 0), tmpReg); 2645 2646 masm.bind(DONE_LABEL); 2647 masm.nop(); // avoid branch to branch 2648 } else { 2649 Label DONE_LABEL, IsInflated, Egress; 2650 2651 masm.movptr(tmpReg, Address(objReg, 0)) ; 2652 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased 2653 masm.jcc (Assembler::notZero, IsInflated) ; 2654 2655 // it's stack-locked, biased or neutral 2656 // TODO: optimize markword triage order to reduce the number of 2657 // conditional branches in the most common cases. 2658 // Beware -- there's a subtle invariant that fetch of the markword 2659 // at [FETCH], below, will never observe a biased encoding (*101b). 2660 // If this invariant is not held we'll suffer exclusion (safety) failure. 2661 2662 if (UseBiasedLocking && !UseOptoBiasInlining) { 2663 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); 2664 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 2665 } 2666 2667 // was q will it destroy high? 2668 masm.orl (tmpReg, 1) ; 2669 masm.movptr(Address(boxReg, 0), tmpReg) ; 2670 if (os::is_MP()) { masm.lock(); } 2671 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 2672 if (_counters != NULL) { 2673 masm.cond_inc32(Assembler::equal, 2674 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 2675 } 2676 masm.jcc (Assembler::equal, DONE_LABEL); 2677 2678 // Recursive locking 2679 masm.subptr(tmpReg, rsp); 2680 masm.andptr(tmpReg, 7 - os::vm_page_size()); 2681 masm.movptr(Address(boxReg, 0), tmpReg); 2682 if (_counters != NULL) { 2683 masm.cond_inc32(Assembler::equal, 2684 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 2685 } 2686 masm.jmp (DONE_LABEL) ; 2687 2688 masm.bind (IsInflated) ; 2689 // It's inflated 2690 2691 // TODO: someday avoid the ST-before-CAS penalty by 2692 // relocating (deferring) the following ST. 2693 // We should also think about trying a CAS without having 2694 // fetched _owner. If the CAS is successful we may 2695 // avoid an RTO->RTS upgrade on the $line. 2696 // Without cast to int32_t a movptr will destroy r10 which is typically obj 2697 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 2698 2699 masm.mov (boxReg, tmpReg) ; 2700 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2701 masm.testptr(tmpReg, tmpReg) ; 2702 masm.jcc (Assembler::notZero, DONE_LABEL) ; 2703 2704 // It's inflated and appears unlocked 2705 if (os::is_MP()) { masm.lock(); } 2706 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2707 // Intentional fall-through into DONE_LABEL ... 2708 2709 masm.bind (DONE_LABEL) ; 2710 masm.nop () ; // avoid jmp to jmp 2711 } 2712 %} 2713 2714 // obj: object to unlock 2715 // box: box address (displaced header location), killed 2716 // RBX: killed tmp; cannot be obj nor box 2717 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) 2718 %{ 2719 2720 Register objReg = as_Register($obj$$reg); 2721 Register boxReg = as_Register($box$$reg); 2722 Register tmpReg = as_Register($tmp$$reg); 2723 MacroAssembler masm(&cbuf); 2724 2725 if (EmitSync & 4) { 2726 masm.cmpptr(rsp, 0) ; 2727 } else 2728 if (EmitSync & 8) { 2729 Label DONE_LABEL; 2730 if (UseBiasedLocking) { 2731 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 2732 } 2733 2734 // Check whether the displaced header is 0 2735 //(=> recursive unlock) 2736 masm.movptr(tmpReg, Address(boxReg, 0)); 2737 masm.testptr(tmpReg, tmpReg); 2738 masm.jcc(Assembler::zero, DONE_LABEL); 2739 2740 // If not recursive lock, reset the header to displaced header 2741 if (os::is_MP()) { 2742 masm.lock(); 2743 } 2744 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 2745 masm.bind(DONE_LABEL); 2746 masm.nop(); // avoid branch to branch 2747 } else { 2748 Label DONE_LABEL, Stacked, CheckSucc ; 2749 2750 if (UseBiasedLocking && !UseOptoBiasInlining) { 2751 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 2752 } 2753 2754 masm.movptr(tmpReg, Address(objReg, 0)) ; 2755 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 2756 masm.jcc (Assembler::zero, DONE_LABEL) ; 2757 masm.testl (tmpReg, 0x02) ; 2758 masm.jcc (Assembler::zero, Stacked) ; 2759 2760 // It's inflated 2761 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 2762 masm.xorptr(boxReg, r15_thread) ; 2763 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 2764 masm.jcc (Assembler::notZero, DONE_LABEL) ; 2765 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 2766 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 2767 masm.jcc (Assembler::notZero, CheckSucc) ; 2768 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2769 masm.jmp (DONE_LABEL) ; 2770 2771 if ((EmitSync & 65536) == 0) { 2772 Label LSuccess, LGoSlowPath ; 2773 masm.bind (CheckSucc) ; 2774 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2775 masm.jcc (Assembler::zero, LGoSlowPath) ; 2776 2777 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the 2778 // the explicit ST;MEMBAR combination, but masm doesn't currently support 2779 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc 2780 // are all faster when the write buffer is populated. 2781 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2782 if (os::is_MP()) { 2783 masm.lock () ; masm.addl (Address(rsp, 0), 0) ; 2784 } 2785 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 2786 masm.jcc (Assembler::notZero, LSuccess) ; 2787 2788 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX 2789 if (os::is_MP()) { masm.lock(); } 2790 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); 2791 masm.jcc (Assembler::notEqual, LSuccess) ; 2792 // Intentional fall-through into slow-path 2793 2794 masm.bind (LGoSlowPath) ; 2795 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure 2796 masm.jmp (DONE_LABEL) ; 2797 2798 masm.bind (LSuccess) ; 2799 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success 2800 masm.jmp (DONE_LABEL) ; 2801 } 2802 2803 masm.bind (Stacked) ; 2804 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch 2805 if (os::is_MP()) { masm.lock(); } 2806 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 2807 2808 if (EmitSync & 65536) { 2809 masm.bind (CheckSucc) ; 2810 } 2811 masm.bind(DONE_LABEL); 2812 if (EmitSync & 32768) { 2813 masm.nop(); // avoid branch to branch 2814 } 2815 } 2816 %} 2817 2818 2819 enc_class enc_rethrow() 2820 %{ 2821 cbuf.set_insts_mark(); 2822 emit_opcode(cbuf, 0xE9); // jmp entry 2823 emit_d32_reloc(cbuf, 2824 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2825 runtime_call_Relocation::spec(), 2826 RELOC_DISP32); 2827 %} 2828 2829%} 2830 2831 2832 2833//----------FRAME-------------------------------------------------------------- 2834// Definition of frame structure and management information. 2835// 2836// S T A C K L A Y O U T Allocators stack-slot number 2837// | (to get allocators register number 2838// G Owned by | | v add OptoReg::stack0()) 2839// r CALLER | | 2840// o | +--------+ pad to even-align allocators stack-slot 2841// w V | pad0 | numbers; owned by CALLER 2842// t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2843// h ^ | in | 5 2844// | | args | 4 Holes in incoming args owned by SELF 2845// | | | | 3 2846// | | +--------+ 2847// V | | old out| Empty on Intel, window on Sparc 2848// | old |preserve| Must be even aligned. 2849// | SP-+--------+----> Matcher::_old_SP, even aligned 2850// | | in | 3 area for Intel ret address 2851// Owned by |preserve| Empty on Sparc. 2852// SELF +--------+ 2853// | | pad2 | 2 pad to align old SP 2854// | +--------+ 1 2855// | | locks | 0 2856// | +--------+----> OptoReg::stack0(), even aligned 2857// | | pad1 | 11 pad to align new SP 2858// | +--------+ 2859// | | | 10 2860// | | spills | 9 spills 2861// V | | 8 (pad0 slot for callee) 2862// -----------+--------+----> Matcher::_out_arg_limit, unaligned 2863// ^ | out | 7 2864// | | args | 6 Holes in outgoing args owned by CALLEE 2865// Owned by +--------+ 2866// CALLEE | new out| 6 Empty on Intel, window on Sparc 2867// | new |preserve| Must be even-aligned. 2868// | SP-+--------+----> Matcher::_new_SP, even aligned 2869// | | | 2870// 2871// Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2872// known from SELF's arguments and the Java calling convention. 2873// Region 6-7 is determined per call site. 2874// Note 2: If the calling convention leaves holes in the incoming argument 2875// area, those holes are owned by SELF. Holes in the outgoing area 2876// are owned by the CALLEE. Holes should not be nessecary in the 2877// incoming area, as the Java calling convention is completely under 2878// the control of the AD file. Doubles can be sorted and packed to 2879// avoid holes. Holes in the outgoing arguments may be nessecary for 2880// varargs C calling conventions. 2881// Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2882// even aligned with pad0 as needed. 2883// Region 6 is even aligned. Region 6-7 is NOT even aligned; 2884// region 6-11 is even aligned; it may be padded out more so that 2885// the region from SP to FP meets the minimum stack alignment. 2886// Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2887// alignment. Region 11, pad1, may be dynamically extended so that 2888// SP meets the minimum alignment. 2889 2890frame 2891%{ 2892 // What direction does stack grow in (assumed to be same for C & Java) 2893 stack_direction(TOWARDS_LOW); 2894 2895 // These three registers define part of the calling convention 2896 // between compiled code and the interpreter. 2897 inline_cache_reg(RAX); // Inline Cache Register 2898 interpreter_method_oop_reg(RBX); // Method Oop Register when 2899 // calling interpreter 2900 2901 // Optional: name the operand used by cisc-spilling to access 2902 // [stack_pointer + offset] 2903 cisc_spilling_operand_name(indOffset32); 2904 2905 // Number of stack slots consumed by locking an object 2906 sync_stack_slots(2); 2907 2908 // Compiled code's Frame Pointer 2909 frame_pointer(RSP); 2910 2911 // Interpreter stores its frame pointer in a register which is 2912 // stored to the stack by I2CAdaptors. 2913 // I2CAdaptors convert from interpreted java to compiled java. 2914 interpreter_frame_pointer(RBP); 2915 2916 // Stack alignment requirement 2917 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2918 2919 // Number of stack slots between incoming argument block and the start of 2920 // a new frame. The PROLOG must add this many slots to the stack. The 2921 // EPILOG must remove this many slots. amd64 needs two slots for 2922 // return address. 2923 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2924 2925 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2926 // for calls to C. Supports the var-args backing area for register parms. 2927 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2928 2929 // The after-PROLOG location of the return address. Location of 2930 // return address specifies a type (REG or STACK) and a number 2931 // representing the register number (i.e. - use a register name) or 2932 // stack slot. 2933 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2934 // Otherwise, it is above the locks and verification slot and alignment word 2935 return_addr(STACK - 2 + 2936 round_to((Compile::current()->in_preserve_stack_slots() + 2937 Compile::current()->fixed_slots()), 2938 stack_alignment_in_slots())); 2939 2940 // Body of function which returns an integer array locating 2941 // arguments either in registers or in stack slots. Passed an array 2942 // of ideal registers called "sig" and a "length" count. Stack-slot 2943 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2944 // arguments for a CALLEE. Incoming stack arguments are 2945 // automatically biased by the preserve_stack_slots field above. 2946 2947 calling_convention 2948 %{ 2949 // No difference between ingoing/outgoing just pass false 2950 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2951 %} 2952 2953 c_calling_convention 2954 %{ 2955 // This is obviously always outgoing 2956 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2957 %} 2958 2959 // Location of compiled Java return values. Same as C for now. 2960 return_value 2961 %{ 2962 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2963 "only return normal values"); 2964 2965 static const int lo[Op_RegL + 1] = { 2966 0, 2967 0, 2968 RAX_num, // Op_RegN 2969 RAX_num, // Op_RegI 2970 RAX_num, // Op_RegP 2971 XMM0_num, // Op_RegF 2972 XMM0_num, // Op_RegD 2973 RAX_num // Op_RegL 2974 }; 2975 static const int hi[Op_RegL + 1] = { 2976 0, 2977 0, 2978 OptoReg::Bad, // Op_RegN 2979 OptoReg::Bad, // Op_RegI 2980 RAX_H_num, // Op_RegP 2981 OptoReg::Bad, // Op_RegF 2982 XMM0b_num, // Op_RegD 2983 RAX_H_num // Op_RegL 2984 }; 2985 // Excluded flags and vector registers. 2986 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type"); 2987 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2988 %} 2989%} 2990 2991//----------ATTRIBUTES--------------------------------------------------------- 2992//----------Operand Attributes------------------------------------------------- 2993op_attrib op_cost(0); // Required cost attribute 2994 2995//----------Instruction Attributes--------------------------------------------- 2996ins_attrib ins_cost(100); // Required cost attribute 2997ins_attrib ins_size(8); // Required size attribute (in bits) 2998ins_attrib ins_short_branch(0); // Required flag: is this instruction 2999 // a non-matching short branch variant 3000 // of some long branch? 3001ins_attrib ins_alignment(1); // Required alignment attribute (must 3002 // be a power of 2) specifies the 3003 // alignment that some part of the 3004 // instruction (not necessarily the 3005 // start) requires. If > 1, a 3006 // compute_padding() function must be 3007 // provided for the instruction 3008 3009//----------OPERANDS----------------------------------------------------------- 3010// Operand definitions must precede instruction definitions for correct parsing 3011// in the ADLC because operands constitute user defined types which are used in 3012// instruction definitions. 3013 3014//----------Simple Operands---------------------------------------------------- 3015// Immediate Operands 3016// Integer Immediate 3017operand immI() 3018%{ 3019 match(ConI); 3020 3021 op_cost(10); 3022 format %{ %} 3023 interface(CONST_INTER); 3024%} 3025 3026// Constant for test vs zero 3027operand immI0() 3028%{ 3029 predicate(n->get_int() == 0); 3030 match(ConI); 3031 3032 op_cost(0); 3033 format %{ %} 3034 interface(CONST_INTER); 3035%} 3036 3037// Constant for increment 3038operand immI1() 3039%{ 3040 predicate(n->get_int() == 1); 3041 match(ConI); 3042 3043 op_cost(0); 3044 format %{ %} 3045 interface(CONST_INTER); 3046%} 3047 3048// Constant for decrement 3049operand immI_M1() 3050%{ 3051 predicate(n->get_int() == -1); 3052 match(ConI); 3053 3054 op_cost(0); 3055 format %{ %} 3056 interface(CONST_INTER); 3057%} 3058 3059// Valid scale values for addressing modes 3060operand immI2() 3061%{ 3062 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 3063 match(ConI); 3064 3065 format %{ %} 3066 interface(CONST_INTER); 3067%} 3068 3069operand immI8() 3070%{ 3071 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 3072 match(ConI); 3073 3074 op_cost(5); 3075 format %{ %} 3076 interface(CONST_INTER); 3077%} 3078 3079operand immI16() 3080%{ 3081 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 3082 match(ConI); 3083 3084 op_cost(10); 3085 format %{ %} 3086 interface(CONST_INTER); 3087%} 3088 3089// Constant for long shifts 3090operand immI_32() 3091%{ 3092 predicate( n->get_int() == 32 ); 3093 match(ConI); 3094 3095 op_cost(0); 3096 format %{ %} 3097 interface(CONST_INTER); 3098%} 3099 3100// Constant for long shifts 3101operand immI_64() 3102%{ 3103 predicate( n->get_int() == 64 ); 3104 match(ConI); 3105 3106 op_cost(0); 3107 format %{ %} 3108 interface(CONST_INTER); 3109%} 3110 3111// Pointer Immediate 3112operand immP() 3113%{ 3114 match(ConP); 3115 3116 op_cost(10); 3117 format %{ %} 3118 interface(CONST_INTER); 3119%} 3120 3121// NULL Pointer Immediate 3122operand immP0() 3123%{ 3124 predicate(n->get_ptr() == 0); 3125 match(ConP); 3126 3127 op_cost(5); 3128 format %{ %} 3129 interface(CONST_INTER); 3130%} 3131 3132// Pointer Immediate 3133operand immN() %{ 3134 match(ConN); 3135 3136 op_cost(10); 3137 format %{ %} 3138 interface(CONST_INTER); 3139%} 3140 3141operand immNKlass() %{ 3142 match(ConNKlass); 3143 3144 op_cost(10); 3145 format %{ %} 3146 interface(CONST_INTER); 3147%} 3148 3149// NULL Pointer Immediate 3150operand immN0() %{ 3151 predicate(n->get_narrowcon() == 0); 3152 match(ConN); 3153 3154 op_cost(5); 3155 format %{ %} 3156 interface(CONST_INTER); 3157%} 3158 3159operand immP31() 3160%{ 3161 predicate(n->as_Type()->type()->reloc() == relocInfo::none 3162 && (n->get_ptr() >> 31) == 0); 3163 match(ConP); 3164 3165 op_cost(5); 3166 format %{ %} 3167 interface(CONST_INTER); 3168%} 3169 3170 3171// Long Immediate 3172operand immL() 3173%{ 3174 match(ConL); 3175 3176 op_cost(20); 3177 format %{ %} 3178 interface(CONST_INTER); 3179%} 3180 3181// Long Immediate 8-bit 3182operand immL8() 3183%{ 3184 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 3185 match(ConL); 3186 3187 op_cost(5); 3188 format %{ %} 3189 interface(CONST_INTER); 3190%} 3191 3192// Long Immediate 32-bit unsigned 3193operand immUL32() 3194%{ 3195 predicate(n->get_long() == (unsigned int) (n->get_long())); 3196 match(ConL); 3197 3198 op_cost(10); 3199 format %{ %} 3200 interface(CONST_INTER); 3201%} 3202 3203// Long Immediate 32-bit signed 3204operand immL32() 3205%{ 3206 predicate(n->get_long() == (int) (n->get_long())); 3207 match(ConL); 3208 3209 op_cost(15); 3210 format %{ %} 3211 interface(CONST_INTER); 3212%} 3213 3214// Long Immediate zero 3215operand immL0() 3216%{ 3217 predicate(n->get_long() == 0L); 3218 match(ConL); 3219 3220 op_cost(10); 3221 format %{ %} 3222 interface(CONST_INTER); 3223%} 3224 3225// Constant for increment 3226operand immL1() 3227%{ 3228 predicate(n->get_long() == 1); 3229 match(ConL); 3230 3231 format %{ %} 3232 interface(CONST_INTER); 3233%} 3234 3235// Constant for decrement 3236operand immL_M1() 3237%{ 3238 predicate(n->get_long() == -1); 3239 match(ConL); 3240 3241 format %{ %} 3242 interface(CONST_INTER); 3243%} 3244 3245// Long Immediate: the value 10 3246operand immL10() 3247%{ 3248 predicate(n->get_long() == 10); 3249 match(ConL); 3250 3251 format %{ %} 3252 interface(CONST_INTER); 3253%} 3254 3255// Long immediate from 0 to 127. 3256// Used for a shorter form of long mul by 10. 3257operand immL_127() 3258%{ 3259 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3260 match(ConL); 3261 3262 op_cost(10); 3263 format %{ %} 3264 interface(CONST_INTER); 3265%} 3266 3267// Long Immediate: low 32-bit mask 3268operand immL_32bits() 3269%{ 3270 predicate(n->get_long() == 0xFFFFFFFFL); 3271 match(ConL); 3272 op_cost(20); 3273 3274 format %{ %} 3275 interface(CONST_INTER); 3276%} 3277 3278// Float Immediate zero 3279operand immF0() 3280%{ 3281 predicate(jint_cast(n->getf()) == 0); 3282 match(ConF); 3283 3284 op_cost(5); 3285 format %{ %} 3286 interface(CONST_INTER); 3287%} 3288 3289// Float Immediate 3290operand immF() 3291%{ 3292 match(ConF); 3293 3294 op_cost(15); 3295 format %{ %} 3296 interface(CONST_INTER); 3297%} 3298 3299// Double Immediate zero 3300operand immD0() 3301%{ 3302 predicate(jlong_cast(n->getd()) == 0); 3303 match(ConD); 3304 3305 op_cost(5); 3306 format %{ %} 3307 interface(CONST_INTER); 3308%} 3309 3310// Double Immediate 3311operand immD() 3312%{ 3313 match(ConD); 3314 3315 op_cost(15); 3316 format %{ %} 3317 interface(CONST_INTER); 3318%} 3319 3320// Immediates for special shifts (sign extend) 3321 3322// Constants for increment 3323operand immI_16() 3324%{ 3325 predicate(n->get_int() == 16); 3326 match(ConI); 3327 3328 format %{ %} 3329 interface(CONST_INTER); 3330%} 3331 3332operand immI_24() 3333%{ 3334 predicate(n->get_int() == 24); 3335 match(ConI); 3336 3337 format %{ %} 3338 interface(CONST_INTER); 3339%} 3340 3341// Constant for byte-wide masking 3342operand immI_255() 3343%{ 3344 predicate(n->get_int() == 255); 3345 match(ConI); 3346 3347 format %{ %} 3348 interface(CONST_INTER); 3349%} 3350 3351// Constant for short-wide masking 3352operand immI_65535() 3353%{ 3354 predicate(n->get_int() == 65535); 3355 match(ConI); 3356 3357 format %{ %} 3358 interface(CONST_INTER); 3359%} 3360 3361// Constant for byte-wide masking 3362operand immL_255() 3363%{ 3364 predicate(n->get_long() == 255); 3365 match(ConL); 3366 3367 format %{ %} 3368 interface(CONST_INTER); 3369%} 3370 3371// Constant for short-wide masking 3372operand immL_65535() 3373%{ 3374 predicate(n->get_long() == 65535); 3375 match(ConL); 3376 3377 format %{ %} 3378 interface(CONST_INTER); 3379%} 3380 3381// Register Operands 3382// Integer Register 3383operand rRegI() 3384%{ 3385 constraint(ALLOC_IN_RC(int_reg)); 3386 match(RegI); 3387 3388 match(rax_RegI); 3389 match(rbx_RegI); 3390 match(rcx_RegI); 3391 match(rdx_RegI); 3392 match(rdi_RegI); 3393 3394 format %{ %} 3395 interface(REG_INTER); 3396%} 3397 3398// Special Registers 3399operand rax_RegI() 3400%{ 3401 constraint(ALLOC_IN_RC(int_rax_reg)); 3402 match(RegI); 3403 match(rRegI); 3404 3405 format %{ "RAX" %} 3406 interface(REG_INTER); 3407%} 3408 3409// Special Registers 3410operand rbx_RegI() 3411%{ 3412 constraint(ALLOC_IN_RC(int_rbx_reg)); 3413 match(RegI); 3414 match(rRegI); 3415 3416 format %{ "RBX" %} 3417 interface(REG_INTER); 3418%} 3419 3420operand rcx_RegI() 3421%{ 3422 constraint(ALLOC_IN_RC(int_rcx_reg)); 3423 match(RegI); 3424 match(rRegI); 3425 3426 format %{ "RCX" %} 3427 interface(REG_INTER); 3428%} 3429 3430operand rdx_RegI() 3431%{ 3432 constraint(ALLOC_IN_RC(int_rdx_reg)); 3433 match(RegI); 3434 match(rRegI); 3435 3436 format %{ "RDX" %} 3437 interface(REG_INTER); 3438%} 3439 3440operand rdi_RegI() 3441%{ 3442 constraint(ALLOC_IN_RC(int_rdi_reg)); 3443 match(RegI); 3444 match(rRegI); 3445 3446 format %{ "RDI" %} 3447 interface(REG_INTER); 3448%} 3449 3450operand no_rcx_RegI() 3451%{ 3452 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3453 match(RegI); 3454 match(rax_RegI); 3455 match(rbx_RegI); 3456 match(rdx_RegI); 3457 match(rdi_RegI); 3458 3459 format %{ %} 3460 interface(REG_INTER); 3461%} 3462 3463operand no_rax_rdx_RegI() 3464%{ 3465 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3466 match(RegI); 3467 match(rbx_RegI); 3468 match(rcx_RegI); 3469 match(rdi_RegI); 3470 3471 format %{ %} 3472 interface(REG_INTER); 3473%} 3474 3475// Pointer Register 3476operand any_RegP() 3477%{ 3478 constraint(ALLOC_IN_RC(any_reg)); 3479 match(RegP); 3480 match(rax_RegP); 3481 match(rbx_RegP); 3482 match(rdi_RegP); 3483 match(rsi_RegP); 3484 match(rbp_RegP); 3485 match(r15_RegP); 3486 match(rRegP); 3487 3488 format %{ %} 3489 interface(REG_INTER); 3490%} 3491 3492operand rRegP() 3493%{ 3494 constraint(ALLOC_IN_RC(ptr_reg)); 3495 match(RegP); 3496 match(rax_RegP); 3497 match(rbx_RegP); 3498 match(rdi_RegP); 3499 match(rsi_RegP); 3500 match(rbp_RegP); 3501 match(r15_RegP); // See Q&A below about r15_RegP. 3502 3503 format %{ %} 3504 interface(REG_INTER); 3505%} 3506 3507operand rRegN() %{ 3508 constraint(ALLOC_IN_RC(int_reg)); 3509 match(RegN); 3510 3511 format %{ %} 3512 interface(REG_INTER); 3513%} 3514 3515// Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3516// Answer: Operand match rules govern the DFA as it processes instruction inputs. 3517// It's fine for an instruction input which expects rRegP to match a r15_RegP. 3518// The output of an instruction is controlled by the allocator, which respects 3519// register class masks, not match rules. Unless an instruction mentions 3520// r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3521// by the allocator as an input. 3522 3523operand no_rax_RegP() 3524%{ 3525 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3526 match(RegP); 3527 match(rbx_RegP); 3528 match(rsi_RegP); 3529 match(rdi_RegP); 3530 3531 format %{ %} 3532 interface(REG_INTER); 3533%} 3534 3535operand no_rbp_RegP() 3536%{ 3537 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); 3538 match(RegP); 3539 match(rbx_RegP); 3540 match(rsi_RegP); 3541 match(rdi_RegP); 3542 3543 format %{ %} 3544 interface(REG_INTER); 3545%} 3546 3547operand no_rax_rbx_RegP() 3548%{ 3549 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3550 match(RegP); 3551 match(rsi_RegP); 3552 match(rdi_RegP); 3553 3554 format %{ %} 3555 interface(REG_INTER); 3556%} 3557 3558// Special Registers 3559// Return a pointer value 3560operand rax_RegP() 3561%{ 3562 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3563 match(RegP); 3564 match(rRegP); 3565 3566 format %{ %} 3567 interface(REG_INTER); 3568%} 3569 3570// Special Registers 3571// Return a compressed pointer value 3572operand rax_RegN() 3573%{ 3574 constraint(ALLOC_IN_RC(int_rax_reg)); 3575 match(RegN); 3576 match(rRegN); 3577 3578 format %{ %} 3579 interface(REG_INTER); 3580%} 3581 3582// Used in AtomicAdd 3583operand rbx_RegP() 3584%{ 3585 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3586 match(RegP); 3587 match(rRegP); 3588 3589 format %{ %} 3590 interface(REG_INTER); 3591%} 3592 3593operand rsi_RegP() 3594%{ 3595 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3596 match(RegP); 3597 match(rRegP); 3598 3599 format %{ %} 3600 interface(REG_INTER); 3601%} 3602 3603// Used in rep stosq 3604operand rdi_RegP() 3605%{ 3606 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3607 match(RegP); 3608 match(rRegP); 3609 3610 format %{ %} 3611 interface(REG_INTER); 3612%} 3613 3614operand rbp_RegP() 3615%{ 3616 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 3617 match(RegP); 3618 match(rRegP); 3619 3620 format %{ %} 3621 interface(REG_INTER); 3622%} 3623 3624operand r15_RegP() 3625%{ 3626 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3627 match(RegP); 3628 match(rRegP); 3629 3630 format %{ %} 3631 interface(REG_INTER); 3632%} 3633 3634operand rRegL() 3635%{ 3636 constraint(ALLOC_IN_RC(long_reg)); 3637 match(RegL); 3638 match(rax_RegL); 3639 match(rdx_RegL); 3640 3641 format %{ %} 3642 interface(REG_INTER); 3643%} 3644 3645// Special Registers 3646operand no_rax_rdx_RegL() 3647%{ 3648 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3649 match(RegL); 3650 match(rRegL); 3651 3652 format %{ %} 3653 interface(REG_INTER); 3654%} 3655 3656operand no_rax_RegL() 3657%{ 3658 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3659 match(RegL); 3660 match(rRegL); 3661 match(rdx_RegL); 3662 3663 format %{ %} 3664 interface(REG_INTER); 3665%} 3666 3667operand no_rcx_RegL() 3668%{ 3669 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3670 match(RegL); 3671 match(rRegL); 3672 3673 format %{ %} 3674 interface(REG_INTER); 3675%} 3676 3677operand rax_RegL() 3678%{ 3679 constraint(ALLOC_IN_RC(long_rax_reg)); 3680 match(RegL); 3681 match(rRegL); 3682 3683 format %{ "RAX" %} 3684 interface(REG_INTER); 3685%} 3686 3687operand rcx_RegL() 3688%{ 3689 constraint(ALLOC_IN_RC(long_rcx_reg)); 3690 match(RegL); 3691 match(rRegL); 3692 3693 format %{ %} 3694 interface(REG_INTER); 3695%} 3696 3697operand rdx_RegL() 3698%{ 3699 constraint(ALLOC_IN_RC(long_rdx_reg)); 3700 match(RegL); 3701 match(rRegL); 3702 3703 format %{ %} 3704 interface(REG_INTER); 3705%} 3706 3707// Flags register, used as output of compare instructions 3708operand rFlagsReg() 3709%{ 3710 constraint(ALLOC_IN_RC(int_flags)); 3711 match(RegFlags); 3712 3713 format %{ "RFLAGS" %} 3714 interface(REG_INTER); 3715%} 3716 3717// Flags register, used as output of FLOATING POINT compare instructions 3718operand rFlagsRegU() 3719%{ 3720 constraint(ALLOC_IN_RC(int_flags)); 3721 match(RegFlags); 3722 3723 format %{ "RFLAGS_U" %} 3724 interface(REG_INTER); 3725%} 3726 3727operand rFlagsRegUCF() %{ 3728 constraint(ALLOC_IN_RC(int_flags)); 3729 match(RegFlags); 3730 predicate(false); 3731 3732 format %{ "RFLAGS_U_CF" %} 3733 interface(REG_INTER); 3734%} 3735 3736// Float register operands 3737operand regF() 3738%{ 3739 constraint(ALLOC_IN_RC(float_reg)); 3740 match(RegF); 3741 3742 format %{ %} 3743 interface(REG_INTER); 3744%} 3745 3746// Double register operands 3747operand regD() 3748%{ 3749 constraint(ALLOC_IN_RC(double_reg)); 3750 match(RegD); 3751 3752 format %{ %} 3753 interface(REG_INTER); 3754%} 3755 3756//----------Memory Operands---------------------------------------------------- 3757// Direct Memory Operand 3758// operand direct(immP addr) 3759// %{ 3760// match(addr); 3761 3762// format %{ "[$addr]" %} 3763// interface(MEMORY_INTER) %{ 3764// base(0xFFFFFFFF); 3765// index(0x4); 3766// scale(0x0); 3767// disp($addr); 3768// %} 3769// %} 3770 3771// Indirect Memory Operand 3772operand indirect(any_RegP reg) 3773%{ 3774 constraint(ALLOC_IN_RC(ptr_reg)); 3775 match(reg); 3776 3777 format %{ "[$reg]" %} 3778 interface(MEMORY_INTER) %{ 3779 base($reg); 3780 index(0x4); 3781 scale(0x0); 3782 disp(0x0); 3783 %} 3784%} 3785 3786// Indirect Memory Plus Short Offset Operand 3787operand indOffset8(any_RegP reg, immL8 off) 3788%{ 3789 constraint(ALLOC_IN_RC(ptr_reg)); 3790 match(AddP reg off); 3791 3792 format %{ "[$reg + $off (8-bit)]" %} 3793 interface(MEMORY_INTER) %{ 3794 base($reg); 3795 index(0x4); 3796 scale(0x0); 3797 disp($off); 3798 %} 3799%} 3800 3801// Indirect Memory Plus Long Offset Operand 3802operand indOffset32(any_RegP reg, immL32 off) 3803%{ 3804 constraint(ALLOC_IN_RC(ptr_reg)); 3805 match(AddP reg off); 3806 3807 format %{ "[$reg + $off (32-bit)]" %} 3808 interface(MEMORY_INTER) %{ 3809 base($reg); 3810 index(0x4); 3811 scale(0x0); 3812 disp($off); 3813 %} 3814%} 3815 3816// Indirect Memory Plus Index Register Plus Offset Operand 3817operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3818%{ 3819 constraint(ALLOC_IN_RC(ptr_reg)); 3820 match(AddP (AddP reg lreg) off); 3821 3822 op_cost(10); 3823 format %{"[$reg + $off + $lreg]" %} 3824 interface(MEMORY_INTER) %{ 3825 base($reg); 3826 index($lreg); 3827 scale(0x0); 3828 disp($off); 3829 %} 3830%} 3831 3832// Indirect Memory Plus Index Register Plus Offset Operand 3833operand indIndex(any_RegP reg, rRegL lreg) 3834%{ 3835 constraint(ALLOC_IN_RC(ptr_reg)); 3836 match(AddP reg lreg); 3837 3838 op_cost(10); 3839 format %{"[$reg + $lreg]" %} 3840 interface(MEMORY_INTER) %{ 3841 base($reg); 3842 index($lreg); 3843 scale(0x0); 3844 disp(0x0); 3845 %} 3846%} 3847 3848// Indirect Memory Times Scale Plus Index Register 3849operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3850%{ 3851 constraint(ALLOC_IN_RC(ptr_reg)); 3852 match(AddP reg (LShiftL lreg scale)); 3853 3854 op_cost(10); 3855 format %{"[$reg + $lreg << $scale]" %} 3856 interface(MEMORY_INTER) %{ 3857 base($reg); 3858 index($lreg); 3859 scale($scale); 3860 disp(0x0); 3861 %} 3862%} 3863 3864// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3865operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3866%{ 3867 constraint(ALLOC_IN_RC(ptr_reg)); 3868 match(AddP (AddP reg (LShiftL lreg scale)) off); 3869 3870 op_cost(10); 3871 format %{"[$reg + $off + $lreg << $scale]" %} 3872 interface(MEMORY_INTER) %{ 3873 base($reg); 3874 index($lreg); 3875 scale($scale); 3876 disp($off); 3877 %} 3878%} 3879 3880// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3881operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3882%{ 3883 constraint(ALLOC_IN_RC(ptr_reg)); 3884 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3885 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3886 3887 op_cost(10); 3888 format %{"[$reg + $off + $idx << $scale]" %} 3889 interface(MEMORY_INTER) %{ 3890 base($reg); 3891 index($idx); 3892 scale($scale); 3893 disp($off); 3894 %} 3895%} 3896 3897// Indirect Narrow Oop Plus Offset Operand 3898// Note: x86 architecture doesn't support "scale * index + offset" without a base 3899// we can't free r12 even with Universe::narrow_oop_base() == NULL. 3900operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3901 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3902 constraint(ALLOC_IN_RC(ptr_reg)); 3903 match(AddP (DecodeN reg) off); 3904 3905 op_cost(10); 3906 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3907 interface(MEMORY_INTER) %{ 3908 base(0xc); // R12 3909 index($reg); 3910 scale(0x3); 3911 disp($off); 3912 %} 3913%} 3914 3915// Indirect Memory Operand 3916operand indirectNarrow(rRegN reg) 3917%{ 3918 predicate(Universe::narrow_oop_shift() == 0); 3919 constraint(ALLOC_IN_RC(ptr_reg)); 3920 match(DecodeN reg); 3921 3922 format %{ "[$reg]" %} 3923 interface(MEMORY_INTER) %{ 3924 base($reg); 3925 index(0x4); 3926 scale(0x0); 3927 disp(0x0); 3928 %} 3929%} 3930 3931// Indirect Memory Plus Short Offset Operand 3932operand indOffset8Narrow(rRegN reg, immL8 off) 3933%{ 3934 predicate(Universe::narrow_oop_shift() == 0); 3935 constraint(ALLOC_IN_RC(ptr_reg)); 3936 match(AddP (DecodeN reg) off); 3937 3938 format %{ "[$reg + $off (8-bit)]" %} 3939 interface(MEMORY_INTER) %{ 3940 base($reg); 3941 index(0x4); 3942 scale(0x0); 3943 disp($off); 3944 %} 3945%} 3946 3947// Indirect Memory Plus Long Offset Operand 3948operand indOffset32Narrow(rRegN reg, immL32 off) 3949%{ 3950 predicate(Universe::narrow_oop_shift() == 0); 3951 constraint(ALLOC_IN_RC(ptr_reg)); 3952 match(AddP (DecodeN reg) off); 3953 3954 format %{ "[$reg + $off (32-bit)]" %} 3955 interface(MEMORY_INTER) %{ 3956 base($reg); 3957 index(0x4); 3958 scale(0x0); 3959 disp($off); 3960 %} 3961%} 3962 3963// Indirect Memory Plus Index Register Plus Offset Operand 3964operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3965%{ 3966 predicate(Universe::narrow_oop_shift() == 0); 3967 constraint(ALLOC_IN_RC(ptr_reg)); 3968 match(AddP (AddP (DecodeN reg) lreg) off); 3969 3970 op_cost(10); 3971 format %{"[$reg + $off + $lreg]" %} 3972 interface(MEMORY_INTER) %{ 3973 base($reg); 3974 index($lreg); 3975 scale(0x0); 3976 disp($off); 3977 %} 3978%} 3979 3980// Indirect Memory Plus Index Register Plus Offset Operand 3981operand indIndexNarrow(rRegN reg, rRegL lreg) 3982%{ 3983 predicate(Universe::narrow_oop_shift() == 0); 3984 constraint(ALLOC_IN_RC(ptr_reg)); 3985 match(AddP (DecodeN reg) lreg); 3986 3987 op_cost(10); 3988 format %{"[$reg + $lreg]" %} 3989 interface(MEMORY_INTER) %{ 3990 base($reg); 3991 index($lreg); 3992 scale(0x0); 3993 disp(0x0); 3994 %} 3995%} 3996 3997// Indirect Memory Times Scale Plus Index Register 3998operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3999%{ 4000 predicate(Universe::narrow_oop_shift() == 0); 4001 constraint(ALLOC_IN_RC(ptr_reg)); 4002 match(AddP (DecodeN reg) (LShiftL lreg scale)); 4003 4004 op_cost(10); 4005 format %{"[$reg + $lreg << $scale]" %} 4006 interface(MEMORY_INTER) %{ 4007 base($reg); 4008 index($lreg); 4009 scale($scale); 4010 disp(0x0); 4011 %} 4012%} 4013 4014// Indirect Memory Times Scale Plus Index Register Plus Offset Operand 4015operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 4016%{ 4017 predicate(Universe::narrow_oop_shift() == 0); 4018 constraint(ALLOC_IN_RC(ptr_reg)); 4019 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 4020 4021 op_cost(10); 4022 format %{"[$reg + $off + $lreg << $scale]" %} 4023 interface(MEMORY_INTER) %{ 4024 base($reg); 4025 index($lreg); 4026 scale($scale); 4027 disp($off); 4028 %} 4029%} 4030 4031// Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 4032operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 4033%{ 4034 constraint(ALLOC_IN_RC(ptr_reg)); 4035 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 4036 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 4037 4038 op_cost(10); 4039 format %{"[$reg + $off + $idx << $scale]" %} 4040 interface(MEMORY_INTER) %{ 4041 base($reg); 4042 index($idx); 4043 scale($scale); 4044 disp($off); 4045 %} 4046%} 4047 4048//----------Special Memory Operands-------------------------------------------- 4049// Stack Slot Operand - This operand is used for loading and storing temporary 4050// values on the stack where a match requires a value to 4051// flow through memory. 4052operand stackSlotP(sRegP reg) 4053%{ 4054 constraint(ALLOC_IN_RC(stack_slots)); 4055 // No match rule because this operand is only generated in matching 4056 4057 format %{ "[$reg]" %} 4058 interface(MEMORY_INTER) %{ 4059 base(0x4); // RSP 4060 index(0x4); // No Index 4061 scale(0x0); // No Scale 4062 disp($reg); // Stack Offset 4063 %} 4064%} 4065 4066operand stackSlotI(sRegI reg) 4067%{ 4068 constraint(ALLOC_IN_RC(stack_slots)); 4069 // No match rule because this operand is only generated in matching 4070 4071 format %{ "[$reg]" %} 4072 interface(MEMORY_INTER) %{ 4073 base(0x4); // RSP 4074 index(0x4); // No Index 4075 scale(0x0); // No Scale 4076 disp($reg); // Stack Offset 4077 %} 4078%} 4079 4080operand stackSlotF(sRegF reg) 4081%{ 4082 constraint(ALLOC_IN_RC(stack_slots)); 4083 // No match rule because this operand is only generated in matching 4084 4085 format %{ "[$reg]" %} 4086 interface(MEMORY_INTER) %{ 4087 base(0x4); // RSP 4088 index(0x4); // No Index 4089 scale(0x0); // No Scale 4090 disp($reg); // Stack Offset 4091 %} 4092%} 4093 4094operand stackSlotD(sRegD reg) 4095%{ 4096 constraint(ALLOC_IN_RC(stack_slots)); 4097 // No match rule because this operand is only generated in matching 4098 4099 format %{ "[$reg]" %} 4100 interface(MEMORY_INTER) %{ 4101 base(0x4); // RSP 4102 index(0x4); // No Index 4103 scale(0x0); // No Scale 4104 disp($reg); // Stack Offset 4105 %} 4106%} 4107operand stackSlotL(sRegL reg) 4108%{ 4109 constraint(ALLOC_IN_RC(stack_slots)); 4110 // No match rule because this operand is only generated in matching 4111 4112 format %{ "[$reg]" %} 4113 interface(MEMORY_INTER) %{ 4114 base(0x4); // RSP 4115 index(0x4); // No Index 4116 scale(0x0); // No Scale 4117 disp($reg); // Stack Offset 4118 %} 4119%} 4120 4121//----------Conditional Branch Operands---------------------------------------- 4122// Comparison Op - This is the operation of the comparison, and is limited to 4123// the following set of codes: 4124// L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 4125// 4126// Other attributes of the comparison, such as unsignedness, are specified 4127// by the comparison instruction that sets a condition code flags register. 4128// That result is represented by a flags operand whose subtype is appropriate 4129// to the unsignedness (etc.) of the comparison. 4130// 4131// Later, the instruction which matches both the Comparison Op (a Bool) and 4132// the flags (produced by the Cmp) specifies the coding of the comparison op 4133// by matching a specific subtype of Bool operand below, such as cmpOpU. 4134 4135// Comparision Code 4136operand cmpOp() 4137%{ 4138 match(Bool); 4139 4140 format %{ "" %} 4141 interface(COND_INTER) %{ 4142 equal(0x4, "e"); 4143 not_equal(0x5, "ne"); 4144 less(0xC, "l"); 4145 greater_equal(0xD, "ge"); 4146 less_equal(0xE, "le"); 4147 greater(0xF, "g"); 4148 overflow(0x0, "o"); 4149 no_overflow(0x1, "no"); 4150 %} 4151%} 4152 4153// Comparison Code, unsigned compare. Used by FP also, with 4154// C2 (unordered) turned into GT or LT already. The other bits 4155// C0 and C3 are turned into Carry & Zero flags. 4156operand cmpOpU() 4157%{ 4158 match(Bool); 4159 4160 format %{ "" %} 4161 interface(COND_INTER) %{ 4162 equal(0x4, "e"); 4163 not_equal(0x5, "ne"); 4164 less(0x2, "b"); 4165 greater_equal(0x3, "nb"); 4166 less_equal(0x6, "be"); 4167 greater(0x7, "nbe"); 4168 overflow(0x0, "o"); 4169 no_overflow(0x1, "no"); 4170 %} 4171%} 4172 4173 4174// Floating comparisons that don't require any fixup for the unordered case 4175operand cmpOpUCF() %{ 4176 match(Bool); 4177 predicate(n->as_Bool()->_test._test == BoolTest::lt || 4178 n->as_Bool()->_test._test == BoolTest::ge || 4179 n->as_Bool()->_test._test == BoolTest::le || 4180 n->as_Bool()->_test._test == BoolTest::gt); 4181 format %{ "" %} 4182 interface(COND_INTER) %{ 4183 equal(0x4, "e"); 4184 not_equal(0x5, "ne"); 4185 less(0x2, "b"); 4186 greater_equal(0x3, "nb"); 4187 less_equal(0x6, "be"); 4188 greater(0x7, "nbe"); 4189 overflow(0x0, "o"); 4190 no_overflow(0x1, "no"); 4191 %} 4192%} 4193 4194 4195// Floating comparisons that can be fixed up with extra conditional jumps 4196operand cmpOpUCF2() %{ 4197 match(Bool); 4198 predicate(n->as_Bool()->_test._test == BoolTest::ne || 4199 n->as_Bool()->_test._test == BoolTest::eq); 4200 format %{ "" %} 4201 interface(COND_INTER) %{ 4202 equal(0x4, "e"); 4203 not_equal(0x5, "ne"); 4204 less(0x2, "b"); 4205 greater_equal(0x3, "nb"); 4206 less_equal(0x6, "be"); 4207 greater(0x7, "nbe"); 4208 overflow(0x0, "o"); 4209 no_overflow(0x1, "no"); 4210 %} 4211%} 4212 4213 4214//----------OPERAND CLASSES---------------------------------------------------- 4215// Operand Classes are groups of operands that are used as to simplify 4216// instruction definitions by not requiring the AD writer to specify separate 4217// instructions for every form of operand when the instruction accepts 4218// multiple operand types with the same basic encoding and format. The classic 4219// case of this is memory operands. 4220 4221opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4222 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 4223 indCompressedOopOffset, 4224 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4225 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4226 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); 4227 4228//----------PIPELINE----------------------------------------------------------- 4229// Rules which define the behavior of the target architectures pipeline. 4230pipeline %{ 4231 4232//----------ATTRIBUTES--------------------------------------------------------- 4233attributes %{ 4234 variable_size_instructions; // Fixed size instructions 4235 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4236 instruction_unit_size = 1; // An instruction is 1 bytes long 4237 instruction_fetch_unit_size = 16; // The processor fetches one line 4238 instruction_fetch_units = 1; // of 16 bytes 4239 4240 // List of nop instructions 4241 nops( MachNop ); 4242%} 4243 4244//----------RESOURCES---------------------------------------------------------- 4245// Resources are the functional units available to the machine 4246 4247// Generic P2/P3 pipeline 4248// 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4249// 3 instructions decoded per cycle. 4250// 2 load/store ops per cycle, 1 branch, 1 FPU, 4251// 3 ALU op, only ALU0 handles mul instructions. 4252resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4253 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4254 BR, FPU, 4255 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4256 4257//----------PIPELINE DESCRIPTION----------------------------------------------- 4258// Pipeline Description specifies the stages in the machine's pipeline 4259 4260// Generic P2/P3 pipeline 4261pipe_desc(S0, S1, S2, S3, S4, S5); 4262 4263//----------PIPELINE CLASSES--------------------------------------------------- 4264// Pipeline Classes describe the stages in which input and output are 4265// referenced by the hardware pipeline. 4266 4267// Naming convention: ialu or fpu 4268// Then: _reg 4269// Then: _reg if there is a 2nd register 4270// Then: _long if it's a pair of instructions implementing a long 4271// Then: _fat if it requires the big decoder 4272// Or: _mem if it requires the big decoder and a memory unit. 4273 4274// Integer ALU reg operation 4275pipe_class ialu_reg(rRegI dst) 4276%{ 4277 single_instruction; 4278 dst : S4(write); 4279 dst : S3(read); 4280 DECODE : S0; // any decoder 4281 ALU : S3; // any alu 4282%} 4283 4284// Long ALU reg operation 4285pipe_class ialu_reg_long(rRegL dst) 4286%{ 4287 instruction_count(2); 4288 dst : S4(write); 4289 dst : S3(read); 4290 DECODE : S0(2); // any 2 decoders 4291 ALU : S3(2); // both alus 4292%} 4293 4294// Integer ALU reg operation using big decoder 4295pipe_class ialu_reg_fat(rRegI dst) 4296%{ 4297 single_instruction; 4298 dst : S4(write); 4299 dst : S3(read); 4300 D0 : S0; // big decoder only 4301 ALU : S3; // any alu 4302%} 4303 4304// Long ALU reg operation using big decoder 4305pipe_class ialu_reg_long_fat(rRegL dst) 4306%{ 4307 instruction_count(2); 4308 dst : S4(write); 4309 dst : S3(read); 4310 D0 : S0(2); // big decoder only; twice 4311 ALU : S3(2); // any 2 alus 4312%} 4313 4314// Integer ALU reg-reg operation 4315pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4316%{ 4317 single_instruction; 4318 dst : S4(write); 4319 src : S3(read); 4320 DECODE : S0; // any decoder 4321 ALU : S3; // any alu 4322%} 4323 4324// Long ALU reg-reg operation 4325pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4326%{ 4327 instruction_count(2); 4328 dst : S4(write); 4329 src : S3(read); 4330 DECODE : S0(2); // any 2 decoders 4331 ALU : S3(2); // both alus 4332%} 4333 4334// Integer ALU reg-reg operation 4335pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4336%{ 4337 single_instruction; 4338 dst : S4(write); 4339 src : S3(read); 4340 D0 : S0; // big decoder only 4341 ALU : S3; // any alu 4342%} 4343 4344// Long ALU reg-reg operation 4345pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4346%{ 4347 instruction_count(2); 4348 dst : S4(write); 4349 src : S3(read); 4350 D0 : S0(2); // big decoder only; twice 4351 ALU : S3(2); // both alus 4352%} 4353 4354// Integer ALU reg-mem operation 4355pipe_class ialu_reg_mem(rRegI dst, memory mem) 4356%{ 4357 single_instruction; 4358 dst : S5(write); 4359 mem : S3(read); 4360 D0 : S0; // big decoder only 4361 ALU : S4; // any alu 4362 MEM : S3; // any mem 4363%} 4364 4365// Integer mem operation (prefetch) 4366pipe_class ialu_mem(memory mem) 4367%{ 4368 single_instruction; 4369 mem : S3(read); 4370 D0 : S0; // big decoder only 4371 MEM : S3; // any mem 4372%} 4373 4374// Integer Store to Memory 4375pipe_class ialu_mem_reg(memory mem, rRegI src) 4376%{ 4377 single_instruction; 4378 mem : S3(read); 4379 src : S5(read); 4380 D0 : S0; // big decoder only 4381 ALU : S4; // any alu 4382 MEM : S3; 4383%} 4384 4385// // Long Store to Memory 4386// pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4387// %{ 4388// instruction_count(2); 4389// mem : S3(read); 4390// src : S5(read); 4391// D0 : S0(2); // big decoder only; twice 4392// ALU : S4(2); // any 2 alus 4393// MEM : S3(2); // Both mems 4394// %} 4395 4396// Integer Store to Memory 4397pipe_class ialu_mem_imm(memory mem) 4398%{ 4399 single_instruction; 4400 mem : S3(read); 4401 D0 : S0; // big decoder only 4402 ALU : S4; // any alu 4403 MEM : S3; 4404%} 4405 4406// Integer ALU0 reg-reg operation 4407pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4408%{ 4409 single_instruction; 4410 dst : S4(write); 4411 src : S3(read); 4412 D0 : S0; // Big decoder only 4413 ALU0 : S3; // only alu0 4414%} 4415 4416// Integer ALU0 reg-mem operation 4417pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4418%{ 4419 single_instruction; 4420 dst : S5(write); 4421 mem : S3(read); 4422 D0 : S0; // big decoder only 4423 ALU0 : S4; // ALU0 only 4424 MEM : S3; // any mem 4425%} 4426 4427// Integer ALU reg-reg operation 4428pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4429%{ 4430 single_instruction; 4431 cr : S4(write); 4432 src1 : S3(read); 4433 src2 : S3(read); 4434 DECODE : S0; // any decoder 4435 ALU : S3; // any alu 4436%} 4437 4438// Integer ALU reg-imm operation 4439pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4440%{ 4441 single_instruction; 4442 cr : S4(write); 4443 src1 : S3(read); 4444 DECODE : S0; // any decoder 4445 ALU : S3; // any alu 4446%} 4447 4448// Integer ALU reg-mem operation 4449pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4450%{ 4451 single_instruction; 4452 cr : S4(write); 4453 src1 : S3(read); 4454 src2 : S3(read); 4455 D0 : S0; // big decoder only 4456 ALU : S4; // any alu 4457 MEM : S3; 4458%} 4459 4460// Conditional move reg-reg 4461pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4462%{ 4463 instruction_count(4); 4464 y : S4(read); 4465 q : S3(read); 4466 p : S3(read); 4467 DECODE : S0(4); // any decoder 4468%} 4469 4470// Conditional move reg-reg 4471pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4472%{ 4473 single_instruction; 4474 dst : S4(write); 4475 src : S3(read); 4476 cr : S3(read); 4477 DECODE : S0; // any decoder 4478%} 4479 4480// Conditional move reg-mem 4481pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4482%{ 4483 single_instruction; 4484 dst : S4(write); 4485 src : S3(read); 4486 cr : S3(read); 4487 DECODE : S0; // any decoder 4488 MEM : S3; 4489%} 4490 4491// Conditional move reg-reg long 4492pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4493%{ 4494 single_instruction; 4495 dst : S4(write); 4496 src : S3(read); 4497 cr : S3(read); 4498 DECODE : S0(2); // any 2 decoders 4499%} 4500 4501// XXX 4502// // Conditional move double reg-reg 4503// pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4504// %{ 4505// single_instruction; 4506// dst : S4(write); 4507// src : S3(read); 4508// cr : S3(read); 4509// DECODE : S0; // any decoder 4510// %} 4511 4512// Float reg-reg operation 4513pipe_class fpu_reg(regD dst) 4514%{ 4515 instruction_count(2); 4516 dst : S3(read); 4517 DECODE : S0(2); // any 2 decoders 4518 FPU : S3; 4519%} 4520 4521// Float reg-reg operation 4522pipe_class fpu_reg_reg(regD dst, regD src) 4523%{ 4524 instruction_count(2); 4525 dst : S4(write); 4526 src : S3(read); 4527 DECODE : S0(2); // any 2 decoders 4528 FPU : S3; 4529%} 4530 4531// Float reg-reg operation 4532pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4533%{ 4534 instruction_count(3); 4535 dst : S4(write); 4536 src1 : S3(read); 4537 src2 : S3(read); 4538 DECODE : S0(3); // any 3 decoders 4539 FPU : S3(2); 4540%} 4541 4542// Float reg-reg operation 4543pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4544%{ 4545 instruction_count(4); 4546 dst : S4(write); 4547 src1 : S3(read); 4548 src2 : S3(read); 4549 src3 : S3(read); 4550 DECODE : S0(4); // any 3 decoders 4551 FPU : S3(2); 4552%} 4553 4554// Float reg-reg operation 4555pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4556%{ 4557 instruction_count(4); 4558 dst : S4(write); 4559 src1 : S3(read); 4560 src2 : S3(read); 4561 src3 : S3(read); 4562 DECODE : S1(3); // any 3 decoders 4563 D0 : S0; // Big decoder only 4564 FPU : S3(2); 4565 MEM : S3; 4566%} 4567 4568// Float reg-mem operation 4569pipe_class fpu_reg_mem(regD dst, memory mem) 4570%{ 4571 instruction_count(2); 4572 dst : S5(write); 4573 mem : S3(read); 4574 D0 : S0; // big decoder only 4575 DECODE : S1; // any decoder for FPU POP 4576 FPU : S4; 4577 MEM : S3; // any mem 4578%} 4579 4580// Float reg-mem operation 4581pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4582%{ 4583 instruction_count(3); 4584 dst : S5(write); 4585 src1 : S3(read); 4586 mem : S3(read); 4587 D0 : S0; // big decoder only 4588 DECODE : S1(2); // any decoder for FPU POP 4589 FPU : S4; 4590 MEM : S3; // any mem 4591%} 4592 4593// Float mem-reg operation 4594pipe_class fpu_mem_reg(memory mem, regD src) 4595%{ 4596 instruction_count(2); 4597 src : S5(read); 4598 mem : S3(read); 4599 DECODE : S0; // any decoder for FPU PUSH 4600 D0 : S1; // big decoder only 4601 FPU : S4; 4602 MEM : S3; // any mem 4603%} 4604 4605pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4606%{ 4607 instruction_count(3); 4608 src1 : S3(read); 4609 src2 : S3(read); 4610 mem : S3(read); 4611 DECODE : S0(2); // any decoder for FPU PUSH 4612 D0 : S1; // big decoder only 4613 FPU : S4; 4614 MEM : S3; // any mem 4615%} 4616 4617pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4618%{ 4619 instruction_count(3); 4620 src1 : S3(read); 4621 src2 : S3(read); 4622 mem : S4(read); 4623 DECODE : S0; // any decoder for FPU PUSH 4624 D0 : S0(2); // big decoder only 4625 FPU : S4; 4626 MEM : S3(2); // any mem 4627%} 4628 4629pipe_class fpu_mem_mem(memory dst, memory src1) 4630%{ 4631 instruction_count(2); 4632 src1 : S3(read); 4633 dst : S4(read); 4634 D0 : S0(2); // big decoder only 4635 MEM : S3(2); // any mem 4636%} 4637 4638pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4639%{ 4640 instruction_count(3); 4641 src1 : S3(read); 4642 src2 : S3(read); 4643 dst : S4(read); 4644 D0 : S0(3); // big decoder only 4645 FPU : S4; 4646 MEM : S3(3); // any mem 4647%} 4648 4649pipe_class fpu_mem_reg_con(memory mem, regD src1) 4650%{ 4651 instruction_count(3); 4652 src1 : S4(read); 4653 mem : S4(read); 4654 DECODE : S0; // any decoder for FPU PUSH 4655 D0 : S0(2); // big decoder only 4656 FPU : S4; 4657 MEM : S3(2); // any mem 4658%} 4659 4660// Float load constant 4661pipe_class fpu_reg_con(regD dst) 4662%{ 4663 instruction_count(2); 4664 dst : S5(write); 4665 D0 : S0; // big decoder only for the load 4666 DECODE : S1; // any decoder for FPU POP 4667 FPU : S4; 4668 MEM : S3; // any mem 4669%} 4670 4671// Float load constant 4672pipe_class fpu_reg_reg_con(regD dst, regD src) 4673%{ 4674 instruction_count(3); 4675 dst : S5(write); 4676 src : S3(read); 4677 D0 : S0; // big decoder only for the load 4678 DECODE : S1(2); // any decoder for FPU POP 4679 FPU : S4; 4680 MEM : S3; // any mem 4681%} 4682 4683// UnConditional branch 4684pipe_class pipe_jmp(label labl) 4685%{ 4686 single_instruction; 4687 BR : S3; 4688%} 4689 4690// Conditional branch 4691pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4692%{ 4693 single_instruction; 4694 cr : S1(read); 4695 BR : S3; 4696%} 4697 4698// Allocation idiom 4699pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4700%{ 4701 instruction_count(1); force_serialization; 4702 fixed_latency(6); 4703 heap_ptr : S3(read); 4704 DECODE : S0(3); 4705 D0 : S2; 4706 MEM : S3; 4707 ALU : S3(2); 4708 dst : S5(write); 4709 BR : S5; 4710%} 4711 4712// Generic big/slow expanded idiom 4713pipe_class pipe_slow() 4714%{ 4715 instruction_count(10); multiple_bundles; force_serialization; 4716 fixed_latency(100); 4717 D0 : S0(2); 4718 MEM : S3(2); 4719%} 4720 4721// The real do-nothing guy 4722pipe_class empty() 4723%{ 4724 instruction_count(0); 4725%} 4726 4727// Define the class for the Nop node 4728define 4729%{ 4730 MachNop = empty; 4731%} 4732 4733%} 4734 4735//----------INSTRUCTIONS------------------------------------------------------- 4736// 4737// match -- States which machine-independent subtree may be replaced 4738// by this instruction. 4739// ins_cost -- The estimated cost of this instruction is used by instruction 4740// selection to identify a minimum cost tree of machine 4741// instructions that matches a tree of machine-independent 4742// instructions. 4743// format -- A string providing the disassembly for this instruction. 4744// The value of an instruction's operand may be inserted 4745// by referring to it with a '$' prefix. 4746// opcode -- Three instruction opcodes may be provided. These are referred 4747// to within an encode class as $primary, $secondary, and $tertiary 4748// rrspectively. The primary opcode is commonly used to 4749// indicate the type of machine instruction, while secondary 4750// and tertiary are often used for prefix options or addressing 4751// modes. 4752// ins_encode -- A list of encode classes with parameters. The encode class 4753// name must have been defined in an 'enc_class' specification 4754// in the encode section of the architecture description. 4755 4756 4757//----------Load/Store/Move Instructions--------------------------------------- 4758//----------Load Instructions-------------------------------------------------- 4759 4760// Load Byte (8 bit signed) 4761instruct loadB(rRegI dst, memory mem) 4762%{ 4763 match(Set dst (LoadB mem)); 4764 4765 ins_cost(125); 4766 format %{ "movsbl $dst, $mem\t# byte" %} 4767 4768 ins_encode %{ 4769 __ movsbl($dst$$Register, $mem$$Address); 4770 %} 4771 4772 ins_pipe(ialu_reg_mem); 4773%} 4774 4775// Load Byte (8 bit signed) into Long Register 4776instruct loadB2L(rRegL dst, memory mem) 4777%{ 4778 match(Set dst (ConvI2L (LoadB mem))); 4779 4780 ins_cost(125); 4781 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4782 4783 ins_encode %{ 4784 __ movsbq($dst$$Register, $mem$$Address); 4785 %} 4786 4787 ins_pipe(ialu_reg_mem); 4788%} 4789 4790// Load Unsigned Byte (8 bit UNsigned) 4791instruct loadUB(rRegI dst, memory mem) 4792%{ 4793 match(Set dst (LoadUB mem)); 4794 4795 ins_cost(125); 4796 format %{ "movzbl $dst, $mem\t# ubyte" %} 4797 4798 ins_encode %{ 4799 __ movzbl($dst$$Register, $mem$$Address); 4800 %} 4801 4802 ins_pipe(ialu_reg_mem); 4803%} 4804 4805// Load Unsigned Byte (8 bit UNsigned) into Long Register 4806instruct loadUB2L(rRegL dst, memory mem) 4807%{ 4808 match(Set dst (ConvI2L (LoadUB mem))); 4809 4810 ins_cost(125); 4811 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4812 4813 ins_encode %{ 4814 __ movzbq($dst$$Register, $mem$$Address); 4815 %} 4816 4817 ins_pipe(ialu_reg_mem); 4818%} 4819 4820// Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 4821instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 4822 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4823 effect(KILL cr); 4824 4825 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 4826 "andl $dst, $mask" %} 4827 ins_encode %{ 4828 Register Rdst = $dst$$Register; 4829 __ movzbq(Rdst, $mem$$Address); 4830 __ andl(Rdst, $mask$$constant); 4831 %} 4832 ins_pipe(ialu_reg_mem); 4833%} 4834 4835// Load Short (16 bit signed) 4836instruct loadS(rRegI dst, memory mem) 4837%{ 4838 match(Set dst (LoadS mem)); 4839 4840 ins_cost(125); 4841 format %{ "movswl $dst, $mem\t# short" %} 4842 4843 ins_encode %{ 4844 __ movswl($dst$$Register, $mem$$Address); 4845 %} 4846 4847 ins_pipe(ialu_reg_mem); 4848%} 4849 4850// Load Short (16 bit signed) to Byte (8 bit signed) 4851instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4852 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4853 4854 ins_cost(125); 4855 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4856 ins_encode %{ 4857 __ movsbl($dst$$Register, $mem$$Address); 4858 %} 4859 ins_pipe(ialu_reg_mem); 4860%} 4861 4862// Load Short (16 bit signed) into Long Register 4863instruct loadS2L(rRegL dst, memory mem) 4864%{ 4865 match(Set dst (ConvI2L (LoadS mem))); 4866 4867 ins_cost(125); 4868 format %{ "movswq $dst, $mem\t# short -> long" %} 4869 4870 ins_encode %{ 4871 __ movswq($dst$$Register, $mem$$Address); 4872 %} 4873 4874 ins_pipe(ialu_reg_mem); 4875%} 4876 4877// Load Unsigned Short/Char (16 bit UNsigned) 4878instruct loadUS(rRegI dst, memory mem) 4879%{ 4880 match(Set dst (LoadUS mem)); 4881 4882 ins_cost(125); 4883 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4884 4885 ins_encode %{ 4886 __ movzwl($dst$$Register, $mem$$Address); 4887 %} 4888 4889 ins_pipe(ialu_reg_mem); 4890%} 4891 4892// Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4893instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4894 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4895 4896 ins_cost(125); 4897 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4898 ins_encode %{ 4899 __ movsbl($dst$$Register, $mem$$Address); 4900 %} 4901 ins_pipe(ialu_reg_mem); 4902%} 4903 4904// Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4905instruct loadUS2L(rRegL dst, memory mem) 4906%{ 4907 match(Set dst (ConvI2L (LoadUS mem))); 4908 4909 ins_cost(125); 4910 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4911 4912 ins_encode %{ 4913 __ movzwq($dst$$Register, $mem$$Address); 4914 %} 4915 4916 ins_pipe(ialu_reg_mem); 4917%} 4918 4919// Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4920instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4921 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4922 4923 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4924 ins_encode %{ 4925 __ movzbq($dst$$Register, $mem$$Address); 4926 %} 4927 ins_pipe(ialu_reg_mem); 4928%} 4929 4930// Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 4931instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 4932 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4933 effect(KILL cr); 4934 4935 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 4936 "andl $dst, $mask" %} 4937 ins_encode %{ 4938 Register Rdst = $dst$$Register; 4939 __ movzwq(Rdst, $mem$$Address); 4940 __ andl(Rdst, $mask$$constant); 4941 %} 4942 ins_pipe(ialu_reg_mem); 4943%} 4944 4945// Load Integer 4946instruct loadI(rRegI dst, memory mem) 4947%{ 4948 match(Set dst (LoadI mem)); 4949 4950 ins_cost(125); 4951 format %{ "movl $dst, $mem\t# int" %} 4952 4953 ins_encode %{ 4954 __ movl($dst$$Register, $mem$$Address); 4955 %} 4956 4957 ins_pipe(ialu_reg_mem); 4958%} 4959 4960// Load Integer (32 bit signed) to Byte (8 bit signed) 4961instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4962 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4963 4964 ins_cost(125); 4965 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4966 ins_encode %{ 4967 __ movsbl($dst$$Register, $mem$$Address); 4968 %} 4969 ins_pipe(ialu_reg_mem); 4970%} 4971 4972// Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4973instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4974 match(Set dst (AndI (LoadI mem) mask)); 4975 4976 ins_cost(125); 4977 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4978 ins_encode %{ 4979 __ movzbl($dst$$Register, $mem$$Address); 4980 %} 4981 ins_pipe(ialu_reg_mem); 4982%} 4983 4984// Load Integer (32 bit signed) to Short (16 bit signed) 4985instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4986 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4987 4988 ins_cost(125); 4989 format %{ "movswl $dst, $mem\t# int -> short" %} 4990 ins_encode %{ 4991 __ movswl($dst$$Register, $mem$$Address); 4992 %} 4993 ins_pipe(ialu_reg_mem); 4994%} 4995 4996// Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4997instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4998 match(Set dst (AndI (LoadI mem) mask)); 4999 5000 ins_cost(125); 5001 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 5002 ins_encode %{ 5003 __ movzwl($dst$$Register, $mem$$Address); 5004 %} 5005 ins_pipe(ialu_reg_mem); 5006%} 5007 5008// Load Integer into Long Register 5009instruct loadI2L(rRegL dst, memory mem) 5010%{ 5011 match(Set dst (ConvI2L (LoadI mem))); 5012 5013 ins_cost(125); 5014 format %{ "movslq $dst, $mem\t# int -> long" %} 5015 5016 ins_encode %{ 5017 __ movslq($dst$$Register, $mem$$Address); 5018 %} 5019 5020 ins_pipe(ialu_reg_mem); 5021%} 5022 5023// Load Integer with mask 0xFF into Long Register 5024instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 5025 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5026 5027 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 5028 ins_encode %{ 5029 __ movzbq($dst$$Register, $mem$$Address); 5030 %} 5031 ins_pipe(ialu_reg_mem); 5032%} 5033 5034// Load Integer with mask 0xFFFF into Long Register 5035instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 5036 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5037 5038 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 5039 ins_encode %{ 5040 __ movzwq($dst$$Register, $mem$$Address); 5041 %} 5042 ins_pipe(ialu_reg_mem); 5043%} 5044 5045// Load Integer with a 32-bit mask into Long Register 5046instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ 5047 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 5048 effect(KILL cr); 5049 5050 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t" 5051 "andl $dst, $mask" %} 5052 ins_encode %{ 5053 Register Rdst = $dst$$Register; 5054 __ movl(Rdst, $mem$$Address); 5055 __ andl(Rdst, $mask$$constant); 5056 %} 5057 ins_pipe(ialu_reg_mem); 5058%} 5059 5060// Load Unsigned Integer into Long Register 5061instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 5062%{ 5063 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 5064 5065 ins_cost(125); 5066 format %{ "movl $dst, $mem\t# uint -> long" %} 5067 5068 ins_encode %{ 5069 __ movl($dst$$Register, $mem$$Address); 5070 %} 5071 5072 ins_pipe(ialu_reg_mem); 5073%} 5074 5075// Load Long 5076instruct loadL(rRegL dst, memory mem) 5077%{ 5078 match(Set dst (LoadL mem)); 5079 5080 ins_cost(125); 5081 format %{ "movq $dst, $mem\t# long" %} 5082 5083 ins_encode %{ 5084 __ movq($dst$$Register, $mem$$Address); 5085 %} 5086 5087 ins_pipe(ialu_reg_mem); // XXX 5088%} 5089 5090// Load Range 5091instruct loadRange(rRegI dst, memory mem) 5092%{ 5093 match(Set dst (LoadRange mem)); 5094 5095 ins_cost(125); // XXX 5096 format %{ "movl $dst, $mem\t# range" %} 5097 opcode(0x8B); 5098 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 5099 ins_pipe(ialu_reg_mem); 5100%} 5101 5102// Load Pointer 5103instruct loadP(rRegP dst, memory mem) 5104%{ 5105 match(Set dst (LoadP mem)); 5106 5107 ins_cost(125); // XXX 5108 format %{ "movq $dst, $mem\t# ptr" %} 5109 opcode(0x8B); 5110 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5111 ins_pipe(ialu_reg_mem); // XXX 5112%} 5113 5114// Load Compressed Pointer 5115instruct loadN(rRegN dst, memory mem) 5116%{ 5117 match(Set dst (LoadN mem)); 5118 5119 ins_cost(125); // XXX 5120 format %{ "movl $dst, $mem\t# compressed ptr" %} 5121 ins_encode %{ 5122 __ movl($dst$$Register, $mem$$Address); 5123 %} 5124 ins_pipe(ialu_reg_mem); // XXX 5125%} 5126 5127 5128// Load Klass Pointer 5129instruct loadKlass(rRegP dst, memory mem) 5130%{ 5131 match(Set dst (LoadKlass mem)); 5132 5133 ins_cost(125); // XXX 5134 format %{ "movq $dst, $mem\t# class" %} 5135 opcode(0x8B); 5136 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5137 ins_pipe(ialu_reg_mem); // XXX 5138%} 5139 5140// Load narrow Klass Pointer 5141instruct loadNKlass(rRegN dst, memory mem) 5142%{ 5143 match(Set dst (LoadNKlass mem)); 5144 5145 ins_cost(125); // XXX 5146 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 5147 ins_encode %{ 5148 __ movl($dst$$Register, $mem$$Address); 5149 %} 5150 ins_pipe(ialu_reg_mem); // XXX 5151%} 5152 5153// Load Float 5154instruct loadF(regF dst, memory mem) 5155%{ 5156 match(Set dst (LoadF mem)); 5157 5158 ins_cost(145); // XXX 5159 format %{ "movss $dst, $mem\t# float" %} 5160 ins_encode %{ 5161 __ movflt($dst$$XMMRegister, $mem$$Address); 5162 %} 5163 ins_pipe(pipe_slow); // XXX 5164%} 5165 5166// Load Double 5167instruct loadD_partial(regD dst, memory mem) 5168%{ 5169 predicate(!UseXmmLoadAndClearUpper); 5170 match(Set dst (LoadD mem)); 5171 5172 ins_cost(145); // XXX 5173 format %{ "movlpd $dst, $mem\t# double" %} 5174 ins_encode %{ 5175 __ movdbl($dst$$XMMRegister, $mem$$Address); 5176 %} 5177 ins_pipe(pipe_slow); // XXX 5178%} 5179 5180instruct loadD(regD dst, memory mem) 5181%{ 5182 predicate(UseXmmLoadAndClearUpper); 5183 match(Set dst (LoadD mem)); 5184 5185 ins_cost(145); // XXX 5186 format %{ "movsd $dst, $mem\t# double" %} 5187 ins_encode %{ 5188 __ movdbl($dst$$XMMRegister, $mem$$Address); 5189 %} 5190 ins_pipe(pipe_slow); // XXX 5191%} 5192 5193// Load Effective Address 5194instruct leaP8(rRegP dst, indOffset8 mem) 5195%{ 5196 match(Set dst mem); 5197 5198 ins_cost(110); // XXX 5199 format %{ "leaq $dst, $mem\t# ptr 8" %} 5200 opcode(0x8D); 5201 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5202 ins_pipe(ialu_reg_reg_fat); 5203%} 5204 5205instruct leaP32(rRegP dst, indOffset32 mem) 5206%{ 5207 match(Set dst mem); 5208 5209 ins_cost(110); 5210 format %{ "leaq $dst, $mem\t# ptr 32" %} 5211 opcode(0x8D); 5212 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5213 ins_pipe(ialu_reg_reg_fat); 5214%} 5215 5216// instruct leaPIdx(rRegP dst, indIndex mem) 5217// %{ 5218// match(Set dst mem); 5219 5220// ins_cost(110); 5221// format %{ "leaq $dst, $mem\t# ptr idx" %} 5222// opcode(0x8D); 5223// ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5224// ins_pipe(ialu_reg_reg_fat); 5225// %} 5226 5227instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5228%{ 5229 match(Set dst mem); 5230 5231 ins_cost(110); 5232 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5233 opcode(0x8D); 5234 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5235 ins_pipe(ialu_reg_reg_fat); 5236%} 5237 5238instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5239%{ 5240 match(Set dst mem); 5241 5242 ins_cost(110); 5243 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5244 opcode(0x8D); 5245 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5246 ins_pipe(ialu_reg_reg_fat); 5247%} 5248 5249instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5250%{ 5251 match(Set dst mem); 5252 5253 ins_cost(110); 5254 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5255 opcode(0x8D); 5256 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5257 ins_pipe(ialu_reg_reg_fat); 5258%} 5259 5260instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5261%{ 5262 match(Set dst mem); 5263 5264 ins_cost(110); 5265 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5266 opcode(0x8D); 5267 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5268 ins_pipe(ialu_reg_reg_fat); 5269%} 5270 5271// Load Effective Address which uses Narrow (32-bits) oop 5272instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5273%{ 5274 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5275 match(Set dst mem); 5276 5277 ins_cost(110); 5278 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5279 opcode(0x8D); 5280 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5281 ins_pipe(ialu_reg_reg_fat); 5282%} 5283 5284instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5285%{ 5286 predicate(Universe::narrow_oop_shift() == 0); 5287 match(Set dst mem); 5288 5289 ins_cost(110); // XXX 5290 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5291 opcode(0x8D); 5292 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5293 ins_pipe(ialu_reg_reg_fat); 5294%} 5295 5296instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5297%{ 5298 predicate(Universe::narrow_oop_shift() == 0); 5299 match(Set dst mem); 5300 5301 ins_cost(110); 5302 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5303 opcode(0x8D); 5304 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5305 ins_pipe(ialu_reg_reg_fat); 5306%} 5307 5308instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5309%{ 5310 predicate(Universe::narrow_oop_shift() == 0); 5311 match(Set dst mem); 5312 5313 ins_cost(110); 5314 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5315 opcode(0x8D); 5316 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5317 ins_pipe(ialu_reg_reg_fat); 5318%} 5319 5320instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5321%{ 5322 predicate(Universe::narrow_oop_shift() == 0); 5323 match(Set dst mem); 5324 5325 ins_cost(110); 5326 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5327 opcode(0x8D); 5328 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5329 ins_pipe(ialu_reg_reg_fat); 5330%} 5331 5332instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5333%{ 5334 predicate(Universe::narrow_oop_shift() == 0); 5335 match(Set dst mem); 5336 5337 ins_cost(110); 5338 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5339 opcode(0x8D); 5340 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5341 ins_pipe(ialu_reg_reg_fat); 5342%} 5343 5344instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5345%{ 5346 predicate(Universe::narrow_oop_shift() == 0); 5347 match(Set dst mem); 5348 5349 ins_cost(110); 5350 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5351 opcode(0x8D); 5352 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5353 ins_pipe(ialu_reg_reg_fat); 5354%} 5355 5356instruct loadConI(rRegI dst, immI src) 5357%{ 5358 match(Set dst src); 5359 5360 format %{ "movl $dst, $src\t# int" %} 5361 ins_encode(load_immI(dst, src)); 5362 ins_pipe(ialu_reg_fat); // XXX 5363%} 5364 5365instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5366%{ 5367 match(Set dst src); 5368 effect(KILL cr); 5369 5370 ins_cost(50); 5371 format %{ "xorl $dst, $dst\t# int" %} 5372 opcode(0x33); /* + rd */ 5373 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5374 ins_pipe(ialu_reg); 5375%} 5376 5377instruct loadConL(rRegL dst, immL src) 5378%{ 5379 match(Set dst src); 5380 5381 ins_cost(150); 5382 format %{ "movq $dst, $src\t# long" %} 5383 ins_encode(load_immL(dst, src)); 5384 ins_pipe(ialu_reg); 5385%} 5386 5387instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5388%{ 5389 match(Set dst src); 5390 effect(KILL cr); 5391 5392 ins_cost(50); 5393 format %{ "xorl $dst, $dst\t# long" %} 5394 opcode(0x33); /* + rd */ 5395 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5396 ins_pipe(ialu_reg); // XXX 5397%} 5398 5399instruct loadConUL32(rRegL dst, immUL32 src) 5400%{ 5401 match(Set dst src); 5402 5403 ins_cost(60); 5404 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5405 ins_encode(load_immUL32(dst, src)); 5406 ins_pipe(ialu_reg); 5407%} 5408 5409instruct loadConL32(rRegL dst, immL32 src) 5410%{ 5411 match(Set dst src); 5412 5413 ins_cost(70); 5414 format %{ "movq $dst, $src\t# long (32-bit)" %} 5415 ins_encode(load_immL32(dst, src)); 5416 ins_pipe(ialu_reg); 5417%} 5418 5419instruct loadConP(rRegP dst, immP con) %{ 5420 match(Set dst con); 5421 5422 format %{ "movq $dst, $con\t# ptr" %} 5423 ins_encode(load_immP(dst, con)); 5424 ins_pipe(ialu_reg_fat); // XXX 5425%} 5426 5427instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5428%{ 5429 match(Set dst src); 5430 effect(KILL cr); 5431 5432 ins_cost(50); 5433 format %{ "xorl $dst, $dst\t# ptr" %} 5434 opcode(0x33); /* + rd */ 5435 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5436 ins_pipe(ialu_reg); 5437%} 5438 5439instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5440%{ 5441 match(Set dst src); 5442 effect(KILL cr); 5443 5444 ins_cost(60); 5445 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5446 ins_encode(load_immP31(dst, src)); 5447 ins_pipe(ialu_reg); 5448%} 5449 5450instruct loadConF(regF dst, immF con) %{ 5451 match(Set dst con); 5452 ins_cost(125); 5453 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5454 ins_encode %{ 5455 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5456 %} 5457 ins_pipe(pipe_slow); 5458%} 5459 5460instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5461 match(Set dst src); 5462 effect(KILL cr); 5463 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5464 ins_encode %{ 5465 __ xorq($dst$$Register, $dst$$Register); 5466 %} 5467 ins_pipe(ialu_reg); 5468%} 5469 5470instruct loadConN(rRegN dst, immN src) %{ 5471 match(Set dst src); 5472 5473 ins_cost(125); 5474 format %{ "movl $dst, $src\t# compressed ptr" %} 5475 ins_encode %{ 5476 address con = (address)$src$$constant; 5477 if (con == NULL) { 5478 ShouldNotReachHere(); 5479 } else { 5480 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5481 } 5482 %} 5483 ins_pipe(ialu_reg_fat); // XXX 5484%} 5485 5486instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5487 match(Set dst src); 5488 5489 ins_cost(125); 5490 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5491 ins_encode %{ 5492 address con = (address)$src$$constant; 5493 if (con == NULL) { 5494 ShouldNotReachHere(); 5495 } else { 5496 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5497 } 5498 %} 5499 ins_pipe(ialu_reg_fat); // XXX 5500%} 5501 5502instruct loadConF0(regF dst, immF0 src) 5503%{ 5504 match(Set dst src); 5505 ins_cost(100); 5506 5507 format %{ "xorps $dst, $dst\t# float 0.0" %} 5508 ins_encode %{ 5509 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5510 %} 5511 ins_pipe(pipe_slow); 5512%} 5513 5514// Use the same format since predicate() can not be used here. 5515instruct loadConD(regD dst, immD con) %{ 5516 match(Set dst con); 5517 ins_cost(125); 5518 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5519 ins_encode %{ 5520 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5521 %} 5522 ins_pipe(pipe_slow); 5523%} 5524 5525instruct loadConD0(regD dst, immD0 src) 5526%{ 5527 match(Set dst src); 5528 ins_cost(100); 5529 5530 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5531 ins_encode %{ 5532 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5533 %} 5534 ins_pipe(pipe_slow); 5535%} 5536 5537instruct loadSSI(rRegI dst, stackSlotI src) 5538%{ 5539 match(Set dst src); 5540 5541 ins_cost(125); 5542 format %{ "movl $dst, $src\t# int stk" %} 5543 opcode(0x8B); 5544 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5545 ins_pipe(ialu_reg_mem); 5546%} 5547 5548instruct loadSSL(rRegL dst, stackSlotL src) 5549%{ 5550 match(Set dst src); 5551 5552 ins_cost(125); 5553 format %{ "movq $dst, $src\t# long stk" %} 5554 opcode(0x8B); 5555 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5556 ins_pipe(ialu_reg_mem); 5557%} 5558 5559instruct loadSSP(rRegP dst, stackSlotP src) 5560%{ 5561 match(Set dst src); 5562 5563 ins_cost(125); 5564 format %{ "movq $dst, $src\t# ptr stk" %} 5565 opcode(0x8B); 5566 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5567 ins_pipe(ialu_reg_mem); 5568%} 5569 5570instruct loadSSF(regF dst, stackSlotF src) 5571%{ 5572 match(Set dst src); 5573 5574 ins_cost(125); 5575 format %{ "movss $dst, $src\t# float stk" %} 5576 ins_encode %{ 5577 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5578 %} 5579 ins_pipe(pipe_slow); // XXX 5580%} 5581 5582// Use the same format since predicate() can not be used here. 5583instruct loadSSD(regD dst, stackSlotD src) 5584%{ 5585 match(Set dst src); 5586 5587 ins_cost(125); 5588 format %{ "movsd $dst, $src\t# double stk" %} 5589 ins_encode %{ 5590 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5591 %} 5592 ins_pipe(pipe_slow); // XXX 5593%} 5594 5595// Prefetch instructions. 5596// Must be safe to execute with invalid address (cannot fault). 5597 5598instruct prefetchr( memory mem ) %{ 5599 predicate(ReadPrefetchInstr==3); 5600 match(PrefetchRead mem); 5601 ins_cost(125); 5602 5603 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 5604 ins_encode %{ 5605 __ prefetchr($mem$$Address); 5606 %} 5607 ins_pipe(ialu_mem); 5608%} 5609 5610instruct prefetchrNTA( memory mem ) %{ 5611 predicate(ReadPrefetchInstr==0); 5612 match(PrefetchRead mem); 5613 ins_cost(125); 5614 5615 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 5616 ins_encode %{ 5617 __ prefetchnta($mem$$Address); 5618 %} 5619 ins_pipe(ialu_mem); 5620%} 5621 5622instruct prefetchrT0( memory mem ) %{ 5623 predicate(ReadPrefetchInstr==1); 5624 match(PrefetchRead mem); 5625 ins_cost(125); 5626 5627 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 5628 ins_encode %{ 5629 __ prefetcht0($mem$$Address); 5630 %} 5631 ins_pipe(ialu_mem); 5632%} 5633 5634instruct prefetchrT2( memory mem ) %{ 5635 predicate(ReadPrefetchInstr==2); 5636 match(PrefetchRead mem); 5637 ins_cost(125); 5638 5639 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 5640 ins_encode %{ 5641 __ prefetcht2($mem$$Address); 5642 %} 5643 ins_pipe(ialu_mem); 5644%} 5645 5646instruct prefetchwNTA( memory mem ) %{ 5647 match(PrefetchWrite mem); 5648 ins_cost(125); 5649 5650 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 5651 ins_encode %{ 5652 __ prefetchnta($mem$$Address); 5653 %} 5654 ins_pipe(ialu_mem); 5655%} 5656 5657// Prefetch instructions for allocation. 5658 5659instruct prefetchAlloc( memory mem ) %{ 5660 predicate(AllocatePrefetchInstr==3); 5661 match(PrefetchAllocation mem); 5662 ins_cost(125); 5663 5664 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5665 ins_encode %{ 5666 __ prefetchw($mem$$Address); 5667 %} 5668 ins_pipe(ialu_mem); 5669%} 5670 5671instruct prefetchAllocNTA( memory mem ) %{ 5672 predicate(AllocatePrefetchInstr==0); 5673 match(PrefetchAllocation mem); 5674 ins_cost(125); 5675 5676 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5677 ins_encode %{ 5678 __ prefetchnta($mem$$Address); 5679 %} 5680 ins_pipe(ialu_mem); 5681%} 5682 5683instruct prefetchAllocT0( memory mem ) %{ 5684 predicate(AllocatePrefetchInstr==1); 5685 match(PrefetchAllocation mem); 5686 ins_cost(125); 5687 5688 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5689 ins_encode %{ 5690 __ prefetcht0($mem$$Address); 5691 %} 5692 ins_pipe(ialu_mem); 5693%} 5694 5695instruct prefetchAllocT2( memory mem ) %{ 5696 predicate(AllocatePrefetchInstr==2); 5697 match(PrefetchAllocation mem); 5698 ins_cost(125); 5699 5700 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5701 ins_encode %{ 5702 __ prefetcht2($mem$$Address); 5703 %} 5704 ins_pipe(ialu_mem); 5705%} 5706 5707//----------Store Instructions------------------------------------------------- 5708 5709// Store Byte 5710instruct storeB(memory mem, rRegI src) 5711%{ 5712 match(Set mem (StoreB mem src)); 5713 5714 ins_cost(125); // XXX 5715 format %{ "movb $mem, $src\t# byte" %} 5716 opcode(0x88); 5717 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5718 ins_pipe(ialu_mem_reg); 5719%} 5720 5721// Store Char/Short 5722instruct storeC(memory mem, rRegI src) 5723%{ 5724 match(Set mem (StoreC mem src)); 5725 5726 ins_cost(125); // XXX 5727 format %{ "movw $mem, $src\t# char/short" %} 5728 opcode(0x89); 5729 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5730 ins_pipe(ialu_mem_reg); 5731%} 5732 5733// Store Integer 5734instruct storeI(memory mem, rRegI src) 5735%{ 5736 match(Set mem (StoreI mem src)); 5737 5738 ins_cost(125); // XXX 5739 format %{ "movl $mem, $src\t# int" %} 5740 opcode(0x89); 5741 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5742 ins_pipe(ialu_mem_reg); 5743%} 5744 5745// Store Long 5746instruct storeL(memory mem, rRegL src) 5747%{ 5748 match(Set mem (StoreL mem src)); 5749 5750 ins_cost(125); // XXX 5751 format %{ "movq $mem, $src\t# long" %} 5752 opcode(0x89); 5753 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5754 ins_pipe(ialu_mem_reg); // XXX 5755%} 5756 5757// Store Pointer 5758instruct storeP(memory mem, any_RegP src) 5759%{ 5760 match(Set mem (StoreP mem src)); 5761 5762 ins_cost(125); // XXX 5763 format %{ "movq $mem, $src\t# ptr" %} 5764 opcode(0x89); 5765 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5766 ins_pipe(ialu_mem_reg); 5767%} 5768 5769instruct storeImmP0(memory mem, immP0 zero) 5770%{ 5771 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5772 match(Set mem (StoreP mem zero)); 5773 5774 ins_cost(125); // XXX 5775 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5776 ins_encode %{ 5777 __ movq($mem$$Address, r12); 5778 %} 5779 ins_pipe(ialu_mem_reg); 5780%} 5781 5782// Store NULL Pointer, mark word, or other simple pointer constant. 5783instruct storeImmP(memory mem, immP31 src) 5784%{ 5785 match(Set mem (StoreP mem src)); 5786 5787 ins_cost(150); // XXX 5788 format %{ "movq $mem, $src\t# ptr" %} 5789 opcode(0xC7); /* C7 /0 */ 5790 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5791 ins_pipe(ialu_mem_imm); 5792%} 5793 5794// Store Compressed Pointer 5795instruct storeN(memory mem, rRegN src) 5796%{ 5797 match(Set mem (StoreN mem src)); 5798 5799 ins_cost(125); // XXX 5800 format %{ "movl $mem, $src\t# compressed ptr" %} 5801 ins_encode %{ 5802 __ movl($mem$$Address, $src$$Register); 5803 %} 5804 ins_pipe(ialu_mem_reg); 5805%} 5806 5807instruct storeNKlass(memory mem, rRegN src) 5808%{ 5809 match(Set mem (StoreNKlass mem src)); 5810 5811 ins_cost(125); // XXX 5812 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5813 ins_encode %{ 5814 __ movl($mem$$Address, $src$$Register); 5815 %} 5816 ins_pipe(ialu_mem_reg); 5817%} 5818 5819instruct storeImmN0(memory mem, immN0 zero) 5820%{ 5821 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5822 match(Set mem (StoreN mem zero)); 5823 5824 ins_cost(125); // XXX 5825 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5826 ins_encode %{ 5827 __ movl($mem$$Address, r12); 5828 %} 5829 ins_pipe(ialu_mem_reg); 5830%} 5831 5832instruct storeImmN(memory mem, immN src) 5833%{ 5834 match(Set mem (StoreN mem src)); 5835 5836 ins_cost(150); // XXX 5837 format %{ "movl $mem, $src\t# compressed ptr" %} 5838 ins_encode %{ 5839 address con = (address)$src$$constant; 5840 if (con == NULL) { 5841 __ movl($mem$$Address, (int32_t)0); 5842 } else { 5843 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5844 } 5845 %} 5846 ins_pipe(ialu_mem_imm); 5847%} 5848 5849instruct storeImmNKlass(memory mem, immNKlass src) 5850%{ 5851 match(Set mem (StoreNKlass mem src)); 5852 5853 ins_cost(150); // XXX 5854 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5855 ins_encode %{ 5856 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5857 %} 5858 ins_pipe(ialu_mem_imm); 5859%} 5860 5861// Store Integer Immediate 5862instruct storeImmI0(memory mem, immI0 zero) 5863%{ 5864 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5865 match(Set mem (StoreI mem zero)); 5866 5867 ins_cost(125); // XXX 5868 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5869 ins_encode %{ 5870 __ movl($mem$$Address, r12); 5871 %} 5872 ins_pipe(ialu_mem_reg); 5873%} 5874 5875instruct storeImmI(memory mem, immI src) 5876%{ 5877 match(Set mem (StoreI mem src)); 5878 5879 ins_cost(150); 5880 format %{ "movl $mem, $src\t# int" %} 5881 opcode(0xC7); /* C7 /0 */ 5882 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5883 ins_pipe(ialu_mem_imm); 5884%} 5885 5886// Store Long Immediate 5887instruct storeImmL0(memory mem, immL0 zero) 5888%{ 5889 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5890 match(Set mem (StoreL mem zero)); 5891 5892 ins_cost(125); // XXX 5893 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5894 ins_encode %{ 5895 __ movq($mem$$Address, r12); 5896 %} 5897 ins_pipe(ialu_mem_reg); 5898%} 5899 5900instruct storeImmL(memory mem, immL32 src) 5901%{ 5902 match(Set mem (StoreL mem src)); 5903 5904 ins_cost(150); 5905 format %{ "movq $mem, $src\t# long" %} 5906 opcode(0xC7); /* C7 /0 */ 5907 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5908 ins_pipe(ialu_mem_imm); 5909%} 5910 5911// Store Short/Char Immediate 5912instruct storeImmC0(memory mem, immI0 zero) 5913%{ 5914 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5915 match(Set mem (StoreC mem zero)); 5916 5917 ins_cost(125); // XXX 5918 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5919 ins_encode %{ 5920 __ movw($mem$$Address, r12); 5921 %} 5922 ins_pipe(ialu_mem_reg); 5923%} 5924 5925instruct storeImmI16(memory mem, immI16 src) 5926%{ 5927 predicate(UseStoreImmI16); 5928 match(Set mem (StoreC mem src)); 5929 5930 ins_cost(150); 5931 format %{ "movw $mem, $src\t# short/char" %} 5932 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 5933 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 5934 ins_pipe(ialu_mem_imm); 5935%} 5936 5937// Store Byte Immediate 5938instruct storeImmB0(memory mem, immI0 zero) 5939%{ 5940 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5941 match(Set mem (StoreB mem zero)); 5942 5943 ins_cost(125); // XXX 5944 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5945 ins_encode %{ 5946 __ movb($mem$$Address, r12); 5947 %} 5948 ins_pipe(ialu_mem_reg); 5949%} 5950 5951instruct storeImmB(memory mem, immI8 src) 5952%{ 5953 match(Set mem (StoreB mem src)); 5954 5955 ins_cost(150); // XXX 5956 format %{ "movb $mem, $src\t# byte" %} 5957 opcode(0xC6); /* C6 /0 */ 5958 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5959 ins_pipe(ialu_mem_imm); 5960%} 5961 5962// Store CMS card-mark Immediate 5963instruct storeImmCM0_reg(memory mem, immI0 zero) 5964%{ 5965 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5966 match(Set mem (StoreCM mem zero)); 5967 5968 ins_cost(125); // XXX 5969 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5970 ins_encode %{ 5971 __ movb($mem$$Address, r12); 5972 %} 5973 ins_pipe(ialu_mem_reg); 5974%} 5975 5976instruct storeImmCM0(memory mem, immI0 src) 5977%{ 5978 match(Set mem (StoreCM mem src)); 5979 5980 ins_cost(150); // XXX 5981 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5982 opcode(0xC6); /* C6 /0 */ 5983 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5984 ins_pipe(ialu_mem_imm); 5985%} 5986 5987// Store Float 5988instruct storeF(memory mem, regF src) 5989%{ 5990 match(Set mem (StoreF mem src)); 5991 5992 ins_cost(95); // XXX 5993 format %{ "movss $mem, $src\t# float" %} 5994 ins_encode %{ 5995 __ movflt($mem$$Address, $src$$XMMRegister); 5996 %} 5997 ins_pipe(pipe_slow); // XXX 5998%} 5999 6000// Store immediate Float value (it is faster than store from XMM register) 6001instruct storeF0(memory mem, immF0 zero) 6002%{ 6003 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6004 match(Set mem (StoreF mem zero)); 6005 6006 ins_cost(25); // XXX 6007 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 6008 ins_encode %{ 6009 __ movl($mem$$Address, r12); 6010 %} 6011 ins_pipe(ialu_mem_reg); 6012%} 6013 6014instruct storeF_imm(memory mem, immF src) 6015%{ 6016 match(Set mem (StoreF mem src)); 6017 6018 ins_cost(50); 6019 format %{ "movl $mem, $src\t# float" %} 6020 opcode(0xC7); /* C7 /0 */ 6021 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6022 ins_pipe(ialu_mem_imm); 6023%} 6024 6025// Store Double 6026instruct storeD(memory mem, regD src) 6027%{ 6028 match(Set mem (StoreD mem src)); 6029 6030 ins_cost(95); // XXX 6031 format %{ "movsd $mem, $src\t# double" %} 6032 ins_encode %{ 6033 __ movdbl($mem$$Address, $src$$XMMRegister); 6034 %} 6035 ins_pipe(pipe_slow); // XXX 6036%} 6037 6038// Store immediate double 0.0 (it is faster than store from XMM register) 6039instruct storeD0_imm(memory mem, immD0 src) 6040%{ 6041 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 6042 match(Set mem (StoreD mem src)); 6043 6044 ins_cost(50); 6045 format %{ "movq $mem, $src\t# double 0." %} 6046 opcode(0xC7); /* C7 /0 */ 6047 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 6048 ins_pipe(ialu_mem_imm); 6049%} 6050 6051instruct storeD0(memory mem, immD0 zero) 6052%{ 6053 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 6054 match(Set mem (StoreD mem zero)); 6055 6056 ins_cost(25); // XXX 6057 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 6058 ins_encode %{ 6059 __ movq($mem$$Address, r12); 6060 %} 6061 ins_pipe(ialu_mem_reg); 6062%} 6063 6064instruct storeSSI(stackSlotI dst, rRegI src) 6065%{ 6066 match(Set dst src); 6067 6068 ins_cost(100); 6069 format %{ "movl $dst, $src\t# int stk" %} 6070 opcode(0x89); 6071 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6072 ins_pipe( ialu_mem_reg ); 6073%} 6074 6075instruct storeSSL(stackSlotL dst, rRegL src) 6076%{ 6077 match(Set dst src); 6078 6079 ins_cost(100); 6080 format %{ "movq $dst, $src\t# long stk" %} 6081 opcode(0x89); 6082 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6083 ins_pipe(ialu_mem_reg); 6084%} 6085 6086instruct storeSSP(stackSlotP dst, rRegP src) 6087%{ 6088 match(Set dst src); 6089 6090 ins_cost(100); 6091 format %{ "movq $dst, $src\t# ptr stk" %} 6092 opcode(0x89); 6093 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6094 ins_pipe(ialu_mem_reg); 6095%} 6096 6097instruct storeSSF(stackSlotF dst, regF src) 6098%{ 6099 match(Set dst src); 6100 6101 ins_cost(95); // XXX 6102 format %{ "movss $dst, $src\t# float stk" %} 6103 ins_encode %{ 6104 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 6105 %} 6106 ins_pipe(pipe_slow); // XXX 6107%} 6108 6109instruct storeSSD(stackSlotD dst, regD src) 6110%{ 6111 match(Set dst src); 6112 6113 ins_cost(95); // XXX 6114 format %{ "movsd $dst, $src\t# double stk" %} 6115 ins_encode %{ 6116 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 6117 %} 6118 ins_pipe(pipe_slow); // XXX 6119%} 6120 6121//----------BSWAP Instructions------------------------------------------------- 6122instruct bytes_reverse_int(rRegI dst) %{ 6123 match(Set dst (ReverseBytesI dst)); 6124 6125 format %{ "bswapl $dst" %} 6126 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 6127 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 6128 ins_pipe( ialu_reg ); 6129%} 6130 6131instruct bytes_reverse_long(rRegL dst) %{ 6132 match(Set dst (ReverseBytesL dst)); 6133 6134 format %{ "bswapq $dst" %} 6135 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 6136 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 6137 ins_pipe( ialu_reg); 6138%} 6139 6140instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 6141 match(Set dst (ReverseBytesUS dst)); 6142 effect(KILL cr); 6143 6144 format %{ "bswapl $dst\n\t" 6145 "shrl $dst,16\n\t" %} 6146 ins_encode %{ 6147 __ bswapl($dst$$Register); 6148 __ shrl($dst$$Register, 16); 6149 %} 6150 ins_pipe( ialu_reg ); 6151%} 6152 6153instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 6154 match(Set dst (ReverseBytesS dst)); 6155 effect(KILL cr); 6156 6157 format %{ "bswapl $dst\n\t" 6158 "sar $dst,16\n\t" %} 6159 ins_encode %{ 6160 __ bswapl($dst$$Register); 6161 __ sarl($dst$$Register, 16); 6162 %} 6163 ins_pipe( ialu_reg ); 6164%} 6165 6166//---------- Zeros Count Instructions ------------------------------------------ 6167 6168instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6169 predicate(UseCountLeadingZerosInstruction); 6170 match(Set dst (CountLeadingZerosI src)); 6171 effect(KILL cr); 6172 6173 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 6174 ins_encode %{ 6175 __ lzcntl($dst$$Register, $src$$Register); 6176 %} 6177 ins_pipe(ialu_reg); 6178%} 6179 6180instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 6181 predicate(!UseCountLeadingZerosInstruction); 6182 match(Set dst (CountLeadingZerosI src)); 6183 effect(KILL cr); 6184 6185 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 6186 "jnz skip\n\t" 6187 "movl $dst, -1\n" 6188 "skip:\n\t" 6189 "negl $dst\n\t" 6190 "addl $dst, 31" %} 6191 ins_encode %{ 6192 Register Rdst = $dst$$Register; 6193 Register Rsrc = $src$$Register; 6194 Label skip; 6195 __ bsrl(Rdst, Rsrc); 6196 __ jccb(Assembler::notZero, skip); 6197 __ movl(Rdst, -1); 6198 __ bind(skip); 6199 __ negl(Rdst); 6200 __ addl(Rdst, BitsPerInt - 1); 6201 %} 6202 ins_pipe(ialu_reg); 6203%} 6204 6205instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6206 predicate(UseCountLeadingZerosInstruction); 6207 match(Set dst (CountLeadingZerosL src)); 6208 effect(KILL cr); 6209 6210 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 6211 ins_encode %{ 6212 __ lzcntq($dst$$Register, $src$$Register); 6213 %} 6214 ins_pipe(ialu_reg); 6215%} 6216 6217instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6218 predicate(!UseCountLeadingZerosInstruction); 6219 match(Set dst (CountLeadingZerosL src)); 6220 effect(KILL cr); 6221 6222 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6223 "jnz skip\n\t" 6224 "movl $dst, -1\n" 6225 "skip:\n\t" 6226 "negl $dst\n\t" 6227 "addl $dst, 63" %} 6228 ins_encode %{ 6229 Register Rdst = $dst$$Register; 6230 Register Rsrc = $src$$Register; 6231 Label skip; 6232 __ bsrq(Rdst, Rsrc); 6233 __ jccb(Assembler::notZero, skip); 6234 __ movl(Rdst, -1); 6235 __ bind(skip); 6236 __ negl(Rdst); 6237 __ addl(Rdst, BitsPerLong - 1); 6238 %} 6239 ins_pipe(ialu_reg); 6240%} 6241 6242instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6243 match(Set dst (CountTrailingZerosI src)); 6244 effect(KILL cr); 6245 6246 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6247 "jnz done\n\t" 6248 "movl $dst, 32\n" 6249 "done:" %} 6250 ins_encode %{ 6251 Register Rdst = $dst$$Register; 6252 Label done; 6253 __ bsfl(Rdst, $src$$Register); 6254 __ jccb(Assembler::notZero, done); 6255 __ movl(Rdst, BitsPerInt); 6256 __ bind(done); 6257 %} 6258 ins_pipe(ialu_reg); 6259%} 6260 6261instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6262 match(Set dst (CountTrailingZerosL src)); 6263 effect(KILL cr); 6264 6265 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6266 "jnz done\n\t" 6267 "movl $dst, 64\n" 6268 "done:" %} 6269 ins_encode %{ 6270 Register Rdst = $dst$$Register; 6271 Label done; 6272 __ bsfq(Rdst, $src$$Register); 6273 __ jccb(Assembler::notZero, done); 6274 __ movl(Rdst, BitsPerLong); 6275 __ bind(done); 6276 %} 6277 ins_pipe(ialu_reg); 6278%} 6279 6280 6281//---------- Population Count Instructions ------------------------------------- 6282 6283instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6284 predicate(UsePopCountInstruction); 6285 match(Set dst (PopCountI src)); 6286 effect(KILL cr); 6287 6288 format %{ "popcnt $dst, $src" %} 6289 ins_encode %{ 6290 __ popcntl($dst$$Register, $src$$Register); 6291 %} 6292 ins_pipe(ialu_reg); 6293%} 6294 6295instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6296 predicate(UsePopCountInstruction); 6297 match(Set dst (PopCountI (LoadI mem))); 6298 effect(KILL cr); 6299 6300 format %{ "popcnt $dst, $mem" %} 6301 ins_encode %{ 6302 __ popcntl($dst$$Register, $mem$$Address); 6303 %} 6304 ins_pipe(ialu_reg); 6305%} 6306 6307// Note: Long.bitCount(long) returns an int. 6308instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6309 predicate(UsePopCountInstruction); 6310 match(Set dst (PopCountL src)); 6311 effect(KILL cr); 6312 6313 format %{ "popcnt $dst, $src" %} 6314 ins_encode %{ 6315 __ popcntq($dst$$Register, $src$$Register); 6316 %} 6317 ins_pipe(ialu_reg); 6318%} 6319 6320// Note: Long.bitCount(long) returns an int. 6321instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6322 predicate(UsePopCountInstruction); 6323 match(Set dst (PopCountL (LoadL mem))); 6324 effect(KILL cr); 6325 6326 format %{ "popcnt $dst, $mem" %} 6327 ins_encode %{ 6328 __ popcntq($dst$$Register, $mem$$Address); 6329 %} 6330 ins_pipe(ialu_reg); 6331%} 6332 6333 6334//----------MemBar Instructions----------------------------------------------- 6335// Memory barrier flavors 6336 6337instruct membar_acquire() 6338%{ 6339 match(MemBarAcquire); 6340 ins_cost(0); 6341 6342 size(0); 6343 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6344 ins_encode(); 6345 ins_pipe(empty); 6346%} 6347 6348instruct membar_acquire_lock() 6349%{ 6350 match(MemBarAcquireLock); 6351 ins_cost(0); 6352 6353 size(0); 6354 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6355 ins_encode(); 6356 ins_pipe(empty); 6357%} 6358 6359instruct membar_release() 6360%{ 6361 match(MemBarRelease); 6362 ins_cost(0); 6363 6364 size(0); 6365 format %{ "MEMBAR-release ! (empty encoding)" %} 6366 ins_encode(); 6367 ins_pipe(empty); 6368%} 6369 6370instruct membar_release_lock() 6371%{ 6372 match(MemBarReleaseLock); 6373 ins_cost(0); 6374 6375 size(0); 6376 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6377 ins_encode(); 6378 ins_pipe(empty); 6379%} 6380 6381instruct membar_volatile(rFlagsReg cr) %{ 6382 match(MemBarVolatile); 6383 effect(KILL cr); 6384 ins_cost(400); 6385 6386 format %{ 6387 $$template 6388 if (os::is_MP()) { 6389 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6390 } else { 6391 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6392 } 6393 %} 6394 ins_encode %{ 6395 __ membar(Assembler::StoreLoad); 6396 %} 6397 ins_pipe(pipe_slow); 6398%} 6399 6400instruct unnecessary_membar_volatile() 6401%{ 6402 match(MemBarVolatile); 6403 predicate(Matcher::post_store_load_barrier(n)); 6404 ins_cost(0); 6405 6406 size(0); 6407 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6408 ins_encode(); 6409 ins_pipe(empty); 6410%} 6411 6412instruct membar_storestore() %{ 6413 match(MemBarStoreStore); 6414 ins_cost(0); 6415 6416 size(0); 6417 format %{ "MEMBAR-storestore (empty encoding)" %} 6418 ins_encode( ); 6419 ins_pipe(empty); 6420%} 6421 6422//----------Move Instructions-------------------------------------------------- 6423 6424instruct castX2P(rRegP dst, rRegL src) 6425%{ 6426 match(Set dst (CastX2P src)); 6427 6428 format %{ "movq $dst, $src\t# long->ptr" %} 6429 ins_encode %{ 6430 if ($dst$$reg != $src$$reg) { 6431 __ movptr($dst$$Register, $src$$Register); 6432 } 6433 %} 6434 ins_pipe(ialu_reg_reg); // XXX 6435%} 6436 6437instruct castP2X(rRegL dst, rRegP src) 6438%{ 6439 match(Set dst (CastP2X src)); 6440 6441 format %{ "movq $dst, $src\t# ptr -> long" %} 6442 ins_encode %{ 6443 if ($dst$$reg != $src$$reg) { 6444 __ movptr($dst$$Register, $src$$Register); 6445 } 6446 %} 6447 ins_pipe(ialu_reg_reg); // XXX 6448%} 6449 6450// Convert oop into int for vectors alignment masking 6451instruct convP2I(rRegI dst, rRegP src) 6452%{ 6453 match(Set dst (ConvL2I (CastP2X src))); 6454 6455 format %{ "movl $dst, $src\t# ptr -> int" %} 6456 ins_encode %{ 6457 __ movl($dst$$Register, $src$$Register); 6458 %} 6459 ins_pipe(ialu_reg_reg); // XXX 6460%} 6461 6462// Convert compressed oop into int for vectors alignment masking 6463// in case of 32bit oops (heap < 4Gb). 6464instruct convN2I(rRegI dst, rRegN src) 6465%{ 6466 predicate(Universe::narrow_oop_shift() == 0); 6467 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6468 6469 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6470 ins_encode %{ 6471 __ movl($dst$$Register, $src$$Register); 6472 %} 6473 ins_pipe(ialu_reg_reg); // XXX 6474%} 6475 6476// Convert oop pointer into compressed form 6477instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6478 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6479 match(Set dst (EncodeP src)); 6480 effect(KILL cr); 6481 format %{ "encode_heap_oop $dst,$src" %} 6482 ins_encode %{ 6483 Register s = $src$$Register; 6484 Register d = $dst$$Register; 6485 if (s != d) { 6486 __ movq(d, s); 6487 } 6488 __ encode_heap_oop(d); 6489 %} 6490 ins_pipe(ialu_reg_long); 6491%} 6492 6493instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6494 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6495 match(Set dst (EncodeP src)); 6496 effect(KILL cr); 6497 format %{ "encode_heap_oop_not_null $dst,$src" %} 6498 ins_encode %{ 6499 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6500 %} 6501 ins_pipe(ialu_reg_long); 6502%} 6503 6504instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6505 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6506 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6507 match(Set dst (DecodeN src)); 6508 effect(KILL cr); 6509 format %{ "decode_heap_oop $dst,$src" %} 6510 ins_encode %{ 6511 Register s = $src$$Register; 6512 Register d = $dst$$Register; 6513 if (s != d) { 6514 __ movq(d, s); 6515 } 6516 __ decode_heap_oop(d); 6517 %} 6518 ins_pipe(ialu_reg_long); 6519%} 6520 6521instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6522 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6523 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6524 match(Set dst (DecodeN src)); 6525 effect(KILL cr); 6526 format %{ "decode_heap_oop_not_null $dst,$src" %} 6527 ins_encode %{ 6528 Register s = $src$$Register; 6529 Register d = $dst$$Register; 6530 if (s != d) { 6531 __ decode_heap_oop_not_null(d, s); 6532 } else { 6533 __ decode_heap_oop_not_null(d); 6534 } 6535 %} 6536 ins_pipe(ialu_reg_long); 6537%} 6538 6539instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6540 match(Set dst (EncodePKlass src)); 6541 effect(KILL cr); 6542 format %{ "encode_klass_not_null $dst,$src" %} 6543 ins_encode %{ 6544 __ encode_klass_not_null($dst$$Register, $src$$Register); 6545 %} 6546 ins_pipe(ialu_reg_long); 6547%} 6548 6549instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6550 match(Set dst (DecodeNKlass src)); 6551 effect(KILL cr); 6552 format %{ "decode_klass_not_null $dst,$src" %} 6553 ins_encode %{ 6554 Register s = $src$$Register; 6555 Register d = $dst$$Register; 6556 if (s != d) { 6557 __ decode_klass_not_null(d, s); 6558 } else { 6559 __ decode_klass_not_null(d); 6560 } 6561 %} 6562 ins_pipe(ialu_reg_long); 6563%} 6564 6565 6566//----------Conditional Move--------------------------------------------------- 6567// Jump 6568// dummy instruction for generating temp registers 6569instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6570 match(Jump (LShiftL switch_val shift)); 6571 ins_cost(350); 6572 predicate(false); 6573 effect(TEMP dest); 6574 6575 format %{ "leaq $dest, [$constantaddress]\n\t" 6576 "jmp [$dest + $switch_val << $shift]\n\t" %} 6577 ins_encode %{ 6578 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6579 // to do that and the compiler is using that register as one it can allocate. 6580 // So we build it all by hand. 6581 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6582 // ArrayAddress dispatch(table, index); 6583 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6584 __ lea($dest$$Register, $constantaddress); 6585 __ jmp(dispatch); 6586 %} 6587 ins_pipe(pipe_jmp); 6588%} 6589 6590instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6591 match(Jump (AddL (LShiftL switch_val shift) offset)); 6592 ins_cost(350); 6593 effect(TEMP dest); 6594 6595 format %{ "leaq $dest, [$constantaddress]\n\t" 6596 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6597 ins_encode %{ 6598 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6599 // to do that and the compiler is using that register as one it can allocate. 6600 // So we build it all by hand. 6601 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6602 // ArrayAddress dispatch(table, index); 6603 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6604 __ lea($dest$$Register, $constantaddress); 6605 __ jmp(dispatch); 6606 %} 6607 ins_pipe(pipe_jmp); 6608%} 6609 6610instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6611 match(Jump switch_val); 6612 ins_cost(350); 6613 effect(TEMP dest); 6614 6615 format %{ "leaq $dest, [$constantaddress]\n\t" 6616 "jmp [$dest + $switch_val]\n\t" %} 6617 ins_encode %{ 6618 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6619 // to do that and the compiler is using that register as one it can allocate. 6620 // So we build it all by hand. 6621 // Address index(noreg, switch_reg, Address::times_1); 6622 // ArrayAddress dispatch(table, index); 6623 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6624 __ lea($dest$$Register, $constantaddress); 6625 __ jmp(dispatch); 6626 %} 6627 ins_pipe(pipe_jmp); 6628%} 6629 6630// Conditional move 6631instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6632%{ 6633 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6634 6635 ins_cost(200); // XXX 6636 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6637 opcode(0x0F, 0x40); 6638 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6639 ins_pipe(pipe_cmov_reg); 6640%} 6641 6642instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6643 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6644 6645 ins_cost(200); // XXX 6646 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6647 opcode(0x0F, 0x40); 6648 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6649 ins_pipe(pipe_cmov_reg); 6650%} 6651 6652instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6653 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6654 ins_cost(200); 6655 expand %{ 6656 cmovI_regU(cop, cr, dst, src); 6657 %} 6658%} 6659 6660// Conditional move 6661instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6662 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6663 6664 ins_cost(250); // XXX 6665 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6666 opcode(0x0F, 0x40); 6667 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6668 ins_pipe(pipe_cmov_mem); 6669%} 6670 6671// Conditional move 6672instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6673%{ 6674 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6675 6676 ins_cost(250); // XXX 6677 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6678 opcode(0x0F, 0x40); 6679 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6680 ins_pipe(pipe_cmov_mem); 6681%} 6682 6683instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6684 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6685 ins_cost(250); 6686 expand %{ 6687 cmovI_memU(cop, cr, dst, src); 6688 %} 6689%} 6690 6691// Conditional move 6692instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6693%{ 6694 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6695 6696 ins_cost(200); // XXX 6697 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6698 opcode(0x0F, 0x40); 6699 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6700 ins_pipe(pipe_cmov_reg); 6701%} 6702 6703// Conditional move 6704instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6705%{ 6706 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6707 6708 ins_cost(200); // XXX 6709 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6710 opcode(0x0F, 0x40); 6711 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6712 ins_pipe(pipe_cmov_reg); 6713%} 6714 6715instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6716 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6717 ins_cost(200); 6718 expand %{ 6719 cmovN_regU(cop, cr, dst, src); 6720 %} 6721%} 6722 6723// Conditional move 6724instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6725%{ 6726 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6727 6728 ins_cost(200); // XXX 6729 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6730 opcode(0x0F, 0x40); 6731 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6732 ins_pipe(pipe_cmov_reg); // XXX 6733%} 6734 6735// Conditional move 6736instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6737%{ 6738 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6739 6740 ins_cost(200); // XXX 6741 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6742 opcode(0x0F, 0x40); 6743 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6744 ins_pipe(pipe_cmov_reg); // XXX 6745%} 6746 6747instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6748 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6749 ins_cost(200); 6750 expand %{ 6751 cmovP_regU(cop, cr, dst, src); 6752 %} 6753%} 6754 6755// DISABLED: Requires the ADLC to emit a bottom_type call that 6756// correctly meets the two pointer arguments; one is an incoming 6757// register but the other is a memory operand. ALSO appears to 6758// be buggy with implicit null checks. 6759// 6760//// Conditional move 6761//instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6762//%{ 6763// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6764// ins_cost(250); 6765// format %{ "CMOV$cop $dst,$src\t# ptr" %} 6766// opcode(0x0F,0x40); 6767// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6768// ins_pipe( pipe_cmov_mem ); 6769//%} 6770// 6771//// Conditional move 6772//instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6773//%{ 6774// match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6775// ins_cost(250); 6776// format %{ "CMOV$cop $dst,$src\t# ptr" %} 6777// opcode(0x0F,0x40); 6778// ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6779// ins_pipe( pipe_cmov_mem ); 6780//%} 6781 6782instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6783%{ 6784 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6785 6786 ins_cost(200); // XXX 6787 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6788 opcode(0x0F, 0x40); 6789 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6790 ins_pipe(pipe_cmov_reg); // XXX 6791%} 6792 6793instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6794%{ 6795 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6796 6797 ins_cost(200); // XXX 6798 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6799 opcode(0x0F, 0x40); 6800 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6801 ins_pipe(pipe_cmov_mem); // XXX 6802%} 6803 6804instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6805%{ 6806 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6807 6808 ins_cost(200); // XXX 6809 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6810 opcode(0x0F, 0x40); 6811 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6812 ins_pipe(pipe_cmov_reg); // XXX 6813%} 6814 6815instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6816 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6817 ins_cost(200); 6818 expand %{ 6819 cmovL_regU(cop, cr, dst, src); 6820 %} 6821%} 6822 6823instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6824%{ 6825 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6826 6827 ins_cost(200); // XXX 6828 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6829 opcode(0x0F, 0x40); 6830 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6831 ins_pipe(pipe_cmov_mem); // XXX 6832%} 6833 6834instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6835 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6836 ins_cost(200); 6837 expand %{ 6838 cmovL_memU(cop, cr, dst, src); 6839 %} 6840%} 6841 6842instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6843%{ 6844 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6845 6846 ins_cost(200); // XXX 6847 format %{ "jn$cop skip\t# signed cmove float\n\t" 6848 "movss $dst, $src\n" 6849 "skip:" %} 6850 ins_encode %{ 6851 Label Lskip; 6852 // Invert sense of branch from sense of CMOV 6853 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6854 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6855 __ bind(Lskip); 6856 %} 6857 ins_pipe(pipe_slow); 6858%} 6859 6860// instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6861// %{ 6862// match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6863 6864// ins_cost(200); // XXX 6865// format %{ "jn$cop skip\t# signed cmove float\n\t" 6866// "movss $dst, $src\n" 6867// "skip:" %} 6868// ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6869// ins_pipe(pipe_slow); 6870// %} 6871 6872instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6873%{ 6874 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6875 6876 ins_cost(200); // XXX 6877 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6878 "movss $dst, $src\n" 6879 "skip:" %} 6880 ins_encode %{ 6881 Label Lskip; 6882 // Invert sense of branch from sense of CMOV 6883 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6884 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6885 __ bind(Lskip); 6886 %} 6887 ins_pipe(pipe_slow); 6888%} 6889 6890instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6891 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6892 ins_cost(200); 6893 expand %{ 6894 cmovF_regU(cop, cr, dst, src); 6895 %} 6896%} 6897 6898instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6899%{ 6900 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6901 6902 ins_cost(200); // XXX 6903 format %{ "jn$cop skip\t# signed cmove double\n\t" 6904 "movsd $dst, $src\n" 6905 "skip:" %} 6906 ins_encode %{ 6907 Label Lskip; 6908 // Invert sense of branch from sense of CMOV 6909 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6910 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6911 __ bind(Lskip); 6912 %} 6913 ins_pipe(pipe_slow); 6914%} 6915 6916instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6917%{ 6918 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6919 6920 ins_cost(200); // XXX 6921 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6922 "movsd $dst, $src\n" 6923 "skip:" %} 6924 ins_encode %{ 6925 Label Lskip; 6926 // Invert sense of branch from sense of CMOV 6927 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6928 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6929 __ bind(Lskip); 6930 %} 6931 ins_pipe(pipe_slow); 6932%} 6933 6934instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6935 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6936 ins_cost(200); 6937 expand %{ 6938 cmovD_regU(cop, cr, dst, src); 6939 %} 6940%} 6941 6942//----------Arithmetic Instructions-------------------------------------------- 6943//----------Addition Instructions---------------------------------------------- 6944 6945instruct addExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) 6946%{ 6947 match(AddExactI dst src); 6948 effect(DEF cr); 6949 6950 format %{ "addl $dst, $src\t# addExact int" %} 6951 ins_encode %{ 6952 __ addl($dst$$Register, $src$$Register); 6953 %} 6954 ins_pipe(ialu_reg_reg); 6955%} 6956 6957instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr) 6958%{ 6959 match(AddExactI dst src); 6960 effect(DEF cr); 6961 6962 format %{ "addl $dst, $src\t# addExact int" %} 6963 ins_encode %{ 6964 __ addl($dst$$Register, $src$$constant); 6965 %} 6966 ins_pipe(ialu_reg_reg); 6967%} 6968 6969instruct addExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) 6970%{ 6971 match(AddExactI dst (LoadI src)); 6972 effect(DEF cr); 6973 6974 ins_cost(125); // XXX 6975 format %{ "addl $dst, $src\t# addExact int" %} 6976 ins_encode %{ 6977 __ addl($dst$$Register, $src$$Address); 6978 %} 6979 6980 ins_pipe(ialu_reg_mem); 6981%} 6982 6983instruct addExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr) 6984%{ 6985 match(AddExactL dst src); 6986 effect(DEF cr); 6987 6988 format %{ "addq $dst, $src\t# addExact long" %} 6989 ins_encode %{ 6990 __ addq($dst$$Register, $src$$Register); 6991 %} 6992 ins_pipe(ialu_reg_reg); 6993%} 6994 6995instruct addExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr) 6996%{ 6997 match(AddExactL dst src); 6998 effect(DEF cr); 6999 7000 format %{ "addq $dst, $src\t# addExact long" %} 7001 ins_encode %{ 7002 __ addq($dst$$Register, $src$$constant); 7003 %} 7004 ins_pipe(ialu_reg_reg); 7005%} 7006 7007instruct addExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr) 7008%{ 7009 match(AddExactL dst (LoadL src)); 7010 effect(DEF cr); 7011 7012 ins_cost(125); // XXX 7013 format %{ "addq $dst, $src\t# addExact long" %} 7014 ins_encode %{ 7015 __ addq($dst$$Register, $src$$Address); 7016 %} 7017 7018 ins_pipe(ialu_reg_mem); 7019%} 7020 7021instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7022%{ 7023 match(Set dst (AddI dst src)); 7024 effect(KILL cr); 7025 7026 format %{ "addl $dst, $src\t# int" %} 7027 opcode(0x03); 7028 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7029 ins_pipe(ialu_reg_reg); 7030%} 7031 7032instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7033%{ 7034 match(Set dst (AddI dst src)); 7035 effect(KILL cr); 7036 7037 format %{ "addl $dst, $src\t# int" %} 7038 opcode(0x81, 0x00); /* /0 id */ 7039 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7040 ins_pipe( ialu_reg ); 7041%} 7042 7043instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7044%{ 7045 match(Set dst (AddI dst (LoadI src))); 7046 effect(KILL cr); 7047 7048 ins_cost(125); // XXX 7049 format %{ "addl $dst, $src\t# int" %} 7050 opcode(0x03); 7051 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7052 ins_pipe(ialu_reg_mem); 7053%} 7054 7055instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7056%{ 7057 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7058 effect(KILL cr); 7059 7060 ins_cost(150); // XXX 7061 format %{ "addl $dst, $src\t# int" %} 7062 opcode(0x01); /* Opcode 01 /r */ 7063 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7064 ins_pipe(ialu_mem_reg); 7065%} 7066 7067instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 7068%{ 7069 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7070 effect(KILL cr); 7071 7072 ins_cost(125); // XXX 7073 format %{ "addl $dst, $src\t# int" %} 7074 opcode(0x81); /* Opcode 81 /0 id */ 7075 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7076 ins_pipe(ialu_mem_imm); 7077%} 7078 7079instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 7080%{ 7081 predicate(UseIncDec); 7082 match(Set dst (AddI dst src)); 7083 effect(KILL cr); 7084 7085 format %{ "incl $dst\t# int" %} 7086 opcode(0xFF, 0x00); // FF /0 7087 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7088 ins_pipe(ialu_reg); 7089%} 7090 7091instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 7092%{ 7093 predicate(UseIncDec); 7094 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7095 effect(KILL cr); 7096 7097 ins_cost(125); // XXX 7098 format %{ "incl $dst\t# int" %} 7099 opcode(0xFF); /* Opcode FF /0 */ 7100 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 7101 ins_pipe(ialu_mem_imm); 7102%} 7103 7104// XXX why does that use AddI 7105instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 7106%{ 7107 predicate(UseIncDec); 7108 match(Set dst (AddI dst src)); 7109 effect(KILL cr); 7110 7111 format %{ "decl $dst\t# int" %} 7112 opcode(0xFF, 0x01); // FF /1 7113 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7114 ins_pipe(ialu_reg); 7115%} 7116 7117// XXX why does that use AddI 7118instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 7119%{ 7120 predicate(UseIncDec); 7121 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 7122 effect(KILL cr); 7123 7124 ins_cost(125); // XXX 7125 format %{ "decl $dst\t# int" %} 7126 opcode(0xFF); /* Opcode FF /1 */ 7127 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 7128 ins_pipe(ialu_mem_imm); 7129%} 7130 7131instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 7132%{ 7133 match(Set dst (AddI src0 src1)); 7134 7135 ins_cost(110); 7136 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 7137 opcode(0x8D); /* 0x8D /r */ 7138 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7139 ins_pipe(ialu_reg_reg); 7140%} 7141 7142instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7143%{ 7144 match(Set dst (AddL dst src)); 7145 effect(KILL cr); 7146 7147 format %{ "addq $dst, $src\t# long" %} 7148 opcode(0x03); 7149 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7150 ins_pipe(ialu_reg_reg); 7151%} 7152 7153instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 7154%{ 7155 match(Set dst (AddL dst src)); 7156 effect(KILL cr); 7157 7158 format %{ "addq $dst, $src\t# long" %} 7159 opcode(0x81, 0x00); /* /0 id */ 7160 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7161 ins_pipe( ialu_reg ); 7162%} 7163 7164instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7165%{ 7166 match(Set dst (AddL dst (LoadL src))); 7167 effect(KILL cr); 7168 7169 ins_cost(125); // XXX 7170 format %{ "addq $dst, $src\t# long" %} 7171 opcode(0x03); 7172 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7173 ins_pipe(ialu_reg_mem); 7174%} 7175 7176instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7177%{ 7178 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7179 effect(KILL cr); 7180 7181 ins_cost(150); // XXX 7182 format %{ "addq $dst, $src\t# long" %} 7183 opcode(0x01); /* Opcode 01 /r */ 7184 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7185 ins_pipe(ialu_mem_reg); 7186%} 7187 7188instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7189%{ 7190 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7191 effect(KILL cr); 7192 7193 ins_cost(125); // XXX 7194 format %{ "addq $dst, $src\t# long" %} 7195 opcode(0x81); /* Opcode 81 /0 id */ 7196 ins_encode(REX_mem_wide(dst), 7197 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 7198 ins_pipe(ialu_mem_imm); 7199%} 7200 7201instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 7202%{ 7203 predicate(UseIncDec); 7204 match(Set dst (AddL dst src)); 7205 effect(KILL cr); 7206 7207 format %{ "incq $dst\t# long" %} 7208 opcode(0xFF, 0x00); // FF /0 7209 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7210 ins_pipe(ialu_reg); 7211%} 7212 7213instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 7214%{ 7215 predicate(UseIncDec); 7216 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7217 effect(KILL cr); 7218 7219 ins_cost(125); // XXX 7220 format %{ "incq $dst\t# long" %} 7221 opcode(0xFF); /* Opcode FF /0 */ 7222 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 7223 ins_pipe(ialu_mem_imm); 7224%} 7225 7226// XXX why does that use AddL 7227instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 7228%{ 7229 predicate(UseIncDec); 7230 match(Set dst (AddL dst src)); 7231 effect(KILL cr); 7232 7233 format %{ "decq $dst\t# long" %} 7234 opcode(0xFF, 0x01); // FF /1 7235 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7236 ins_pipe(ialu_reg); 7237%} 7238 7239// XXX why does that use AddL 7240instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 7241%{ 7242 predicate(UseIncDec); 7243 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 7244 effect(KILL cr); 7245 7246 ins_cost(125); // XXX 7247 format %{ "decq $dst\t# long" %} 7248 opcode(0xFF); /* Opcode FF /1 */ 7249 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 7250 ins_pipe(ialu_mem_imm); 7251%} 7252 7253instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 7254%{ 7255 match(Set dst (AddL src0 src1)); 7256 7257 ins_cost(110); 7258 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 7259 opcode(0x8D); /* 0x8D /r */ 7260 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 7261 ins_pipe(ialu_reg_reg); 7262%} 7263 7264instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7265%{ 7266 match(Set dst (AddP dst src)); 7267 effect(KILL cr); 7268 7269 format %{ "addq $dst, $src\t# ptr" %} 7270 opcode(0x03); 7271 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7272 ins_pipe(ialu_reg_reg); 7273%} 7274 7275instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7276%{ 7277 match(Set dst (AddP dst src)); 7278 effect(KILL cr); 7279 7280 format %{ "addq $dst, $src\t# ptr" %} 7281 opcode(0x81, 0x00); /* /0 id */ 7282 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7283 ins_pipe( ialu_reg ); 7284%} 7285 7286// XXX addP mem ops ???? 7287 7288instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7289%{ 7290 match(Set dst (AddP src0 src1)); 7291 7292 ins_cost(110); 7293 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7294 opcode(0x8D); /* 0x8D /r */ 7295 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7296 ins_pipe(ialu_reg_reg); 7297%} 7298 7299instruct checkCastPP(rRegP dst) 7300%{ 7301 match(Set dst (CheckCastPP dst)); 7302 7303 size(0); 7304 format %{ "# checkcastPP of $dst" %} 7305 ins_encode(/* empty encoding */); 7306 ins_pipe(empty); 7307%} 7308 7309instruct castPP(rRegP dst) 7310%{ 7311 match(Set dst (CastPP dst)); 7312 7313 size(0); 7314 format %{ "# castPP of $dst" %} 7315 ins_encode(/* empty encoding */); 7316 ins_pipe(empty); 7317%} 7318 7319instruct castII(rRegI dst) 7320%{ 7321 match(Set dst (CastII dst)); 7322 7323 size(0); 7324 format %{ "# castII of $dst" %} 7325 ins_encode(/* empty encoding */); 7326 ins_cost(0); 7327 ins_pipe(empty); 7328%} 7329 7330// LoadP-locked same as a regular LoadP when used with compare-swap 7331instruct loadPLocked(rRegP dst, memory mem) 7332%{ 7333 match(Set dst (LoadPLocked mem)); 7334 7335 ins_cost(125); // XXX 7336 format %{ "movq $dst, $mem\t# ptr locked" %} 7337 opcode(0x8B); 7338 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7339 ins_pipe(ialu_reg_mem); // XXX 7340%} 7341 7342// Conditional-store of the updated heap-top. 7343// Used during allocation of the shared heap. 7344// Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7345 7346instruct storePConditional(memory heap_top_ptr, 7347 rax_RegP oldval, rRegP newval, 7348 rFlagsReg cr) 7349%{ 7350 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7351 7352 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7353 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7354 opcode(0x0F, 0xB1); 7355 ins_encode(lock_prefix, 7356 REX_reg_mem_wide(newval, heap_top_ptr), 7357 OpcP, OpcS, 7358 reg_mem(newval, heap_top_ptr)); 7359 ins_pipe(pipe_cmpxchg); 7360%} 7361 7362// Conditional-store of an int value. 7363// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7364instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7365%{ 7366 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7367 effect(KILL oldval); 7368 7369 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7370 opcode(0x0F, 0xB1); 7371 ins_encode(lock_prefix, 7372 REX_reg_mem(newval, mem), 7373 OpcP, OpcS, 7374 reg_mem(newval, mem)); 7375 ins_pipe(pipe_cmpxchg); 7376%} 7377 7378// Conditional-store of a long value. 7379// ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7380instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7381%{ 7382 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7383 effect(KILL oldval); 7384 7385 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7386 opcode(0x0F, 0xB1); 7387 ins_encode(lock_prefix, 7388 REX_reg_mem_wide(newval, mem), 7389 OpcP, OpcS, 7390 reg_mem(newval, mem)); 7391 ins_pipe(pipe_cmpxchg); 7392%} 7393 7394 7395// XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7396instruct compareAndSwapP(rRegI res, 7397 memory mem_ptr, 7398 rax_RegP oldval, rRegP newval, 7399 rFlagsReg cr) 7400%{ 7401 predicate(VM_Version::supports_cx8()); 7402 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7403 effect(KILL cr, KILL oldval); 7404 7405 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7406 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7407 "sete $res\n\t" 7408 "movzbl $res, $res" %} 7409 opcode(0x0F, 0xB1); 7410 ins_encode(lock_prefix, 7411 REX_reg_mem_wide(newval, mem_ptr), 7412 OpcP, OpcS, 7413 reg_mem(newval, mem_ptr), 7414 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7415 REX_reg_breg(res, res), // movzbl 7416 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7417 ins_pipe( pipe_cmpxchg ); 7418%} 7419 7420instruct compareAndSwapL(rRegI res, 7421 memory mem_ptr, 7422 rax_RegL oldval, rRegL newval, 7423 rFlagsReg cr) 7424%{ 7425 predicate(VM_Version::supports_cx8()); 7426 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7427 effect(KILL cr, KILL oldval); 7428 7429 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7430 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7431 "sete $res\n\t" 7432 "movzbl $res, $res" %} 7433 opcode(0x0F, 0xB1); 7434 ins_encode(lock_prefix, 7435 REX_reg_mem_wide(newval, mem_ptr), 7436 OpcP, OpcS, 7437 reg_mem(newval, mem_ptr), 7438 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7439 REX_reg_breg(res, res), // movzbl 7440 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7441 ins_pipe( pipe_cmpxchg ); 7442%} 7443 7444instruct compareAndSwapI(rRegI res, 7445 memory mem_ptr, 7446 rax_RegI oldval, rRegI newval, 7447 rFlagsReg cr) 7448%{ 7449 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7450 effect(KILL cr, KILL oldval); 7451 7452 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7453 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7454 "sete $res\n\t" 7455 "movzbl $res, $res" %} 7456 opcode(0x0F, 0xB1); 7457 ins_encode(lock_prefix, 7458 REX_reg_mem(newval, mem_ptr), 7459 OpcP, OpcS, 7460 reg_mem(newval, mem_ptr), 7461 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7462 REX_reg_breg(res, res), // movzbl 7463 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7464 ins_pipe( pipe_cmpxchg ); 7465%} 7466 7467 7468instruct compareAndSwapN(rRegI res, 7469 memory mem_ptr, 7470 rax_RegN oldval, rRegN newval, 7471 rFlagsReg cr) %{ 7472 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7473 effect(KILL cr, KILL oldval); 7474 7475 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7476 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7477 "sete $res\n\t" 7478 "movzbl $res, $res" %} 7479 opcode(0x0F, 0xB1); 7480 ins_encode(lock_prefix, 7481 REX_reg_mem(newval, mem_ptr), 7482 OpcP, OpcS, 7483 reg_mem(newval, mem_ptr), 7484 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7485 REX_reg_breg(res, res), // movzbl 7486 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7487 ins_pipe( pipe_cmpxchg ); 7488%} 7489 7490instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7491 predicate(n->as_LoadStore()->result_not_used()); 7492 match(Set dummy (GetAndAddI mem add)); 7493 effect(KILL cr); 7494 format %{ "ADDL [$mem],$add" %} 7495 ins_encode %{ 7496 if (os::is_MP()) { __ lock(); } 7497 __ addl($mem$$Address, $add$$constant); 7498 %} 7499 ins_pipe( pipe_cmpxchg ); 7500%} 7501 7502instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7503 match(Set newval (GetAndAddI mem newval)); 7504 effect(KILL cr); 7505 format %{ "XADDL [$mem],$newval" %} 7506 ins_encode %{ 7507 if (os::is_MP()) { __ lock(); } 7508 __ xaddl($mem$$Address, $newval$$Register); 7509 %} 7510 ins_pipe( pipe_cmpxchg ); 7511%} 7512 7513instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7514 predicate(n->as_LoadStore()->result_not_used()); 7515 match(Set dummy (GetAndAddL mem add)); 7516 effect(KILL cr); 7517 format %{ "ADDQ [$mem],$add" %} 7518 ins_encode %{ 7519 if (os::is_MP()) { __ lock(); } 7520 __ addq($mem$$Address, $add$$constant); 7521 %} 7522 ins_pipe( pipe_cmpxchg ); 7523%} 7524 7525instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7526 match(Set newval (GetAndAddL mem newval)); 7527 effect(KILL cr); 7528 format %{ "XADDQ [$mem],$newval" %} 7529 ins_encode %{ 7530 if (os::is_MP()) { __ lock(); } 7531 __ xaddq($mem$$Address, $newval$$Register); 7532 %} 7533 ins_pipe( pipe_cmpxchg ); 7534%} 7535 7536instruct xchgI( memory mem, rRegI newval) %{ 7537 match(Set newval (GetAndSetI mem newval)); 7538 format %{ "XCHGL $newval,[$mem]" %} 7539 ins_encode %{ 7540 __ xchgl($newval$$Register, $mem$$Address); 7541 %} 7542 ins_pipe( pipe_cmpxchg ); 7543%} 7544 7545instruct xchgL( memory mem, rRegL newval) %{ 7546 match(Set newval (GetAndSetL mem newval)); 7547 format %{ "XCHGL $newval,[$mem]" %} 7548 ins_encode %{ 7549 __ xchgq($newval$$Register, $mem$$Address); 7550 %} 7551 ins_pipe( pipe_cmpxchg ); 7552%} 7553 7554instruct xchgP( memory mem, rRegP newval) %{ 7555 match(Set newval (GetAndSetP mem newval)); 7556 format %{ "XCHGQ $newval,[$mem]" %} 7557 ins_encode %{ 7558 __ xchgq($newval$$Register, $mem$$Address); 7559 %} 7560 ins_pipe( pipe_cmpxchg ); 7561%} 7562 7563instruct xchgN( memory mem, rRegN newval) %{ 7564 match(Set newval (GetAndSetN mem newval)); 7565 format %{ "XCHGL $newval,$mem]" %} 7566 ins_encode %{ 7567 __ xchgl($newval$$Register, $mem$$Address); 7568 %} 7569 ins_pipe( pipe_cmpxchg ); 7570%} 7571 7572//----------Subtraction Instructions------------------------------------------- 7573 7574// Integer Subtraction Instructions 7575instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7576%{ 7577 match(Set dst (SubI dst src)); 7578 effect(KILL cr); 7579 7580 format %{ "subl $dst, $src\t# int" %} 7581 opcode(0x2B); 7582 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7583 ins_pipe(ialu_reg_reg); 7584%} 7585 7586instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7587%{ 7588 match(Set dst (SubI dst src)); 7589 effect(KILL cr); 7590 7591 format %{ "subl $dst, $src\t# int" %} 7592 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7593 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7594 ins_pipe(ialu_reg); 7595%} 7596 7597instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7598%{ 7599 match(Set dst (SubI dst (LoadI src))); 7600 effect(KILL cr); 7601 7602 ins_cost(125); 7603 format %{ "subl $dst, $src\t# int" %} 7604 opcode(0x2B); 7605 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7606 ins_pipe(ialu_reg_mem); 7607%} 7608 7609instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7610%{ 7611 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7612 effect(KILL cr); 7613 7614 ins_cost(150); 7615 format %{ "subl $dst, $src\t# int" %} 7616 opcode(0x29); /* Opcode 29 /r */ 7617 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7618 ins_pipe(ialu_mem_reg); 7619%} 7620 7621instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7622%{ 7623 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7624 effect(KILL cr); 7625 7626 ins_cost(125); // XXX 7627 format %{ "subl $dst, $src\t# int" %} 7628 opcode(0x81); /* Opcode 81 /5 id */ 7629 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7630 ins_pipe(ialu_mem_imm); 7631%} 7632 7633instruct subExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) 7634%{ 7635 match(SubExactI dst src); 7636 effect(DEF cr); 7637 7638 format %{ "subl $dst, $src\t# subExact int" %} 7639 ins_encode %{ 7640 __ subl($dst$$Register, $src$$Register); 7641 %} 7642 ins_pipe(ialu_reg_reg); 7643%} 7644 7645instruct subExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr) 7646%{ 7647 match(SubExactI dst src); 7648 effect(DEF cr); 7649 7650 format %{ "subl $dst, $src\t# subExact int" %} 7651 ins_encode %{ 7652 __ subl($dst$$Register, $src$$constant); 7653 %} 7654 ins_pipe(ialu_reg_reg); 7655%} 7656 7657instruct subExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) 7658%{ 7659 match(SubExactI dst (LoadI src)); 7660 effect(DEF cr); 7661 7662 ins_cost(125); 7663 format %{ "subl $dst, $src\t# subExact int" %} 7664 ins_encode %{ 7665 __ subl($dst$$Register, $src$$Address); 7666 %} 7667 ins_pipe(ialu_reg_mem); 7668%} 7669 7670instruct subExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr) 7671%{ 7672 match(SubExactL dst src); 7673 effect(DEF cr); 7674 7675 format %{ "subq $dst, $src\t# subExact long" %} 7676 ins_encode %{ 7677 __ subq($dst$$Register, $src$$Register); 7678 %} 7679 ins_pipe(ialu_reg_reg); 7680%} 7681 7682instruct subExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr) 7683%{ 7684 match(SubExactL dst (LoadL src)); 7685 effect(DEF cr); 7686 7687 format %{ "subq $dst, $src\t# subExact long" %} 7688 ins_encode %{ 7689 __ subq($dst$$Register, $src$$constant); 7690 %} 7691 ins_pipe(ialu_reg_reg); 7692%} 7693 7694instruct subExactL_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) 7695%{ 7696 match(SubExactI dst src); 7697 effect(DEF cr); 7698 7699 ins_cost(125); 7700 format %{ "subq $dst, $src\t# subExact long" %} 7701 ins_encode %{ 7702 __ subq($dst$$Register, $src$$Address); 7703 %} 7704 ins_pipe(ialu_reg_mem); 7705%} 7706 7707instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7708%{ 7709 match(Set dst (SubL dst src)); 7710 effect(KILL cr); 7711 7712 format %{ "subq $dst, $src\t# long" %} 7713 opcode(0x2B); 7714 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7715 ins_pipe(ialu_reg_reg); 7716%} 7717 7718instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7719%{ 7720 match(Set dst (SubL dst src)); 7721 effect(KILL cr); 7722 7723 format %{ "subq $dst, $src\t# long" %} 7724 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7725 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7726 ins_pipe(ialu_reg); 7727%} 7728 7729instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7730%{ 7731 match(Set dst (SubL dst (LoadL src))); 7732 effect(KILL cr); 7733 7734 ins_cost(125); 7735 format %{ "subq $dst, $src\t# long" %} 7736 opcode(0x2B); 7737 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7738 ins_pipe(ialu_reg_mem); 7739%} 7740 7741instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7742%{ 7743 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7744 effect(KILL cr); 7745 7746 ins_cost(150); 7747 format %{ "subq $dst, $src\t# long" %} 7748 opcode(0x29); /* Opcode 29 /r */ 7749 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7750 ins_pipe(ialu_mem_reg); 7751%} 7752 7753instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7754%{ 7755 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7756 effect(KILL cr); 7757 7758 ins_cost(125); // XXX 7759 format %{ "subq $dst, $src\t# long" %} 7760 opcode(0x81); /* Opcode 81 /5 id */ 7761 ins_encode(REX_mem_wide(dst), 7762 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7763 ins_pipe(ialu_mem_imm); 7764%} 7765 7766// Subtract from a pointer 7767// XXX hmpf??? 7768instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7769%{ 7770 match(Set dst (AddP dst (SubI zero src))); 7771 effect(KILL cr); 7772 7773 format %{ "subq $dst, $src\t# ptr - int" %} 7774 opcode(0x2B); 7775 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7776 ins_pipe(ialu_reg_reg); 7777%} 7778 7779instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7780%{ 7781 match(Set dst (SubI zero dst)); 7782 effect(KILL cr); 7783 7784 format %{ "negl $dst\t# int" %} 7785 opcode(0xF7, 0x03); // Opcode F7 /3 7786 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7787 ins_pipe(ialu_reg); 7788%} 7789 7790instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7791%{ 7792 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7793 effect(KILL cr); 7794 7795 format %{ "negl $dst\t# int" %} 7796 opcode(0xF7, 0x03); // Opcode F7 /3 7797 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7798 ins_pipe(ialu_reg); 7799%} 7800 7801instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7802%{ 7803 match(Set dst (SubL zero dst)); 7804 effect(KILL cr); 7805 7806 format %{ "negq $dst\t# long" %} 7807 opcode(0xF7, 0x03); // Opcode F7 /3 7808 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7809 ins_pipe(ialu_reg); 7810%} 7811 7812instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7813%{ 7814 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7815 effect(KILL cr); 7816 7817 format %{ "negq $dst\t# long" %} 7818 opcode(0xF7, 0x03); // Opcode F7 /3 7819 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7820 ins_pipe(ialu_reg); 7821%} 7822 7823instruct negExactI_rReg(rax_RegI dst, rFlagsReg cr) 7824%{ 7825 match(NegExactI dst); 7826 effect(KILL cr); 7827 7828 format %{ "negl $dst\t# negExact int" %} 7829 ins_encode %{ 7830 __ negl($dst$$Register); 7831 %} 7832 ins_pipe(ialu_reg); 7833%} 7834 7835instruct negExactL_rReg(rax_RegL dst, rFlagsReg cr) 7836%{ 7837 match(NegExactL dst); 7838 effect(KILL cr); 7839 7840 format %{ "negq $dst\t# negExact long" %} 7841 ins_encode %{ 7842 __ negq($dst$$Register); 7843 %} 7844 ins_pipe(ialu_reg); 7845%} 7846 7847 7848//----------Multiplication/Division Instructions------------------------------- 7849// Integer Multiplication Instructions 7850// Multiply Register 7851 7852instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7853%{ 7854 match(Set dst (MulI dst src)); 7855 effect(KILL cr); 7856 7857 ins_cost(300); 7858 format %{ "imull $dst, $src\t# int" %} 7859 opcode(0x0F, 0xAF); 7860 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7861 ins_pipe(ialu_reg_reg_alu0); 7862%} 7863 7864instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7865%{ 7866 match(Set dst (MulI src imm)); 7867 effect(KILL cr); 7868 7869 ins_cost(300); 7870 format %{ "imull $dst, $src, $imm\t# int" %} 7871 opcode(0x69); /* 69 /r id */ 7872 ins_encode(REX_reg_reg(dst, src), 7873 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7874 ins_pipe(ialu_reg_reg_alu0); 7875%} 7876 7877instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7878%{ 7879 match(Set dst (MulI dst (LoadI src))); 7880 effect(KILL cr); 7881 7882 ins_cost(350); 7883 format %{ "imull $dst, $src\t# int" %} 7884 opcode(0x0F, 0xAF); 7885 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7886 ins_pipe(ialu_reg_mem_alu0); 7887%} 7888 7889instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7890%{ 7891 match(Set dst (MulI (LoadI src) imm)); 7892 effect(KILL cr); 7893 7894 ins_cost(300); 7895 format %{ "imull $dst, $src, $imm\t# int" %} 7896 opcode(0x69); /* 69 /r id */ 7897 ins_encode(REX_reg_mem(dst, src), 7898 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7899 ins_pipe(ialu_reg_mem_alu0); 7900%} 7901 7902instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7903%{ 7904 match(Set dst (MulL dst src)); 7905 effect(KILL cr); 7906 7907 ins_cost(300); 7908 format %{ "imulq $dst, $src\t# long" %} 7909 opcode(0x0F, 0xAF); 7910 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7911 ins_pipe(ialu_reg_reg_alu0); 7912%} 7913 7914instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7915%{ 7916 match(Set dst (MulL src imm)); 7917 effect(KILL cr); 7918 7919 ins_cost(300); 7920 format %{ "imulq $dst, $src, $imm\t# long" %} 7921 opcode(0x69); /* 69 /r id */ 7922 ins_encode(REX_reg_reg_wide(dst, src), 7923 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7924 ins_pipe(ialu_reg_reg_alu0); 7925%} 7926 7927instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7928%{ 7929 match(Set dst (MulL dst (LoadL src))); 7930 effect(KILL cr); 7931 7932 ins_cost(350); 7933 format %{ "imulq $dst, $src\t# long" %} 7934 opcode(0x0F, 0xAF); 7935 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7936 ins_pipe(ialu_reg_mem_alu0); 7937%} 7938 7939instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7940%{ 7941 match(Set dst (MulL (LoadL src) imm)); 7942 effect(KILL cr); 7943 7944 ins_cost(300); 7945 format %{ "imulq $dst, $src, $imm\t# long" %} 7946 opcode(0x69); /* 69 /r id */ 7947 ins_encode(REX_reg_mem_wide(dst, src), 7948 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7949 ins_pipe(ialu_reg_mem_alu0); 7950%} 7951 7952instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7953%{ 7954 match(Set dst (MulHiL src rax)); 7955 effect(USE_KILL rax, KILL cr); 7956 7957 ins_cost(300); 7958 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7959 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7960 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7961 ins_pipe(ialu_reg_reg_alu0); 7962%} 7963 7964 7965instruct mulExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) 7966%{ 7967 match(MulExactI dst src); 7968 effect(DEF cr); 7969 7970 ins_cost(300); 7971 format %{ "imull $dst, $src\t# mulExact int" %} 7972 ins_encode %{ 7973 __ imull($dst$$Register, $src$$Register); 7974 %} 7975 ins_pipe(ialu_reg_reg_alu0); 7976%} 7977 7978 7979instruct mulExactI_rReg_imm(rax_RegI dst, rRegI src, immI imm, rFlagsReg cr) 7980%{ 7981 match(MulExactI src imm); 7982 effect(DEF cr); 7983 7984 ins_cost(300); 7985 format %{ "imull $dst, $src, $imm\t# mulExact int" %} 7986 ins_encode %{ 7987 __ imull($dst$$Register, $src$$Register, $imm$$constant); 7988 %} 7989 ins_pipe(ialu_reg_reg_alu0); 7990%} 7991 7992instruct mulExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) 7993%{ 7994 match(MulExactI dst (LoadI src)); 7995 effect(DEF cr); 7996 7997 ins_cost(350); 7998 format %{ "imull $dst, $src\t# mulExact int" %} 7999 ins_encode %{ 8000 __ imull($dst$$Register, $src$$Address); 8001 %} 8002 ins_pipe(ialu_reg_mem_alu0); 8003%} 8004 8005instruct mulExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr) 8006%{ 8007 match(MulExactL dst src); 8008 effect(DEF cr); 8009 8010 ins_cost(300); 8011 format %{ "imulq $dst, $src\t# mulExact long" %} 8012 ins_encode %{ 8013 __ imulq($dst$$Register, $src$$Register); 8014 %} 8015 ins_pipe(ialu_reg_reg_alu0); 8016%} 8017 8018instruct mulExactL_rReg_imm(rax_RegL dst, rRegL src, immL32 imm, rFlagsReg cr) 8019%{ 8020 match(MulExactL src imm); 8021 effect(DEF cr); 8022 8023 ins_cost(300); 8024 format %{ "imulq $dst, $src, $imm\t# mulExact long" %} 8025 ins_encode %{ 8026 __ imulq($dst$$Register, $src$$Register, $imm$$constant); 8027 %} 8028 ins_pipe(ialu_reg_reg_alu0); 8029%} 8030 8031instruct mulExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr) 8032%{ 8033 match(MulExactL dst (LoadL src)); 8034 effect(DEF cr); 8035 8036 ins_cost(350); 8037 format %{ "imulq $dst, $src\t# mulExact long" %} 8038 ins_encode %{ 8039 __ imulq($dst$$Register, $src$$Address); 8040 %} 8041 ins_pipe(ialu_reg_mem_alu0); 8042%} 8043 8044instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8045 rFlagsReg cr) 8046%{ 8047 match(Set rax (DivI rax div)); 8048 effect(KILL rdx, KILL cr); 8049 8050 ins_cost(30*100+10*100); // XXX 8051 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8052 "jne,s normal\n\t" 8053 "xorl rdx, rdx\n\t" 8054 "cmpl $div, -1\n\t" 8055 "je,s done\n" 8056 "normal: cdql\n\t" 8057 "idivl $div\n" 8058 "done:" %} 8059 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8060 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8061 ins_pipe(ialu_reg_reg_alu0); 8062%} 8063 8064instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8065 rFlagsReg cr) 8066%{ 8067 match(Set rax (DivL rax div)); 8068 effect(KILL rdx, KILL cr); 8069 8070 ins_cost(30*100+10*100); // XXX 8071 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8072 "cmpq rax, rdx\n\t" 8073 "jne,s normal\n\t" 8074 "xorl rdx, rdx\n\t" 8075 "cmpq $div, -1\n\t" 8076 "je,s done\n" 8077 "normal: cdqq\n\t" 8078 "idivq $div\n" 8079 "done:" %} 8080 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8081 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8082 ins_pipe(ialu_reg_reg_alu0); 8083%} 8084 8085// Integer DIVMOD with Register, both quotient and mod results 8086instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 8087 rFlagsReg cr) 8088%{ 8089 match(DivModI rax div); 8090 effect(KILL cr); 8091 8092 ins_cost(30*100+10*100); // XXX 8093 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 8094 "jne,s normal\n\t" 8095 "xorl rdx, rdx\n\t" 8096 "cmpl $div, -1\n\t" 8097 "je,s done\n" 8098 "normal: cdql\n\t" 8099 "idivl $div\n" 8100 "done:" %} 8101 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8102 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8103 ins_pipe(pipe_slow); 8104%} 8105 8106// Long DIVMOD with Register, both quotient and mod results 8107instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 8108 rFlagsReg cr) 8109%{ 8110 match(DivModL rax div); 8111 effect(KILL cr); 8112 8113 ins_cost(30*100+10*100); // XXX 8114 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 8115 "cmpq rax, rdx\n\t" 8116 "jne,s normal\n\t" 8117 "xorl rdx, rdx\n\t" 8118 "cmpq $div, -1\n\t" 8119 "je,s done\n" 8120 "normal: cdqq\n\t" 8121 "idivq $div\n" 8122 "done:" %} 8123 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8124 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8125 ins_pipe(pipe_slow); 8126%} 8127 8128//----------- DivL-By-Constant-Expansions-------------------------------------- 8129// DivI cases are handled by the compiler 8130 8131// Magic constant, reciprocal of 10 8132instruct loadConL_0x6666666666666667(rRegL dst) 8133%{ 8134 effect(DEF dst); 8135 8136 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 8137 ins_encode(load_immL(dst, 0x6666666666666667)); 8138 ins_pipe(ialu_reg); 8139%} 8140 8141instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 8142%{ 8143 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 8144 8145 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 8146 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 8147 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 8148 ins_pipe(ialu_reg_reg_alu0); 8149%} 8150 8151instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 8152%{ 8153 effect(USE_DEF dst, KILL cr); 8154 8155 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 8156 opcode(0xC1, 0x7); /* C1 /7 ib */ 8157 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 8158 ins_pipe(ialu_reg); 8159%} 8160 8161instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 8162%{ 8163 effect(USE_DEF dst, KILL cr); 8164 8165 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 8166 opcode(0xC1, 0x7); /* C1 /7 ib */ 8167 ins_encode(reg_opc_imm_wide(dst, 0x2)); 8168 ins_pipe(ialu_reg); 8169%} 8170 8171instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 8172%{ 8173 match(Set dst (DivL src div)); 8174 8175 ins_cost((5+8)*100); 8176 expand %{ 8177 rax_RegL rax; // Killed temp 8178 rFlagsReg cr; // Killed 8179 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 8180 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 8181 sarL_rReg_63(src, cr); // sarq src, 63 8182 sarL_rReg_2(dst, cr); // sarq rdx, 2 8183 subL_rReg(dst, src, cr); // subl rdx, src 8184 %} 8185%} 8186 8187//----------------------------------------------------------------------------- 8188 8189instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 8190 rFlagsReg cr) 8191%{ 8192 match(Set rdx (ModI rax div)); 8193 effect(KILL rax, KILL cr); 8194 8195 ins_cost(300); // XXX 8196 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 8197 "jne,s normal\n\t" 8198 "xorl rdx, rdx\n\t" 8199 "cmpl $div, -1\n\t" 8200 "je,s done\n" 8201 "normal: cdql\n\t" 8202 "idivl $div\n" 8203 "done:" %} 8204 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8205 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 8206 ins_pipe(ialu_reg_reg_alu0); 8207%} 8208 8209instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 8210 rFlagsReg cr) 8211%{ 8212 match(Set rdx (ModL rax div)); 8213 effect(KILL rax, KILL cr); 8214 8215 ins_cost(300); // XXX 8216 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 8217 "cmpq rax, rdx\n\t" 8218 "jne,s normal\n\t" 8219 "xorl rdx, rdx\n\t" 8220 "cmpq $div, -1\n\t" 8221 "je,s done\n" 8222 "normal: cdqq\n\t" 8223 "idivq $div\n" 8224 "done:" %} 8225 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 8226 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 8227 ins_pipe(ialu_reg_reg_alu0); 8228%} 8229 8230// Integer Shift Instructions 8231// Shift Left by one 8232instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8233%{ 8234 match(Set dst (LShiftI dst shift)); 8235 effect(KILL cr); 8236 8237 format %{ "sall $dst, $shift" %} 8238 opcode(0xD1, 0x4); /* D1 /4 */ 8239 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8240 ins_pipe(ialu_reg); 8241%} 8242 8243// Shift Left by one 8244instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8245%{ 8246 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8247 effect(KILL cr); 8248 8249 format %{ "sall $dst, $shift\t" %} 8250 opcode(0xD1, 0x4); /* D1 /4 */ 8251 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8252 ins_pipe(ialu_mem_imm); 8253%} 8254 8255// Shift Left by 8-bit immediate 8256instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8257%{ 8258 match(Set dst (LShiftI dst shift)); 8259 effect(KILL cr); 8260 8261 format %{ "sall $dst, $shift" %} 8262 opcode(0xC1, 0x4); /* C1 /4 ib */ 8263 ins_encode(reg_opc_imm(dst, shift)); 8264 ins_pipe(ialu_reg); 8265%} 8266 8267// Shift Left by 8-bit immediate 8268instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8269%{ 8270 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8271 effect(KILL cr); 8272 8273 format %{ "sall $dst, $shift" %} 8274 opcode(0xC1, 0x4); /* C1 /4 ib */ 8275 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8276 ins_pipe(ialu_mem_imm); 8277%} 8278 8279// Shift Left by variable 8280instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8281%{ 8282 match(Set dst (LShiftI dst shift)); 8283 effect(KILL cr); 8284 8285 format %{ "sall $dst, $shift" %} 8286 opcode(0xD3, 0x4); /* D3 /4 */ 8287 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8288 ins_pipe(ialu_reg_reg); 8289%} 8290 8291// Shift Left by variable 8292instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8293%{ 8294 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 8295 effect(KILL cr); 8296 8297 format %{ "sall $dst, $shift" %} 8298 opcode(0xD3, 0x4); /* D3 /4 */ 8299 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8300 ins_pipe(ialu_mem_reg); 8301%} 8302 8303// Arithmetic shift right by one 8304instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8305%{ 8306 match(Set dst (RShiftI dst shift)); 8307 effect(KILL cr); 8308 8309 format %{ "sarl $dst, $shift" %} 8310 opcode(0xD1, 0x7); /* D1 /7 */ 8311 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8312 ins_pipe(ialu_reg); 8313%} 8314 8315// Arithmetic shift right by one 8316instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8317%{ 8318 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8319 effect(KILL cr); 8320 8321 format %{ "sarl $dst, $shift" %} 8322 opcode(0xD1, 0x7); /* D1 /7 */ 8323 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8324 ins_pipe(ialu_mem_imm); 8325%} 8326 8327// Arithmetic Shift Right by 8-bit immediate 8328instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8329%{ 8330 match(Set dst (RShiftI dst shift)); 8331 effect(KILL cr); 8332 8333 format %{ "sarl $dst, $shift" %} 8334 opcode(0xC1, 0x7); /* C1 /7 ib */ 8335 ins_encode(reg_opc_imm(dst, shift)); 8336 ins_pipe(ialu_mem_imm); 8337%} 8338 8339// Arithmetic Shift Right by 8-bit immediate 8340instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8341%{ 8342 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8343 effect(KILL cr); 8344 8345 format %{ "sarl $dst, $shift" %} 8346 opcode(0xC1, 0x7); /* C1 /7 ib */ 8347 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8348 ins_pipe(ialu_mem_imm); 8349%} 8350 8351// Arithmetic Shift Right by variable 8352instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8353%{ 8354 match(Set dst (RShiftI dst shift)); 8355 effect(KILL cr); 8356 8357 format %{ "sarl $dst, $shift" %} 8358 opcode(0xD3, 0x7); /* D3 /7 */ 8359 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8360 ins_pipe(ialu_reg_reg); 8361%} 8362 8363// Arithmetic Shift Right by variable 8364instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8365%{ 8366 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 8367 effect(KILL cr); 8368 8369 format %{ "sarl $dst, $shift" %} 8370 opcode(0xD3, 0x7); /* D3 /7 */ 8371 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8372 ins_pipe(ialu_mem_reg); 8373%} 8374 8375// Logical shift right by one 8376instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 8377%{ 8378 match(Set dst (URShiftI dst shift)); 8379 effect(KILL cr); 8380 8381 format %{ "shrl $dst, $shift" %} 8382 opcode(0xD1, 0x5); /* D1 /5 */ 8383 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8384 ins_pipe(ialu_reg); 8385%} 8386 8387// Logical shift right by one 8388instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8389%{ 8390 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8391 effect(KILL cr); 8392 8393 format %{ "shrl $dst, $shift" %} 8394 opcode(0xD1, 0x5); /* D1 /5 */ 8395 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8396 ins_pipe(ialu_mem_imm); 8397%} 8398 8399// Logical Shift Right by 8-bit immediate 8400instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 8401%{ 8402 match(Set dst (URShiftI dst shift)); 8403 effect(KILL cr); 8404 8405 format %{ "shrl $dst, $shift" %} 8406 opcode(0xC1, 0x5); /* C1 /5 ib */ 8407 ins_encode(reg_opc_imm(dst, shift)); 8408 ins_pipe(ialu_reg); 8409%} 8410 8411// Logical Shift Right by 8-bit immediate 8412instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8413%{ 8414 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8415 effect(KILL cr); 8416 8417 format %{ "shrl $dst, $shift" %} 8418 opcode(0xC1, 0x5); /* C1 /5 ib */ 8419 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 8420 ins_pipe(ialu_mem_imm); 8421%} 8422 8423// Logical Shift Right by variable 8424instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 8425%{ 8426 match(Set dst (URShiftI dst shift)); 8427 effect(KILL cr); 8428 8429 format %{ "shrl $dst, $shift" %} 8430 opcode(0xD3, 0x5); /* D3 /5 */ 8431 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8432 ins_pipe(ialu_reg_reg); 8433%} 8434 8435// Logical Shift Right by variable 8436instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8437%{ 8438 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 8439 effect(KILL cr); 8440 8441 format %{ "shrl $dst, $shift" %} 8442 opcode(0xD3, 0x5); /* D3 /5 */ 8443 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8444 ins_pipe(ialu_mem_reg); 8445%} 8446 8447// Long Shift Instructions 8448// Shift Left by one 8449instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8450%{ 8451 match(Set dst (LShiftL dst shift)); 8452 effect(KILL cr); 8453 8454 format %{ "salq $dst, $shift" %} 8455 opcode(0xD1, 0x4); /* D1 /4 */ 8456 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8457 ins_pipe(ialu_reg); 8458%} 8459 8460// Shift Left by one 8461instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8462%{ 8463 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8464 effect(KILL cr); 8465 8466 format %{ "salq $dst, $shift" %} 8467 opcode(0xD1, 0x4); /* D1 /4 */ 8468 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8469 ins_pipe(ialu_mem_imm); 8470%} 8471 8472// Shift Left by 8-bit immediate 8473instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8474%{ 8475 match(Set dst (LShiftL dst shift)); 8476 effect(KILL cr); 8477 8478 format %{ "salq $dst, $shift" %} 8479 opcode(0xC1, 0x4); /* C1 /4 ib */ 8480 ins_encode(reg_opc_imm_wide(dst, shift)); 8481 ins_pipe(ialu_reg); 8482%} 8483 8484// Shift Left by 8-bit immediate 8485instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8486%{ 8487 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8488 effect(KILL cr); 8489 8490 format %{ "salq $dst, $shift" %} 8491 opcode(0xC1, 0x4); /* C1 /4 ib */ 8492 ins_encode(REX_mem_wide(dst), OpcP, 8493 RM_opc_mem(secondary, dst), Con8or32(shift)); 8494 ins_pipe(ialu_mem_imm); 8495%} 8496 8497// Shift Left by variable 8498instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8499%{ 8500 match(Set dst (LShiftL dst shift)); 8501 effect(KILL cr); 8502 8503 format %{ "salq $dst, $shift" %} 8504 opcode(0xD3, 0x4); /* D3 /4 */ 8505 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8506 ins_pipe(ialu_reg_reg); 8507%} 8508 8509// Shift Left by variable 8510instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8511%{ 8512 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8513 effect(KILL cr); 8514 8515 format %{ "salq $dst, $shift" %} 8516 opcode(0xD3, 0x4); /* D3 /4 */ 8517 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8518 ins_pipe(ialu_mem_reg); 8519%} 8520 8521// Arithmetic shift right by one 8522instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8523%{ 8524 match(Set dst (RShiftL dst shift)); 8525 effect(KILL cr); 8526 8527 format %{ "sarq $dst, $shift" %} 8528 opcode(0xD1, 0x7); /* D1 /7 */ 8529 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8530 ins_pipe(ialu_reg); 8531%} 8532 8533// Arithmetic shift right by one 8534instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8535%{ 8536 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8537 effect(KILL cr); 8538 8539 format %{ "sarq $dst, $shift" %} 8540 opcode(0xD1, 0x7); /* D1 /7 */ 8541 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8542 ins_pipe(ialu_mem_imm); 8543%} 8544 8545// Arithmetic Shift Right by 8-bit immediate 8546instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8547%{ 8548 match(Set dst (RShiftL dst shift)); 8549 effect(KILL cr); 8550 8551 format %{ "sarq $dst, $shift" %} 8552 opcode(0xC1, 0x7); /* C1 /7 ib */ 8553 ins_encode(reg_opc_imm_wide(dst, shift)); 8554 ins_pipe(ialu_mem_imm); 8555%} 8556 8557// Arithmetic Shift Right by 8-bit immediate 8558instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8559%{ 8560 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8561 effect(KILL cr); 8562 8563 format %{ "sarq $dst, $shift" %} 8564 opcode(0xC1, 0x7); /* C1 /7 ib */ 8565 ins_encode(REX_mem_wide(dst), OpcP, 8566 RM_opc_mem(secondary, dst), Con8or32(shift)); 8567 ins_pipe(ialu_mem_imm); 8568%} 8569 8570// Arithmetic Shift Right by variable 8571instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8572%{ 8573 match(Set dst (RShiftL dst shift)); 8574 effect(KILL cr); 8575 8576 format %{ "sarq $dst, $shift" %} 8577 opcode(0xD3, 0x7); /* D3 /7 */ 8578 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8579 ins_pipe(ialu_reg_reg); 8580%} 8581 8582// Arithmetic Shift Right by variable 8583instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8584%{ 8585 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8586 effect(KILL cr); 8587 8588 format %{ "sarq $dst, $shift" %} 8589 opcode(0xD3, 0x7); /* D3 /7 */ 8590 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8591 ins_pipe(ialu_mem_reg); 8592%} 8593 8594// Logical shift right by one 8595instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8596%{ 8597 match(Set dst (URShiftL dst shift)); 8598 effect(KILL cr); 8599 8600 format %{ "shrq $dst, $shift" %} 8601 opcode(0xD1, 0x5); /* D1 /5 */ 8602 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8603 ins_pipe(ialu_reg); 8604%} 8605 8606// Logical shift right by one 8607instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8608%{ 8609 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8610 effect(KILL cr); 8611 8612 format %{ "shrq $dst, $shift" %} 8613 opcode(0xD1, 0x5); /* D1 /5 */ 8614 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8615 ins_pipe(ialu_mem_imm); 8616%} 8617 8618// Logical Shift Right by 8-bit immediate 8619instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8620%{ 8621 match(Set dst (URShiftL dst shift)); 8622 effect(KILL cr); 8623 8624 format %{ "shrq $dst, $shift" %} 8625 opcode(0xC1, 0x5); /* C1 /5 ib */ 8626 ins_encode(reg_opc_imm_wide(dst, shift)); 8627 ins_pipe(ialu_reg); 8628%} 8629 8630 8631// Logical Shift Right by 8-bit immediate 8632instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8633%{ 8634 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8635 effect(KILL cr); 8636 8637 format %{ "shrq $dst, $shift" %} 8638 opcode(0xC1, 0x5); /* C1 /5 ib */ 8639 ins_encode(REX_mem_wide(dst), OpcP, 8640 RM_opc_mem(secondary, dst), Con8or32(shift)); 8641 ins_pipe(ialu_mem_imm); 8642%} 8643 8644// Logical Shift Right by variable 8645instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8646%{ 8647 match(Set dst (URShiftL dst shift)); 8648 effect(KILL cr); 8649 8650 format %{ "shrq $dst, $shift" %} 8651 opcode(0xD3, 0x5); /* D3 /5 */ 8652 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8653 ins_pipe(ialu_reg_reg); 8654%} 8655 8656// Logical Shift Right by variable 8657instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8658%{ 8659 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8660 effect(KILL cr); 8661 8662 format %{ "shrq $dst, $shift" %} 8663 opcode(0xD3, 0x5); /* D3 /5 */ 8664 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8665 ins_pipe(ialu_mem_reg); 8666%} 8667 8668// Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8669// This idiom is used by the compiler for the i2b bytecode. 8670instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8671%{ 8672 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8673 8674 format %{ "movsbl $dst, $src\t# i2b" %} 8675 opcode(0x0F, 0xBE); 8676 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8677 ins_pipe(ialu_reg_reg); 8678%} 8679 8680// Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8681// This idiom is used by the compiler the i2s bytecode. 8682instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8683%{ 8684 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8685 8686 format %{ "movswl $dst, $src\t# i2s" %} 8687 opcode(0x0F, 0xBF); 8688 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8689 ins_pipe(ialu_reg_reg); 8690%} 8691 8692// ROL/ROR instructions 8693 8694// ROL expand 8695instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8696 effect(KILL cr, USE_DEF dst); 8697 8698 format %{ "roll $dst" %} 8699 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8700 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8701 ins_pipe(ialu_reg); 8702%} 8703 8704instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8705 effect(USE_DEF dst, USE shift, KILL cr); 8706 8707 format %{ "roll $dst, $shift" %} 8708 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8709 ins_encode( reg_opc_imm(dst, shift) ); 8710 ins_pipe(ialu_reg); 8711%} 8712 8713instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8714%{ 8715 effect(USE_DEF dst, USE shift, KILL cr); 8716 8717 format %{ "roll $dst, $shift" %} 8718 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8719 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8720 ins_pipe(ialu_reg_reg); 8721%} 8722// end of ROL expand 8723 8724// Rotate Left by one 8725instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8726%{ 8727 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8728 8729 expand %{ 8730 rolI_rReg_imm1(dst, cr); 8731 %} 8732%} 8733 8734// Rotate Left by 8-bit immediate 8735instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8736%{ 8737 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8738 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8739 8740 expand %{ 8741 rolI_rReg_imm8(dst, lshift, cr); 8742 %} 8743%} 8744 8745// Rotate Left by variable 8746instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8747%{ 8748 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8749 8750 expand %{ 8751 rolI_rReg_CL(dst, shift, cr); 8752 %} 8753%} 8754 8755// Rotate Left by variable 8756instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8757%{ 8758 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8759 8760 expand %{ 8761 rolI_rReg_CL(dst, shift, cr); 8762 %} 8763%} 8764 8765// ROR expand 8766instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8767%{ 8768 effect(USE_DEF dst, KILL cr); 8769 8770 format %{ "rorl $dst" %} 8771 opcode(0xD1, 0x1); /* D1 /1 */ 8772 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8773 ins_pipe(ialu_reg); 8774%} 8775 8776instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8777%{ 8778 effect(USE_DEF dst, USE shift, KILL cr); 8779 8780 format %{ "rorl $dst, $shift" %} 8781 opcode(0xC1, 0x1); /* C1 /1 ib */ 8782 ins_encode(reg_opc_imm(dst, shift)); 8783 ins_pipe(ialu_reg); 8784%} 8785 8786instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8787%{ 8788 effect(USE_DEF dst, USE shift, KILL cr); 8789 8790 format %{ "rorl $dst, $shift" %} 8791 opcode(0xD3, 0x1); /* D3 /1 */ 8792 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8793 ins_pipe(ialu_reg_reg); 8794%} 8795// end of ROR expand 8796 8797// Rotate Right by one 8798instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8799%{ 8800 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8801 8802 expand %{ 8803 rorI_rReg_imm1(dst, cr); 8804 %} 8805%} 8806 8807// Rotate Right by 8-bit immediate 8808instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8809%{ 8810 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8811 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8812 8813 expand %{ 8814 rorI_rReg_imm8(dst, rshift, cr); 8815 %} 8816%} 8817 8818// Rotate Right by variable 8819instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8820%{ 8821 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8822 8823 expand %{ 8824 rorI_rReg_CL(dst, shift, cr); 8825 %} 8826%} 8827 8828// Rotate Right by variable 8829instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8830%{ 8831 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8832 8833 expand %{ 8834 rorI_rReg_CL(dst, shift, cr); 8835 %} 8836%} 8837 8838// for long rotate 8839// ROL expand 8840instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8841 effect(USE_DEF dst, KILL cr); 8842 8843 format %{ "rolq $dst" %} 8844 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8845 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8846 ins_pipe(ialu_reg); 8847%} 8848 8849instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8850 effect(USE_DEF dst, USE shift, KILL cr); 8851 8852 format %{ "rolq $dst, $shift" %} 8853 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8854 ins_encode( reg_opc_imm_wide(dst, shift) ); 8855 ins_pipe(ialu_reg); 8856%} 8857 8858instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8859%{ 8860 effect(USE_DEF dst, USE shift, KILL cr); 8861 8862 format %{ "rolq $dst, $shift" %} 8863 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8864 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8865 ins_pipe(ialu_reg_reg); 8866%} 8867// end of ROL expand 8868 8869// Rotate Left by one 8870instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8871%{ 8872 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8873 8874 expand %{ 8875 rolL_rReg_imm1(dst, cr); 8876 %} 8877%} 8878 8879// Rotate Left by 8-bit immediate 8880instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8881%{ 8882 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8883 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8884 8885 expand %{ 8886 rolL_rReg_imm8(dst, lshift, cr); 8887 %} 8888%} 8889 8890// Rotate Left by variable 8891instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8892%{ 8893 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8894 8895 expand %{ 8896 rolL_rReg_CL(dst, shift, cr); 8897 %} 8898%} 8899 8900// Rotate Left by variable 8901instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8902%{ 8903 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8904 8905 expand %{ 8906 rolL_rReg_CL(dst, shift, cr); 8907 %} 8908%} 8909 8910// ROR expand 8911instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8912%{ 8913 effect(USE_DEF dst, KILL cr); 8914 8915 format %{ "rorq $dst" %} 8916 opcode(0xD1, 0x1); /* D1 /1 */ 8917 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8918 ins_pipe(ialu_reg); 8919%} 8920 8921instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8922%{ 8923 effect(USE_DEF dst, USE shift, KILL cr); 8924 8925 format %{ "rorq $dst, $shift" %} 8926 opcode(0xC1, 0x1); /* C1 /1 ib */ 8927 ins_encode(reg_opc_imm_wide(dst, shift)); 8928 ins_pipe(ialu_reg); 8929%} 8930 8931instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8932%{ 8933 effect(USE_DEF dst, USE shift, KILL cr); 8934 8935 format %{ "rorq $dst, $shift" %} 8936 opcode(0xD3, 0x1); /* D3 /1 */ 8937 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8938 ins_pipe(ialu_reg_reg); 8939%} 8940// end of ROR expand 8941 8942// Rotate Right by one 8943instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8944%{ 8945 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8946 8947 expand %{ 8948 rorL_rReg_imm1(dst, cr); 8949 %} 8950%} 8951 8952// Rotate Right by 8-bit immediate 8953instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8954%{ 8955 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8956 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8957 8958 expand %{ 8959 rorL_rReg_imm8(dst, rshift, cr); 8960 %} 8961%} 8962 8963// Rotate Right by variable 8964instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8965%{ 8966 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8967 8968 expand %{ 8969 rorL_rReg_CL(dst, shift, cr); 8970 %} 8971%} 8972 8973// Rotate Right by variable 8974instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8975%{ 8976 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8977 8978 expand %{ 8979 rorL_rReg_CL(dst, shift, cr); 8980 %} 8981%} 8982 8983// Logical Instructions 8984 8985// Integer Logical Instructions 8986 8987// And Instructions 8988// And Register with Register 8989instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8990%{ 8991 match(Set dst (AndI dst src)); 8992 effect(KILL cr); 8993 8994 format %{ "andl $dst, $src\t# int" %} 8995 opcode(0x23); 8996 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8997 ins_pipe(ialu_reg_reg); 8998%} 8999 9000// And Register with Immediate 255 9001instruct andI_rReg_imm255(rRegI dst, immI_255 src) 9002%{ 9003 match(Set dst (AndI dst src)); 9004 9005 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 9006 opcode(0x0F, 0xB6); 9007 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9008 ins_pipe(ialu_reg); 9009%} 9010 9011// And Register with Immediate 255 and promote to long 9012instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 9013%{ 9014 match(Set dst (ConvI2L (AndI src mask))); 9015 9016 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 9017 opcode(0x0F, 0xB6); 9018 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9019 ins_pipe(ialu_reg); 9020%} 9021 9022// And Register with Immediate 65535 9023instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 9024%{ 9025 match(Set dst (AndI dst src)); 9026 9027 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 9028 opcode(0x0F, 0xB7); 9029 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9030 ins_pipe(ialu_reg); 9031%} 9032 9033// And Register with Immediate 65535 and promote to long 9034instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 9035%{ 9036 match(Set dst (ConvI2L (AndI src mask))); 9037 9038 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 9039 opcode(0x0F, 0xB7); 9040 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 9041 ins_pipe(ialu_reg); 9042%} 9043 9044// And Register with Immediate 9045instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9046%{ 9047 match(Set dst (AndI dst src)); 9048 effect(KILL cr); 9049 9050 format %{ "andl $dst, $src\t# int" %} 9051 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9052 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9053 ins_pipe(ialu_reg); 9054%} 9055 9056// And Register with Memory 9057instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9058%{ 9059 match(Set dst (AndI dst (LoadI src))); 9060 effect(KILL cr); 9061 9062 ins_cost(125); 9063 format %{ "andl $dst, $src\t# int" %} 9064 opcode(0x23); 9065 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9066 ins_pipe(ialu_reg_mem); 9067%} 9068 9069// And Memory with Register 9070instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9071%{ 9072 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9073 effect(KILL cr); 9074 9075 ins_cost(150); 9076 format %{ "andl $dst, $src\t# int" %} 9077 opcode(0x21); /* Opcode 21 /r */ 9078 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9079 ins_pipe(ialu_mem_reg); 9080%} 9081 9082// And Memory with Immediate 9083instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 9084%{ 9085 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 9086 effect(KILL cr); 9087 9088 ins_cost(125); 9089 format %{ "andl $dst, $src\t# int" %} 9090 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9091 ins_encode(REX_mem(dst), OpcSE(src), 9092 RM_opc_mem(secondary, dst), Con8or32(src)); 9093 ins_pipe(ialu_mem_imm); 9094%} 9095 9096// Or Instructions 9097// Or Register with Register 9098instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9099%{ 9100 match(Set dst (OrI dst src)); 9101 effect(KILL cr); 9102 9103 format %{ "orl $dst, $src\t# int" %} 9104 opcode(0x0B); 9105 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9106 ins_pipe(ialu_reg_reg); 9107%} 9108 9109// Or Register with Immediate 9110instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9111%{ 9112 match(Set dst (OrI dst src)); 9113 effect(KILL cr); 9114 9115 format %{ "orl $dst, $src\t# int" %} 9116 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9117 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9118 ins_pipe(ialu_reg); 9119%} 9120 9121// Or Register with Memory 9122instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9123%{ 9124 match(Set dst (OrI dst (LoadI src))); 9125 effect(KILL cr); 9126 9127 ins_cost(125); 9128 format %{ "orl $dst, $src\t# int" %} 9129 opcode(0x0B); 9130 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9131 ins_pipe(ialu_reg_mem); 9132%} 9133 9134// Or Memory with Register 9135instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9136%{ 9137 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9138 effect(KILL cr); 9139 9140 ins_cost(150); 9141 format %{ "orl $dst, $src\t# int" %} 9142 opcode(0x09); /* Opcode 09 /r */ 9143 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9144 ins_pipe(ialu_mem_reg); 9145%} 9146 9147// Or Memory with Immediate 9148instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 9149%{ 9150 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 9151 effect(KILL cr); 9152 9153 ins_cost(125); 9154 format %{ "orl $dst, $src\t# int" %} 9155 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9156 ins_encode(REX_mem(dst), OpcSE(src), 9157 RM_opc_mem(secondary, dst), Con8or32(src)); 9158 ins_pipe(ialu_mem_imm); 9159%} 9160 9161// Xor Instructions 9162// Xor Register with Register 9163instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 9164%{ 9165 match(Set dst (XorI dst src)); 9166 effect(KILL cr); 9167 9168 format %{ "xorl $dst, $src\t# int" %} 9169 opcode(0x33); 9170 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 9171 ins_pipe(ialu_reg_reg); 9172%} 9173 9174// Xor Register with Immediate -1 9175instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9176 match(Set dst (XorI dst imm)); 9177 9178 format %{ "not $dst" %} 9179 ins_encode %{ 9180 __ notl($dst$$Register); 9181 %} 9182 ins_pipe(ialu_reg); 9183%} 9184 9185// Xor Register with Immediate 9186instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 9187%{ 9188 match(Set dst (XorI dst src)); 9189 effect(KILL cr); 9190 9191 format %{ "xorl $dst, $src\t# int" %} 9192 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9193 ins_encode(OpcSErm(dst, src), Con8or32(src)); 9194 ins_pipe(ialu_reg); 9195%} 9196 9197// Xor Register with Memory 9198instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 9199%{ 9200 match(Set dst (XorI dst (LoadI src))); 9201 effect(KILL cr); 9202 9203 ins_cost(125); 9204 format %{ "xorl $dst, $src\t# int" %} 9205 opcode(0x33); 9206 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 9207 ins_pipe(ialu_reg_mem); 9208%} 9209 9210// Xor Memory with Register 9211instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 9212%{ 9213 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9214 effect(KILL cr); 9215 9216 ins_cost(150); 9217 format %{ "xorl $dst, $src\t# int" %} 9218 opcode(0x31); /* Opcode 31 /r */ 9219 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 9220 ins_pipe(ialu_mem_reg); 9221%} 9222 9223// Xor Memory with Immediate 9224instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 9225%{ 9226 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 9227 effect(KILL cr); 9228 9229 ins_cost(125); 9230 format %{ "xorl $dst, $src\t# int" %} 9231 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9232 ins_encode(REX_mem(dst), OpcSE(src), 9233 RM_opc_mem(secondary, dst), Con8or32(src)); 9234 ins_pipe(ialu_mem_imm); 9235%} 9236 9237 9238// Long Logical Instructions 9239 9240// And Instructions 9241// And Register with Register 9242instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9243%{ 9244 match(Set dst (AndL dst src)); 9245 effect(KILL cr); 9246 9247 format %{ "andq $dst, $src\t# long" %} 9248 opcode(0x23); 9249 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9250 ins_pipe(ialu_reg_reg); 9251%} 9252 9253// And Register with Immediate 255 9254instruct andL_rReg_imm255(rRegL dst, immL_255 src) 9255%{ 9256 match(Set dst (AndL dst src)); 9257 9258 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 9259 opcode(0x0F, 0xB6); 9260 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9261 ins_pipe(ialu_reg); 9262%} 9263 9264// And Register with Immediate 65535 9265instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 9266%{ 9267 match(Set dst (AndL dst src)); 9268 9269 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 9270 opcode(0x0F, 0xB7); 9271 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 9272 ins_pipe(ialu_reg); 9273%} 9274 9275// And Register with Immediate 9276instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9277%{ 9278 match(Set dst (AndL dst src)); 9279 effect(KILL cr); 9280 9281 format %{ "andq $dst, $src\t# long" %} 9282 opcode(0x81, 0x04); /* Opcode 81 /4 */ 9283 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9284 ins_pipe(ialu_reg); 9285%} 9286 9287// And Register with Memory 9288instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9289%{ 9290 match(Set dst (AndL dst (LoadL src))); 9291 effect(KILL cr); 9292 9293 ins_cost(125); 9294 format %{ "andq $dst, $src\t# long" %} 9295 opcode(0x23); 9296 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9297 ins_pipe(ialu_reg_mem); 9298%} 9299 9300// And Memory with Register 9301instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9302%{ 9303 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9304 effect(KILL cr); 9305 9306 ins_cost(150); 9307 format %{ "andq $dst, $src\t# long" %} 9308 opcode(0x21); /* Opcode 21 /r */ 9309 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9310 ins_pipe(ialu_mem_reg); 9311%} 9312 9313// And Memory with Immediate 9314instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9315%{ 9316 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 9317 effect(KILL cr); 9318 9319 ins_cost(125); 9320 format %{ "andq $dst, $src\t# long" %} 9321 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 9322 ins_encode(REX_mem_wide(dst), OpcSE(src), 9323 RM_opc_mem(secondary, dst), Con8or32(src)); 9324 ins_pipe(ialu_mem_imm); 9325%} 9326 9327// Or Instructions 9328// Or Register with Register 9329instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9330%{ 9331 match(Set dst (OrL dst src)); 9332 effect(KILL cr); 9333 9334 format %{ "orq $dst, $src\t# long" %} 9335 opcode(0x0B); 9336 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9337 ins_pipe(ialu_reg_reg); 9338%} 9339 9340// Use any_RegP to match R15 (TLS register) without spilling. 9341instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9342 match(Set dst (OrL dst (CastP2X src))); 9343 effect(KILL cr); 9344 9345 format %{ "orq $dst, $src\t# long" %} 9346 opcode(0x0B); 9347 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9348 ins_pipe(ialu_reg_reg); 9349%} 9350 9351 9352// Or Register with Immediate 9353instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9354%{ 9355 match(Set dst (OrL dst src)); 9356 effect(KILL cr); 9357 9358 format %{ "orq $dst, $src\t# long" %} 9359 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9360 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9361 ins_pipe(ialu_reg); 9362%} 9363 9364// Or Register with Memory 9365instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9366%{ 9367 match(Set dst (OrL dst (LoadL src))); 9368 effect(KILL cr); 9369 9370 ins_cost(125); 9371 format %{ "orq $dst, $src\t# long" %} 9372 opcode(0x0B); 9373 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9374 ins_pipe(ialu_reg_mem); 9375%} 9376 9377// Or Memory with Register 9378instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9379%{ 9380 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9381 effect(KILL cr); 9382 9383 ins_cost(150); 9384 format %{ "orq $dst, $src\t# long" %} 9385 opcode(0x09); /* Opcode 09 /r */ 9386 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9387 ins_pipe(ialu_mem_reg); 9388%} 9389 9390// Or Memory with Immediate 9391instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9392%{ 9393 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9394 effect(KILL cr); 9395 9396 ins_cost(125); 9397 format %{ "orq $dst, $src\t# long" %} 9398 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9399 ins_encode(REX_mem_wide(dst), OpcSE(src), 9400 RM_opc_mem(secondary, dst), Con8or32(src)); 9401 ins_pipe(ialu_mem_imm); 9402%} 9403 9404// Xor Instructions 9405// Xor Register with Register 9406instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9407%{ 9408 match(Set dst (XorL dst src)); 9409 effect(KILL cr); 9410 9411 format %{ "xorq $dst, $src\t# long" %} 9412 opcode(0x33); 9413 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9414 ins_pipe(ialu_reg_reg); 9415%} 9416 9417// Xor Register with Immediate -1 9418instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9419 match(Set dst (XorL dst imm)); 9420 9421 format %{ "notq $dst" %} 9422 ins_encode %{ 9423 __ notq($dst$$Register); 9424 %} 9425 ins_pipe(ialu_reg); 9426%} 9427 9428// Xor Register with Immediate 9429instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9430%{ 9431 match(Set dst (XorL dst src)); 9432 effect(KILL cr); 9433 9434 format %{ "xorq $dst, $src\t# long" %} 9435 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9436 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9437 ins_pipe(ialu_reg); 9438%} 9439 9440// Xor Register with Memory 9441instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9442%{ 9443 match(Set dst (XorL dst (LoadL src))); 9444 effect(KILL cr); 9445 9446 ins_cost(125); 9447 format %{ "xorq $dst, $src\t# long" %} 9448 opcode(0x33); 9449 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9450 ins_pipe(ialu_reg_mem); 9451%} 9452 9453// Xor Memory with Register 9454instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9455%{ 9456 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9457 effect(KILL cr); 9458 9459 ins_cost(150); 9460 format %{ "xorq $dst, $src\t# long" %} 9461 opcode(0x31); /* Opcode 31 /r */ 9462 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9463 ins_pipe(ialu_mem_reg); 9464%} 9465 9466// Xor Memory with Immediate 9467instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9468%{ 9469 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9470 effect(KILL cr); 9471 9472 ins_cost(125); 9473 format %{ "xorq $dst, $src\t# long" %} 9474 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9475 ins_encode(REX_mem_wide(dst), OpcSE(src), 9476 RM_opc_mem(secondary, dst), Con8or32(src)); 9477 ins_pipe(ialu_mem_imm); 9478%} 9479 9480// Convert Int to Boolean 9481instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9482%{ 9483 match(Set dst (Conv2B src)); 9484 effect(KILL cr); 9485 9486 format %{ "testl $src, $src\t# ci2b\n\t" 9487 "setnz $dst\n\t" 9488 "movzbl $dst, $dst" %} 9489 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9490 setNZ_reg(dst), 9491 REX_reg_breg(dst, dst), // movzbl 9492 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9493 ins_pipe(pipe_slow); // XXX 9494%} 9495 9496// Convert Pointer to Boolean 9497instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9498%{ 9499 match(Set dst (Conv2B src)); 9500 effect(KILL cr); 9501 9502 format %{ "testq $src, $src\t# cp2b\n\t" 9503 "setnz $dst\n\t" 9504 "movzbl $dst, $dst" %} 9505 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9506 setNZ_reg(dst), 9507 REX_reg_breg(dst, dst), // movzbl 9508 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9509 ins_pipe(pipe_slow); // XXX 9510%} 9511 9512instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9513%{ 9514 match(Set dst (CmpLTMask p q)); 9515 effect(KILL cr); 9516 9517 ins_cost(400); 9518 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9519 "setlt $dst\n\t" 9520 "movzbl $dst, $dst\n\t" 9521 "negl $dst" %} 9522 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9523 setLT_reg(dst), 9524 REX_reg_breg(dst, dst), // movzbl 9525 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9526 neg_reg(dst)); 9527 ins_pipe(pipe_slow); 9528%} 9529 9530instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9531%{ 9532 match(Set dst (CmpLTMask dst zero)); 9533 effect(KILL cr); 9534 9535 ins_cost(100); 9536 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9537 ins_encode %{ 9538 __ sarl($dst$$Register, 31); 9539 %} 9540 ins_pipe(ialu_reg); 9541%} 9542 9543/* Better to save a register than avoid a branch */ 9544instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9545%{ 9546 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9547 effect(KILL cr); 9548 ins_cost(300); 9549 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9550 "jge done\n\t" 9551 "addl $p,$y\n" 9552 "done: " %} 9553 ins_encode %{ 9554 Register Rp = $p$$Register; 9555 Register Rq = $q$$Register; 9556 Register Ry = $y$$Register; 9557 Label done; 9558 __ subl(Rp, Rq); 9559 __ jccb(Assembler::greaterEqual, done); 9560 __ addl(Rp, Ry); 9561 __ bind(done); 9562 %} 9563 ins_pipe(pipe_cmplt); 9564%} 9565 9566/* Better to save a register than avoid a branch */ 9567instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9568%{ 9569 match(Set y (AndI (CmpLTMask p q) y)); 9570 effect(KILL cr); 9571 9572 ins_cost(300); 9573 9574 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9575 "jlt done\n\t" 9576 "xorl $y, $y\n" 9577 "done: " %} 9578 ins_encode %{ 9579 Register Rp = $p$$Register; 9580 Register Rq = $q$$Register; 9581 Register Ry = $y$$Register; 9582 Label done; 9583 __ cmpl(Rp, Rq); 9584 __ jccb(Assembler::less, done); 9585 __ xorl(Ry, Ry); 9586 __ bind(done); 9587 %} 9588 ins_pipe(pipe_cmplt); 9589%} 9590 9591 9592//---------- FP Instructions------------------------------------------------ 9593 9594instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9595%{ 9596 match(Set cr (CmpF src1 src2)); 9597 9598 ins_cost(145); 9599 format %{ "ucomiss $src1, $src2\n\t" 9600 "jnp,s exit\n\t" 9601 "pushfq\t# saw NaN, set CF\n\t" 9602 "andq [rsp], #0xffffff2b\n\t" 9603 "popfq\n" 9604 "exit:" %} 9605 ins_encode %{ 9606 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9607 emit_cmpfp_fixup(_masm); 9608 %} 9609 ins_pipe(pipe_slow); 9610%} 9611 9612instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9613 match(Set cr (CmpF src1 src2)); 9614 9615 ins_cost(100); 9616 format %{ "ucomiss $src1, $src2" %} 9617 ins_encode %{ 9618 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9619 %} 9620 ins_pipe(pipe_slow); 9621%} 9622 9623instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9624%{ 9625 match(Set cr (CmpF src1 (LoadF src2))); 9626 9627 ins_cost(145); 9628 format %{ "ucomiss $src1, $src2\n\t" 9629 "jnp,s exit\n\t" 9630 "pushfq\t# saw NaN, set CF\n\t" 9631 "andq [rsp], #0xffffff2b\n\t" 9632 "popfq\n" 9633 "exit:" %} 9634 ins_encode %{ 9635 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9636 emit_cmpfp_fixup(_masm); 9637 %} 9638 ins_pipe(pipe_slow); 9639%} 9640 9641instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9642 match(Set cr (CmpF src1 (LoadF src2))); 9643 9644 ins_cost(100); 9645 format %{ "ucomiss $src1, $src2" %} 9646 ins_encode %{ 9647 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9648 %} 9649 ins_pipe(pipe_slow); 9650%} 9651 9652instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9653 match(Set cr (CmpF src con)); 9654 9655 ins_cost(145); 9656 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9657 "jnp,s exit\n\t" 9658 "pushfq\t# saw NaN, set CF\n\t" 9659 "andq [rsp], #0xffffff2b\n\t" 9660 "popfq\n" 9661 "exit:" %} 9662 ins_encode %{ 9663 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9664 emit_cmpfp_fixup(_masm); 9665 %} 9666 ins_pipe(pipe_slow); 9667%} 9668 9669instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9670 match(Set cr (CmpF src con)); 9671 ins_cost(100); 9672 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9673 ins_encode %{ 9674 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9675 %} 9676 ins_pipe(pipe_slow); 9677%} 9678 9679instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9680%{ 9681 match(Set cr (CmpD src1 src2)); 9682 9683 ins_cost(145); 9684 format %{ "ucomisd $src1, $src2\n\t" 9685 "jnp,s exit\n\t" 9686 "pushfq\t# saw NaN, set CF\n\t" 9687 "andq [rsp], #0xffffff2b\n\t" 9688 "popfq\n" 9689 "exit:" %} 9690 ins_encode %{ 9691 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9692 emit_cmpfp_fixup(_masm); 9693 %} 9694 ins_pipe(pipe_slow); 9695%} 9696 9697instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9698 match(Set cr (CmpD src1 src2)); 9699 9700 ins_cost(100); 9701 format %{ "ucomisd $src1, $src2 test" %} 9702 ins_encode %{ 9703 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9704 %} 9705 ins_pipe(pipe_slow); 9706%} 9707 9708instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9709%{ 9710 match(Set cr (CmpD src1 (LoadD src2))); 9711 9712 ins_cost(145); 9713 format %{ "ucomisd $src1, $src2\n\t" 9714 "jnp,s exit\n\t" 9715 "pushfq\t# saw NaN, set CF\n\t" 9716 "andq [rsp], #0xffffff2b\n\t" 9717 "popfq\n" 9718 "exit:" %} 9719 ins_encode %{ 9720 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9721 emit_cmpfp_fixup(_masm); 9722 %} 9723 ins_pipe(pipe_slow); 9724%} 9725 9726instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9727 match(Set cr (CmpD src1 (LoadD src2))); 9728 9729 ins_cost(100); 9730 format %{ "ucomisd $src1, $src2" %} 9731 ins_encode %{ 9732 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9733 %} 9734 ins_pipe(pipe_slow); 9735%} 9736 9737instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9738 match(Set cr (CmpD src con)); 9739 9740 ins_cost(145); 9741 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9742 "jnp,s exit\n\t" 9743 "pushfq\t# saw NaN, set CF\n\t" 9744 "andq [rsp], #0xffffff2b\n\t" 9745 "popfq\n" 9746 "exit:" %} 9747 ins_encode %{ 9748 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9749 emit_cmpfp_fixup(_masm); 9750 %} 9751 ins_pipe(pipe_slow); 9752%} 9753 9754instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9755 match(Set cr (CmpD src con)); 9756 ins_cost(100); 9757 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9758 ins_encode %{ 9759 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9760 %} 9761 ins_pipe(pipe_slow); 9762%} 9763 9764// Compare into -1,0,1 9765instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9766%{ 9767 match(Set dst (CmpF3 src1 src2)); 9768 effect(KILL cr); 9769 9770 ins_cost(275); 9771 format %{ "ucomiss $src1, $src2\n\t" 9772 "movl $dst, #-1\n\t" 9773 "jp,s done\n\t" 9774 "jb,s done\n\t" 9775 "setne $dst\n\t" 9776 "movzbl $dst, $dst\n" 9777 "done:" %} 9778 ins_encode %{ 9779 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9780 emit_cmpfp3(_masm, $dst$$Register); 9781 %} 9782 ins_pipe(pipe_slow); 9783%} 9784 9785// Compare into -1,0,1 9786instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9787%{ 9788 match(Set dst (CmpF3 src1 (LoadF src2))); 9789 effect(KILL cr); 9790 9791 ins_cost(275); 9792 format %{ "ucomiss $src1, $src2\n\t" 9793 "movl $dst, #-1\n\t" 9794 "jp,s done\n\t" 9795 "jb,s done\n\t" 9796 "setne $dst\n\t" 9797 "movzbl $dst, $dst\n" 9798 "done:" %} 9799 ins_encode %{ 9800 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9801 emit_cmpfp3(_masm, $dst$$Register); 9802 %} 9803 ins_pipe(pipe_slow); 9804%} 9805 9806// Compare into -1,0,1 9807instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9808 match(Set dst (CmpF3 src con)); 9809 effect(KILL cr); 9810 9811 ins_cost(275); 9812 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9813 "movl $dst, #-1\n\t" 9814 "jp,s done\n\t" 9815 "jb,s done\n\t" 9816 "setne $dst\n\t" 9817 "movzbl $dst, $dst\n" 9818 "done:" %} 9819 ins_encode %{ 9820 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9821 emit_cmpfp3(_masm, $dst$$Register); 9822 %} 9823 ins_pipe(pipe_slow); 9824%} 9825 9826// Compare into -1,0,1 9827instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9828%{ 9829 match(Set dst (CmpD3 src1 src2)); 9830 effect(KILL cr); 9831 9832 ins_cost(275); 9833 format %{ "ucomisd $src1, $src2\n\t" 9834 "movl $dst, #-1\n\t" 9835 "jp,s done\n\t" 9836 "jb,s done\n\t" 9837 "setne $dst\n\t" 9838 "movzbl $dst, $dst\n" 9839 "done:" %} 9840 ins_encode %{ 9841 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9842 emit_cmpfp3(_masm, $dst$$Register); 9843 %} 9844 ins_pipe(pipe_slow); 9845%} 9846 9847// Compare into -1,0,1 9848instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9849%{ 9850 match(Set dst (CmpD3 src1 (LoadD src2))); 9851 effect(KILL cr); 9852 9853 ins_cost(275); 9854 format %{ "ucomisd $src1, $src2\n\t" 9855 "movl $dst, #-1\n\t" 9856 "jp,s done\n\t" 9857 "jb,s done\n\t" 9858 "setne $dst\n\t" 9859 "movzbl $dst, $dst\n" 9860 "done:" %} 9861 ins_encode %{ 9862 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9863 emit_cmpfp3(_masm, $dst$$Register); 9864 %} 9865 ins_pipe(pipe_slow); 9866%} 9867 9868// Compare into -1,0,1 9869instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9870 match(Set dst (CmpD3 src con)); 9871 effect(KILL cr); 9872 9873 ins_cost(275); 9874 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9875 "movl $dst, #-1\n\t" 9876 "jp,s done\n\t" 9877 "jb,s done\n\t" 9878 "setne $dst\n\t" 9879 "movzbl $dst, $dst\n" 9880 "done:" %} 9881 ins_encode %{ 9882 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9883 emit_cmpfp3(_masm, $dst$$Register); 9884 %} 9885 ins_pipe(pipe_slow); 9886%} 9887 9888// -----------Trig and Trancendental Instructions------------------------------ 9889instruct cosD_reg(regD dst) %{ 9890 match(Set dst (CosD dst)); 9891 9892 format %{ "dcos $dst\n\t" %} 9893 opcode(0xD9, 0xFF); 9894 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9895 ins_pipe( pipe_slow ); 9896%} 9897 9898instruct sinD_reg(regD dst) %{ 9899 match(Set dst (SinD dst)); 9900 9901 format %{ "dsin $dst\n\t" %} 9902 opcode(0xD9, 0xFE); 9903 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9904 ins_pipe( pipe_slow ); 9905%} 9906 9907instruct tanD_reg(regD dst) %{ 9908 match(Set dst (TanD dst)); 9909 9910 format %{ "dtan $dst\n\t" %} 9911 ins_encode( Push_SrcXD(dst), 9912 Opcode(0xD9), Opcode(0xF2), //fptan 9913 Opcode(0xDD), Opcode(0xD8), //fstp st 9914 Push_ResultXD(dst) ); 9915 ins_pipe( pipe_slow ); 9916%} 9917 9918instruct log10D_reg(regD dst) %{ 9919 // The source and result Double operands in XMM registers 9920 match(Set dst (Log10D dst)); 9921 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9922 // fyl2x ; compute log_10(2) * log_2(x) 9923 format %{ "fldlg2\t\t\t#Log10\n\t" 9924 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9925 %} 9926 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9927 Push_SrcXD(dst), 9928 Opcode(0xD9), Opcode(0xF1), // fyl2x 9929 Push_ResultXD(dst)); 9930 9931 ins_pipe( pipe_slow ); 9932%} 9933 9934instruct logD_reg(regD dst) %{ 9935 // The source and result Double operands in XMM registers 9936 match(Set dst (LogD dst)); 9937 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 9938 // fyl2x ; compute log_e(2) * log_2(x) 9939 format %{ "fldln2\t\t\t#Log_e\n\t" 9940 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 9941 %} 9942 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 9943 Push_SrcXD(dst), 9944 Opcode(0xD9), Opcode(0xF1), // fyl2x 9945 Push_ResultXD(dst)); 9946 ins_pipe( pipe_slow ); 9947%} 9948 9949instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9950 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 9951 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 9952 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} 9953 ins_encode %{ 9954 __ subptr(rsp, 8); 9955 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 9956 __ fld_d(Address(rsp, 0)); 9957 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 9958 __ fld_d(Address(rsp, 0)); 9959 __ fast_pow(); 9960 __ fstp_d(Address(rsp, 0)); 9961 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9962 __ addptr(rsp, 8); 9963 %} 9964 ins_pipe( pipe_slow ); 9965%} 9966 9967instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9968 match(Set dst (ExpD src)); 9969 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); 9970 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %} 9971 ins_encode %{ 9972 __ subptr(rsp, 8); 9973 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9974 __ fld_d(Address(rsp, 0)); 9975 __ fast_exp(); 9976 __ fstp_d(Address(rsp, 0)); 9977 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9978 __ addptr(rsp, 8); 9979 %} 9980 ins_pipe( pipe_slow ); 9981%} 9982 9983//----------Arithmetic Conversion Instructions--------------------------------- 9984 9985instruct roundFloat_nop(regF dst) 9986%{ 9987 match(Set dst (RoundFloat dst)); 9988 9989 ins_cost(0); 9990 ins_encode(); 9991 ins_pipe(empty); 9992%} 9993 9994instruct roundDouble_nop(regD dst) 9995%{ 9996 match(Set dst (RoundDouble dst)); 9997 9998 ins_cost(0); 9999 ins_encode(); 10000 ins_pipe(empty); 10001%} 10002 10003instruct convF2D_reg_reg(regD dst, regF src) 10004%{ 10005 match(Set dst (ConvF2D src)); 10006 10007 format %{ "cvtss2sd $dst, $src" %} 10008 ins_encode %{ 10009 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 10010 %} 10011 ins_pipe(pipe_slow); // XXX 10012%} 10013 10014instruct convF2D_reg_mem(regD dst, memory src) 10015%{ 10016 match(Set dst (ConvF2D (LoadF src))); 10017 10018 format %{ "cvtss2sd $dst, $src" %} 10019 ins_encode %{ 10020 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 10021 %} 10022 ins_pipe(pipe_slow); // XXX 10023%} 10024 10025instruct convD2F_reg_reg(regF dst, regD src) 10026%{ 10027 match(Set dst (ConvD2F src)); 10028 10029 format %{ "cvtsd2ss $dst, $src" %} 10030 ins_encode %{ 10031 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 10032 %} 10033 ins_pipe(pipe_slow); // XXX 10034%} 10035 10036instruct convD2F_reg_mem(regF dst, memory src) 10037%{ 10038 match(Set dst (ConvD2F (LoadD src))); 10039 10040 format %{ "cvtsd2ss $dst, $src" %} 10041 ins_encode %{ 10042 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 10043 %} 10044 ins_pipe(pipe_slow); // XXX 10045%} 10046 10047// XXX do mem variants 10048instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 10049%{ 10050 match(Set dst (ConvF2I src)); 10051 effect(KILL cr); 10052 10053 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 10054 "cmpl $dst, #0x80000000\n\t" 10055 "jne,s done\n\t" 10056 "subq rsp, #8\n\t" 10057 "movss [rsp], $src\n\t" 10058 "call f2i_fixup\n\t" 10059 "popq $dst\n" 10060 "done: "%} 10061 ins_encode %{ 10062 Label done; 10063 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 10064 __ cmpl($dst$$Register, 0x80000000); 10065 __ jccb(Assembler::notEqual, done); 10066 __ subptr(rsp, 8); 10067 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10068 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 10069 __ pop($dst$$Register); 10070 __ bind(done); 10071 %} 10072 ins_pipe(pipe_slow); 10073%} 10074 10075instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 10076%{ 10077 match(Set dst (ConvF2L src)); 10078 effect(KILL cr); 10079 10080 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 10081 "cmpq $dst, [0x8000000000000000]\n\t" 10082 "jne,s done\n\t" 10083 "subq rsp, #8\n\t" 10084 "movss [rsp], $src\n\t" 10085 "call f2l_fixup\n\t" 10086 "popq $dst\n" 10087 "done: "%} 10088 ins_encode %{ 10089 Label done; 10090 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 10091 __ cmp64($dst$$Register, 10092 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10093 __ jccb(Assembler::notEqual, done); 10094 __ subptr(rsp, 8); 10095 __ movflt(Address(rsp, 0), $src$$XMMRegister); 10096 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 10097 __ pop($dst$$Register); 10098 __ bind(done); 10099 %} 10100 ins_pipe(pipe_slow); 10101%} 10102 10103instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 10104%{ 10105 match(Set dst (ConvD2I src)); 10106 effect(KILL cr); 10107 10108 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 10109 "cmpl $dst, #0x80000000\n\t" 10110 "jne,s done\n\t" 10111 "subq rsp, #8\n\t" 10112 "movsd [rsp], $src\n\t" 10113 "call d2i_fixup\n\t" 10114 "popq $dst\n" 10115 "done: "%} 10116 ins_encode %{ 10117 Label done; 10118 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 10119 __ cmpl($dst$$Register, 0x80000000); 10120 __ jccb(Assembler::notEqual, done); 10121 __ subptr(rsp, 8); 10122 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10123 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 10124 __ pop($dst$$Register); 10125 __ bind(done); 10126 %} 10127 ins_pipe(pipe_slow); 10128%} 10129 10130instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 10131%{ 10132 match(Set dst (ConvD2L src)); 10133 effect(KILL cr); 10134 10135 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 10136 "cmpq $dst, [0x8000000000000000]\n\t" 10137 "jne,s done\n\t" 10138 "subq rsp, #8\n\t" 10139 "movsd [rsp], $src\n\t" 10140 "call d2l_fixup\n\t" 10141 "popq $dst\n" 10142 "done: "%} 10143 ins_encode %{ 10144 Label done; 10145 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 10146 __ cmp64($dst$$Register, 10147 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 10148 __ jccb(Assembler::notEqual, done); 10149 __ subptr(rsp, 8); 10150 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 10151 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 10152 __ pop($dst$$Register); 10153 __ bind(done); 10154 %} 10155 ins_pipe(pipe_slow); 10156%} 10157 10158instruct convI2F_reg_reg(regF dst, rRegI src) 10159%{ 10160 predicate(!UseXmmI2F); 10161 match(Set dst (ConvI2F src)); 10162 10163 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10164 ins_encode %{ 10165 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 10166 %} 10167 ins_pipe(pipe_slow); // XXX 10168%} 10169 10170instruct convI2F_reg_mem(regF dst, memory src) 10171%{ 10172 match(Set dst (ConvI2F (LoadI src))); 10173 10174 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 10175 ins_encode %{ 10176 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 10177 %} 10178 ins_pipe(pipe_slow); // XXX 10179%} 10180 10181instruct convI2D_reg_reg(regD dst, rRegI src) 10182%{ 10183 predicate(!UseXmmI2D); 10184 match(Set dst (ConvI2D src)); 10185 10186 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10187 ins_encode %{ 10188 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 10189 %} 10190 ins_pipe(pipe_slow); // XXX 10191%} 10192 10193instruct convI2D_reg_mem(regD dst, memory src) 10194%{ 10195 match(Set dst (ConvI2D (LoadI src))); 10196 10197 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 10198 ins_encode %{ 10199 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 10200 %} 10201 ins_pipe(pipe_slow); // XXX 10202%} 10203 10204instruct convXI2F_reg(regF dst, rRegI src) 10205%{ 10206 predicate(UseXmmI2F); 10207 match(Set dst (ConvI2F src)); 10208 10209 format %{ "movdl $dst, $src\n\t" 10210 "cvtdq2psl $dst, $dst\t# i2f" %} 10211 ins_encode %{ 10212 __ movdl($dst$$XMMRegister, $src$$Register); 10213 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10214 %} 10215 ins_pipe(pipe_slow); // XXX 10216%} 10217 10218instruct convXI2D_reg(regD dst, rRegI src) 10219%{ 10220 predicate(UseXmmI2D); 10221 match(Set dst (ConvI2D src)); 10222 10223 format %{ "movdl $dst, $src\n\t" 10224 "cvtdq2pdl $dst, $dst\t# i2d" %} 10225 ins_encode %{ 10226 __ movdl($dst$$XMMRegister, $src$$Register); 10227 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10228 %} 10229 ins_pipe(pipe_slow); // XXX 10230%} 10231 10232instruct convL2F_reg_reg(regF dst, rRegL src) 10233%{ 10234 match(Set dst (ConvL2F src)); 10235 10236 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10237 ins_encode %{ 10238 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10239 %} 10240 ins_pipe(pipe_slow); // XXX 10241%} 10242 10243instruct convL2F_reg_mem(regF dst, memory src) 10244%{ 10245 match(Set dst (ConvL2F (LoadL src))); 10246 10247 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10248 ins_encode %{ 10249 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10250 %} 10251 ins_pipe(pipe_slow); // XXX 10252%} 10253 10254instruct convL2D_reg_reg(regD dst, rRegL src) 10255%{ 10256 match(Set dst (ConvL2D src)); 10257 10258 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10259 ins_encode %{ 10260 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10261 %} 10262 ins_pipe(pipe_slow); // XXX 10263%} 10264 10265instruct convL2D_reg_mem(regD dst, memory src) 10266%{ 10267 match(Set dst (ConvL2D (LoadL src))); 10268 10269 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10270 ins_encode %{ 10271 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10272 %} 10273 ins_pipe(pipe_slow); // XXX 10274%} 10275 10276instruct convI2L_reg_reg(rRegL dst, rRegI src) 10277%{ 10278 match(Set dst (ConvI2L src)); 10279 10280 ins_cost(125); 10281 format %{ "movslq $dst, $src\t# i2l" %} 10282 ins_encode %{ 10283 __ movslq($dst$$Register, $src$$Register); 10284 %} 10285 ins_pipe(ialu_reg_reg); 10286%} 10287 10288// instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10289// %{ 10290// match(Set dst (ConvI2L src)); 10291// // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10292// // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10293// predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10294// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10295// ((const TypeNode*) n)->type()->is_long()->_lo == 10296// (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10297 10298// format %{ "movl $dst, $src\t# unsigned i2l" %} 10299// ins_encode(enc_copy(dst, src)); 10300// // opcode(0x63); // needs REX.W 10301// // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10302// ins_pipe(ialu_reg_reg); 10303// %} 10304 10305// Zero-extend convert int to long 10306instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10307%{ 10308 match(Set dst (AndL (ConvI2L src) mask)); 10309 10310 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10311 ins_encode %{ 10312 if ($dst$$reg != $src$$reg) { 10313 __ movl($dst$$Register, $src$$Register); 10314 } 10315 %} 10316 ins_pipe(ialu_reg_reg); 10317%} 10318 10319// Zero-extend convert int to long 10320instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10321%{ 10322 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10323 10324 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10325 ins_encode %{ 10326 __ movl($dst$$Register, $src$$Address); 10327 %} 10328 ins_pipe(ialu_reg_mem); 10329%} 10330 10331instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10332%{ 10333 match(Set dst (AndL src mask)); 10334 10335 format %{ "movl $dst, $src\t# zero-extend long" %} 10336 ins_encode %{ 10337 __ movl($dst$$Register, $src$$Register); 10338 %} 10339 ins_pipe(ialu_reg_reg); 10340%} 10341 10342instruct convL2I_reg_reg(rRegI dst, rRegL src) 10343%{ 10344 match(Set dst (ConvL2I src)); 10345 10346 format %{ "movl $dst, $src\t# l2i" %} 10347 ins_encode %{ 10348 __ movl($dst$$Register, $src$$Register); 10349 %} 10350 ins_pipe(ialu_reg_reg); 10351%} 10352 10353 10354instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10355 match(Set dst (MoveF2I src)); 10356 effect(DEF dst, USE src); 10357 10358 ins_cost(125); 10359 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10360 ins_encode %{ 10361 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10362 %} 10363 ins_pipe(ialu_reg_mem); 10364%} 10365 10366instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10367 match(Set dst (MoveI2F src)); 10368 effect(DEF dst, USE src); 10369 10370 ins_cost(125); 10371 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10372 ins_encode %{ 10373 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10374 %} 10375 ins_pipe(pipe_slow); 10376%} 10377 10378instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10379 match(Set dst (MoveD2L src)); 10380 effect(DEF dst, USE src); 10381 10382 ins_cost(125); 10383 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10384 ins_encode %{ 10385 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10386 %} 10387 ins_pipe(ialu_reg_mem); 10388%} 10389 10390instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10391 predicate(!UseXmmLoadAndClearUpper); 10392 match(Set dst (MoveL2D src)); 10393 effect(DEF dst, USE src); 10394 10395 ins_cost(125); 10396 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10397 ins_encode %{ 10398 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10399 %} 10400 ins_pipe(pipe_slow); 10401%} 10402 10403instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10404 predicate(UseXmmLoadAndClearUpper); 10405 match(Set dst (MoveL2D src)); 10406 effect(DEF dst, USE src); 10407 10408 ins_cost(125); 10409 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10410 ins_encode %{ 10411 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10412 %} 10413 ins_pipe(pipe_slow); 10414%} 10415 10416 10417instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10418 match(Set dst (MoveF2I src)); 10419 effect(DEF dst, USE src); 10420 10421 ins_cost(95); // XXX 10422 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10423 ins_encode %{ 10424 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10425 %} 10426 ins_pipe(pipe_slow); 10427%} 10428 10429instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10430 match(Set dst (MoveI2F src)); 10431 effect(DEF dst, USE src); 10432 10433 ins_cost(100); 10434 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10435 ins_encode %{ 10436 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10437 %} 10438 ins_pipe( ialu_mem_reg ); 10439%} 10440 10441instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10442 match(Set dst (MoveD2L src)); 10443 effect(DEF dst, USE src); 10444 10445 ins_cost(95); // XXX 10446 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10447 ins_encode %{ 10448 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10449 %} 10450 ins_pipe(pipe_slow); 10451%} 10452 10453instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10454 match(Set dst (MoveL2D src)); 10455 effect(DEF dst, USE src); 10456 10457 ins_cost(100); 10458 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10459 ins_encode %{ 10460 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10461 %} 10462 ins_pipe(ialu_mem_reg); 10463%} 10464 10465instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10466 match(Set dst (MoveF2I src)); 10467 effect(DEF dst, USE src); 10468 ins_cost(85); 10469 format %{ "movd $dst,$src\t# MoveF2I" %} 10470 ins_encode %{ 10471 __ movdl($dst$$Register, $src$$XMMRegister); 10472 %} 10473 ins_pipe( pipe_slow ); 10474%} 10475 10476instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10477 match(Set dst (MoveD2L src)); 10478 effect(DEF dst, USE src); 10479 ins_cost(85); 10480 format %{ "movd $dst,$src\t# MoveD2L" %} 10481 ins_encode %{ 10482 __ movdq($dst$$Register, $src$$XMMRegister); 10483 %} 10484 ins_pipe( pipe_slow ); 10485%} 10486 10487instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10488 match(Set dst (MoveI2F src)); 10489 effect(DEF dst, USE src); 10490 ins_cost(100); 10491 format %{ "movd $dst,$src\t# MoveI2F" %} 10492 ins_encode %{ 10493 __ movdl($dst$$XMMRegister, $src$$Register); 10494 %} 10495 ins_pipe( pipe_slow ); 10496%} 10497 10498instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10499 match(Set dst (MoveL2D src)); 10500 effect(DEF dst, USE src); 10501 ins_cost(100); 10502 format %{ "movd $dst,$src\t# MoveL2D" %} 10503 ins_encode %{ 10504 __ movdq($dst$$XMMRegister, $src$$Register); 10505 %} 10506 ins_pipe( pipe_slow ); 10507%} 10508 10509 10510// ======================================================================= 10511// fast clearing of an array 10512instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10513 rFlagsReg cr) 10514%{ 10515 predicate(!UseFastStosb); 10516 match(Set dummy (ClearArray cnt base)); 10517 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10518 10519 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10520 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 10521 ins_encode %{ 10522 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10523 %} 10524 ins_pipe(pipe_slow); 10525%} 10526 10527instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10528 rFlagsReg cr) 10529%{ 10530 predicate(UseFastStosb); 10531 match(Set dummy (ClearArray cnt base)); 10532 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10533 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10534 "shlq rcx,3\t# Convert doublewords to bytes\n\t" 10535 "rep stosb\t# Store rax to *rdi++ while rcx--" %} 10536 ins_encode %{ 10537 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10538 %} 10539 ins_pipe( pipe_slow ); 10540%} 10541 10542instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10543 rax_RegI result, regD tmp1, rFlagsReg cr) 10544%{ 10545 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10546 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10547 10548 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10549 ins_encode %{ 10550 __ string_compare($str1$$Register, $str2$$Register, 10551 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10552 $tmp1$$XMMRegister); 10553 %} 10554 ins_pipe( pipe_slow ); 10555%} 10556 10557// fast search of substring with known size. 10558instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10559 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10560%{ 10561 predicate(UseSSE42Intrinsics); 10562 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10563 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10564 10565 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10566 ins_encode %{ 10567 int icnt2 = (int)$int_cnt2$$constant; 10568 if (icnt2 >= 8) { 10569 // IndexOf for constant substrings with size >= 8 elements 10570 // which don't need to be loaded through stack. 10571 __ string_indexofC8($str1$$Register, $str2$$Register, 10572 $cnt1$$Register, $cnt2$$Register, 10573 icnt2, $result$$Register, 10574 $vec$$XMMRegister, $tmp$$Register); 10575 } else { 10576 // Small strings are loaded through stack if they cross page boundary. 10577 __ string_indexof($str1$$Register, $str2$$Register, 10578 $cnt1$$Register, $cnt2$$Register, 10579 icnt2, $result$$Register, 10580 $vec$$XMMRegister, $tmp$$Register); 10581 } 10582 %} 10583 ins_pipe( pipe_slow ); 10584%} 10585 10586instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10587 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10588%{ 10589 predicate(UseSSE42Intrinsics); 10590 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10591 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10592 10593 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10594 ins_encode %{ 10595 __ string_indexof($str1$$Register, $str2$$Register, 10596 $cnt1$$Register, $cnt2$$Register, 10597 (-1), $result$$Register, 10598 $vec$$XMMRegister, $tmp$$Register); 10599 %} 10600 ins_pipe( pipe_slow ); 10601%} 10602 10603// fast string equals 10604instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10605 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10606%{ 10607 match(Set result (StrEquals (Binary str1 str2) cnt)); 10608 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10609 10610 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10611 ins_encode %{ 10612 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 10613 $cnt$$Register, $result$$Register, $tmp3$$Register, 10614 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10615 %} 10616 ins_pipe( pipe_slow ); 10617%} 10618 10619// fast array equals 10620instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10621 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10622%{ 10623 match(Set result (AryEq ary1 ary2)); 10624 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10625 //ins_cost(300); 10626 10627 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10628 ins_encode %{ 10629 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 10630 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10631 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10632 %} 10633 ins_pipe( pipe_slow ); 10634%} 10635 10636// encode char[] to byte[] in ISO_8859_1 10637instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 10638 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 10639 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 10640 match(Set result (EncodeISOArray src (Binary dst len))); 10641 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 10642 10643 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 10644 ins_encode %{ 10645 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 10646 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 10647 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 10648 %} 10649 ins_pipe( pipe_slow ); 10650%} 10651 10652 10653//----------Control Flow Instructions------------------------------------------ 10654// Signed compare Instructions 10655 10656// XXX more variants!! 10657instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10658%{ 10659 match(Set cr (CmpI op1 op2)); 10660 effect(DEF cr, USE op1, USE op2); 10661 10662 format %{ "cmpl $op1, $op2" %} 10663 opcode(0x3B); /* Opcode 3B /r */ 10664 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10665 ins_pipe(ialu_cr_reg_reg); 10666%} 10667 10668instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10669%{ 10670 match(Set cr (CmpI op1 op2)); 10671 10672 format %{ "cmpl $op1, $op2" %} 10673 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10674 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10675 ins_pipe(ialu_cr_reg_imm); 10676%} 10677 10678instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10679%{ 10680 match(Set cr (CmpI op1 (LoadI op2))); 10681 10682 ins_cost(500); // XXX 10683 format %{ "cmpl $op1, $op2" %} 10684 opcode(0x3B); /* Opcode 3B /r */ 10685 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10686 ins_pipe(ialu_cr_reg_mem); 10687%} 10688 10689instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10690%{ 10691 match(Set cr (CmpI src zero)); 10692 10693 format %{ "testl $src, $src" %} 10694 opcode(0x85); 10695 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10696 ins_pipe(ialu_cr_reg_imm); 10697%} 10698 10699instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10700%{ 10701 match(Set cr (CmpI (AndI src con) zero)); 10702 10703 format %{ "testl $src, $con" %} 10704 opcode(0xF7, 0x00); 10705 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10706 ins_pipe(ialu_cr_reg_imm); 10707%} 10708 10709instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10710%{ 10711 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10712 10713 format %{ "testl $src, $mem" %} 10714 opcode(0x85); 10715 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10716 ins_pipe(ialu_cr_reg_mem); 10717%} 10718 10719// Unsigned compare Instructions; really, same as signed except they 10720// produce an rFlagsRegU instead of rFlagsReg. 10721instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 10722%{ 10723 match(Set cr (CmpU op1 op2)); 10724 10725 format %{ "cmpl $op1, $op2\t# unsigned" %} 10726 opcode(0x3B); /* Opcode 3B /r */ 10727 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10728 ins_pipe(ialu_cr_reg_reg); 10729%} 10730 10731instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 10732%{ 10733 match(Set cr (CmpU op1 op2)); 10734 10735 format %{ "cmpl $op1, $op2\t# unsigned" %} 10736 opcode(0x81,0x07); /* Opcode 81 /7 */ 10737 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10738 ins_pipe(ialu_cr_reg_imm); 10739%} 10740 10741instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 10742%{ 10743 match(Set cr (CmpU op1 (LoadI op2))); 10744 10745 ins_cost(500); // XXX 10746 format %{ "cmpl $op1, $op2\t# unsigned" %} 10747 opcode(0x3B); /* Opcode 3B /r */ 10748 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10749 ins_pipe(ialu_cr_reg_mem); 10750%} 10751 10752// // // Cisc-spilled version of cmpU_rReg 10753// //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 10754// //%{ 10755// // match(Set cr (CmpU (LoadI op1) op2)); 10756// // 10757// // format %{ "CMPu $op1,$op2" %} 10758// // ins_cost(500); 10759// // opcode(0x39); /* Opcode 39 /r */ 10760// // ins_encode( OpcP, reg_mem( op1, op2) ); 10761// //%} 10762 10763instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 10764%{ 10765 match(Set cr (CmpU src zero)); 10766 10767 format %{ "testl $src, $src\t# unsigned" %} 10768 opcode(0x85); 10769 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10770 ins_pipe(ialu_cr_reg_imm); 10771%} 10772 10773instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 10774%{ 10775 match(Set cr (CmpP op1 op2)); 10776 10777 format %{ "cmpq $op1, $op2\t# ptr" %} 10778 opcode(0x3B); /* Opcode 3B /r */ 10779 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10780 ins_pipe(ialu_cr_reg_reg); 10781%} 10782 10783instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 10784%{ 10785 match(Set cr (CmpP op1 (LoadP op2))); 10786 10787 ins_cost(500); // XXX 10788 format %{ "cmpq $op1, $op2\t# ptr" %} 10789 opcode(0x3B); /* Opcode 3B /r */ 10790 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10791 ins_pipe(ialu_cr_reg_mem); 10792%} 10793 10794// // // Cisc-spilled version of cmpP_rReg 10795// //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 10796// //%{ 10797// // match(Set cr (CmpP (LoadP op1) op2)); 10798// // 10799// // format %{ "CMPu $op1,$op2" %} 10800// // ins_cost(500); 10801// // opcode(0x39); /* Opcode 39 /r */ 10802// // ins_encode( OpcP, reg_mem( op1, op2) ); 10803// //%} 10804 10805// XXX this is generalized by compP_rReg_mem??? 10806// Compare raw pointer (used in out-of-heap check). 10807// Only works because non-oop pointers must be raw pointers 10808// and raw pointers have no anti-dependencies. 10809instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 10810%{ 10811 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 10812 match(Set cr (CmpP op1 (LoadP op2))); 10813 10814 format %{ "cmpq $op1, $op2\t# raw ptr" %} 10815 opcode(0x3B); /* Opcode 3B /r */ 10816 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10817 ins_pipe(ialu_cr_reg_mem); 10818%} 10819 10820// This will generate a signed flags result. This should be OK since 10821// any compare to a zero should be eq/neq. 10822instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 10823%{ 10824 match(Set cr (CmpP src zero)); 10825 10826 format %{ "testq $src, $src\t# ptr" %} 10827 opcode(0x85); 10828 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10829 ins_pipe(ialu_cr_reg_imm); 10830%} 10831 10832// This will generate a signed flags result. This should be OK since 10833// any compare to a zero should be eq/neq. 10834instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 10835%{ 10836 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 10837 match(Set cr (CmpP (LoadP op) zero)); 10838 10839 ins_cost(500); // XXX 10840 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 10841 opcode(0xF7); /* Opcode F7 /0 */ 10842 ins_encode(REX_mem_wide(op), 10843 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 10844 ins_pipe(ialu_cr_reg_imm); 10845%} 10846 10847instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 10848%{ 10849 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 10850 match(Set cr (CmpP (LoadP mem) zero)); 10851 10852 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 10853 ins_encode %{ 10854 __ cmpq(r12, $mem$$Address); 10855 %} 10856 ins_pipe(ialu_cr_reg_mem); 10857%} 10858 10859instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 10860%{ 10861 match(Set cr (CmpN op1 op2)); 10862 10863 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10864 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 10865 ins_pipe(ialu_cr_reg_reg); 10866%} 10867 10868instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 10869%{ 10870 match(Set cr (CmpN src (LoadN mem))); 10871 10872 format %{ "cmpl $src, $mem\t# compressed ptr" %} 10873 ins_encode %{ 10874 __ cmpl($src$$Register, $mem$$Address); 10875 %} 10876 ins_pipe(ialu_cr_reg_mem); 10877%} 10878 10879instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 10880 match(Set cr (CmpN op1 op2)); 10881 10882 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10883 ins_encode %{ 10884 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 10885 %} 10886 ins_pipe(ialu_cr_reg_imm); 10887%} 10888 10889instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 10890%{ 10891 match(Set cr (CmpN src (LoadN mem))); 10892 10893 format %{ "cmpl $mem, $src\t# compressed ptr" %} 10894 ins_encode %{ 10895 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 10896 %} 10897 ins_pipe(ialu_cr_reg_mem); 10898%} 10899 10900instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 10901 match(Set cr (CmpN op1 op2)); 10902 10903 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 10904 ins_encode %{ 10905 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 10906 %} 10907 ins_pipe(ialu_cr_reg_imm); 10908%} 10909 10910instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 10911%{ 10912 match(Set cr (CmpN src (LoadNKlass mem))); 10913 10914 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 10915 ins_encode %{ 10916 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 10917 %} 10918 ins_pipe(ialu_cr_reg_mem); 10919%} 10920 10921instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 10922 match(Set cr (CmpN src zero)); 10923 10924 format %{ "testl $src, $src\t# compressed ptr" %} 10925 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 10926 ins_pipe(ialu_cr_reg_imm); 10927%} 10928 10929instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 10930%{ 10931 predicate(Universe::narrow_oop_base() != NULL); 10932 match(Set cr (CmpN (LoadN mem) zero)); 10933 10934 ins_cost(500); // XXX 10935 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 10936 ins_encode %{ 10937 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 10938 %} 10939 ins_pipe(ialu_cr_reg_mem); 10940%} 10941 10942instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 10943%{ 10944 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 10945 match(Set cr (CmpN (LoadN mem) zero)); 10946 10947 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 10948 ins_encode %{ 10949 __ cmpl(r12, $mem$$Address); 10950 %} 10951 ins_pipe(ialu_cr_reg_mem); 10952%} 10953 10954// Yanked all unsigned pointer compare operations. 10955// Pointer compares are done with CmpP which is already unsigned. 10956 10957instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10958%{ 10959 match(Set cr (CmpL op1 op2)); 10960 10961 format %{ "cmpq $op1, $op2" %} 10962 opcode(0x3B); /* Opcode 3B /r */ 10963 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10964 ins_pipe(ialu_cr_reg_reg); 10965%} 10966 10967instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10968%{ 10969 match(Set cr (CmpL op1 op2)); 10970 10971 format %{ "cmpq $op1, $op2" %} 10972 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10973 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 10974 ins_pipe(ialu_cr_reg_imm); 10975%} 10976 10977instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 10978%{ 10979 match(Set cr (CmpL op1 (LoadL op2))); 10980 10981 format %{ "cmpq $op1, $op2" %} 10982 opcode(0x3B); /* Opcode 3B /r */ 10983 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10984 ins_pipe(ialu_cr_reg_mem); 10985%} 10986 10987instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 10988%{ 10989 match(Set cr (CmpL src zero)); 10990 10991 format %{ "testq $src, $src" %} 10992 opcode(0x85); 10993 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10994 ins_pipe(ialu_cr_reg_imm); 10995%} 10996 10997instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 10998%{ 10999 match(Set cr (CmpL (AndL src con) zero)); 11000 11001 format %{ "testq $src, $con\t# long" %} 11002 opcode(0xF7, 0x00); 11003 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 11004 ins_pipe(ialu_cr_reg_imm); 11005%} 11006 11007instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 11008%{ 11009 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 11010 11011 format %{ "testq $src, $mem" %} 11012 opcode(0x85); 11013 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 11014 ins_pipe(ialu_cr_reg_mem); 11015%} 11016 11017// Manifest a CmpL result in an integer register. Very painful. 11018// This is the test to avoid. 11019instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 11020%{ 11021 match(Set dst (CmpL3 src1 src2)); 11022 effect(KILL flags); 11023 11024 ins_cost(275); // XXX 11025 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 11026 "movl $dst, -1\n\t" 11027 "jl,s done\n\t" 11028 "setne $dst\n\t" 11029 "movzbl $dst, $dst\n\t" 11030 "done:" %} 11031 ins_encode(cmpl3_flag(src1, src2, dst)); 11032 ins_pipe(pipe_slow); 11033%} 11034 11035//----------Max and Min-------------------------------------------------------- 11036// Min Instructions 11037 11038instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 11039%{ 11040 effect(USE_DEF dst, USE src, USE cr); 11041 11042 format %{ "cmovlgt $dst, $src\t# min" %} 11043 opcode(0x0F, 0x4F); 11044 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11045 ins_pipe(pipe_cmov_reg); 11046%} 11047 11048 11049instruct minI_rReg(rRegI dst, rRegI src) 11050%{ 11051 match(Set dst (MinI dst src)); 11052 11053 ins_cost(200); 11054 expand %{ 11055 rFlagsReg cr; 11056 compI_rReg(cr, dst, src); 11057 cmovI_reg_g(dst, src, cr); 11058 %} 11059%} 11060 11061instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11062%{ 11063 effect(USE_DEF dst, USE src, USE cr); 11064 11065 format %{ "cmovllt $dst, $src\t# max" %} 11066 opcode(0x0F, 0x4C); 11067 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11068 ins_pipe(pipe_cmov_reg); 11069%} 11070 11071 11072instruct maxI_rReg(rRegI dst, rRegI src) 11073%{ 11074 match(Set dst (MaxI dst src)); 11075 11076 ins_cost(200); 11077 expand %{ 11078 rFlagsReg cr; 11079 compI_rReg(cr, dst, src); 11080 cmovI_reg_l(dst, src, cr); 11081 %} 11082%} 11083 11084// ============================================================================ 11085// Branch Instructions 11086 11087// Jump Direct - Label defines a relative address from JMP+1 11088instruct jmpDir(label labl) 11089%{ 11090 match(Goto); 11091 effect(USE labl); 11092 11093 ins_cost(300); 11094 format %{ "jmp $labl" %} 11095 size(5); 11096 ins_encode %{ 11097 Label* L = $labl$$label; 11098 __ jmp(*L, false); // Always long jump 11099 %} 11100 ins_pipe(pipe_jmp); 11101%} 11102 11103// Jump Direct Conditional - Label defines a relative address from Jcc+1 11104instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11105%{ 11106 match(If cop cr); 11107 effect(USE labl); 11108 11109 ins_cost(300); 11110 format %{ "j$cop $labl" %} 11111 size(6); 11112 ins_encode %{ 11113 Label* L = $labl$$label; 11114 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11115 %} 11116 ins_pipe(pipe_jcc); 11117%} 11118 11119// Jump Direct Conditional - Label defines a relative address from Jcc+1 11120instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11121%{ 11122 match(CountedLoopEnd cop cr); 11123 effect(USE labl); 11124 11125 ins_cost(300); 11126 format %{ "j$cop $labl\t# loop end" %} 11127 size(6); 11128 ins_encode %{ 11129 Label* L = $labl$$label; 11130 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11131 %} 11132 ins_pipe(pipe_jcc); 11133%} 11134 11135// Jump Direct Conditional - Label defines a relative address from Jcc+1 11136instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11137 match(CountedLoopEnd cop cmp); 11138 effect(USE labl); 11139 11140 ins_cost(300); 11141 format %{ "j$cop,u $labl\t# loop end" %} 11142 size(6); 11143 ins_encode %{ 11144 Label* L = $labl$$label; 11145 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11146 %} 11147 ins_pipe(pipe_jcc); 11148%} 11149 11150instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11151 match(CountedLoopEnd cop cmp); 11152 effect(USE labl); 11153 11154 ins_cost(200); 11155 format %{ "j$cop,u $labl\t# loop end" %} 11156 size(6); 11157 ins_encode %{ 11158 Label* L = $labl$$label; 11159 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11160 %} 11161 ins_pipe(pipe_jcc); 11162%} 11163 11164// Jump Direct Conditional - using unsigned comparison 11165instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11166 match(If cop cmp); 11167 effect(USE labl); 11168 11169 ins_cost(300); 11170 format %{ "j$cop,u $labl" %} 11171 size(6); 11172 ins_encode %{ 11173 Label* L = $labl$$label; 11174 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11175 %} 11176 ins_pipe(pipe_jcc); 11177%} 11178 11179instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11180 match(If cop cmp); 11181 effect(USE labl); 11182 11183 ins_cost(200); 11184 format %{ "j$cop,u $labl" %} 11185 size(6); 11186 ins_encode %{ 11187 Label* L = $labl$$label; 11188 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11189 %} 11190 ins_pipe(pipe_jcc); 11191%} 11192 11193instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11194 match(If cop cmp); 11195 effect(USE labl); 11196 11197 ins_cost(200); 11198 format %{ $$template 11199 if ($cop$$cmpcode == Assembler::notEqual) { 11200 $$emit$$"jp,u $labl\n\t" 11201 $$emit$$"j$cop,u $labl" 11202 } else { 11203 $$emit$$"jp,u done\n\t" 11204 $$emit$$"j$cop,u $labl\n\t" 11205 $$emit$$"done:" 11206 } 11207 %} 11208 ins_encode %{ 11209 Label* l = $labl$$label; 11210 if ($cop$$cmpcode == Assembler::notEqual) { 11211 __ jcc(Assembler::parity, *l, false); 11212 __ jcc(Assembler::notEqual, *l, false); 11213 } else if ($cop$$cmpcode == Assembler::equal) { 11214 Label done; 11215 __ jccb(Assembler::parity, done); 11216 __ jcc(Assembler::equal, *l, false); 11217 __ bind(done); 11218 } else { 11219 ShouldNotReachHere(); 11220 } 11221 %} 11222 ins_pipe(pipe_jcc); 11223%} 11224 11225// ============================================================================ 11226// The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11227// superklass array for an instance of the superklass. Set a hidden 11228// internal cache on a hit (cache is checked with exposed code in 11229// gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11230// encoding ALSO sets flags. 11231 11232instruct partialSubtypeCheck(rdi_RegP result, 11233 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11234 rFlagsReg cr) 11235%{ 11236 match(Set result (PartialSubtypeCheck sub super)); 11237 effect(KILL rcx, KILL cr); 11238 11239 ins_cost(1100); // slightly larger than the next version 11240 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11241 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11242 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11243 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11244 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11245 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11246 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11247 "miss:\t" %} 11248 11249 opcode(0x1); // Force a XOR of RDI 11250 ins_encode(enc_PartialSubtypeCheck()); 11251 ins_pipe(pipe_slow); 11252%} 11253 11254instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11255 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11256 immP0 zero, 11257 rdi_RegP result) 11258%{ 11259 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11260 effect(KILL rcx, KILL result); 11261 11262 ins_cost(1000); 11263 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11264 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11265 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11266 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11267 "jne,s miss\t\t# Missed: flags nz\n\t" 11268 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11269 "miss:\t" %} 11270 11271 opcode(0x0); // No need to XOR RDI 11272 ins_encode(enc_PartialSubtypeCheck()); 11273 ins_pipe(pipe_slow); 11274%} 11275 11276// ============================================================================ 11277// Branch Instructions -- short offset versions 11278// 11279// These instructions are used to replace jumps of a long offset (the default 11280// match) with jumps of a shorter offset. These instructions are all tagged 11281// with the ins_short_branch attribute, which causes the ADLC to suppress the 11282// match rules in general matching. Instead, the ADLC generates a conversion 11283// method in the MachNode which can be used to do in-place replacement of the 11284// long variant with the shorter variant. The compiler will determine if a 11285// branch can be taken by the is_short_branch_offset() predicate in the machine 11286// specific code section of the file. 11287 11288// Jump Direct - Label defines a relative address from JMP+1 11289instruct jmpDir_short(label labl) %{ 11290 match(Goto); 11291 effect(USE labl); 11292 11293 ins_cost(300); 11294 format %{ "jmp,s $labl" %} 11295 size(2); 11296 ins_encode %{ 11297 Label* L = $labl$$label; 11298 __ jmpb(*L); 11299 %} 11300 ins_pipe(pipe_jmp); 11301 ins_short_branch(1); 11302%} 11303 11304// Jump Direct Conditional - Label defines a relative address from Jcc+1 11305instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11306 match(If cop cr); 11307 effect(USE labl); 11308 11309 ins_cost(300); 11310 format %{ "j$cop,s $labl" %} 11311 size(2); 11312 ins_encode %{ 11313 Label* L = $labl$$label; 11314 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11315 %} 11316 ins_pipe(pipe_jcc); 11317 ins_short_branch(1); 11318%} 11319 11320// Jump Direct Conditional - Label defines a relative address from Jcc+1 11321instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11322 match(CountedLoopEnd cop cr); 11323 effect(USE labl); 11324 11325 ins_cost(300); 11326 format %{ "j$cop,s $labl\t# loop end" %} 11327 size(2); 11328 ins_encode %{ 11329 Label* L = $labl$$label; 11330 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11331 %} 11332 ins_pipe(pipe_jcc); 11333 ins_short_branch(1); 11334%} 11335 11336// Jump Direct Conditional - Label defines a relative address from Jcc+1 11337instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11338 match(CountedLoopEnd cop cmp); 11339 effect(USE labl); 11340 11341 ins_cost(300); 11342 format %{ "j$cop,us $labl\t# loop end" %} 11343 size(2); 11344 ins_encode %{ 11345 Label* L = $labl$$label; 11346 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11347 %} 11348 ins_pipe(pipe_jcc); 11349 ins_short_branch(1); 11350%} 11351 11352instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11353 match(CountedLoopEnd cop cmp); 11354 effect(USE labl); 11355 11356 ins_cost(300); 11357 format %{ "j$cop,us $labl\t# loop end" %} 11358 size(2); 11359 ins_encode %{ 11360 Label* L = $labl$$label; 11361 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11362 %} 11363 ins_pipe(pipe_jcc); 11364 ins_short_branch(1); 11365%} 11366 11367// Jump Direct Conditional - using unsigned comparison 11368instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11369 match(If cop cmp); 11370 effect(USE labl); 11371 11372 ins_cost(300); 11373 format %{ "j$cop,us $labl" %} 11374 size(2); 11375 ins_encode %{ 11376 Label* L = $labl$$label; 11377 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11378 %} 11379 ins_pipe(pipe_jcc); 11380 ins_short_branch(1); 11381%} 11382 11383instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11384 match(If cop cmp); 11385 effect(USE labl); 11386 11387 ins_cost(300); 11388 format %{ "j$cop,us $labl" %} 11389 size(2); 11390 ins_encode %{ 11391 Label* L = $labl$$label; 11392 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11393 %} 11394 ins_pipe(pipe_jcc); 11395 ins_short_branch(1); 11396%} 11397 11398instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11399 match(If cop cmp); 11400 effect(USE labl); 11401 11402 ins_cost(300); 11403 format %{ $$template 11404 if ($cop$$cmpcode == Assembler::notEqual) { 11405 $$emit$$"jp,u,s $labl\n\t" 11406 $$emit$$"j$cop,u,s $labl" 11407 } else { 11408 $$emit$$"jp,u,s done\n\t" 11409 $$emit$$"j$cop,u,s $labl\n\t" 11410 $$emit$$"done:" 11411 } 11412 %} 11413 size(4); 11414 ins_encode %{ 11415 Label* l = $labl$$label; 11416 if ($cop$$cmpcode == Assembler::notEqual) { 11417 __ jccb(Assembler::parity, *l); 11418 __ jccb(Assembler::notEqual, *l); 11419 } else if ($cop$$cmpcode == Assembler::equal) { 11420 Label done; 11421 __ jccb(Assembler::parity, done); 11422 __ jccb(Assembler::equal, *l); 11423 __ bind(done); 11424 } else { 11425 ShouldNotReachHere(); 11426 } 11427 %} 11428 ins_pipe(pipe_jcc); 11429 ins_short_branch(1); 11430%} 11431 11432// ============================================================================ 11433// inlined locking and unlocking 11434 11435instruct cmpFastLock(rFlagsReg cr, 11436 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) 11437%{ 11438 match(Set cr (FastLock object box)); 11439 effect(TEMP tmp, TEMP scr, USE_KILL box); 11440 11441 ins_cost(300); 11442 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 11443 ins_encode(Fast_Lock(object, box, tmp, scr)); 11444 ins_pipe(pipe_slow); 11445%} 11446 11447instruct cmpFastUnlock(rFlagsReg cr, 11448 rRegP object, rax_RegP box, rRegP tmp) 11449%{ 11450 match(Set cr (FastUnlock object box)); 11451 effect(TEMP tmp, USE_KILL box); 11452 11453 ins_cost(300); 11454 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 11455 ins_encode(Fast_Unlock(object, box, tmp)); 11456 ins_pipe(pipe_slow); 11457%} 11458 11459 11460// ============================================================================ 11461// Safepoint Instructions 11462instruct safePoint_poll(rFlagsReg cr) 11463%{ 11464 predicate(!Assembler::is_polling_page_far()); 11465 match(SafePoint); 11466 effect(KILL cr); 11467 11468 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11469 "# Safepoint: poll for GC" %} 11470 ins_cost(125); 11471 ins_encode %{ 11472 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 11473 __ testl(rax, addr); 11474 %} 11475 ins_pipe(ialu_reg_mem); 11476%} 11477 11478instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 11479%{ 11480 predicate(Assembler::is_polling_page_far()); 11481 match(SafePoint poll); 11482 effect(KILL cr, USE poll); 11483 11484 format %{ "testl rax, [$poll]\t" 11485 "# Safepoint: poll for GC" %} 11486 ins_cost(125); 11487 ins_encode %{ 11488 __ relocate(relocInfo::poll_type); 11489 __ testl(rax, Address($poll$$Register, 0)); 11490 %} 11491 ins_pipe(ialu_reg_mem); 11492%} 11493 11494// ============================================================================ 11495// Procedure Call/Return Instructions 11496// Call Java Static Instruction 11497// Note: If this code changes, the corresponding ret_addr_offset() and 11498// compute_padding() functions will have to be adjusted. 11499instruct CallStaticJavaDirect(method meth) %{ 11500 match(CallStaticJava); 11501 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11502 effect(USE meth); 11503 11504 ins_cost(300); 11505 format %{ "call,static " %} 11506 opcode(0xE8); /* E8 cd */ 11507 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 11508 ins_pipe(pipe_slow); 11509 ins_alignment(4); 11510%} 11511 11512// Call Java Static Instruction (method handle version) 11513// Note: If this code changes, the corresponding ret_addr_offset() and 11514// compute_padding() functions will have to be adjusted. 11515instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ 11516 match(CallStaticJava); 11517 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11518 effect(USE meth); 11519 // RBP is saved by all callees (for interpreter stack correction). 11520 // We use it here for a similar purpose, in {preserve,restore}_SP. 11521 11522 ins_cost(300); 11523 format %{ "call,static/MethodHandle " %} 11524 opcode(0xE8); /* E8 cd */ 11525 ins_encode(clear_avx, preserve_SP, 11526 Java_Static_Call(meth), 11527 restore_SP, 11528 call_epilog); 11529 ins_pipe(pipe_slow); 11530 ins_alignment(4); 11531%} 11532 11533// Call Java Dynamic Instruction 11534// Note: If this code changes, the corresponding ret_addr_offset() and 11535// compute_padding() functions will have to be adjusted. 11536instruct CallDynamicJavaDirect(method meth) 11537%{ 11538 match(CallDynamicJava); 11539 effect(USE meth); 11540 11541 ins_cost(300); 11542 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11543 "call,dynamic " %} 11544 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 11545 ins_pipe(pipe_slow); 11546 ins_alignment(4); 11547%} 11548 11549// Call Runtime Instruction 11550instruct CallRuntimeDirect(method meth) 11551%{ 11552 match(CallRuntime); 11553 effect(USE meth); 11554 11555 ins_cost(300); 11556 format %{ "call,runtime " %} 11557 ins_encode(clear_avx, Java_To_Runtime(meth)); 11558 ins_pipe(pipe_slow); 11559%} 11560 11561// Call runtime without safepoint 11562instruct CallLeafDirect(method meth) 11563%{ 11564 match(CallLeaf); 11565 effect(USE meth); 11566 11567 ins_cost(300); 11568 format %{ "call_leaf,runtime " %} 11569 ins_encode(clear_avx, Java_To_Runtime(meth)); 11570 ins_pipe(pipe_slow); 11571%} 11572 11573// Call runtime without safepoint 11574instruct CallLeafNoFPDirect(method meth) 11575%{ 11576 match(CallLeafNoFP); 11577 effect(USE meth); 11578 11579 ins_cost(300); 11580 format %{ "call_leaf_nofp,runtime " %} 11581 ins_encode(Java_To_Runtime(meth)); 11582 ins_pipe(pipe_slow); 11583%} 11584 11585// Return Instruction 11586// Remove the return address & jump to it. 11587// Notice: We always emit a nop after a ret to make sure there is room 11588// for safepoint patching 11589instruct Ret() 11590%{ 11591 match(Return); 11592 11593 format %{ "ret" %} 11594 opcode(0xC3); 11595 ins_encode(OpcP); 11596 ins_pipe(pipe_jmp); 11597%} 11598 11599// Tail Call; Jump from runtime stub to Java code. 11600// Also known as an 'interprocedural jump'. 11601// Target of jump will eventually return to caller. 11602// TailJump below removes the return address. 11603instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11604%{ 11605 match(TailCall jump_target method_oop); 11606 11607 ins_cost(300); 11608 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11609 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11610 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11611 ins_pipe(pipe_jmp); 11612%} 11613 11614// Tail Jump; remove the return address; jump to target. 11615// TailCall above leaves the return address around. 11616instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11617%{ 11618 match(TailJump jump_target ex_oop); 11619 11620 ins_cost(300); 11621 format %{ "popq rdx\t# pop return address\n\t" 11622 "jmp $jump_target" %} 11623 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11624 ins_encode(Opcode(0x5a), // popq rdx 11625 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11626 ins_pipe(pipe_jmp); 11627%} 11628 11629// Create exception oop: created by stack-crawling runtime code. 11630// Created exception is now available to this handler, and is setup 11631// just prior to jumping to this handler. No code emitted. 11632instruct CreateException(rax_RegP ex_oop) 11633%{ 11634 match(Set ex_oop (CreateEx)); 11635 11636 size(0); 11637 // use the following format syntax 11638 format %{ "# exception oop is in rax; no code emitted" %} 11639 ins_encode(); 11640 ins_pipe(empty); 11641%} 11642 11643// Rethrow exception: 11644// The exception oop will come in the first argument position. 11645// Then JUMP (not call) to the rethrow stub code. 11646instruct RethrowException() 11647%{ 11648 match(Rethrow); 11649 11650 // use the following format syntax 11651 format %{ "jmp rethrow_stub" %} 11652 ins_encode(enc_rethrow); 11653 ins_pipe(pipe_jmp); 11654%} 11655 11656 11657// ============================================================================ 11658// This name is KNOWN by the ADLC and cannot be changed. 11659// The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11660// for this guy. 11661instruct tlsLoadP(r15_RegP dst) %{ 11662 match(Set dst (ThreadLocal)); 11663 effect(DEF dst); 11664 11665 size(0); 11666 format %{ "# TLS is in R15" %} 11667 ins_encode( /*empty encoding*/ ); 11668 ins_pipe(ialu_reg_reg); 11669%} 11670 11671 11672//----------PEEPHOLE RULES----------------------------------------------------- 11673// These must follow all instruction definitions as they use the names 11674// defined in the instructions definitions. 11675// 11676// peepmatch ( root_instr_name [preceding_instruction]* ); 11677// 11678// peepconstraint %{ 11679// (instruction_number.operand_name relational_op instruction_number.operand_name 11680// [, ...] ); 11681// // instruction numbers are zero-based using left to right order in peepmatch 11682// 11683// peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11684// // provide an instruction_number.operand_name for each operand that appears 11685// // in the replacement instruction's match rule 11686// 11687// ---------VM FLAGS--------------------------------------------------------- 11688// 11689// All peephole optimizations can be turned off using -XX:-OptoPeephole 11690// 11691// Each peephole rule is given an identifying number starting with zero and 11692// increasing by one in the order seen by the parser. An individual peephole 11693// can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11694// on the command-line. 11695// 11696// ---------CURRENT LIMITATIONS---------------------------------------------- 11697// 11698// Only match adjacent instructions in same basic block 11699// Only equality constraints 11700// Only constraints between operands, not (0.dest_reg == RAX_enc) 11701// Only one replacement instruction 11702// 11703// ---------EXAMPLE---------------------------------------------------------- 11704// 11705// // pertinent parts of existing instructions in architecture description 11706// instruct movI(rRegI dst, rRegI src) 11707// %{ 11708// match(Set dst (CopyI src)); 11709// %} 11710// 11711// instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11712// %{ 11713// match(Set dst (AddI dst src)); 11714// effect(KILL cr); 11715// %} 11716// 11717// // Change (inc mov) to lea 11718// peephole %{ 11719// // increment preceeded by register-register move 11720// peepmatch ( incI_rReg movI ); 11721// // require that the destination register of the increment 11722// // match the destination register of the move 11723// peepconstraint ( 0.dst == 1.dst ); 11724// // construct a replacement instruction that sets 11725// // the destination to ( move's source register + one ) 11726// peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 11727// %} 11728// 11729 11730// Implementation no longer uses movX instructions since 11731// machine-independent system no longer uses CopyX nodes. 11732// 11733// peephole 11734// %{ 11735// peepmatch (incI_rReg movI); 11736// peepconstraint (0.dst == 1.dst); 11737// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11738// %} 11739 11740// peephole 11741// %{ 11742// peepmatch (decI_rReg movI); 11743// peepconstraint (0.dst == 1.dst); 11744// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11745// %} 11746 11747// peephole 11748// %{ 11749// peepmatch (addI_rReg_imm movI); 11750// peepconstraint (0.dst == 1.dst); 11751// peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11752// %} 11753 11754// peephole 11755// %{ 11756// peepmatch (incL_rReg movL); 11757// peepconstraint (0.dst == 1.dst); 11758// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11759// %} 11760 11761// peephole 11762// %{ 11763// peepmatch (decL_rReg movL); 11764// peepconstraint (0.dst == 1.dst); 11765// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11766// %} 11767 11768// peephole 11769// %{ 11770// peepmatch (addL_rReg_imm movL); 11771// peepconstraint (0.dst == 1.dst); 11772// peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11773// %} 11774 11775// peephole 11776// %{ 11777// peepmatch (addP_rReg_imm movP); 11778// peepconstraint (0.dst == 1.dst); 11779// peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 11780// %} 11781 11782// // Change load of spilled value to only a spill 11783// instruct storeI(memory mem, rRegI src) 11784// %{ 11785// match(Set mem (StoreI mem src)); 11786// %} 11787// 11788// instruct loadI(rRegI dst, memory mem) 11789// %{ 11790// match(Set dst (LoadI mem)); 11791// %} 11792// 11793 11794peephole 11795%{ 11796 peepmatch (loadI storeI); 11797 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11798 peepreplace (storeI(1.mem 1.mem 1.src)); 11799%} 11800 11801peephole 11802%{ 11803 peepmatch (loadL storeL); 11804 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11805 peepreplace (storeL(1.mem 1.mem 1.src)); 11806%} 11807 11808//----------SMARTSPILL RULES--------------------------------------------------- 11809// These must follow all instruction definitions as they use the names 11810// defined in the instructions definitions. 11811