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