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