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