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