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