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