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