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