1 // 2 // Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 // 5 // This code is free software; you can redistribute it and/or modify it 6 // under the terms of the GNU General Public License version 2 only, as 7 // published by the Free Software Foundation. 8 // 9 // This code is distributed in the hope that it will be useful, but WITHOUT 10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // version 2 for more details (a copy is included in the LICENSE file that 13 // accompanied this code). 14 // 15 // You should have received a copy of the GNU General Public License version 16 // 2 along with this work; if not, write to the Free Software Foundation, 17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 // 19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 // or visit www.oracle.com if you need additional information or have any 21 // questions. 22 // 23 // 24 25 // AMD64 Architecture Description File 26 27 //----------REGISTER DEFINITION BLOCK------------------------------------------ 28 // This information is used by the matcher and the register allocator to 29 // describe individual registers and classes of registers within the target 30 // archtecture. 31 32 register %{ 33 //----------Architecture Description Register Definitions---------------------- 34 // General Registers 35 // "reg_def" name ( register save type, C convention save type, 36 // ideal register type, encoding ); 37 // Register Save Types: 38 // 39 // NS = No-Save: The register allocator assumes that these registers 40 // can be used without saving upon entry to the method, & 41 // that they do not need to be saved at call sites. 42 // 43 // SOC = Save-On-Call: The register allocator assumes that these registers 44 // can be used without saving upon entry to the method, 45 // but that they must be saved at call sites. 46 // 47 // SOE = Save-On-Entry: The register allocator assumes that these registers 48 // must be saved before using them upon entry to the 49 // method, but they do not need to be saved at call 50 // sites. 51 // 52 // AS = Always-Save: The register allocator assumes that these registers 53 // must be saved before using them upon entry to the 54 // method, & that they must be saved at call sites. 55 // 56 // Ideal Register Type is used to determine how to save & restore a 57 // register. Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get 58 // spilled with LoadP/StoreP. If the register supports both, use Op_RegI. 59 // 60 // The encoding number is the actual bit-pattern placed into the opcodes. 61 62 // General Registers 63 // R8-R15 must be encoded with REX. (RSP, RBP, RSI, RDI need REX when 64 // used as byte registers) 65 66 // Previously set RBX, RSI, and RDI as save-on-entry for java code 67 // Turn off SOE in java-code due to frequent use of uncommon-traps. 68 // Now that allocator is better, turn on RSI and RDI as SOE registers. 69 70 reg_def RAX (SOC, SOC, Op_RegI, 0, rax->as_VMReg()); 71 reg_def RAX_H(SOC, SOC, Op_RegI, 0, rax->as_VMReg()->next()); 72 73 reg_def RCX (SOC, SOC, Op_RegI, 1, rcx->as_VMReg()); 74 reg_def RCX_H(SOC, SOC, Op_RegI, 1, rcx->as_VMReg()->next()); 75 76 reg_def RDX (SOC, SOC, Op_RegI, 2, rdx->as_VMReg()); 77 reg_def RDX_H(SOC, SOC, Op_RegI, 2, rdx->as_VMReg()->next()); 78 79 reg_def RBX (SOC, SOE, Op_RegI, 3, rbx->as_VMReg()); 80 reg_def RBX_H(SOC, SOE, Op_RegI, 3, rbx->as_VMReg()->next()); 81 82 reg_def RSP (NS, NS, Op_RegI, 4, rsp->as_VMReg()); 83 reg_def RSP_H(NS, NS, Op_RegI, 4, rsp->as_VMReg()->next()); 84 85 // now that adapter frames are gone RBP is always saved and restored by the prolog/epilog code 86 reg_def RBP (NS, SOE, Op_RegI, 5, rbp->as_VMReg()); 87 reg_def RBP_H(NS, SOE, Op_RegI, 5, rbp->as_VMReg()->next()); 88 89 #ifdef _WIN64 90 91 reg_def RSI (SOC, SOE, Op_RegI, 6, rsi->as_VMReg()); 92 reg_def RSI_H(SOC, SOE, Op_RegI, 6, rsi->as_VMReg()->next()); 93 94 reg_def RDI (SOC, SOE, Op_RegI, 7, rdi->as_VMReg()); 95 reg_def RDI_H(SOC, SOE, Op_RegI, 7, rdi->as_VMReg()->next()); 96 97 #else 98 99 reg_def RSI (SOC, SOC, Op_RegI, 6, rsi->as_VMReg()); 100 reg_def RSI_H(SOC, SOC, Op_RegI, 6, rsi->as_VMReg()->next()); 101 102 reg_def RDI (SOC, SOC, Op_RegI, 7, rdi->as_VMReg()); 103 reg_def RDI_H(SOC, SOC, Op_RegI, 7, rdi->as_VMReg()->next()); 104 105 #endif 106 107 reg_def R8 (SOC, SOC, Op_RegI, 8, r8->as_VMReg()); 108 reg_def R8_H (SOC, SOC, Op_RegI, 8, r8->as_VMReg()->next()); 109 110 reg_def R9 (SOC, SOC, Op_RegI, 9, r9->as_VMReg()); 111 reg_def R9_H (SOC, SOC, Op_RegI, 9, r9->as_VMReg()->next()); 112 113 reg_def R10 (SOC, SOC, Op_RegI, 10, r10->as_VMReg()); 114 reg_def R10_H(SOC, SOC, Op_RegI, 10, r10->as_VMReg()->next()); 115 116 reg_def R11 (SOC, SOC, Op_RegI, 11, r11->as_VMReg()); 117 reg_def R11_H(SOC, SOC, Op_RegI, 11, r11->as_VMReg()->next()); 118 119 reg_def R12 (SOC, SOE, Op_RegI, 12, r12->as_VMReg()); 120 reg_def R12_H(SOC, SOE, Op_RegI, 12, r12->as_VMReg()->next()); 121 122 reg_def R13 (SOC, SOE, Op_RegI, 13, r13->as_VMReg()); 123 reg_def R13_H(SOC, SOE, Op_RegI, 13, r13->as_VMReg()->next()); 124 125 reg_def R14 (SOC, SOE, Op_RegI, 14, r14->as_VMReg()); 126 reg_def R14_H(SOC, SOE, Op_RegI, 14, r14->as_VMReg()->next()); 127 128 reg_def R15 (SOC, SOE, Op_RegI, 15, r15->as_VMReg()); 129 reg_def R15_H(SOC, SOE, Op_RegI, 15, r15->as_VMReg()->next()); 130 131 132 // Floating Point Registers 133 134 // Specify priority of register selection within phases of register 135 // allocation. Highest priority is first. A useful heuristic is to 136 // give registers a low priority when they are required by machine 137 // instructions, like EAX and EDX on I486, and choose no-save registers 138 // before save-on-call, & save-on-call before save-on-entry. Registers 139 // which participate in fixed calling sequences should come last. 140 // Registers which are used as pairs must fall on an even boundary. 141 142 alloc_class chunk0(R10, R10_H, 143 R11, R11_H, 144 R8, R8_H, 145 R9, R9_H, 146 R12, R12_H, 147 RCX, RCX_H, 148 RBX, RBX_H, 149 RDI, RDI_H, 150 RDX, RDX_H, 151 RSI, RSI_H, 152 RAX, RAX_H, 153 RBP, RBP_H, 154 R13, R13_H, 155 R14, R14_H, 156 R15, R15_H, 157 RSP, RSP_H); 158 159 160 //----------Architecture Description Register Classes-------------------------- 161 // Several register classes are automatically defined based upon information in 162 // this architecture description. 163 // 1) reg_class inline_cache_reg ( /* as def'd in frame section */ ) 164 // 2) reg_class compiler_method_oop_reg ( /* as def'd in frame section */ ) 165 // 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ ) 166 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ ) 167 // 168 169 // Class for all pointer registers (including RSP) 170 reg_class any_reg(RAX, RAX_H, 171 RDX, RDX_H, 172 RBP, RBP_H, 173 RDI, RDI_H, 174 RSI, RSI_H, 175 RCX, RCX_H, 176 RBX, RBX_H, 177 RSP, RSP_H, 178 R8, R8_H, 179 R9, R9_H, 180 R10, R10_H, 181 R11, R11_H, 182 R12, R12_H, 183 R13, R13_H, 184 R14, R14_H, 185 R15, R15_H); 186 187 // Class for all pointer registers except RSP 188 reg_class ptr_reg(RAX, RAX_H, 189 RDX, RDX_H, 190 RBP, RBP_H, 191 RDI, RDI_H, 192 RSI, RSI_H, 193 RCX, RCX_H, 194 RBX, RBX_H, 195 R8, R8_H, 196 R9, R9_H, 197 R10, R10_H, 198 R11, R11_H, 199 R13, R13_H, 200 R14, R14_H); 201 202 // Class for all pointer registers except RAX and RSP 203 reg_class ptr_no_rax_reg(RDX, RDX_H, 204 RBP, RBP_H, 205 RDI, RDI_H, 206 RSI, RSI_H, 207 RCX, RCX_H, 208 RBX, RBX_H, 209 R8, R8_H, 210 R9, R9_H, 211 R10, R10_H, 212 R11, R11_H, 213 R13, R13_H, 214 R14, R14_H); 215 216 reg_class ptr_no_rbp_reg(RDX, RDX_H, 217 RAX, RAX_H, 218 RDI, RDI_H, 219 RSI, RSI_H, 220 RCX, RCX_H, 221 RBX, RBX_H, 222 R8, R8_H, 223 R9, R9_H, 224 R10, R10_H, 225 R11, R11_H, 226 R13, R13_H, 227 R14, R14_H); 228 229 // Class for all pointer registers except RAX, RBX and RSP 230 reg_class ptr_no_rax_rbx_reg(RDX, RDX_H, 231 RBP, RBP_H, 232 RDI, RDI_H, 233 RSI, RSI_H, 234 RCX, RCX_H, 235 R8, R8_H, 236 R9, R9_H, 237 R10, R10_H, 238 R11, R11_H, 239 R13, R13_H, 240 R14, R14_H); 241 242 // Singleton class for RAX pointer register 243 reg_class ptr_rax_reg(RAX, RAX_H); 244 245 // Singleton class for RBX pointer register 246 reg_class ptr_rbx_reg(RBX, RBX_H); 247 248 // Singleton class for RSI pointer register 249 reg_class ptr_rsi_reg(RSI, RSI_H); 250 251 // Singleton class for RDI pointer register 252 reg_class ptr_rdi_reg(RDI, RDI_H); 253 254 // Singleton class for RBP pointer register 255 reg_class ptr_rbp_reg(RBP, RBP_H); 256 257 // Singleton class for stack pointer 258 reg_class ptr_rsp_reg(RSP, RSP_H); 259 260 // Singleton class for TLS pointer 261 reg_class ptr_r15_reg(R15, R15_H); 262 263 // Class for all long registers (except RSP) 264 reg_class long_reg(RAX, RAX_H, 265 RDX, RDX_H, 266 RBP, RBP_H, 267 RDI, RDI_H, 268 RSI, RSI_H, 269 RCX, RCX_H, 270 RBX, RBX_H, 271 R8, R8_H, 272 R9, R9_H, 273 R10, R10_H, 274 R11, R11_H, 275 R13, R13_H, 276 R14, R14_H); 277 278 // Class for all long registers except RAX, RDX (and RSP) 279 reg_class long_no_rax_rdx_reg(RBP, RBP_H, 280 RDI, RDI_H, 281 RSI, RSI_H, 282 RCX, RCX_H, 283 RBX, RBX_H, 284 R8, R8_H, 285 R9, R9_H, 286 R10, R10_H, 287 R11, R11_H, 288 R13, R13_H, 289 R14, R14_H); 290 291 // Class for all long registers except RCX (and RSP) 292 reg_class long_no_rcx_reg(RBP, RBP_H, 293 RDI, RDI_H, 294 RSI, RSI_H, 295 RAX, RAX_H, 296 RDX, RDX_H, 297 RBX, RBX_H, 298 R8, R8_H, 299 R9, R9_H, 300 R10, R10_H, 301 R11, R11_H, 302 R13, R13_H, 303 R14, R14_H); 304 305 // Class for all long registers except RAX (and RSP) 306 reg_class long_no_rax_reg(RBP, RBP_H, 307 RDX, RDX_H, 308 RDI, RDI_H, 309 RSI, RSI_H, 310 RCX, RCX_H, 311 RBX, RBX_H, 312 R8, R8_H, 313 R9, R9_H, 314 R10, R10_H, 315 R11, R11_H, 316 R13, R13_H, 317 R14, R14_H); 318 319 // Singleton class for RAX long register 320 reg_class long_rax_reg(RAX, RAX_H); 321 322 // Singleton class for RCX long register 323 reg_class long_rcx_reg(RCX, RCX_H); 324 325 // Singleton class for RDX long register 326 reg_class long_rdx_reg(RDX, RDX_H); 327 328 // Class for all int registers (except RSP) 329 reg_class int_reg(RAX, 330 RDX, 331 RBP, 332 RDI, 333 RSI, 334 RCX, 335 RBX, 336 R8, 337 R9, 338 R10, 339 R11, 340 R13, 341 R14); 342 343 // Class for all int registers except RCX (and RSP) 344 reg_class int_no_rcx_reg(RAX, 345 RDX, 346 RBP, 347 RDI, 348 RSI, 349 RBX, 350 R8, 351 R9, 352 R10, 353 R11, 354 R13, 355 R14); 356 357 // Class for all int registers except RAX, RDX (and RSP) 358 reg_class int_no_rax_rdx_reg(RBP, 359 RDI, 360 RSI, 361 RCX, 362 RBX, 363 R8, 364 R9, 365 R10, 366 R11, 367 R13, 368 R14); 369 370 // Singleton class for RAX int register 371 reg_class int_rax_reg(RAX); 372 373 // Singleton class for RBX int register 374 reg_class int_rbx_reg(RBX); 375 376 // Singleton class for RCX int register 377 reg_class int_rcx_reg(RCX); 378 379 // Singleton class for RCX int register 380 reg_class int_rdx_reg(RDX); 381 382 // Singleton class for RCX int register 383 reg_class int_rdi_reg(RDI); 384 385 // Singleton class for instruction pointer 386 // reg_class ip_reg(RIP); 387 388 %} 389 390 //----------SOURCE BLOCK------------------------------------------------------- 391 // This is a block of C++ code which provides values, functions, and 392 // definitions necessary in the rest of the architecture description 393 source %{ 394 #define RELOC_IMM64 Assembler::imm_operand 395 #define RELOC_DISP32 Assembler::disp32_operand 396 397 #define __ _masm. 398 399 static int preserve_SP_size() { 400 return 3; // rex.w, op, rm(reg/reg) 401 } 402 static int clear_avx_size() { 403 return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper 404 } 405 406 // !!!!! Special hack to get all types of calls to specify the byte offset 407 // from the start of the call to the point where the return address 408 // will point. 409 int MachCallStaticJavaNode::ret_addr_offset() 410 { 411 int offset = 5; // 5 bytes from start of call to where return address points 412 offset += clear_avx_size(); 413 if (_method_handle_invoke) 414 offset += preserve_SP_size(); 415 return offset; 416 } 417 418 int MachCallDynamicJavaNode::ret_addr_offset() 419 { 420 int offset = 15; // 15 bytes from start of call to where return address points 421 offset += clear_avx_size(); 422 return offset; 423 } 424 425 int MachCallRuntimeNode::ret_addr_offset() { 426 int offset = 13; // movq r10,#addr; callq (r10) 427 offset += clear_avx_size(); 428 return offset; 429 } 430 431 // Indicate if the safepoint node needs the polling page as an input, 432 // it does if the polling page is more than disp32 away. 433 bool SafePointNode::needs_polling_address_input() 434 { 435 return Assembler::is_polling_page_far(); 436 } 437 438 // 439 // Compute padding required for nodes which need alignment 440 // 441 442 // The address of the call instruction needs to be 4-byte aligned to 443 // ensure that it does not span a cache line so that it can be patched. 444 int CallStaticJavaDirectNode::compute_padding(int current_offset) const 445 { 446 current_offset += clear_avx_size(); // skip vzeroupper 447 current_offset += 1; // skip call opcode byte 448 return round_to(current_offset, alignment_required()) - current_offset; 449 } 450 451 // The address of the call instruction needs to be 4-byte aligned to 452 // ensure that it does not span a cache line so that it can be patched. 453 int CallStaticJavaHandleNode::compute_padding(int current_offset) const 454 { 455 current_offset += preserve_SP_size(); // skip mov rbp, rsp 456 current_offset += clear_avx_size(); // skip vzeroupper 457 current_offset += 1; // skip call opcode byte 458 return round_to(current_offset, alignment_required()) - current_offset; 459 } 460 461 // The address of the call instruction needs to be 4-byte aligned to 462 // ensure that it does not span a cache line so that it can be patched. 463 int CallDynamicJavaDirectNode::compute_padding(int current_offset) const 464 { 465 current_offset += clear_avx_size(); // skip vzeroupper 466 current_offset += 11; // skip movq instruction + call opcode byte 467 return round_to(current_offset, alignment_required()) - current_offset; 468 } 469 470 // EMIT_RM() 471 void emit_rm(CodeBuffer &cbuf, int f1, int f2, int f3) { 472 unsigned char c = (unsigned char) ((f1 << 6) | (f2 << 3) | f3); 473 cbuf.insts()->emit_int8(c); 474 } 475 476 // EMIT_CC() 477 void emit_cc(CodeBuffer &cbuf, int f1, int f2) { 478 unsigned char c = (unsigned char) (f1 | f2); 479 cbuf.insts()->emit_int8(c); 480 } 481 482 // EMIT_OPCODE() 483 void emit_opcode(CodeBuffer &cbuf, int code) { 484 cbuf.insts()->emit_int8((unsigned char) code); 485 } 486 487 // EMIT_OPCODE() w/ relocation information 488 void emit_opcode(CodeBuffer &cbuf, 489 int code, relocInfo::relocType reloc, int offset, int format) 490 { 491 cbuf.relocate(cbuf.insts_mark() + offset, reloc, format); 492 emit_opcode(cbuf, code); 493 } 494 495 // EMIT_D8() 496 void emit_d8(CodeBuffer &cbuf, int d8) { 497 cbuf.insts()->emit_int8((unsigned char) d8); 498 } 499 500 // EMIT_D16() 501 void emit_d16(CodeBuffer &cbuf, int d16) { 502 cbuf.insts()->emit_int16(d16); 503 } 504 505 // EMIT_D32() 506 void emit_d32(CodeBuffer &cbuf, int d32) { 507 cbuf.insts()->emit_int32(d32); 508 } 509 510 // EMIT_D64() 511 void emit_d64(CodeBuffer &cbuf, int64_t d64) { 512 cbuf.insts()->emit_int64(d64); 513 } 514 515 // emit 32 bit value and construct relocation entry from relocInfo::relocType 516 void emit_d32_reloc(CodeBuffer& cbuf, 517 int d32, 518 relocInfo::relocType reloc, 519 int format) 520 { 521 assert(reloc != relocInfo::external_word_type, "use 2-arg emit_d32_reloc"); 522 cbuf.relocate(cbuf.insts_mark(), reloc, format); 523 cbuf.insts()->emit_int32(d32); 524 } 525 526 // emit 32 bit value and construct relocation entry from RelocationHolder 527 void emit_d32_reloc(CodeBuffer& cbuf, int d32, RelocationHolder const& rspec, int format) { 528 #ifdef ASSERT 529 if (rspec.reloc()->type() == relocInfo::oop_type && 530 d32 != 0 && d32 != (intptr_t) Universe::non_oop_word()) { 531 assert(Universe::heap()->is_in_reserved((address)(intptr_t)d32), "should be real oop"); 532 assert(cast_to_oop((intptr_t)d32)->is_oop() && (ScavengeRootsInCode || !cast_to_oop((intptr_t)d32)->is_scavengable()), "cannot embed scavengable oops in code"); 533 } 534 #endif 535 cbuf.relocate(cbuf.insts_mark(), rspec, format); 536 cbuf.insts()->emit_int32(d32); 537 } 538 539 void emit_d32_reloc(CodeBuffer& cbuf, address addr) { 540 address next_ip = cbuf.insts_end() + 4; 541 emit_d32_reloc(cbuf, (int) (addr - next_ip), 542 external_word_Relocation::spec(addr), 543 RELOC_DISP32); 544 } 545 546 547 // emit 64 bit value and construct relocation entry from relocInfo::relocType 548 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, relocInfo::relocType reloc, int format) { 549 cbuf.relocate(cbuf.insts_mark(), reloc, format); 550 cbuf.insts()->emit_int64(d64); 551 } 552 553 // emit 64 bit value and construct relocation entry from RelocationHolder 554 void emit_d64_reloc(CodeBuffer& cbuf, int64_t d64, RelocationHolder const& rspec, int format) { 555 #ifdef ASSERT 556 if (rspec.reloc()->type() == relocInfo::oop_type && 557 d64 != 0 && d64 != (int64_t) Universe::non_oop_word()) { 558 assert(Universe::heap()->is_in_reserved((address)d64), "should be real oop"); 559 assert(cast_to_oop(d64)->is_oop() && (ScavengeRootsInCode || !cast_to_oop(d64)->is_scavengable()), 560 "cannot embed scavengable oops in code"); 561 } 562 #endif 563 cbuf.relocate(cbuf.insts_mark(), rspec, format); 564 cbuf.insts()->emit_int64(d64); 565 } 566 567 // Access stack slot for load or store 568 void store_to_stackslot(CodeBuffer &cbuf, int opcode, int rm_field, int disp) 569 { 570 emit_opcode(cbuf, opcode); // (e.g., FILD [RSP+src]) 571 if (-0x80 <= disp && disp < 0x80) { 572 emit_rm(cbuf, 0x01, rm_field, RSP_enc); // R/M byte 573 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 574 emit_d8(cbuf, disp); // Displacement // R/M byte 575 } else { 576 emit_rm(cbuf, 0x02, rm_field, RSP_enc); // R/M byte 577 emit_rm(cbuf, 0x00, RSP_enc, RSP_enc); // SIB byte 578 emit_d32(cbuf, disp); // Displacement // R/M byte 579 } 580 } 581 582 // rRegI ereg, memory mem) %{ // emit_reg_mem 583 void encode_RegMem(CodeBuffer &cbuf, 584 int reg, 585 int base, int index, int scale, int disp, relocInfo::relocType disp_reloc) 586 { 587 assert(disp_reloc == relocInfo::none, "cannot have disp"); 588 int regenc = reg & 7; 589 int baseenc = base & 7; 590 int indexenc = index & 7; 591 592 // There is no index & no scale, use form without SIB byte 593 if (index == 0x4 && scale == 0 && base != RSP_enc && base != R12_enc) { 594 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 595 if (disp == 0 && base != RBP_enc && base != R13_enc) { 596 emit_rm(cbuf, 0x0, regenc, baseenc); // * 597 } else if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 598 // If 8-bit displacement, mode 0x1 599 emit_rm(cbuf, 0x1, regenc, baseenc); // * 600 emit_d8(cbuf, disp); 601 } else { 602 // If 32-bit displacement 603 if (base == -1) { // Special flag for absolute address 604 emit_rm(cbuf, 0x0, regenc, 0x5); // * 605 if (disp_reloc != relocInfo::none) { 606 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 607 } else { 608 emit_d32(cbuf, disp); 609 } 610 } else { 611 // Normal base + offset 612 emit_rm(cbuf, 0x2, regenc, baseenc); // * 613 if (disp_reloc != relocInfo::none) { 614 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 615 } else { 616 emit_d32(cbuf, disp); 617 } 618 } 619 } 620 } else { 621 // Else, encode with the SIB byte 622 // If no displacement, mode is 0x0; unless base is [RBP] or [R13] 623 if (disp == 0 && base != RBP_enc && base != R13_enc) { 624 // If no displacement 625 emit_rm(cbuf, 0x0, regenc, 0x4); // * 626 emit_rm(cbuf, scale, indexenc, baseenc); 627 } else { 628 if (-0x80 <= disp && disp < 0x80 && disp_reloc == relocInfo::none) { 629 // If 8-bit displacement, mode 0x1 630 emit_rm(cbuf, 0x1, regenc, 0x4); // * 631 emit_rm(cbuf, scale, indexenc, baseenc); 632 emit_d8(cbuf, disp); 633 } else { 634 // If 32-bit displacement 635 if (base == 0x04 ) { 636 emit_rm(cbuf, 0x2, regenc, 0x4); 637 emit_rm(cbuf, scale, indexenc, 0x04); // XXX is this valid??? 638 } else { 639 emit_rm(cbuf, 0x2, regenc, 0x4); 640 emit_rm(cbuf, scale, indexenc, baseenc); // * 641 } 642 if (disp_reloc != relocInfo::none) { 643 emit_d32_reloc(cbuf, disp, relocInfo::oop_type, RELOC_DISP32); 644 } else { 645 emit_d32(cbuf, disp); 646 } 647 } 648 } 649 } 650 } 651 652 // This could be in MacroAssembler but it's fairly C2 specific 653 void emit_cmpfp_fixup(MacroAssembler& _masm) { 654 Label exit; 655 __ jccb(Assembler::noParity, exit); 656 __ pushf(); 657 // 658 // comiss/ucomiss instructions set ZF,PF,CF flags and 659 // zero OF,AF,SF for NaN values. 660 // Fixup flags by zeroing ZF,PF so that compare of NaN 661 // values returns 'less than' result (CF is set). 662 // Leave the rest of flags unchanged. 663 // 664 // 7 6 5 4 3 2 1 0 665 // |S|Z|r|A|r|P|r|C| (r - reserved bit) 666 // 0 0 1 0 1 0 1 1 (0x2B) 667 // 668 __ andq(Address(rsp, 0), 0xffffff2b); 669 __ popf(); 670 __ bind(exit); 671 } 672 673 void emit_cmpfp3(MacroAssembler& _masm, Register dst) { 674 Label done; 675 __ movl(dst, -1); 676 __ jcc(Assembler::parity, done); 677 __ jcc(Assembler::below, done); 678 __ setb(Assembler::notEqual, dst); 679 __ movzbl(dst, dst); 680 __ bind(done); 681 } 682 683 684 //============================================================================= 685 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; 686 687 int Compile::ConstantTable::calculate_table_base_offset() const { 688 return 0; // absolute addressing, no offset 689 } 690 691 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } 692 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { 693 ShouldNotReachHere(); 694 } 695 696 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { 697 // Empty encoding 698 } 699 700 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { 701 return 0; 702 } 703 704 #ifndef PRODUCT 705 void MachConstantBaseNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 706 st->print("# MachConstantBaseNode (empty encoding)"); 707 } 708 #endif 709 710 711 //============================================================================= 712 #ifndef PRODUCT 713 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { 714 Compile* C = ra_->C; 715 716 int framesize = C->frame_size_in_bytes(); 717 int bangsize = C->bang_size_in_bytes(); 718 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 719 // Remove wordSize for return addr which is already pushed. 720 framesize -= wordSize; 721 722 if (C->need_stack_bang(bangsize)) { 723 framesize -= wordSize; 724 st->print("# stack bang (%d bytes)", bangsize); 725 st->print("\n\t"); 726 st->print("pushq rbp\t# Save rbp"); 727 if (framesize) { 728 st->print("\n\t"); 729 st->print("subq rsp, #%d\t# Create frame",framesize); 730 } 731 } else { 732 st->print("subq rsp, #%d\t# Create frame",framesize); 733 st->print("\n\t"); 734 framesize -= wordSize; 735 st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize); 736 } 737 738 if (VerifyStackAtCalls) { 739 st->print("\n\t"); 740 framesize -= wordSize; 741 st->print("movq [rsp + #%d], 0xbadb100d\t# Majik cookie for stack depth check",framesize); 742 #ifdef ASSERT 743 st->print("\n\t"); 744 st->print("# stack alignment check"); 745 #endif 746 } 747 st->cr(); 748 } 749 #endif 750 751 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 752 Compile* C = ra_->C; 753 MacroAssembler _masm(&cbuf); 754 755 int framesize = C->frame_size_in_bytes(); 756 int bangsize = C->bang_size_in_bytes(); 757 758 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); 759 760 C->set_frame_complete(cbuf.insts_size()); 761 762 if (C->has_mach_constant_base_node()) { 763 // NOTE: We set the table base offset here because users might be 764 // emitted before MachConstantBaseNode. 765 Compile::ConstantTable& constant_table = C->constant_table(); 766 constant_table.set_table_base_offset(constant_table.calculate_table_base_offset()); 767 } 768 } 769 770 uint MachPrologNode::size(PhaseRegAlloc* ra_) const 771 { 772 return MachNode::size(ra_); // too many variables; just compute it 773 // the hard way 774 } 775 776 int MachPrologNode::reloc() const 777 { 778 return 0; // a large enough number 779 } 780 781 //============================================================================= 782 #ifndef PRODUCT 783 void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const 784 { 785 Compile* C = ra_->C; 786 if (C->max_vector_size() > 16) { 787 st->print("vzeroupper"); 788 st->cr(); st->print("\t"); 789 } 790 791 int framesize = C->frame_size_in_bytes(); 792 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 793 // Remove word for return adr already pushed 794 // and RBP 795 framesize -= 2*wordSize; 796 797 if (framesize) { 798 st->print_cr("addq rsp, %d\t# Destroy frame", framesize); 799 st->print("\t"); 800 } 801 802 st->print_cr("popq rbp"); 803 if (do_polling() && C->is_method_compilation()) { 804 st->print("\t"); 805 if (Assembler::is_polling_page_far()) { 806 st->print_cr("movq rscratch1, #polling_page_address\n\t" 807 "testl rax, [rscratch1]\t" 808 "# Safepoint: poll for GC"); 809 } else { 810 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t" 811 "# Safepoint: poll for GC"); 812 } 813 } 814 } 815 #endif 816 817 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 818 { 819 Compile* C = ra_->C; 820 if (C->max_vector_size() > 16) { 821 // Clear upper bits of YMM registers when current compiled code uses 822 // wide vectors to avoid AVX <-> SSE transition penalty during call. 823 MacroAssembler _masm(&cbuf); 824 __ vzeroupper(); 825 } 826 827 int framesize = C->frame_size_in_bytes(); 828 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); 829 // Remove word for return adr already pushed 830 // and RBP 831 framesize -= 2*wordSize; 832 833 // Note that VerifyStackAtCalls' Majik cookie does not change the frame size popped here 834 835 if (framesize) { 836 emit_opcode(cbuf, Assembler::REX_W); 837 if (framesize < 0x80) { 838 emit_opcode(cbuf, 0x83); // addq rsp, #framesize 839 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 840 emit_d8(cbuf, framesize); 841 } else { 842 emit_opcode(cbuf, 0x81); // addq rsp, #framesize 843 emit_rm(cbuf, 0x3, 0x00, RSP_enc); 844 emit_d32(cbuf, framesize); 845 } 846 } 847 848 // popq rbp 849 emit_opcode(cbuf, 0x58 | RBP_enc); 850 851 if (do_polling() && C->is_method_compilation()) { 852 MacroAssembler _masm(&cbuf); 853 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); 854 if (Assembler::is_polling_page_far()) { 855 __ lea(rscratch1, polling_page); 856 __ relocate(relocInfo::poll_return_type); 857 __ testl(rax, Address(rscratch1, 0)); 858 } else { 859 __ testl(rax, polling_page); 860 } 861 } 862 } 863 864 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 865 { 866 return MachNode::size(ra_); // too many variables; just compute it 867 // the hard way 868 } 869 870 int MachEpilogNode::reloc() const 871 { 872 return 2; // a large enough number 873 } 874 875 const Pipeline* MachEpilogNode::pipeline() const 876 { 877 return MachNode::pipeline_class(); 878 } 879 880 int MachEpilogNode::safepoint_offset() const 881 { 882 return 0; 883 } 884 885 //============================================================================= 886 887 enum RC { 888 rc_bad, 889 rc_int, 890 rc_float, 891 rc_stack 892 }; 893 894 static enum RC rc_class(OptoReg::Name reg) 895 { 896 if( !OptoReg::is_valid(reg) ) return rc_bad; 897 898 if (OptoReg::is_stack(reg)) return rc_stack; 899 900 VMReg r = OptoReg::as_VMReg(reg); 901 902 if (r->is_Register()) return rc_int; 903 904 assert(r->is_XMMRegister(), "must be"); 905 return rc_float; 906 } 907 908 // Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad. 909 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo, 910 int src_hi, int dst_hi, uint ireg, outputStream* st); 911 912 static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load, 913 int stack_offset, int reg, uint ireg, outputStream* st); 914 915 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset, 916 int dst_offset, uint ireg, outputStream* st) { 917 if (cbuf) { 918 MacroAssembler _masm(cbuf); 919 switch (ireg) { 920 case Op_VecS: 921 __ movq(Address(rsp, -8), rax); 922 __ movl(rax, Address(rsp, src_offset)); 923 __ movl(Address(rsp, dst_offset), rax); 924 __ movq(rax, Address(rsp, -8)); 925 break; 926 case Op_VecD: 927 __ pushq(Address(rsp, src_offset)); 928 __ popq (Address(rsp, dst_offset)); 929 break; 930 case Op_VecX: 931 __ pushq(Address(rsp, src_offset)); 932 __ popq (Address(rsp, dst_offset)); 933 __ pushq(Address(rsp, src_offset+8)); 934 __ popq (Address(rsp, dst_offset+8)); 935 break; 936 case Op_VecY: 937 __ vmovdqu(Address(rsp, -32), xmm0); 938 __ vmovdqu(xmm0, Address(rsp, src_offset)); 939 __ vmovdqu(Address(rsp, dst_offset), xmm0); 940 __ vmovdqu(xmm0, Address(rsp, -32)); 941 break; 942 default: 943 ShouldNotReachHere(); 944 } 945 #ifndef PRODUCT 946 } else { 947 switch (ireg) { 948 case Op_VecS: 949 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 950 "movl rax, [rsp + #%d]\n\t" 951 "movl [rsp + #%d], rax\n\t" 952 "movq rax, [rsp - #8]", 953 src_offset, dst_offset); 954 break; 955 case Op_VecD: 956 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 957 "popq [rsp + #%d]", 958 src_offset, dst_offset); 959 break; 960 case Op_VecX: 961 st->print("pushq [rsp + #%d]\t# 128-bit mem-mem spill\n\t" 962 "popq [rsp + #%d]\n\t" 963 "pushq [rsp + #%d]\n\t" 964 "popq [rsp + #%d]", 965 src_offset, dst_offset, src_offset+8, dst_offset+8); 966 break; 967 case Op_VecY: 968 st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t" 969 "vmovdqu xmm0, [rsp + #%d]\n\t" 970 "vmovdqu [rsp + #%d], xmm0\n\t" 971 "vmovdqu xmm0, [rsp - #32]", 972 src_offset, dst_offset); 973 break; 974 default: 975 ShouldNotReachHere(); 976 } 977 #endif 978 } 979 } 980 981 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf, 982 PhaseRegAlloc* ra_, 983 bool do_size, 984 outputStream* st) const { 985 assert(cbuf != NULL || st != NULL, "sanity"); 986 // Get registers to move 987 OptoReg::Name src_second = ra_->get_reg_second(in(1)); 988 OptoReg::Name src_first = ra_->get_reg_first(in(1)); 989 OptoReg::Name dst_second = ra_->get_reg_second(this); 990 OptoReg::Name dst_first = ra_->get_reg_first(this); 991 992 enum RC src_second_rc = rc_class(src_second); 993 enum RC src_first_rc = rc_class(src_first); 994 enum RC dst_second_rc = rc_class(dst_second); 995 enum RC dst_first_rc = rc_class(dst_first); 996 997 assert(OptoReg::is_valid(src_first) && OptoReg::is_valid(dst_first), 998 "must move at least 1 register" ); 999 1000 if (src_first == dst_first && src_second == dst_second) { 1001 // Self copy, no move 1002 return 0; 1003 } 1004 if (bottom_type()->isa_vect() != NULL) { 1005 uint ireg = ideal_reg(); 1006 assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity"); 1007 assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity"); 1008 if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) { 1009 // mem -> mem 1010 int src_offset = ra_->reg2offset(src_first); 1011 int dst_offset = ra_->reg2offset(dst_first); 1012 vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st); 1013 } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) { 1014 vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st); 1015 } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) { 1016 int stack_offset = ra_->reg2offset(dst_first); 1017 vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st); 1018 } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) { 1019 int stack_offset = ra_->reg2offset(src_first); 1020 vec_spill_helper(cbuf, false, true, stack_offset, dst_first, ireg, st); 1021 } else { 1022 ShouldNotReachHere(); 1023 } 1024 return 0; 1025 } 1026 if (src_first_rc == rc_stack) { 1027 // mem -> 1028 if (dst_first_rc == rc_stack) { 1029 // mem -> mem 1030 assert(src_second != dst_first, "overlap"); 1031 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1032 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1033 // 64-bit 1034 int src_offset = ra_->reg2offset(src_first); 1035 int dst_offset = ra_->reg2offset(dst_first); 1036 if (cbuf) { 1037 MacroAssembler _masm(cbuf); 1038 __ pushq(Address(rsp, src_offset)); 1039 __ popq (Address(rsp, dst_offset)); 1040 #ifndef PRODUCT 1041 } else { 1042 st->print("pushq [rsp + #%d]\t# 64-bit mem-mem spill\n\t" 1043 "popq [rsp + #%d]", 1044 src_offset, dst_offset); 1045 #endif 1046 } 1047 } else { 1048 // 32-bit 1049 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1050 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1051 // No pushl/popl, so: 1052 int src_offset = ra_->reg2offset(src_first); 1053 int dst_offset = ra_->reg2offset(dst_first); 1054 if (cbuf) { 1055 MacroAssembler _masm(cbuf); 1056 __ movq(Address(rsp, -8), rax); 1057 __ movl(rax, Address(rsp, src_offset)); 1058 __ movl(Address(rsp, dst_offset), rax); 1059 __ movq(rax, Address(rsp, -8)); 1060 #ifndef PRODUCT 1061 } else { 1062 st->print("movq [rsp - #8], rax\t# 32-bit mem-mem spill\n\t" 1063 "movl rax, [rsp + #%d]\n\t" 1064 "movl [rsp + #%d], rax\n\t" 1065 "movq rax, [rsp - #8]", 1066 src_offset, dst_offset); 1067 #endif 1068 } 1069 } 1070 return 0; 1071 } else if (dst_first_rc == rc_int) { 1072 // mem -> gpr 1073 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1074 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1075 // 64-bit 1076 int offset = ra_->reg2offset(src_first); 1077 if (cbuf) { 1078 MacroAssembler _masm(cbuf); 1079 __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1080 #ifndef PRODUCT 1081 } else { 1082 st->print("movq %s, [rsp + #%d]\t# spill", 1083 Matcher::regName[dst_first], 1084 offset); 1085 #endif 1086 } 1087 } else { 1088 // 32-bit 1089 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1090 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1091 int offset = ra_->reg2offset(src_first); 1092 if (cbuf) { 1093 MacroAssembler _masm(cbuf); 1094 __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1095 #ifndef PRODUCT 1096 } else { 1097 st->print("movl %s, [rsp + #%d]\t# spill", 1098 Matcher::regName[dst_first], 1099 offset); 1100 #endif 1101 } 1102 } 1103 return 0; 1104 } else if (dst_first_rc == rc_float) { 1105 // mem-> xmm 1106 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1107 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1108 // 64-bit 1109 int offset = ra_->reg2offset(src_first); 1110 if (cbuf) { 1111 MacroAssembler _masm(cbuf); 1112 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1113 #ifndef PRODUCT 1114 } else { 1115 st->print("%s %s, [rsp + #%d]\t# spill", 1116 UseXmmLoadAndClearUpper ? "movsd " : "movlpd", 1117 Matcher::regName[dst_first], 1118 offset); 1119 #endif 1120 } 1121 } else { 1122 // 32-bit 1123 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1124 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1125 int offset = ra_->reg2offset(src_first); 1126 if (cbuf) { 1127 MacroAssembler _masm(cbuf); 1128 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset)); 1129 #ifndef PRODUCT 1130 } else { 1131 st->print("movss %s, [rsp + #%d]\t# spill", 1132 Matcher::regName[dst_first], 1133 offset); 1134 #endif 1135 } 1136 } 1137 return 0; 1138 } 1139 } else if (src_first_rc == rc_int) { 1140 // gpr -> 1141 if (dst_first_rc == rc_stack) { 1142 // gpr -> mem 1143 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1144 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1145 // 64-bit 1146 int offset = ra_->reg2offset(dst_first); 1147 if (cbuf) { 1148 MacroAssembler _masm(cbuf); 1149 __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1150 #ifndef PRODUCT 1151 } else { 1152 st->print("movq [rsp + #%d], %s\t# spill", 1153 offset, 1154 Matcher::regName[src_first]); 1155 #endif 1156 } 1157 } else { 1158 // 32-bit 1159 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1160 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1161 int offset = ra_->reg2offset(dst_first); 1162 if (cbuf) { 1163 MacroAssembler _masm(cbuf); 1164 __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first])); 1165 #ifndef PRODUCT 1166 } else { 1167 st->print("movl [rsp + #%d], %s\t# spill", 1168 offset, 1169 Matcher::regName[src_first]); 1170 #endif 1171 } 1172 } 1173 return 0; 1174 } else if (dst_first_rc == rc_int) { 1175 // gpr -> gpr 1176 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1177 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1178 // 64-bit 1179 if (cbuf) { 1180 MacroAssembler _masm(cbuf); 1181 __ movq(as_Register(Matcher::_regEncode[dst_first]), 1182 as_Register(Matcher::_regEncode[src_first])); 1183 #ifndef PRODUCT 1184 } else { 1185 st->print("movq %s, %s\t# spill", 1186 Matcher::regName[dst_first], 1187 Matcher::regName[src_first]); 1188 #endif 1189 } 1190 return 0; 1191 } else { 1192 // 32-bit 1193 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1194 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1195 if (cbuf) { 1196 MacroAssembler _masm(cbuf); 1197 __ movl(as_Register(Matcher::_regEncode[dst_first]), 1198 as_Register(Matcher::_regEncode[src_first])); 1199 #ifndef PRODUCT 1200 } else { 1201 st->print("movl %s, %s\t# spill", 1202 Matcher::regName[dst_first], 1203 Matcher::regName[src_first]); 1204 #endif 1205 } 1206 return 0; 1207 } 1208 } else if (dst_first_rc == rc_float) { 1209 // gpr -> xmm 1210 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1211 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1212 // 64-bit 1213 if (cbuf) { 1214 MacroAssembler _masm(cbuf); 1215 __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1216 #ifndef PRODUCT 1217 } else { 1218 st->print("movdq %s, %s\t# spill", 1219 Matcher::regName[dst_first], 1220 Matcher::regName[src_first]); 1221 #endif 1222 } 1223 } else { 1224 // 32-bit 1225 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1226 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1227 if (cbuf) { 1228 MacroAssembler _masm(cbuf); 1229 __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first])); 1230 #ifndef PRODUCT 1231 } else { 1232 st->print("movdl %s, %s\t# spill", 1233 Matcher::regName[dst_first], 1234 Matcher::regName[src_first]); 1235 #endif 1236 } 1237 } 1238 return 0; 1239 } 1240 } else if (src_first_rc == rc_float) { 1241 // xmm -> 1242 if (dst_first_rc == rc_stack) { 1243 // xmm -> mem 1244 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1245 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1246 // 64-bit 1247 int offset = ra_->reg2offset(dst_first); 1248 if (cbuf) { 1249 MacroAssembler _masm(cbuf); 1250 __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1251 #ifndef PRODUCT 1252 } else { 1253 st->print("movsd [rsp + #%d], %s\t# spill", 1254 offset, 1255 Matcher::regName[src_first]); 1256 #endif 1257 } 1258 } else { 1259 // 32-bit 1260 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1261 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1262 int offset = ra_->reg2offset(dst_first); 1263 if (cbuf) { 1264 MacroAssembler _masm(cbuf); 1265 __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first])); 1266 #ifndef PRODUCT 1267 } else { 1268 st->print("movss [rsp + #%d], %s\t# spill", 1269 offset, 1270 Matcher::regName[src_first]); 1271 #endif 1272 } 1273 } 1274 return 0; 1275 } else if (dst_first_rc == rc_int) { 1276 // xmm -> gpr 1277 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1278 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1279 // 64-bit 1280 if (cbuf) { 1281 MacroAssembler _masm(cbuf); 1282 __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1283 #ifndef PRODUCT 1284 } else { 1285 st->print("movdq %s, %s\t# spill", 1286 Matcher::regName[dst_first], 1287 Matcher::regName[src_first]); 1288 #endif 1289 } 1290 } else { 1291 // 32-bit 1292 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1293 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1294 if (cbuf) { 1295 MacroAssembler _masm(cbuf); 1296 __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1297 #ifndef PRODUCT 1298 } else { 1299 st->print("movdl %s, %s\t# spill", 1300 Matcher::regName[dst_first], 1301 Matcher::regName[src_first]); 1302 #endif 1303 } 1304 } 1305 return 0; 1306 } else if (dst_first_rc == rc_float) { 1307 // xmm -> xmm 1308 if ((src_first & 1) == 0 && src_first + 1 == src_second && 1309 (dst_first & 1) == 0 && dst_first + 1 == dst_second) { 1310 // 64-bit 1311 if (cbuf) { 1312 MacroAssembler _masm(cbuf); 1313 __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1314 #ifndef PRODUCT 1315 } else { 1316 st->print("%s %s, %s\t# spill", 1317 UseXmmRegToRegMoveAll ? "movapd" : "movsd ", 1318 Matcher::regName[dst_first], 1319 Matcher::regName[src_first]); 1320 #endif 1321 } 1322 } else { 1323 // 32-bit 1324 assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform"); 1325 assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform"); 1326 if (cbuf) { 1327 MacroAssembler _masm(cbuf); 1328 __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first])); 1329 #ifndef PRODUCT 1330 } else { 1331 st->print("%s %s, %s\t# spill", 1332 UseXmmRegToRegMoveAll ? "movaps" : "movss ", 1333 Matcher::regName[dst_first], 1334 Matcher::regName[src_first]); 1335 #endif 1336 } 1337 } 1338 return 0; 1339 } 1340 } 1341 1342 assert(0," foo "); 1343 Unimplemented(); 1344 return 0; 1345 } 1346 1347 #ifndef PRODUCT 1348 void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const { 1349 implementation(NULL, ra_, false, st); 1350 } 1351 #endif 1352 1353 void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { 1354 implementation(&cbuf, ra_, false, NULL); 1355 } 1356 1357 uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const { 1358 return MachNode::size(ra_); 1359 } 1360 1361 //============================================================================= 1362 #ifndef PRODUCT 1363 void BoxLockNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1364 { 1365 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1366 int reg = ra_->get_reg_first(this); 1367 st->print("leaq %s, [rsp + #%d]\t# box lock", 1368 Matcher::regName[reg], offset); 1369 } 1370 #endif 1371 1372 void BoxLockNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1373 { 1374 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1375 int reg = ra_->get_encode(this); 1376 if (offset >= 0x80) { 1377 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1378 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1379 emit_rm(cbuf, 0x2, reg & 7, 0x04); 1380 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1381 emit_d32(cbuf, offset); 1382 } else { 1383 emit_opcode(cbuf, reg < 8 ? Assembler::REX_W : Assembler::REX_WR); 1384 emit_opcode(cbuf, 0x8D); // LEA reg,[SP+offset] 1385 emit_rm(cbuf, 0x1, reg & 7, 0x04); 1386 emit_rm(cbuf, 0x0, 0x04, RSP_enc); 1387 emit_d8(cbuf, offset); 1388 } 1389 } 1390 1391 uint BoxLockNode::size(PhaseRegAlloc *ra_) const 1392 { 1393 int offset = ra_->reg2offset(in_RegMask(0).find_first_elem()); 1394 return (offset < 0x80) ? 5 : 8; // REX 1395 } 1396 1397 //============================================================================= 1398 #ifndef PRODUCT 1399 void MachUEPNode::format(PhaseRegAlloc* ra_, outputStream* st) const 1400 { 1401 if (UseCompressedClassPointers) { 1402 st->print_cr("movl rscratch1, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t# compressed klass"); 1403 st->print_cr("\tdecode_klass_not_null rscratch1, rscratch1"); 1404 st->print_cr("\tcmpq rax, rscratch1\t # Inline cache check"); 1405 } else { 1406 st->print_cr("\tcmpq rax, [j_rarg0 + oopDesc::klass_offset_in_bytes()]\t" 1407 "# Inline cache check"); 1408 } 1409 st->print_cr("\tjne SharedRuntime::_ic_miss_stub"); 1410 st->print_cr("\tnop\t# nops to align entry point"); 1411 } 1412 #endif 1413 1414 void MachUEPNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1415 { 1416 MacroAssembler masm(&cbuf); 1417 uint insts_size = cbuf.insts_size(); 1418 if (UseCompressedClassPointers) { 1419 masm.load_klass(rscratch1, j_rarg0); 1420 masm.cmpptr(rax, rscratch1); 1421 } else { 1422 masm.cmpptr(rax, Address(j_rarg0, oopDesc::klass_offset_in_bytes())); 1423 } 1424 1425 masm.jump_cc(Assembler::notEqual, RuntimeAddress(SharedRuntime::get_ic_miss_stub())); 1426 1427 /* WARNING these NOPs are critical so that verified entry point is properly 1428 4 bytes aligned for patching by NativeJump::patch_verified_entry() */ 1429 int nops_cnt = 4 - ((cbuf.insts_size() - insts_size) & 0x3); 1430 if (OptoBreakpoint) { 1431 // Leave space for int3 1432 nops_cnt -= 1; 1433 } 1434 nops_cnt &= 0x3; // Do not add nops if code is aligned. 1435 if (nops_cnt > 0) 1436 masm.nop(nops_cnt); 1437 } 1438 1439 uint MachUEPNode::size(PhaseRegAlloc* ra_) const 1440 { 1441 return MachNode::size(ra_); // too many variables; just compute it 1442 // the hard way 1443 } 1444 1445 1446 //============================================================================= 1447 uint size_exception_handler() 1448 { 1449 // NativeCall instruction size is the same as NativeJump. 1450 // Note that this value is also credited (in output.cpp) to 1451 // the size of the code section. 1452 return NativeJump::instruction_size; 1453 } 1454 1455 // Emit exception handler code. 1456 int emit_exception_handler(CodeBuffer& cbuf) 1457 { 1458 1459 // Note that the code buffer's insts_mark is always relative to insts. 1460 // That's why we must use the macroassembler to generate a handler. 1461 MacroAssembler _masm(&cbuf); 1462 address base = 1463 __ start_a_stub(size_exception_handler()); 1464 if (base == NULL) return 0; // CodeBuffer::expand failed 1465 int offset = __ offset(); 1466 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); 1467 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); 1468 __ end_a_stub(); 1469 return offset; 1470 } 1471 1472 uint size_deopt_handler() 1473 { 1474 // three 5 byte instructions 1475 return 15; 1476 } 1477 1478 // Emit deopt handler code. 1479 int emit_deopt_handler(CodeBuffer& cbuf) 1480 { 1481 1482 // Note that the code buffer's insts_mark is always relative to insts. 1483 // That's why we must use the macroassembler to generate a handler. 1484 MacroAssembler _masm(&cbuf); 1485 address base = 1486 __ start_a_stub(size_deopt_handler()); 1487 if (base == NULL) return 0; // CodeBuffer::expand failed 1488 int offset = __ offset(); 1489 address the_pc = (address) __ pc(); 1490 Label next; 1491 // push a "the_pc" on the stack without destroying any registers 1492 // as they all may be live. 1493 1494 // push address of "next" 1495 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 1496 __ bind(next); 1497 // adjust it so it matches "the_pc" 1498 __ subptr(Address(rsp, 0), __ offset() - offset); 1499 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); 1500 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); 1501 __ end_a_stub(); 1502 return offset; 1503 } 1504 1505 int Matcher::regnum_to_fpu_offset(int regnum) 1506 { 1507 return regnum - 32; // The FP registers are in the second chunk 1508 } 1509 1510 // This is UltraSparc specific, true just means we have fast l2f conversion 1511 const bool Matcher::convL2FSupported(void) { 1512 return true; 1513 } 1514 1515 // Is this branch offset short enough that a short branch can be used? 1516 // 1517 // NOTE: If the platform does not provide any short branch variants, then 1518 // this method should return false for offset 0. 1519 bool Matcher::is_short_branch_offset(int rule, int br_size, int offset) { 1520 // The passed offset is relative to address of the branch. 1521 // On 86 a branch displacement is calculated relative to address 1522 // of a next instruction. 1523 offset -= br_size; 1524 1525 // the short version of jmpConUCF2 contains multiple branches, 1526 // making the reach slightly less 1527 if (rule == jmpConUCF2_rule) 1528 return (-126 <= offset && offset <= 125); 1529 return (-128 <= offset && offset <= 127); 1530 } 1531 1532 const bool Matcher::isSimpleConstant64(jlong value) { 1533 // Will one (StoreL ConL) be cheaper than two (StoreI ConI)?. 1534 //return value == (int) value; // Cf. storeImmL and immL32. 1535 1536 // Probably always true, even if a temp register is required. 1537 return true; 1538 } 1539 1540 // The ecx parameter to rep stosq for the ClearArray node is in words. 1541 const bool Matcher::init_array_count_is_in_bytes = false; 1542 1543 // Threshold size for cleararray. 1544 const int Matcher::init_array_short_size = 8 * BytesPerLong; 1545 1546 // No additional cost for CMOVL. 1547 const int Matcher::long_cmove_cost() { return 0; } 1548 1549 // No CMOVF/CMOVD with SSE2 1550 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } 1551 1552 // Does the CPU require late expand (see block.cpp for description of late expand)? 1553 const bool Matcher::require_postalloc_expand = false; 1554 1555 // Should the Matcher clone shifts on addressing modes, expecting them 1556 // to be subsumed into complex addressing expressions or compute them 1557 // into registers? True for Intel but false for most RISCs 1558 const bool Matcher::clone_shift_expressions = true; 1559 1560 // Do we need to mask the count passed to shift instructions or does 1561 // the cpu only look at the lower 5/6 bits anyway? 1562 const bool Matcher::need_masked_shift_count = false; 1563 1564 bool Matcher::narrow_oop_use_complex_address() { 1565 assert(UseCompressedOops, "only for compressed oops code"); 1566 return (LogMinObjAlignmentInBytes <= 3); 1567 } 1568 1569 bool Matcher::narrow_klass_use_complex_address() { 1570 assert(UseCompressedClassPointers, "only for compressed klass code"); 1571 return (LogKlassAlignmentInBytes <= 3); 1572 } 1573 1574 // Is it better to copy float constants, or load them directly from 1575 // memory? Intel can load a float constant from a direct address, 1576 // requiring no extra registers. Most RISCs will have to materialize 1577 // an address into a register first, so they would do better to copy 1578 // the constant from stack. 1579 const bool Matcher::rematerialize_float_constants = true; // XXX 1580 1581 // If CPU can load and store mis-aligned doubles directly then no 1582 // fixup is needed. Else we split the double into 2 integer pieces 1583 // and move it piece-by-piece. Only happens when passing doubles into 1584 // C code as the Java calling convention forces doubles to be aligned. 1585 const bool Matcher::misaligned_doubles_ok = true; 1586 1587 // No-op on amd64 1588 void Matcher::pd_implicit_null_fixup(MachNode *node, uint idx) {} 1589 1590 // Advertise here if the CPU requires explicit rounding operations to 1591 // implement the UseStrictFP mode. 1592 const bool Matcher::strict_fp_requires_explicit_rounding = true; 1593 1594 // Are floats conerted to double when stored to stack during deoptimization? 1595 // On x64 it is stored without convertion so we can use normal access. 1596 bool Matcher::float_in_double() { return false; } 1597 1598 // Do ints take an entire long register or just half? 1599 const bool Matcher::int_in_long = true; 1600 1601 // Return whether or not this register is ever used as an argument. 1602 // This function is used on startup to build the trampoline stubs in 1603 // generateOptoStub. Registers not mentioned will be killed by the VM 1604 // call in the trampoline, and arguments in those registers not be 1605 // available to the callee. 1606 bool Matcher::can_be_java_arg(int reg) 1607 { 1608 return 1609 reg == RDI_num || reg == RDI_H_num || 1610 reg == RSI_num || reg == RSI_H_num || 1611 reg == RDX_num || reg == RDX_H_num || 1612 reg == RCX_num || reg == RCX_H_num || 1613 reg == R8_num || reg == R8_H_num || 1614 reg == R9_num || reg == R9_H_num || 1615 reg == R12_num || reg == R12_H_num || 1616 reg == XMM0_num || reg == XMM0b_num || 1617 reg == XMM1_num || reg == XMM1b_num || 1618 reg == XMM2_num || reg == XMM2b_num || 1619 reg == XMM3_num || reg == XMM3b_num || 1620 reg == XMM4_num || reg == XMM4b_num || 1621 reg == XMM5_num || reg == XMM5b_num || 1622 reg == XMM6_num || reg == XMM6b_num || 1623 reg == XMM7_num || reg == XMM7b_num; 1624 } 1625 1626 bool Matcher::is_spillable_arg(int reg) 1627 { 1628 return can_be_java_arg(reg); 1629 } 1630 1631 bool Matcher::use_asm_for_ldiv_by_con( jlong divisor ) { 1632 // In 64 bit mode a code which use multiply when 1633 // devisor is constant is faster than hardware 1634 // DIV instruction (it uses MulHiL). 1635 return false; 1636 } 1637 1638 // Register for DIVI projection of divmodI 1639 RegMask Matcher::divI_proj_mask() { 1640 return INT_RAX_REG_mask(); 1641 } 1642 1643 // Register for MODI projection of divmodI 1644 RegMask Matcher::modI_proj_mask() { 1645 return INT_RDX_REG_mask(); 1646 } 1647 1648 // Register for DIVL projection of divmodL 1649 RegMask Matcher::divL_proj_mask() { 1650 return LONG_RAX_REG_mask(); 1651 } 1652 1653 // Register for MODL projection of divmodL 1654 RegMask Matcher::modL_proj_mask() { 1655 return LONG_RDX_REG_mask(); 1656 } 1657 1658 const RegMask Matcher::method_handle_invoke_SP_save_mask() { 1659 return PTR_RBP_REG_mask(); 1660 } 1661 1662 %} 1663 1664 //----------ENCODING BLOCK----------------------------------------------------- 1665 // This block specifies the encoding classes used by the compiler to 1666 // output byte streams. Encoding classes are parameterized macros 1667 // used by Machine Instruction Nodes in order to generate the bit 1668 // encoding of the instruction. Operands specify their base encoding 1669 // interface with the interface keyword. There are currently 1670 // supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, & 1671 // COND_INTER. REG_INTER causes an operand to generate a function 1672 // which returns its register number when queried. CONST_INTER causes 1673 // an operand to generate a function which returns the value of the 1674 // constant when queried. MEMORY_INTER causes an operand to generate 1675 // four functions which return the Base Register, the Index Register, 1676 // the Scale Value, and the Offset Value of the operand when queried. 1677 // COND_INTER causes an operand to generate six functions which return 1678 // the encoding code (ie - encoding bits for the instruction) 1679 // associated with each basic boolean condition for a conditional 1680 // instruction. 1681 // 1682 // Instructions specify two basic values for encoding. Again, a 1683 // function is available to check if the constant displacement is an 1684 // oop. They use the ins_encode keyword to specify their encoding 1685 // classes (which must be a sequence of enc_class names, and their 1686 // parameters, specified in the encoding block), and they use the 1687 // opcode keyword to specify, in order, their primary, secondary, and 1688 // tertiary opcode. Only the opcode sections which a particular 1689 // instruction needs for encoding need to be specified. 1690 encode %{ 1691 // Build emit functions for each basic byte or larger field in the 1692 // intel encoding scheme (opcode, rm, sib, immediate), and call them 1693 // from C++ code in the enc_class source block. Emit functions will 1694 // live in the main source block for now. In future, we can 1695 // generalize this by adding a syntax that specifies the sizes of 1696 // fields in an order, so that the adlc can build the emit functions 1697 // automagically 1698 1699 // Emit primary opcode 1700 enc_class OpcP 1701 %{ 1702 emit_opcode(cbuf, $primary); 1703 %} 1704 1705 // Emit secondary opcode 1706 enc_class OpcS 1707 %{ 1708 emit_opcode(cbuf, $secondary); 1709 %} 1710 1711 // Emit tertiary opcode 1712 enc_class OpcT 1713 %{ 1714 emit_opcode(cbuf, $tertiary); 1715 %} 1716 1717 // Emit opcode directly 1718 enc_class Opcode(immI d8) 1719 %{ 1720 emit_opcode(cbuf, $d8$$constant); 1721 %} 1722 1723 // Emit size prefix 1724 enc_class SizePrefix 1725 %{ 1726 emit_opcode(cbuf, 0x66); 1727 %} 1728 1729 enc_class reg(rRegI reg) 1730 %{ 1731 emit_rm(cbuf, 0x3, 0, $reg$$reg & 7); 1732 %} 1733 1734 enc_class reg_reg(rRegI dst, rRegI src) 1735 %{ 1736 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1737 %} 1738 1739 enc_class opc_reg_reg(immI opcode, rRegI dst, rRegI src) 1740 %{ 1741 emit_opcode(cbuf, $opcode$$constant); 1742 emit_rm(cbuf, 0x3, $dst$$reg & 7, $src$$reg & 7); 1743 %} 1744 1745 enc_class cdql_enc(no_rax_rdx_RegI div) 1746 %{ 1747 // Full implementation of Java idiv and irem; checks for 1748 // special case as described in JVM spec., p.243 & p.271. 1749 // 1750 // normal case special case 1751 // 1752 // input : rax: dividend min_int 1753 // reg: divisor -1 1754 // 1755 // output: rax: quotient (= rax idiv reg) min_int 1756 // rdx: remainder (= rax irem reg) 0 1757 // 1758 // Code sequnce: 1759 // 1760 // 0: 3d 00 00 00 80 cmp $0x80000000,%eax 1761 // 5: 75 07/08 jne e <normal> 1762 // 7: 33 d2 xor %edx,%edx 1763 // [div >= 8 -> offset + 1] 1764 // [REX_B] 1765 // 9: 83 f9 ff cmp $0xffffffffffffffff,$div 1766 // c: 74 03/04 je 11 <done> 1767 // 000000000000000e <normal>: 1768 // e: 99 cltd 1769 // [div >= 8 -> offset + 1] 1770 // [REX_B] 1771 // f: f7 f9 idiv $div 1772 // 0000000000000011 <done>: 1773 1774 // cmp $0x80000000,%eax 1775 emit_opcode(cbuf, 0x3d); 1776 emit_d8(cbuf, 0x00); 1777 emit_d8(cbuf, 0x00); 1778 emit_d8(cbuf, 0x00); 1779 emit_d8(cbuf, 0x80); 1780 1781 // jne e <normal> 1782 emit_opcode(cbuf, 0x75); 1783 emit_d8(cbuf, $div$$reg < 8 ? 0x07 : 0x08); 1784 1785 // xor %edx,%edx 1786 emit_opcode(cbuf, 0x33); 1787 emit_d8(cbuf, 0xD2); 1788 1789 // cmp $0xffffffffffffffff,%ecx 1790 if ($div$$reg >= 8) { 1791 emit_opcode(cbuf, Assembler::REX_B); 1792 } 1793 emit_opcode(cbuf, 0x83); 1794 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1795 emit_d8(cbuf, 0xFF); 1796 1797 // je 11 <done> 1798 emit_opcode(cbuf, 0x74); 1799 emit_d8(cbuf, $div$$reg < 8 ? 0x03 : 0x04); 1800 1801 // <normal> 1802 // cltd 1803 emit_opcode(cbuf, 0x99); 1804 1805 // idivl (note: must be emitted by the user of this rule) 1806 // <done> 1807 %} 1808 1809 enc_class cdqq_enc(no_rax_rdx_RegL div) 1810 %{ 1811 // Full implementation of Java ldiv and lrem; checks for 1812 // special case as described in JVM spec., p.243 & p.271. 1813 // 1814 // normal case special case 1815 // 1816 // input : rax: dividend min_long 1817 // reg: divisor -1 1818 // 1819 // output: rax: quotient (= rax idiv reg) min_long 1820 // rdx: remainder (= rax irem reg) 0 1821 // 1822 // Code sequnce: 1823 // 1824 // 0: 48 ba 00 00 00 00 00 mov $0x8000000000000000,%rdx 1825 // 7: 00 00 80 1826 // a: 48 39 d0 cmp %rdx,%rax 1827 // d: 75 08 jne 17 <normal> 1828 // f: 33 d2 xor %edx,%edx 1829 // 11: 48 83 f9 ff cmp $0xffffffffffffffff,$div 1830 // 15: 74 05 je 1c <done> 1831 // 0000000000000017 <normal>: 1832 // 17: 48 99 cqto 1833 // 19: 48 f7 f9 idiv $div 1834 // 000000000000001c <done>: 1835 1836 // mov $0x8000000000000000,%rdx 1837 emit_opcode(cbuf, Assembler::REX_W); 1838 emit_opcode(cbuf, 0xBA); 1839 emit_d8(cbuf, 0x00); 1840 emit_d8(cbuf, 0x00); 1841 emit_d8(cbuf, 0x00); 1842 emit_d8(cbuf, 0x00); 1843 emit_d8(cbuf, 0x00); 1844 emit_d8(cbuf, 0x00); 1845 emit_d8(cbuf, 0x00); 1846 emit_d8(cbuf, 0x80); 1847 1848 // cmp %rdx,%rax 1849 emit_opcode(cbuf, Assembler::REX_W); 1850 emit_opcode(cbuf, 0x39); 1851 emit_d8(cbuf, 0xD0); 1852 1853 // jne 17 <normal> 1854 emit_opcode(cbuf, 0x75); 1855 emit_d8(cbuf, 0x08); 1856 1857 // xor %edx,%edx 1858 emit_opcode(cbuf, 0x33); 1859 emit_d8(cbuf, 0xD2); 1860 1861 // cmp $0xffffffffffffffff,$div 1862 emit_opcode(cbuf, $div$$reg < 8 ? Assembler::REX_W : Assembler::REX_WB); 1863 emit_opcode(cbuf, 0x83); 1864 emit_rm(cbuf, 0x3, 0x7, $div$$reg & 7); 1865 emit_d8(cbuf, 0xFF); 1866 1867 // je 1e <done> 1868 emit_opcode(cbuf, 0x74); 1869 emit_d8(cbuf, 0x05); 1870 1871 // <normal> 1872 // cqto 1873 emit_opcode(cbuf, Assembler::REX_W); 1874 emit_opcode(cbuf, 0x99); 1875 1876 // idivq (note: must be emitted by the user of this rule) 1877 // <done> 1878 %} 1879 1880 // Opcde enc_class for 8/32 bit immediate instructions with sign-extension 1881 enc_class OpcSE(immI imm) 1882 %{ 1883 // Emit primary opcode and set sign-extend bit 1884 // Check for 8-bit immediate, and set sign extend bit in opcode 1885 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1886 emit_opcode(cbuf, $primary | 0x02); 1887 } else { 1888 // 32-bit immediate 1889 emit_opcode(cbuf, $primary); 1890 } 1891 %} 1892 1893 enc_class OpcSErm(rRegI dst, immI imm) 1894 %{ 1895 // OpcSEr/m 1896 int dstenc = $dst$$reg; 1897 if (dstenc >= 8) { 1898 emit_opcode(cbuf, Assembler::REX_B); 1899 dstenc -= 8; 1900 } 1901 // Emit primary opcode and set sign-extend bit 1902 // Check for 8-bit immediate, and set sign extend bit in opcode 1903 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1904 emit_opcode(cbuf, $primary | 0x02); 1905 } else { 1906 // 32-bit immediate 1907 emit_opcode(cbuf, $primary); 1908 } 1909 // Emit r/m byte with secondary opcode, after primary opcode. 1910 emit_rm(cbuf, 0x3, $secondary, dstenc); 1911 %} 1912 1913 enc_class OpcSErm_wide(rRegL dst, immI imm) 1914 %{ 1915 // OpcSEr/m 1916 int dstenc = $dst$$reg; 1917 if (dstenc < 8) { 1918 emit_opcode(cbuf, Assembler::REX_W); 1919 } else { 1920 emit_opcode(cbuf, Assembler::REX_WB); 1921 dstenc -= 8; 1922 } 1923 // Emit primary opcode and set sign-extend bit 1924 // Check for 8-bit immediate, and set sign extend bit in opcode 1925 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1926 emit_opcode(cbuf, $primary | 0x02); 1927 } else { 1928 // 32-bit immediate 1929 emit_opcode(cbuf, $primary); 1930 } 1931 // Emit r/m byte with secondary opcode, after primary opcode. 1932 emit_rm(cbuf, 0x3, $secondary, dstenc); 1933 %} 1934 1935 enc_class Con8or32(immI imm) 1936 %{ 1937 // Check for 8-bit immediate, and set sign extend bit in opcode 1938 if (-0x80 <= $imm$$constant && $imm$$constant < 0x80) { 1939 $$$emit8$imm$$constant; 1940 } else { 1941 // 32-bit immediate 1942 $$$emit32$imm$$constant; 1943 } 1944 %} 1945 1946 enc_class opc2_reg(rRegI dst) 1947 %{ 1948 // BSWAP 1949 emit_cc(cbuf, $secondary, $dst$$reg); 1950 %} 1951 1952 enc_class opc3_reg(rRegI dst) 1953 %{ 1954 // BSWAP 1955 emit_cc(cbuf, $tertiary, $dst$$reg); 1956 %} 1957 1958 enc_class reg_opc(rRegI div) 1959 %{ 1960 // INC, DEC, IDIV, IMOD, JMP indirect, ... 1961 emit_rm(cbuf, 0x3, $secondary, $div$$reg & 7); 1962 %} 1963 1964 enc_class enc_cmov(cmpOp cop) 1965 %{ 1966 // CMOV 1967 $$$emit8$primary; 1968 emit_cc(cbuf, $secondary, $cop$$cmpcode); 1969 %} 1970 1971 enc_class enc_PartialSubtypeCheck() 1972 %{ 1973 Register Rrdi = as_Register(RDI_enc); // result register 1974 Register Rrax = as_Register(RAX_enc); // super class 1975 Register Rrcx = as_Register(RCX_enc); // killed 1976 Register Rrsi = as_Register(RSI_enc); // sub class 1977 Label miss; 1978 const bool set_cond_codes = true; 1979 1980 MacroAssembler _masm(&cbuf); 1981 __ check_klass_subtype_slow_path(Rrsi, Rrax, Rrcx, Rrdi, 1982 NULL, &miss, 1983 /*set_cond_codes:*/ true); 1984 if ($primary) { 1985 __ xorptr(Rrdi, Rrdi); 1986 } 1987 __ bind(miss); 1988 %} 1989 1990 enc_class clear_avx %{ 1991 debug_only(int off0 = cbuf.insts_size()); 1992 if (ra_->C->max_vector_size() > 16) { 1993 // Clear upper bits of YMM registers when current compiled code uses 1994 // wide vectors to avoid AVX <-> SSE transition penalty during call. 1995 MacroAssembler _masm(&cbuf); 1996 __ vzeroupper(); 1997 } 1998 debug_only(int off1 = cbuf.insts_size()); 1999 assert(off1 - off0 == clear_avx_size(), "correct size prediction"); 2000 %} 2001 2002 enc_class Java_To_Runtime(method meth) %{ 2003 // No relocation needed 2004 MacroAssembler _masm(&cbuf); 2005 __ mov64(r10, (int64_t) $meth$$method); 2006 __ call(r10); 2007 %} 2008 2009 enc_class Java_To_Interpreter(method meth) 2010 %{ 2011 // CALL Java_To_Interpreter 2012 // This is the instruction starting address for relocation info. 2013 cbuf.set_insts_mark(); 2014 $$$emit8$primary; 2015 // CALL directly to the runtime 2016 emit_d32_reloc(cbuf, 2017 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2018 runtime_call_Relocation::spec(), 2019 RELOC_DISP32); 2020 %} 2021 2022 enc_class Java_Static_Call(method meth) 2023 %{ 2024 // JAVA STATIC CALL 2025 // CALL to fixup routine. Fixup routine uses ScopeDesc info to 2026 // determine who we intended to call. 2027 cbuf.set_insts_mark(); 2028 $$$emit8$primary; 2029 2030 if (!_method) { 2031 emit_d32_reloc(cbuf, 2032 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2033 runtime_call_Relocation::spec(), 2034 RELOC_DISP32); 2035 } else if (_optimized_virtual) { 2036 emit_d32_reloc(cbuf, 2037 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2038 opt_virtual_call_Relocation::spec(), 2039 RELOC_DISP32); 2040 } else { 2041 emit_d32_reloc(cbuf, 2042 (int) ($meth$$method - ((intptr_t) cbuf.insts_end()) - 4), 2043 static_call_Relocation::spec(), 2044 RELOC_DISP32); 2045 } 2046 if (_method) { 2047 // Emit stub for static call. 2048 CompiledStaticCall::emit_to_interp_stub(cbuf); 2049 } 2050 %} 2051 2052 enc_class Java_Dynamic_Call(method meth) %{ 2053 MacroAssembler _masm(&cbuf); 2054 __ ic_call((address)$meth$$method); 2055 %} 2056 2057 enc_class Java_Compiled_Call(method meth) 2058 %{ 2059 // JAVA COMPILED CALL 2060 int disp = in_bytes(Method:: from_compiled_offset()); 2061 2062 // XXX XXX offset is 128 is 1.5 NON-PRODUCT !!! 2063 // assert(-0x80 <= disp && disp < 0x80, "compiled_code_offset isn't small"); 2064 2065 // callq *disp(%rax) 2066 cbuf.set_insts_mark(); 2067 $$$emit8$primary; 2068 if (disp < 0x80) { 2069 emit_rm(cbuf, 0x01, $secondary, RAX_enc); // R/M byte 2070 emit_d8(cbuf, disp); // Displacement 2071 } else { 2072 emit_rm(cbuf, 0x02, $secondary, RAX_enc); // R/M byte 2073 emit_d32(cbuf, disp); // Displacement 2074 } 2075 %} 2076 2077 enc_class reg_opc_imm(rRegI dst, immI8 shift) 2078 %{ 2079 // SAL, SAR, SHR 2080 int dstenc = $dst$$reg; 2081 if (dstenc >= 8) { 2082 emit_opcode(cbuf, Assembler::REX_B); 2083 dstenc -= 8; 2084 } 2085 $$$emit8$primary; 2086 emit_rm(cbuf, 0x3, $secondary, dstenc); 2087 $$$emit8$shift$$constant; 2088 %} 2089 2090 enc_class reg_opc_imm_wide(rRegL dst, immI8 shift) 2091 %{ 2092 // SAL, SAR, SHR 2093 int dstenc = $dst$$reg; 2094 if (dstenc < 8) { 2095 emit_opcode(cbuf, Assembler::REX_W); 2096 } else { 2097 emit_opcode(cbuf, Assembler::REX_WB); 2098 dstenc -= 8; 2099 } 2100 $$$emit8$primary; 2101 emit_rm(cbuf, 0x3, $secondary, dstenc); 2102 $$$emit8$shift$$constant; 2103 %} 2104 2105 enc_class load_immI(rRegI dst, immI src) 2106 %{ 2107 int dstenc = $dst$$reg; 2108 if (dstenc >= 8) { 2109 emit_opcode(cbuf, Assembler::REX_B); 2110 dstenc -= 8; 2111 } 2112 emit_opcode(cbuf, 0xB8 | dstenc); 2113 $$$emit32$src$$constant; 2114 %} 2115 2116 enc_class load_immL(rRegL dst, immL src) 2117 %{ 2118 int dstenc = $dst$$reg; 2119 if (dstenc < 8) { 2120 emit_opcode(cbuf, Assembler::REX_W); 2121 } else { 2122 emit_opcode(cbuf, Assembler::REX_WB); 2123 dstenc -= 8; 2124 } 2125 emit_opcode(cbuf, 0xB8 | dstenc); 2126 emit_d64(cbuf, $src$$constant); 2127 %} 2128 2129 enc_class load_immUL32(rRegL dst, immUL32 src) 2130 %{ 2131 // same as load_immI, but this time we care about zeroes in the high word 2132 int dstenc = $dst$$reg; 2133 if (dstenc >= 8) { 2134 emit_opcode(cbuf, Assembler::REX_B); 2135 dstenc -= 8; 2136 } 2137 emit_opcode(cbuf, 0xB8 | dstenc); 2138 $$$emit32$src$$constant; 2139 %} 2140 2141 enc_class load_immL32(rRegL dst, immL32 src) 2142 %{ 2143 int dstenc = $dst$$reg; 2144 if (dstenc < 8) { 2145 emit_opcode(cbuf, Assembler::REX_W); 2146 } else { 2147 emit_opcode(cbuf, Assembler::REX_WB); 2148 dstenc -= 8; 2149 } 2150 emit_opcode(cbuf, 0xC7); 2151 emit_rm(cbuf, 0x03, 0x00, dstenc); 2152 $$$emit32$src$$constant; 2153 %} 2154 2155 enc_class load_immP31(rRegP dst, immP32 src) 2156 %{ 2157 // same as load_immI, but this time we care about zeroes in the high word 2158 int dstenc = $dst$$reg; 2159 if (dstenc >= 8) { 2160 emit_opcode(cbuf, Assembler::REX_B); 2161 dstenc -= 8; 2162 } 2163 emit_opcode(cbuf, 0xB8 | dstenc); 2164 $$$emit32$src$$constant; 2165 %} 2166 2167 enc_class load_immP(rRegP dst, immP src) 2168 %{ 2169 int dstenc = $dst$$reg; 2170 if (dstenc < 8) { 2171 emit_opcode(cbuf, Assembler::REX_W); 2172 } else { 2173 emit_opcode(cbuf, Assembler::REX_WB); 2174 dstenc -= 8; 2175 } 2176 emit_opcode(cbuf, 0xB8 | dstenc); 2177 // This next line should be generated from ADLC 2178 if ($src->constant_reloc() != relocInfo::none) { 2179 emit_d64_reloc(cbuf, $src$$constant, $src->constant_reloc(), RELOC_IMM64); 2180 } else { 2181 emit_d64(cbuf, $src$$constant); 2182 } 2183 %} 2184 2185 enc_class Con32(immI src) 2186 %{ 2187 // Output immediate 2188 $$$emit32$src$$constant; 2189 %} 2190 2191 enc_class Con32F_as_bits(immF src) 2192 %{ 2193 // Output Float immediate bits 2194 jfloat jf = $src$$constant; 2195 jint jf_as_bits = jint_cast(jf); 2196 emit_d32(cbuf, jf_as_bits); 2197 %} 2198 2199 enc_class Con16(immI src) 2200 %{ 2201 // Output immediate 2202 $$$emit16$src$$constant; 2203 %} 2204 2205 // How is this different from Con32??? XXX 2206 enc_class Con_d32(immI src) 2207 %{ 2208 emit_d32(cbuf,$src$$constant); 2209 %} 2210 2211 enc_class conmemref (rRegP t1) %{ // Con32(storeImmI) 2212 // Output immediate memory reference 2213 emit_rm(cbuf, 0x00, $t1$$reg, 0x05 ); 2214 emit_d32(cbuf, 0x00); 2215 %} 2216 2217 enc_class lock_prefix() 2218 %{ 2219 if (os::is_MP()) { 2220 emit_opcode(cbuf, 0xF0); // lock 2221 } 2222 %} 2223 2224 enc_class REX_mem(memory mem) 2225 %{ 2226 if ($mem$$base >= 8) { 2227 if ($mem$$index < 8) { 2228 emit_opcode(cbuf, Assembler::REX_B); 2229 } else { 2230 emit_opcode(cbuf, Assembler::REX_XB); 2231 } 2232 } else { 2233 if ($mem$$index >= 8) { 2234 emit_opcode(cbuf, Assembler::REX_X); 2235 } 2236 } 2237 %} 2238 2239 enc_class REX_mem_wide(memory mem) 2240 %{ 2241 if ($mem$$base >= 8) { 2242 if ($mem$$index < 8) { 2243 emit_opcode(cbuf, Assembler::REX_WB); 2244 } else { 2245 emit_opcode(cbuf, Assembler::REX_WXB); 2246 } 2247 } else { 2248 if ($mem$$index < 8) { 2249 emit_opcode(cbuf, Assembler::REX_W); 2250 } else { 2251 emit_opcode(cbuf, Assembler::REX_WX); 2252 } 2253 } 2254 %} 2255 2256 // for byte regs 2257 enc_class REX_breg(rRegI reg) 2258 %{ 2259 if ($reg$$reg >= 4) { 2260 emit_opcode(cbuf, $reg$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2261 } 2262 %} 2263 2264 // for byte regs 2265 enc_class REX_reg_breg(rRegI dst, rRegI src) 2266 %{ 2267 if ($dst$$reg < 8) { 2268 if ($src$$reg >= 4) { 2269 emit_opcode(cbuf, $src$$reg < 8 ? Assembler::REX : Assembler::REX_B); 2270 } 2271 } else { 2272 if ($src$$reg < 8) { 2273 emit_opcode(cbuf, Assembler::REX_R); 2274 } else { 2275 emit_opcode(cbuf, Assembler::REX_RB); 2276 } 2277 } 2278 %} 2279 2280 // for byte regs 2281 enc_class REX_breg_mem(rRegI reg, memory mem) 2282 %{ 2283 if ($reg$$reg < 8) { 2284 if ($mem$$base < 8) { 2285 if ($mem$$index >= 8) { 2286 emit_opcode(cbuf, Assembler::REX_X); 2287 } else if ($reg$$reg >= 4) { 2288 emit_opcode(cbuf, Assembler::REX); 2289 } 2290 } else { 2291 if ($mem$$index < 8) { 2292 emit_opcode(cbuf, Assembler::REX_B); 2293 } else { 2294 emit_opcode(cbuf, Assembler::REX_XB); 2295 } 2296 } 2297 } else { 2298 if ($mem$$base < 8) { 2299 if ($mem$$index < 8) { 2300 emit_opcode(cbuf, Assembler::REX_R); 2301 } else { 2302 emit_opcode(cbuf, Assembler::REX_RX); 2303 } 2304 } else { 2305 if ($mem$$index < 8) { 2306 emit_opcode(cbuf, Assembler::REX_RB); 2307 } else { 2308 emit_opcode(cbuf, Assembler::REX_RXB); 2309 } 2310 } 2311 } 2312 %} 2313 2314 enc_class REX_reg(rRegI reg) 2315 %{ 2316 if ($reg$$reg >= 8) { 2317 emit_opcode(cbuf, Assembler::REX_B); 2318 } 2319 %} 2320 2321 enc_class REX_reg_wide(rRegI reg) 2322 %{ 2323 if ($reg$$reg < 8) { 2324 emit_opcode(cbuf, Assembler::REX_W); 2325 } else { 2326 emit_opcode(cbuf, Assembler::REX_WB); 2327 } 2328 %} 2329 2330 enc_class REX_reg_reg(rRegI dst, rRegI src) 2331 %{ 2332 if ($dst$$reg < 8) { 2333 if ($src$$reg >= 8) { 2334 emit_opcode(cbuf, Assembler::REX_B); 2335 } 2336 } else { 2337 if ($src$$reg < 8) { 2338 emit_opcode(cbuf, Assembler::REX_R); 2339 } else { 2340 emit_opcode(cbuf, Assembler::REX_RB); 2341 } 2342 } 2343 %} 2344 2345 enc_class REX_reg_reg_wide(rRegI dst, rRegI src) 2346 %{ 2347 if ($dst$$reg < 8) { 2348 if ($src$$reg < 8) { 2349 emit_opcode(cbuf, Assembler::REX_W); 2350 } else { 2351 emit_opcode(cbuf, Assembler::REX_WB); 2352 } 2353 } else { 2354 if ($src$$reg < 8) { 2355 emit_opcode(cbuf, Assembler::REX_WR); 2356 } else { 2357 emit_opcode(cbuf, Assembler::REX_WRB); 2358 } 2359 } 2360 %} 2361 2362 enc_class REX_reg_mem(rRegI reg, memory mem) 2363 %{ 2364 if ($reg$$reg < 8) { 2365 if ($mem$$base < 8) { 2366 if ($mem$$index >= 8) { 2367 emit_opcode(cbuf, Assembler::REX_X); 2368 } 2369 } else { 2370 if ($mem$$index < 8) { 2371 emit_opcode(cbuf, Assembler::REX_B); 2372 } else { 2373 emit_opcode(cbuf, Assembler::REX_XB); 2374 } 2375 } 2376 } else { 2377 if ($mem$$base < 8) { 2378 if ($mem$$index < 8) { 2379 emit_opcode(cbuf, Assembler::REX_R); 2380 } else { 2381 emit_opcode(cbuf, Assembler::REX_RX); 2382 } 2383 } else { 2384 if ($mem$$index < 8) { 2385 emit_opcode(cbuf, Assembler::REX_RB); 2386 } else { 2387 emit_opcode(cbuf, Assembler::REX_RXB); 2388 } 2389 } 2390 } 2391 %} 2392 2393 enc_class REX_reg_mem_wide(rRegL reg, memory mem) 2394 %{ 2395 if ($reg$$reg < 8) { 2396 if ($mem$$base < 8) { 2397 if ($mem$$index < 8) { 2398 emit_opcode(cbuf, Assembler::REX_W); 2399 } else { 2400 emit_opcode(cbuf, Assembler::REX_WX); 2401 } 2402 } else { 2403 if ($mem$$index < 8) { 2404 emit_opcode(cbuf, Assembler::REX_WB); 2405 } else { 2406 emit_opcode(cbuf, Assembler::REX_WXB); 2407 } 2408 } 2409 } else { 2410 if ($mem$$base < 8) { 2411 if ($mem$$index < 8) { 2412 emit_opcode(cbuf, Assembler::REX_WR); 2413 } else { 2414 emit_opcode(cbuf, Assembler::REX_WRX); 2415 } 2416 } else { 2417 if ($mem$$index < 8) { 2418 emit_opcode(cbuf, Assembler::REX_WRB); 2419 } else { 2420 emit_opcode(cbuf, Assembler::REX_WRXB); 2421 } 2422 } 2423 } 2424 %} 2425 2426 enc_class reg_mem(rRegI ereg, memory mem) 2427 %{ 2428 // High registers handle in encode_RegMem 2429 int reg = $ereg$$reg; 2430 int base = $mem$$base; 2431 int index = $mem$$index; 2432 int scale = $mem$$scale; 2433 int disp = $mem$$disp; 2434 relocInfo::relocType disp_reloc = $mem->disp_reloc(); 2435 2436 encode_RegMem(cbuf, reg, base, index, scale, disp, disp_reloc); 2437 %} 2438 2439 enc_class RM_opc_mem(immI rm_opcode, memory mem) 2440 %{ 2441 int rm_byte_opcode = $rm_opcode$$constant; 2442 2443 // High registers handle in encode_RegMem 2444 int base = $mem$$base; 2445 int index = $mem$$index; 2446 int scale = $mem$$scale; 2447 int displace = $mem$$disp; 2448 2449 relocInfo::relocType disp_reloc = $mem->disp_reloc(); // disp-as-oop when 2450 // working with static 2451 // globals 2452 encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, 2453 disp_reloc); 2454 %} 2455 2456 enc_class reg_lea(rRegI dst, rRegI src0, immI src1) 2457 %{ 2458 int reg_encoding = $dst$$reg; 2459 int base = $src0$$reg; // 0xFFFFFFFF indicates no base 2460 int index = 0x04; // 0x04 indicates no index 2461 int scale = 0x00; // 0x00 indicates no scale 2462 int displace = $src1$$constant; // 0x00 indicates no displacement 2463 relocInfo::relocType disp_reloc = relocInfo::none; 2464 encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, 2465 disp_reloc); 2466 %} 2467 2468 enc_class neg_reg(rRegI dst) 2469 %{ 2470 int dstenc = $dst$$reg; 2471 if (dstenc >= 8) { 2472 emit_opcode(cbuf, Assembler::REX_B); 2473 dstenc -= 8; 2474 } 2475 // NEG $dst 2476 emit_opcode(cbuf, 0xF7); 2477 emit_rm(cbuf, 0x3, 0x03, dstenc); 2478 %} 2479 2480 enc_class neg_reg_wide(rRegI dst) 2481 %{ 2482 int dstenc = $dst$$reg; 2483 if (dstenc < 8) { 2484 emit_opcode(cbuf, Assembler::REX_W); 2485 } else { 2486 emit_opcode(cbuf, Assembler::REX_WB); 2487 dstenc -= 8; 2488 } 2489 // NEG $dst 2490 emit_opcode(cbuf, 0xF7); 2491 emit_rm(cbuf, 0x3, 0x03, dstenc); 2492 %} 2493 2494 enc_class setLT_reg(rRegI dst) 2495 %{ 2496 int dstenc = $dst$$reg; 2497 if (dstenc >= 8) { 2498 emit_opcode(cbuf, Assembler::REX_B); 2499 dstenc -= 8; 2500 } else if (dstenc >= 4) { 2501 emit_opcode(cbuf, Assembler::REX); 2502 } 2503 // SETLT $dst 2504 emit_opcode(cbuf, 0x0F); 2505 emit_opcode(cbuf, 0x9C); 2506 emit_rm(cbuf, 0x3, 0x0, dstenc); 2507 %} 2508 2509 enc_class setNZ_reg(rRegI dst) 2510 %{ 2511 int dstenc = $dst$$reg; 2512 if (dstenc >= 8) { 2513 emit_opcode(cbuf, Assembler::REX_B); 2514 dstenc -= 8; 2515 } else if (dstenc >= 4) { 2516 emit_opcode(cbuf, Assembler::REX); 2517 } 2518 // SETNZ $dst 2519 emit_opcode(cbuf, 0x0F); 2520 emit_opcode(cbuf, 0x95); 2521 emit_rm(cbuf, 0x3, 0x0, dstenc); 2522 %} 2523 2524 2525 // Compare the lonogs and set -1, 0, or 1 into dst 2526 enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst) 2527 %{ 2528 int src1enc = $src1$$reg; 2529 int src2enc = $src2$$reg; 2530 int dstenc = $dst$$reg; 2531 2532 // cmpq $src1, $src2 2533 if (src1enc < 8) { 2534 if (src2enc < 8) { 2535 emit_opcode(cbuf, Assembler::REX_W); 2536 } else { 2537 emit_opcode(cbuf, Assembler::REX_WB); 2538 } 2539 } else { 2540 if (src2enc < 8) { 2541 emit_opcode(cbuf, Assembler::REX_WR); 2542 } else { 2543 emit_opcode(cbuf, Assembler::REX_WRB); 2544 } 2545 } 2546 emit_opcode(cbuf, 0x3B); 2547 emit_rm(cbuf, 0x3, src1enc & 7, src2enc & 7); 2548 2549 // movl $dst, -1 2550 if (dstenc >= 8) { 2551 emit_opcode(cbuf, Assembler::REX_B); 2552 } 2553 emit_opcode(cbuf, 0xB8 | (dstenc & 7)); 2554 emit_d32(cbuf, -1); 2555 2556 // jl,s done 2557 emit_opcode(cbuf, 0x7C); 2558 emit_d8(cbuf, dstenc < 4 ? 0x06 : 0x08); 2559 2560 // setne $dst 2561 if (dstenc >= 4) { 2562 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_B); 2563 } 2564 emit_opcode(cbuf, 0x0F); 2565 emit_opcode(cbuf, 0x95); 2566 emit_opcode(cbuf, 0xC0 | (dstenc & 7)); 2567 2568 // movzbl $dst, $dst 2569 if (dstenc >= 4) { 2570 emit_opcode(cbuf, dstenc < 8 ? Assembler::REX : Assembler::REX_RB); 2571 } 2572 emit_opcode(cbuf, 0x0F); 2573 emit_opcode(cbuf, 0xB6); 2574 emit_rm(cbuf, 0x3, dstenc & 7, dstenc & 7); 2575 %} 2576 2577 enc_class Push_ResultXD(regD dst) %{ 2578 MacroAssembler _masm(&cbuf); 2579 __ fstp_d(Address(rsp, 0)); 2580 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 2581 __ addptr(rsp, 8); 2582 %} 2583 2584 enc_class Push_SrcXD(regD src) %{ 2585 MacroAssembler _masm(&cbuf); 2586 __ subptr(rsp, 8); 2587 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 2588 __ fld_d(Address(rsp, 0)); 2589 %} 2590 2591 2592 enc_class enc_rethrow() 2593 %{ 2594 cbuf.set_insts_mark(); 2595 emit_opcode(cbuf, 0xE9); // jmp entry 2596 emit_d32_reloc(cbuf, 2597 (int) (OptoRuntime::rethrow_stub() - cbuf.insts_end() - 4), 2598 runtime_call_Relocation::spec(), 2599 RELOC_DISP32); 2600 %} 2601 2602 %} 2603 2604 2605 2606 //----------FRAME-------------------------------------------------------------- 2607 // Definition of frame structure and management information. 2608 // 2609 // S T A C K L A Y O U T Allocators stack-slot number 2610 // | (to get allocators register number 2611 // G Owned by | | v add OptoReg::stack0()) 2612 // r CALLER | | 2613 // o | +--------+ pad to even-align allocators stack-slot 2614 // w V | pad0 | numbers; owned by CALLER 2615 // t -----------+--------+----> Matcher::_in_arg_limit, unaligned 2616 // h ^ | in | 5 2617 // | | args | 4 Holes in incoming args owned by SELF 2618 // | | | | 3 2619 // | | +--------+ 2620 // V | | old out| Empty on Intel, window on Sparc 2621 // | old |preserve| Must be even aligned. 2622 // | SP-+--------+----> Matcher::_old_SP, even aligned 2623 // | | in | 3 area for Intel ret address 2624 // Owned by |preserve| Empty on Sparc. 2625 // SELF +--------+ 2626 // | | pad2 | 2 pad to align old SP 2627 // | +--------+ 1 2628 // | | locks | 0 2629 // | +--------+----> OptoReg::stack0(), even aligned 2630 // | | pad1 | 11 pad to align new SP 2631 // | +--------+ 2632 // | | | 10 2633 // | | spills | 9 spills 2634 // V | | 8 (pad0 slot for callee) 2635 // -----------+--------+----> Matcher::_out_arg_limit, unaligned 2636 // ^ | out | 7 2637 // | | args | 6 Holes in outgoing args owned by CALLEE 2638 // Owned by +--------+ 2639 // CALLEE | new out| 6 Empty on Intel, window on Sparc 2640 // | new |preserve| Must be even-aligned. 2641 // | SP-+--------+----> Matcher::_new_SP, even aligned 2642 // | | | 2643 // 2644 // Note 1: Only region 8-11 is determined by the allocator. Region 0-5 is 2645 // known from SELF's arguments and the Java calling convention. 2646 // Region 6-7 is determined per call site. 2647 // Note 2: If the calling convention leaves holes in the incoming argument 2648 // area, those holes are owned by SELF. Holes in the outgoing area 2649 // are owned by the CALLEE. Holes should not be nessecary in the 2650 // incoming area, as the Java calling convention is completely under 2651 // the control of the AD file. Doubles can be sorted and packed to 2652 // avoid holes. Holes in the outgoing arguments may be nessecary for 2653 // varargs C calling conventions. 2654 // Note 3: Region 0-3 is even aligned, with pad2 as needed. Region 3-5 is 2655 // even aligned with pad0 as needed. 2656 // Region 6 is even aligned. Region 6-7 is NOT even aligned; 2657 // region 6-11 is even aligned; it may be padded out more so that 2658 // the region from SP to FP meets the minimum stack alignment. 2659 // Note 4: For I2C adapters, the incoming FP may not meet the minimum stack 2660 // alignment. Region 11, pad1, may be dynamically extended so that 2661 // SP meets the minimum alignment. 2662 2663 frame 2664 %{ 2665 // What direction does stack grow in (assumed to be same for C & Java) 2666 stack_direction(TOWARDS_LOW); 2667 2668 // These three registers define part of the calling convention 2669 // between compiled code and the interpreter. 2670 inline_cache_reg(RAX); // Inline Cache Register 2671 interpreter_method_oop_reg(RBX); // Method Oop Register when 2672 // calling interpreter 2673 2674 // Optional: name the operand used by cisc-spilling to access 2675 // [stack_pointer + offset] 2676 cisc_spilling_operand_name(indOffset32); 2677 2678 // Number of stack slots consumed by locking an object 2679 sync_stack_slots(2); 2680 2681 // Compiled code's Frame Pointer 2682 frame_pointer(RSP); 2683 2684 // Interpreter stores its frame pointer in a register which is 2685 // stored to the stack by I2CAdaptors. 2686 // I2CAdaptors convert from interpreted java to compiled java. 2687 interpreter_frame_pointer(RBP); 2688 2689 // Stack alignment requirement 2690 stack_alignment(StackAlignmentInBytes); // Alignment size in bytes (128-bit -> 16 bytes) 2691 2692 // Number of stack slots between incoming argument block and the start of 2693 // a new frame. The PROLOG must add this many slots to the stack. The 2694 // EPILOG must remove this many slots. amd64 needs two slots for 2695 // return address. 2696 in_preserve_stack_slots(4 + 2 * VerifyStackAtCalls); 2697 2698 // Number of outgoing stack slots killed above the out_preserve_stack_slots 2699 // for calls to C. Supports the var-args backing area for register parms. 2700 varargs_C_out_slots_killed(frame::arg_reg_save_area_bytes/BytesPerInt); 2701 2702 // The after-PROLOG location of the return address. Location of 2703 // return address specifies a type (REG or STACK) and a number 2704 // representing the register number (i.e. - use a register name) or 2705 // stack slot. 2706 // Ret Addr is on stack in slot 0 if no locks or verification or alignment. 2707 // Otherwise, it is above the locks and verification slot and alignment word 2708 return_addr(STACK - 2 + 2709 round_to((Compile::current()->in_preserve_stack_slots() + 2710 Compile::current()->fixed_slots()), 2711 stack_alignment_in_slots())); 2712 2713 // Body of function which returns an integer array locating 2714 // arguments either in registers or in stack slots. Passed an array 2715 // of ideal registers called "sig" and a "length" count. Stack-slot 2716 // offsets are based on outgoing arguments, i.e. a CALLER setting up 2717 // arguments for a CALLEE. Incoming stack arguments are 2718 // automatically biased by the preserve_stack_slots field above. 2719 2720 calling_convention 2721 %{ 2722 // No difference between ingoing/outgoing just pass false 2723 SharedRuntime::java_calling_convention(sig_bt, regs, length, false); 2724 %} 2725 2726 c_calling_convention 2727 %{ 2728 // This is obviously always outgoing 2729 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); 2730 %} 2731 2732 // Location of compiled Java return values. Same as C for now. 2733 return_value 2734 %{ 2735 assert(ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, 2736 "only return normal values"); 2737 2738 static const int lo[Op_RegL + 1] = { 2739 0, 2740 0, 2741 RAX_num, // Op_RegN 2742 RAX_num, // Op_RegI 2743 RAX_num, // Op_RegP 2744 XMM0_num, // Op_RegF 2745 XMM0_num, // Op_RegD 2746 RAX_num // Op_RegL 2747 }; 2748 static const int hi[Op_RegL + 1] = { 2749 0, 2750 0, 2751 OptoReg::Bad, // Op_RegN 2752 OptoReg::Bad, // Op_RegI 2753 RAX_H_num, // Op_RegP 2754 OptoReg::Bad, // Op_RegF 2755 XMM0b_num, // Op_RegD 2756 RAX_H_num // Op_RegL 2757 }; 2758 // Excluded flags and vector registers. 2759 assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type"); 2760 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 2761 %} 2762 %} 2763 2764 //----------ATTRIBUTES--------------------------------------------------------- 2765 //----------Operand Attributes------------------------------------------------- 2766 op_attrib op_cost(0); // Required cost attribute 2767 2768 //----------Instruction Attributes--------------------------------------------- 2769 ins_attrib ins_cost(100); // Required cost attribute 2770 ins_attrib ins_size(8); // Required size attribute (in bits) 2771 ins_attrib ins_short_branch(0); // Required flag: is this instruction 2772 // a non-matching short branch variant 2773 // of some long branch? 2774 ins_attrib ins_alignment(1); // Required alignment attribute (must 2775 // be a power of 2) specifies the 2776 // alignment that some part of the 2777 // instruction (not necessarily the 2778 // start) requires. If > 1, a 2779 // compute_padding() function must be 2780 // provided for the instruction 2781 2782 //----------OPERANDS----------------------------------------------------------- 2783 // Operand definitions must precede instruction definitions for correct parsing 2784 // in the ADLC because operands constitute user defined types which are used in 2785 // instruction definitions. 2786 2787 //----------Simple Operands---------------------------------------------------- 2788 // Immediate Operands 2789 // Integer Immediate 2790 operand immI() 2791 %{ 2792 match(ConI); 2793 2794 op_cost(10); 2795 format %{ %} 2796 interface(CONST_INTER); 2797 %} 2798 2799 // Constant for test vs zero 2800 operand immI0() 2801 %{ 2802 predicate(n->get_int() == 0); 2803 match(ConI); 2804 2805 op_cost(0); 2806 format %{ %} 2807 interface(CONST_INTER); 2808 %} 2809 2810 // Constant for increment 2811 operand immI1() 2812 %{ 2813 predicate(n->get_int() == 1); 2814 match(ConI); 2815 2816 op_cost(0); 2817 format %{ %} 2818 interface(CONST_INTER); 2819 %} 2820 2821 // Constant for decrement 2822 operand immI_M1() 2823 %{ 2824 predicate(n->get_int() == -1); 2825 match(ConI); 2826 2827 op_cost(0); 2828 format %{ %} 2829 interface(CONST_INTER); 2830 %} 2831 2832 // Valid scale values for addressing modes 2833 operand immI2() 2834 %{ 2835 predicate(0 <= n->get_int() && (n->get_int() <= 3)); 2836 match(ConI); 2837 2838 format %{ %} 2839 interface(CONST_INTER); 2840 %} 2841 2842 operand immI8() 2843 %{ 2844 predicate((-0x80 <= n->get_int()) && (n->get_int() < 0x80)); 2845 match(ConI); 2846 2847 op_cost(5); 2848 format %{ %} 2849 interface(CONST_INTER); 2850 %} 2851 2852 operand immI16() 2853 %{ 2854 predicate((-32768 <= n->get_int()) && (n->get_int() <= 32767)); 2855 match(ConI); 2856 2857 op_cost(10); 2858 format %{ %} 2859 interface(CONST_INTER); 2860 %} 2861 2862 // Int Immediate non-negative 2863 operand immU31() 2864 %{ 2865 predicate(n->get_int() >= 0); 2866 match(ConI); 2867 2868 op_cost(0); 2869 format %{ %} 2870 interface(CONST_INTER); 2871 %} 2872 2873 // Constant for long shifts 2874 operand immI_32() 2875 %{ 2876 predicate( n->get_int() == 32 ); 2877 match(ConI); 2878 2879 op_cost(0); 2880 format %{ %} 2881 interface(CONST_INTER); 2882 %} 2883 2884 // Constant for long shifts 2885 operand immI_64() 2886 %{ 2887 predicate( n->get_int() == 64 ); 2888 match(ConI); 2889 2890 op_cost(0); 2891 format %{ %} 2892 interface(CONST_INTER); 2893 %} 2894 2895 // Pointer Immediate 2896 operand immP() 2897 %{ 2898 match(ConP); 2899 2900 op_cost(10); 2901 format %{ %} 2902 interface(CONST_INTER); 2903 %} 2904 2905 // NULL Pointer Immediate 2906 operand immP0() 2907 %{ 2908 predicate(n->get_ptr() == 0); 2909 match(ConP); 2910 2911 op_cost(5); 2912 format %{ %} 2913 interface(CONST_INTER); 2914 %} 2915 2916 // Pointer Immediate 2917 operand immN() %{ 2918 match(ConN); 2919 2920 op_cost(10); 2921 format %{ %} 2922 interface(CONST_INTER); 2923 %} 2924 2925 operand immNKlass() %{ 2926 match(ConNKlass); 2927 2928 op_cost(10); 2929 format %{ %} 2930 interface(CONST_INTER); 2931 %} 2932 2933 // NULL Pointer Immediate 2934 operand immN0() %{ 2935 predicate(n->get_narrowcon() == 0); 2936 match(ConN); 2937 2938 op_cost(5); 2939 format %{ %} 2940 interface(CONST_INTER); 2941 %} 2942 2943 operand immP31() 2944 %{ 2945 predicate(n->as_Type()->type()->reloc() == relocInfo::none 2946 && (n->get_ptr() >> 31) == 0); 2947 match(ConP); 2948 2949 op_cost(5); 2950 format %{ %} 2951 interface(CONST_INTER); 2952 %} 2953 2954 2955 // Long Immediate 2956 operand immL() 2957 %{ 2958 match(ConL); 2959 2960 op_cost(20); 2961 format %{ %} 2962 interface(CONST_INTER); 2963 %} 2964 2965 // Long Immediate 8-bit 2966 operand immL8() 2967 %{ 2968 predicate(-0x80L <= n->get_long() && n->get_long() < 0x80L); 2969 match(ConL); 2970 2971 op_cost(5); 2972 format %{ %} 2973 interface(CONST_INTER); 2974 %} 2975 2976 // Long Immediate 32-bit unsigned 2977 operand immUL32() 2978 %{ 2979 predicate(n->get_long() == (unsigned int) (n->get_long())); 2980 match(ConL); 2981 2982 op_cost(10); 2983 format %{ %} 2984 interface(CONST_INTER); 2985 %} 2986 2987 // Long Immediate 32-bit signed 2988 operand immL32() 2989 %{ 2990 predicate(n->get_long() == (int) (n->get_long())); 2991 match(ConL); 2992 2993 op_cost(15); 2994 format %{ %} 2995 interface(CONST_INTER); 2996 %} 2997 2998 // Long Immediate zero 2999 operand immL0() 3000 %{ 3001 predicate(n->get_long() == 0L); 3002 match(ConL); 3003 3004 op_cost(10); 3005 format %{ %} 3006 interface(CONST_INTER); 3007 %} 3008 3009 // Constant for increment 3010 operand immL1() 3011 %{ 3012 predicate(n->get_long() == 1); 3013 match(ConL); 3014 3015 format %{ %} 3016 interface(CONST_INTER); 3017 %} 3018 3019 // Constant for decrement 3020 operand immL_M1() 3021 %{ 3022 predicate(n->get_long() == -1); 3023 match(ConL); 3024 3025 format %{ %} 3026 interface(CONST_INTER); 3027 %} 3028 3029 // Long Immediate: the value 10 3030 operand immL10() 3031 %{ 3032 predicate(n->get_long() == 10); 3033 match(ConL); 3034 3035 format %{ %} 3036 interface(CONST_INTER); 3037 %} 3038 3039 // Long immediate from 0 to 127. 3040 // Used for a shorter form of long mul by 10. 3041 operand immL_127() 3042 %{ 3043 predicate(0 <= n->get_long() && n->get_long() < 0x80); 3044 match(ConL); 3045 3046 op_cost(10); 3047 format %{ %} 3048 interface(CONST_INTER); 3049 %} 3050 3051 // Long Immediate: low 32-bit mask 3052 operand immL_32bits() 3053 %{ 3054 predicate(n->get_long() == 0xFFFFFFFFL); 3055 match(ConL); 3056 op_cost(20); 3057 3058 format %{ %} 3059 interface(CONST_INTER); 3060 %} 3061 3062 // Float Immediate zero 3063 operand immF0() 3064 %{ 3065 predicate(jint_cast(n->getf()) == 0); 3066 match(ConF); 3067 3068 op_cost(5); 3069 format %{ %} 3070 interface(CONST_INTER); 3071 %} 3072 3073 // Float Immediate 3074 operand immF() 3075 %{ 3076 match(ConF); 3077 3078 op_cost(15); 3079 format %{ %} 3080 interface(CONST_INTER); 3081 %} 3082 3083 // Double Immediate zero 3084 operand immD0() 3085 %{ 3086 predicate(jlong_cast(n->getd()) == 0); 3087 match(ConD); 3088 3089 op_cost(5); 3090 format %{ %} 3091 interface(CONST_INTER); 3092 %} 3093 3094 // Double Immediate 3095 operand immD() 3096 %{ 3097 match(ConD); 3098 3099 op_cost(15); 3100 format %{ %} 3101 interface(CONST_INTER); 3102 %} 3103 3104 // Immediates for special shifts (sign extend) 3105 3106 // Constants for increment 3107 operand immI_16() 3108 %{ 3109 predicate(n->get_int() == 16); 3110 match(ConI); 3111 3112 format %{ %} 3113 interface(CONST_INTER); 3114 %} 3115 3116 operand immI_24() 3117 %{ 3118 predicate(n->get_int() == 24); 3119 match(ConI); 3120 3121 format %{ %} 3122 interface(CONST_INTER); 3123 %} 3124 3125 // Constant for byte-wide masking 3126 operand immI_255() 3127 %{ 3128 predicate(n->get_int() == 255); 3129 match(ConI); 3130 3131 format %{ %} 3132 interface(CONST_INTER); 3133 %} 3134 3135 // Constant for short-wide masking 3136 operand immI_65535() 3137 %{ 3138 predicate(n->get_int() == 65535); 3139 match(ConI); 3140 3141 format %{ %} 3142 interface(CONST_INTER); 3143 %} 3144 3145 // Constant for byte-wide masking 3146 operand immL_255() 3147 %{ 3148 predicate(n->get_long() == 255); 3149 match(ConL); 3150 3151 format %{ %} 3152 interface(CONST_INTER); 3153 %} 3154 3155 // Constant for short-wide masking 3156 operand immL_65535() 3157 %{ 3158 predicate(n->get_long() == 65535); 3159 match(ConL); 3160 3161 format %{ %} 3162 interface(CONST_INTER); 3163 %} 3164 3165 // Register Operands 3166 // Integer Register 3167 operand rRegI() 3168 %{ 3169 constraint(ALLOC_IN_RC(int_reg)); 3170 match(RegI); 3171 3172 match(rax_RegI); 3173 match(rbx_RegI); 3174 match(rcx_RegI); 3175 match(rdx_RegI); 3176 match(rdi_RegI); 3177 3178 format %{ %} 3179 interface(REG_INTER); 3180 %} 3181 3182 // Special Registers 3183 operand rax_RegI() 3184 %{ 3185 constraint(ALLOC_IN_RC(int_rax_reg)); 3186 match(RegI); 3187 match(rRegI); 3188 3189 format %{ "RAX" %} 3190 interface(REG_INTER); 3191 %} 3192 3193 // Special Registers 3194 operand rbx_RegI() 3195 %{ 3196 constraint(ALLOC_IN_RC(int_rbx_reg)); 3197 match(RegI); 3198 match(rRegI); 3199 3200 format %{ "RBX" %} 3201 interface(REG_INTER); 3202 %} 3203 3204 operand rcx_RegI() 3205 %{ 3206 constraint(ALLOC_IN_RC(int_rcx_reg)); 3207 match(RegI); 3208 match(rRegI); 3209 3210 format %{ "RCX" %} 3211 interface(REG_INTER); 3212 %} 3213 3214 operand rdx_RegI() 3215 %{ 3216 constraint(ALLOC_IN_RC(int_rdx_reg)); 3217 match(RegI); 3218 match(rRegI); 3219 3220 format %{ "RDX" %} 3221 interface(REG_INTER); 3222 %} 3223 3224 operand rdi_RegI() 3225 %{ 3226 constraint(ALLOC_IN_RC(int_rdi_reg)); 3227 match(RegI); 3228 match(rRegI); 3229 3230 format %{ "RDI" %} 3231 interface(REG_INTER); 3232 %} 3233 3234 operand no_rcx_RegI() 3235 %{ 3236 constraint(ALLOC_IN_RC(int_no_rcx_reg)); 3237 match(RegI); 3238 match(rax_RegI); 3239 match(rbx_RegI); 3240 match(rdx_RegI); 3241 match(rdi_RegI); 3242 3243 format %{ %} 3244 interface(REG_INTER); 3245 %} 3246 3247 operand no_rax_rdx_RegI() 3248 %{ 3249 constraint(ALLOC_IN_RC(int_no_rax_rdx_reg)); 3250 match(RegI); 3251 match(rbx_RegI); 3252 match(rcx_RegI); 3253 match(rdi_RegI); 3254 3255 format %{ %} 3256 interface(REG_INTER); 3257 %} 3258 3259 // Pointer Register 3260 operand any_RegP() 3261 %{ 3262 constraint(ALLOC_IN_RC(any_reg)); 3263 match(RegP); 3264 match(rax_RegP); 3265 match(rbx_RegP); 3266 match(rdi_RegP); 3267 match(rsi_RegP); 3268 match(rbp_RegP); 3269 match(r15_RegP); 3270 match(rRegP); 3271 3272 format %{ %} 3273 interface(REG_INTER); 3274 %} 3275 3276 operand rRegP() 3277 %{ 3278 constraint(ALLOC_IN_RC(ptr_reg)); 3279 match(RegP); 3280 match(rax_RegP); 3281 match(rbx_RegP); 3282 match(rdi_RegP); 3283 match(rsi_RegP); 3284 match(rbp_RegP); 3285 match(r15_RegP); // See Q&A below about r15_RegP. 3286 3287 format %{ %} 3288 interface(REG_INTER); 3289 %} 3290 3291 operand rRegN() %{ 3292 constraint(ALLOC_IN_RC(int_reg)); 3293 match(RegN); 3294 3295 format %{ %} 3296 interface(REG_INTER); 3297 %} 3298 3299 // Question: Why is r15_RegP (the read-only TLS register) a match for rRegP? 3300 // Answer: Operand match rules govern the DFA as it processes instruction inputs. 3301 // It's fine for an instruction input which expects rRegP to match a r15_RegP. 3302 // The output of an instruction is controlled by the allocator, which respects 3303 // register class masks, not match rules. Unless an instruction mentions 3304 // r15_RegP or any_RegP explicitly as its output, r15 will not be considered 3305 // by the allocator as an input. 3306 3307 operand no_rax_RegP() 3308 %{ 3309 constraint(ALLOC_IN_RC(ptr_no_rax_reg)); 3310 match(RegP); 3311 match(rbx_RegP); 3312 match(rsi_RegP); 3313 match(rdi_RegP); 3314 3315 format %{ %} 3316 interface(REG_INTER); 3317 %} 3318 3319 operand no_rbp_RegP() 3320 %{ 3321 constraint(ALLOC_IN_RC(ptr_no_rbp_reg)); 3322 match(RegP); 3323 match(rbx_RegP); 3324 match(rsi_RegP); 3325 match(rdi_RegP); 3326 3327 format %{ %} 3328 interface(REG_INTER); 3329 %} 3330 3331 operand no_rax_rbx_RegP() 3332 %{ 3333 constraint(ALLOC_IN_RC(ptr_no_rax_rbx_reg)); 3334 match(RegP); 3335 match(rsi_RegP); 3336 match(rdi_RegP); 3337 3338 format %{ %} 3339 interface(REG_INTER); 3340 %} 3341 3342 // Special Registers 3343 // Return a pointer value 3344 operand rax_RegP() 3345 %{ 3346 constraint(ALLOC_IN_RC(ptr_rax_reg)); 3347 match(RegP); 3348 match(rRegP); 3349 3350 format %{ %} 3351 interface(REG_INTER); 3352 %} 3353 3354 // Special Registers 3355 // Return a compressed pointer value 3356 operand rax_RegN() 3357 %{ 3358 constraint(ALLOC_IN_RC(int_rax_reg)); 3359 match(RegN); 3360 match(rRegN); 3361 3362 format %{ %} 3363 interface(REG_INTER); 3364 %} 3365 3366 // Used in AtomicAdd 3367 operand rbx_RegP() 3368 %{ 3369 constraint(ALLOC_IN_RC(ptr_rbx_reg)); 3370 match(RegP); 3371 match(rRegP); 3372 3373 format %{ %} 3374 interface(REG_INTER); 3375 %} 3376 3377 operand rsi_RegP() 3378 %{ 3379 constraint(ALLOC_IN_RC(ptr_rsi_reg)); 3380 match(RegP); 3381 match(rRegP); 3382 3383 format %{ %} 3384 interface(REG_INTER); 3385 %} 3386 3387 // Used in rep stosq 3388 operand rdi_RegP() 3389 %{ 3390 constraint(ALLOC_IN_RC(ptr_rdi_reg)); 3391 match(RegP); 3392 match(rRegP); 3393 3394 format %{ %} 3395 interface(REG_INTER); 3396 %} 3397 3398 operand rbp_RegP() 3399 %{ 3400 constraint(ALLOC_IN_RC(ptr_rbp_reg)); 3401 match(RegP); 3402 match(rRegP); 3403 3404 format %{ %} 3405 interface(REG_INTER); 3406 %} 3407 3408 operand r15_RegP() 3409 %{ 3410 constraint(ALLOC_IN_RC(ptr_r15_reg)); 3411 match(RegP); 3412 match(rRegP); 3413 3414 format %{ %} 3415 interface(REG_INTER); 3416 %} 3417 3418 operand rRegL() 3419 %{ 3420 constraint(ALLOC_IN_RC(long_reg)); 3421 match(RegL); 3422 match(rax_RegL); 3423 match(rdx_RegL); 3424 3425 format %{ %} 3426 interface(REG_INTER); 3427 %} 3428 3429 // Special Registers 3430 operand no_rax_rdx_RegL() 3431 %{ 3432 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3433 match(RegL); 3434 match(rRegL); 3435 3436 format %{ %} 3437 interface(REG_INTER); 3438 %} 3439 3440 operand no_rax_RegL() 3441 %{ 3442 constraint(ALLOC_IN_RC(long_no_rax_rdx_reg)); 3443 match(RegL); 3444 match(rRegL); 3445 match(rdx_RegL); 3446 3447 format %{ %} 3448 interface(REG_INTER); 3449 %} 3450 3451 operand no_rcx_RegL() 3452 %{ 3453 constraint(ALLOC_IN_RC(long_no_rcx_reg)); 3454 match(RegL); 3455 match(rRegL); 3456 3457 format %{ %} 3458 interface(REG_INTER); 3459 %} 3460 3461 operand rax_RegL() 3462 %{ 3463 constraint(ALLOC_IN_RC(long_rax_reg)); 3464 match(RegL); 3465 match(rRegL); 3466 3467 format %{ "RAX" %} 3468 interface(REG_INTER); 3469 %} 3470 3471 operand rcx_RegL() 3472 %{ 3473 constraint(ALLOC_IN_RC(long_rcx_reg)); 3474 match(RegL); 3475 match(rRegL); 3476 3477 format %{ %} 3478 interface(REG_INTER); 3479 %} 3480 3481 operand rdx_RegL() 3482 %{ 3483 constraint(ALLOC_IN_RC(long_rdx_reg)); 3484 match(RegL); 3485 match(rRegL); 3486 3487 format %{ %} 3488 interface(REG_INTER); 3489 %} 3490 3491 // Flags register, used as output of compare instructions 3492 operand rFlagsReg() 3493 %{ 3494 constraint(ALLOC_IN_RC(int_flags)); 3495 match(RegFlags); 3496 3497 format %{ "RFLAGS" %} 3498 interface(REG_INTER); 3499 %} 3500 3501 // Flags register, used as output of FLOATING POINT compare instructions 3502 operand rFlagsRegU() 3503 %{ 3504 constraint(ALLOC_IN_RC(int_flags)); 3505 match(RegFlags); 3506 3507 format %{ "RFLAGS_U" %} 3508 interface(REG_INTER); 3509 %} 3510 3511 operand rFlagsRegUCF() %{ 3512 constraint(ALLOC_IN_RC(int_flags)); 3513 match(RegFlags); 3514 predicate(false); 3515 3516 format %{ "RFLAGS_U_CF" %} 3517 interface(REG_INTER); 3518 %} 3519 3520 // Float register operands 3521 operand regF() 3522 %{ 3523 constraint(ALLOC_IN_RC(float_reg)); 3524 match(RegF); 3525 3526 format %{ %} 3527 interface(REG_INTER); 3528 %} 3529 3530 // Double register operands 3531 operand regD() 3532 %{ 3533 constraint(ALLOC_IN_RC(double_reg)); 3534 match(RegD); 3535 3536 format %{ %} 3537 interface(REG_INTER); 3538 %} 3539 3540 //----------Memory Operands---------------------------------------------------- 3541 // Direct Memory Operand 3542 // operand direct(immP addr) 3543 // %{ 3544 // match(addr); 3545 3546 // format %{ "[$addr]" %} 3547 // interface(MEMORY_INTER) %{ 3548 // base(0xFFFFFFFF); 3549 // index(0x4); 3550 // scale(0x0); 3551 // disp($addr); 3552 // %} 3553 // %} 3554 3555 // Indirect Memory Operand 3556 operand indirect(any_RegP reg) 3557 %{ 3558 constraint(ALLOC_IN_RC(ptr_reg)); 3559 match(reg); 3560 3561 format %{ "[$reg]" %} 3562 interface(MEMORY_INTER) %{ 3563 base($reg); 3564 index(0x4); 3565 scale(0x0); 3566 disp(0x0); 3567 %} 3568 %} 3569 3570 // Indirect Memory Plus Short Offset Operand 3571 operand indOffset8(any_RegP reg, immL8 off) 3572 %{ 3573 constraint(ALLOC_IN_RC(ptr_reg)); 3574 match(AddP reg off); 3575 3576 format %{ "[$reg + $off (8-bit)]" %} 3577 interface(MEMORY_INTER) %{ 3578 base($reg); 3579 index(0x4); 3580 scale(0x0); 3581 disp($off); 3582 %} 3583 %} 3584 3585 // Indirect Memory Plus Long Offset Operand 3586 operand indOffset32(any_RegP reg, immL32 off) 3587 %{ 3588 constraint(ALLOC_IN_RC(ptr_reg)); 3589 match(AddP reg off); 3590 3591 format %{ "[$reg + $off (32-bit)]" %} 3592 interface(MEMORY_INTER) %{ 3593 base($reg); 3594 index(0x4); 3595 scale(0x0); 3596 disp($off); 3597 %} 3598 %} 3599 3600 // Indirect Memory Plus Index Register Plus Offset Operand 3601 operand indIndexOffset(any_RegP reg, rRegL lreg, immL32 off) 3602 %{ 3603 constraint(ALLOC_IN_RC(ptr_reg)); 3604 match(AddP (AddP reg lreg) off); 3605 3606 op_cost(10); 3607 format %{"[$reg + $off + $lreg]" %} 3608 interface(MEMORY_INTER) %{ 3609 base($reg); 3610 index($lreg); 3611 scale(0x0); 3612 disp($off); 3613 %} 3614 %} 3615 3616 // Indirect Memory Plus Index Register Plus Offset Operand 3617 operand indIndex(any_RegP reg, rRegL lreg) 3618 %{ 3619 constraint(ALLOC_IN_RC(ptr_reg)); 3620 match(AddP reg lreg); 3621 3622 op_cost(10); 3623 format %{"[$reg + $lreg]" %} 3624 interface(MEMORY_INTER) %{ 3625 base($reg); 3626 index($lreg); 3627 scale(0x0); 3628 disp(0x0); 3629 %} 3630 %} 3631 3632 // Indirect Memory Times Scale Plus Index Register 3633 operand indIndexScale(any_RegP reg, rRegL lreg, immI2 scale) 3634 %{ 3635 constraint(ALLOC_IN_RC(ptr_reg)); 3636 match(AddP reg (LShiftL lreg scale)); 3637 3638 op_cost(10); 3639 format %{"[$reg + $lreg << $scale]" %} 3640 interface(MEMORY_INTER) %{ 3641 base($reg); 3642 index($lreg); 3643 scale($scale); 3644 disp(0x0); 3645 %} 3646 %} 3647 3648 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3649 operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale) 3650 %{ 3651 constraint(ALLOC_IN_RC(ptr_reg)); 3652 match(AddP (AddP reg (LShiftL lreg scale)) off); 3653 3654 op_cost(10); 3655 format %{"[$reg + $off + $lreg << $scale]" %} 3656 interface(MEMORY_INTER) %{ 3657 base($reg); 3658 index($lreg); 3659 scale($scale); 3660 disp($off); 3661 %} 3662 %} 3663 3664 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3665 operand indPosIndexScaleOffset(any_RegP reg, immL32 off, rRegI idx, immI2 scale) 3666 %{ 3667 constraint(ALLOC_IN_RC(ptr_reg)); 3668 predicate(n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3669 match(AddP (AddP reg (LShiftL (ConvI2L idx) scale)) off); 3670 3671 op_cost(10); 3672 format %{"[$reg + $off + $idx << $scale]" %} 3673 interface(MEMORY_INTER) %{ 3674 base($reg); 3675 index($idx); 3676 scale($scale); 3677 disp($off); 3678 %} 3679 %} 3680 3681 // Indirect Narrow Oop Plus Offset Operand 3682 // Note: x86 architecture doesn't support "scale * index + offset" without a base 3683 // we can't free r12 even with Universe::narrow_oop_base() == NULL. 3684 operand indCompressedOopOffset(rRegN reg, immL32 off) %{ 3685 predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8)); 3686 constraint(ALLOC_IN_RC(ptr_reg)); 3687 match(AddP (DecodeN reg) off); 3688 3689 op_cost(10); 3690 format %{"[R12 + $reg << 3 + $off] (compressed oop addressing)" %} 3691 interface(MEMORY_INTER) %{ 3692 base(0xc); // R12 3693 index($reg); 3694 scale(0x3); 3695 disp($off); 3696 %} 3697 %} 3698 3699 // Indirect Memory Operand 3700 operand indirectNarrow(rRegN reg) 3701 %{ 3702 predicate(Universe::narrow_oop_shift() == 0); 3703 constraint(ALLOC_IN_RC(ptr_reg)); 3704 match(DecodeN reg); 3705 3706 format %{ "[$reg]" %} 3707 interface(MEMORY_INTER) %{ 3708 base($reg); 3709 index(0x4); 3710 scale(0x0); 3711 disp(0x0); 3712 %} 3713 %} 3714 3715 // Indirect Memory Plus Short Offset Operand 3716 operand indOffset8Narrow(rRegN reg, immL8 off) 3717 %{ 3718 predicate(Universe::narrow_oop_shift() == 0); 3719 constraint(ALLOC_IN_RC(ptr_reg)); 3720 match(AddP (DecodeN reg) off); 3721 3722 format %{ "[$reg + $off (8-bit)]" %} 3723 interface(MEMORY_INTER) %{ 3724 base($reg); 3725 index(0x4); 3726 scale(0x0); 3727 disp($off); 3728 %} 3729 %} 3730 3731 // Indirect Memory Plus Long Offset Operand 3732 operand indOffset32Narrow(rRegN reg, immL32 off) 3733 %{ 3734 predicate(Universe::narrow_oop_shift() == 0); 3735 constraint(ALLOC_IN_RC(ptr_reg)); 3736 match(AddP (DecodeN reg) off); 3737 3738 format %{ "[$reg + $off (32-bit)]" %} 3739 interface(MEMORY_INTER) %{ 3740 base($reg); 3741 index(0x4); 3742 scale(0x0); 3743 disp($off); 3744 %} 3745 %} 3746 3747 // Indirect Memory Plus Index Register Plus Offset Operand 3748 operand indIndexOffsetNarrow(rRegN reg, rRegL lreg, immL32 off) 3749 %{ 3750 predicate(Universe::narrow_oop_shift() == 0); 3751 constraint(ALLOC_IN_RC(ptr_reg)); 3752 match(AddP (AddP (DecodeN reg) lreg) off); 3753 3754 op_cost(10); 3755 format %{"[$reg + $off + $lreg]" %} 3756 interface(MEMORY_INTER) %{ 3757 base($reg); 3758 index($lreg); 3759 scale(0x0); 3760 disp($off); 3761 %} 3762 %} 3763 3764 // Indirect Memory Plus Index Register Plus Offset Operand 3765 operand indIndexNarrow(rRegN reg, rRegL lreg) 3766 %{ 3767 predicate(Universe::narrow_oop_shift() == 0); 3768 constraint(ALLOC_IN_RC(ptr_reg)); 3769 match(AddP (DecodeN reg) lreg); 3770 3771 op_cost(10); 3772 format %{"[$reg + $lreg]" %} 3773 interface(MEMORY_INTER) %{ 3774 base($reg); 3775 index($lreg); 3776 scale(0x0); 3777 disp(0x0); 3778 %} 3779 %} 3780 3781 // Indirect Memory Times Scale Plus Index Register 3782 operand indIndexScaleNarrow(rRegN reg, rRegL lreg, immI2 scale) 3783 %{ 3784 predicate(Universe::narrow_oop_shift() == 0); 3785 constraint(ALLOC_IN_RC(ptr_reg)); 3786 match(AddP (DecodeN reg) (LShiftL lreg scale)); 3787 3788 op_cost(10); 3789 format %{"[$reg + $lreg << $scale]" %} 3790 interface(MEMORY_INTER) %{ 3791 base($reg); 3792 index($lreg); 3793 scale($scale); 3794 disp(0x0); 3795 %} 3796 %} 3797 3798 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand 3799 operand indIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegL lreg, immI2 scale) 3800 %{ 3801 predicate(Universe::narrow_oop_shift() == 0); 3802 constraint(ALLOC_IN_RC(ptr_reg)); 3803 match(AddP (AddP (DecodeN reg) (LShiftL lreg scale)) off); 3804 3805 op_cost(10); 3806 format %{"[$reg + $off + $lreg << $scale]" %} 3807 interface(MEMORY_INTER) %{ 3808 base($reg); 3809 index($lreg); 3810 scale($scale); 3811 disp($off); 3812 %} 3813 %} 3814 3815 // Indirect Memory Times Scale Plus Positive Index Register Plus Offset Operand 3816 operand indPosIndexScaleOffsetNarrow(rRegN reg, immL32 off, rRegI idx, immI2 scale) 3817 %{ 3818 constraint(ALLOC_IN_RC(ptr_reg)); 3819 predicate(Universe::narrow_oop_shift() == 0 && n->in(2)->in(3)->in(1)->as_Type()->type()->is_long()->_lo >= 0); 3820 match(AddP (AddP (DecodeN reg) (LShiftL (ConvI2L idx) scale)) off); 3821 3822 op_cost(10); 3823 format %{"[$reg + $off + $idx << $scale]" %} 3824 interface(MEMORY_INTER) %{ 3825 base($reg); 3826 index($idx); 3827 scale($scale); 3828 disp($off); 3829 %} 3830 %} 3831 3832 //----------Special Memory Operands-------------------------------------------- 3833 // Stack Slot Operand - This operand is used for loading and storing temporary 3834 // values on the stack where a match requires a value to 3835 // flow through memory. 3836 operand stackSlotP(sRegP reg) 3837 %{ 3838 constraint(ALLOC_IN_RC(stack_slots)); 3839 // No match rule because this operand is only generated in matching 3840 3841 format %{ "[$reg]" %} 3842 interface(MEMORY_INTER) %{ 3843 base(0x4); // RSP 3844 index(0x4); // No Index 3845 scale(0x0); // No Scale 3846 disp($reg); // Stack Offset 3847 %} 3848 %} 3849 3850 operand stackSlotI(sRegI reg) 3851 %{ 3852 constraint(ALLOC_IN_RC(stack_slots)); 3853 // No match rule because this operand is only generated in matching 3854 3855 format %{ "[$reg]" %} 3856 interface(MEMORY_INTER) %{ 3857 base(0x4); // RSP 3858 index(0x4); // No Index 3859 scale(0x0); // No Scale 3860 disp($reg); // Stack Offset 3861 %} 3862 %} 3863 3864 operand stackSlotF(sRegF reg) 3865 %{ 3866 constraint(ALLOC_IN_RC(stack_slots)); 3867 // No match rule because this operand is only generated in matching 3868 3869 format %{ "[$reg]" %} 3870 interface(MEMORY_INTER) %{ 3871 base(0x4); // RSP 3872 index(0x4); // No Index 3873 scale(0x0); // No Scale 3874 disp($reg); // Stack Offset 3875 %} 3876 %} 3877 3878 operand stackSlotD(sRegD reg) 3879 %{ 3880 constraint(ALLOC_IN_RC(stack_slots)); 3881 // No match rule because this operand is only generated in matching 3882 3883 format %{ "[$reg]" %} 3884 interface(MEMORY_INTER) %{ 3885 base(0x4); // RSP 3886 index(0x4); // No Index 3887 scale(0x0); // No Scale 3888 disp($reg); // Stack Offset 3889 %} 3890 %} 3891 operand stackSlotL(sRegL reg) 3892 %{ 3893 constraint(ALLOC_IN_RC(stack_slots)); 3894 // No match rule because this operand is only generated in matching 3895 3896 format %{ "[$reg]" %} 3897 interface(MEMORY_INTER) %{ 3898 base(0x4); // RSP 3899 index(0x4); // No Index 3900 scale(0x0); // No Scale 3901 disp($reg); // Stack Offset 3902 %} 3903 %} 3904 3905 //----------Conditional Branch Operands---------------------------------------- 3906 // Comparison Op - This is the operation of the comparison, and is limited to 3907 // the following set of codes: 3908 // L (<), LE (<=), G (>), GE (>=), E (==), NE (!=) 3909 // 3910 // Other attributes of the comparison, such as unsignedness, are specified 3911 // by the comparison instruction that sets a condition code flags register. 3912 // That result is represented by a flags operand whose subtype is appropriate 3913 // to the unsignedness (etc.) of the comparison. 3914 // 3915 // Later, the instruction which matches both the Comparison Op (a Bool) and 3916 // the flags (produced by the Cmp) specifies the coding of the comparison op 3917 // by matching a specific subtype of Bool operand below, such as cmpOpU. 3918 3919 // Comparision Code 3920 operand cmpOp() 3921 %{ 3922 match(Bool); 3923 3924 format %{ "" %} 3925 interface(COND_INTER) %{ 3926 equal(0x4, "e"); 3927 not_equal(0x5, "ne"); 3928 less(0xC, "l"); 3929 greater_equal(0xD, "ge"); 3930 less_equal(0xE, "le"); 3931 greater(0xF, "g"); 3932 overflow(0x0, "o"); 3933 no_overflow(0x1, "no"); 3934 %} 3935 %} 3936 3937 // Comparison Code, unsigned compare. Used by FP also, with 3938 // C2 (unordered) turned into GT or LT already. The other bits 3939 // C0 and C3 are turned into Carry & Zero flags. 3940 operand cmpOpU() 3941 %{ 3942 match(Bool); 3943 3944 format %{ "" %} 3945 interface(COND_INTER) %{ 3946 equal(0x4, "e"); 3947 not_equal(0x5, "ne"); 3948 less(0x2, "b"); 3949 greater_equal(0x3, "nb"); 3950 less_equal(0x6, "be"); 3951 greater(0x7, "nbe"); 3952 overflow(0x0, "o"); 3953 no_overflow(0x1, "no"); 3954 %} 3955 %} 3956 3957 3958 // Floating comparisons that don't require any fixup for the unordered case 3959 operand cmpOpUCF() %{ 3960 match(Bool); 3961 predicate(n->as_Bool()->_test._test == BoolTest::lt || 3962 n->as_Bool()->_test._test == BoolTest::ge || 3963 n->as_Bool()->_test._test == BoolTest::le || 3964 n->as_Bool()->_test._test == BoolTest::gt); 3965 format %{ "" %} 3966 interface(COND_INTER) %{ 3967 equal(0x4, "e"); 3968 not_equal(0x5, "ne"); 3969 less(0x2, "b"); 3970 greater_equal(0x3, "nb"); 3971 less_equal(0x6, "be"); 3972 greater(0x7, "nbe"); 3973 overflow(0x0, "o"); 3974 no_overflow(0x1, "no"); 3975 %} 3976 %} 3977 3978 3979 // Floating comparisons that can be fixed up with extra conditional jumps 3980 operand cmpOpUCF2() %{ 3981 match(Bool); 3982 predicate(n->as_Bool()->_test._test == BoolTest::ne || 3983 n->as_Bool()->_test._test == BoolTest::eq); 3984 format %{ "" %} 3985 interface(COND_INTER) %{ 3986 equal(0x4, "e"); 3987 not_equal(0x5, "ne"); 3988 less(0x2, "b"); 3989 greater_equal(0x3, "nb"); 3990 less_equal(0x6, "be"); 3991 greater(0x7, "nbe"); 3992 overflow(0x0, "o"); 3993 no_overflow(0x1, "no"); 3994 %} 3995 %} 3996 3997 3998 //----------OPERAND CLASSES---------------------------------------------------- 3999 // Operand Classes are groups of operands that are used as to simplify 4000 // instruction definitions by not requiring the AD writer to specify separate 4001 // instructions for every form of operand when the instruction accepts 4002 // multiple operand types with the same basic encoding and format. The classic 4003 // case of this is memory operands. 4004 4005 opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, 4006 indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, 4007 indCompressedOopOffset, 4008 indirectNarrow, indOffset8Narrow, indOffset32Narrow, 4009 indIndexOffsetNarrow, indIndexNarrow, indIndexScaleNarrow, 4010 indIndexScaleOffsetNarrow, indPosIndexScaleOffsetNarrow); 4011 4012 //----------PIPELINE----------------------------------------------------------- 4013 // Rules which define the behavior of the target architectures pipeline. 4014 pipeline %{ 4015 4016 //----------ATTRIBUTES--------------------------------------------------------- 4017 attributes %{ 4018 variable_size_instructions; // Fixed size instructions 4019 max_instructions_per_bundle = 3; // Up to 3 instructions per bundle 4020 instruction_unit_size = 1; // An instruction is 1 bytes long 4021 instruction_fetch_unit_size = 16; // The processor fetches one line 4022 instruction_fetch_units = 1; // of 16 bytes 4023 4024 // List of nop instructions 4025 nops( MachNop ); 4026 %} 4027 4028 //----------RESOURCES---------------------------------------------------------- 4029 // Resources are the functional units available to the machine 4030 4031 // Generic P2/P3 pipeline 4032 // 3 decoders, only D0 handles big operands; a "bundle" is the limit of 4033 // 3 instructions decoded per cycle. 4034 // 2 load/store ops per cycle, 1 branch, 1 FPU, 4035 // 3 ALU op, only ALU0 handles mul instructions. 4036 resources( D0, D1, D2, DECODE = D0 | D1 | D2, 4037 MS0, MS1, MS2, MEM = MS0 | MS1 | MS2, 4038 BR, FPU, 4039 ALU0, ALU1, ALU2, ALU = ALU0 | ALU1 | ALU2); 4040 4041 //----------PIPELINE DESCRIPTION----------------------------------------------- 4042 // Pipeline Description specifies the stages in the machine's pipeline 4043 4044 // Generic P2/P3 pipeline 4045 pipe_desc(S0, S1, S2, S3, S4, S5); 4046 4047 //----------PIPELINE CLASSES--------------------------------------------------- 4048 // Pipeline Classes describe the stages in which input and output are 4049 // referenced by the hardware pipeline. 4050 4051 // Naming convention: ialu or fpu 4052 // Then: _reg 4053 // Then: _reg if there is a 2nd register 4054 // Then: _long if it's a pair of instructions implementing a long 4055 // Then: _fat if it requires the big decoder 4056 // Or: _mem if it requires the big decoder and a memory unit. 4057 4058 // Integer ALU reg operation 4059 pipe_class ialu_reg(rRegI dst) 4060 %{ 4061 single_instruction; 4062 dst : S4(write); 4063 dst : S3(read); 4064 DECODE : S0; // any decoder 4065 ALU : S3; // any alu 4066 %} 4067 4068 // Long ALU reg operation 4069 pipe_class ialu_reg_long(rRegL dst) 4070 %{ 4071 instruction_count(2); 4072 dst : S4(write); 4073 dst : S3(read); 4074 DECODE : S0(2); // any 2 decoders 4075 ALU : S3(2); // both alus 4076 %} 4077 4078 // Integer ALU reg operation using big decoder 4079 pipe_class ialu_reg_fat(rRegI dst) 4080 %{ 4081 single_instruction; 4082 dst : S4(write); 4083 dst : S3(read); 4084 D0 : S0; // big decoder only 4085 ALU : S3; // any alu 4086 %} 4087 4088 // Long ALU reg operation using big decoder 4089 pipe_class ialu_reg_long_fat(rRegL dst) 4090 %{ 4091 instruction_count(2); 4092 dst : S4(write); 4093 dst : S3(read); 4094 D0 : S0(2); // big decoder only; twice 4095 ALU : S3(2); // any 2 alus 4096 %} 4097 4098 // Integer ALU reg-reg operation 4099 pipe_class ialu_reg_reg(rRegI dst, rRegI src) 4100 %{ 4101 single_instruction; 4102 dst : S4(write); 4103 src : S3(read); 4104 DECODE : S0; // any decoder 4105 ALU : S3; // any alu 4106 %} 4107 4108 // Long ALU reg-reg operation 4109 pipe_class ialu_reg_reg_long(rRegL dst, rRegL src) 4110 %{ 4111 instruction_count(2); 4112 dst : S4(write); 4113 src : S3(read); 4114 DECODE : S0(2); // any 2 decoders 4115 ALU : S3(2); // both alus 4116 %} 4117 4118 // Integer ALU reg-reg operation 4119 pipe_class ialu_reg_reg_fat(rRegI dst, memory src) 4120 %{ 4121 single_instruction; 4122 dst : S4(write); 4123 src : S3(read); 4124 D0 : S0; // big decoder only 4125 ALU : S3; // any alu 4126 %} 4127 4128 // Long ALU reg-reg operation 4129 pipe_class ialu_reg_reg_long_fat(rRegL dst, rRegL src) 4130 %{ 4131 instruction_count(2); 4132 dst : S4(write); 4133 src : S3(read); 4134 D0 : S0(2); // big decoder only; twice 4135 ALU : S3(2); // both alus 4136 %} 4137 4138 // Integer ALU reg-mem operation 4139 pipe_class ialu_reg_mem(rRegI dst, memory mem) 4140 %{ 4141 single_instruction; 4142 dst : S5(write); 4143 mem : S3(read); 4144 D0 : S0; // big decoder only 4145 ALU : S4; // any alu 4146 MEM : S3; // any mem 4147 %} 4148 4149 // Integer mem operation (prefetch) 4150 pipe_class ialu_mem(memory mem) 4151 %{ 4152 single_instruction; 4153 mem : S3(read); 4154 D0 : S0; // big decoder only 4155 MEM : S3; // any mem 4156 %} 4157 4158 // Integer Store to Memory 4159 pipe_class ialu_mem_reg(memory mem, rRegI src) 4160 %{ 4161 single_instruction; 4162 mem : S3(read); 4163 src : S5(read); 4164 D0 : S0; // big decoder only 4165 ALU : S4; // any alu 4166 MEM : S3; 4167 %} 4168 4169 // // Long Store to Memory 4170 // pipe_class ialu_mem_long_reg(memory mem, rRegL src) 4171 // %{ 4172 // instruction_count(2); 4173 // mem : S3(read); 4174 // src : S5(read); 4175 // D0 : S0(2); // big decoder only; twice 4176 // ALU : S4(2); // any 2 alus 4177 // MEM : S3(2); // Both mems 4178 // %} 4179 4180 // Integer Store to Memory 4181 pipe_class ialu_mem_imm(memory mem) 4182 %{ 4183 single_instruction; 4184 mem : S3(read); 4185 D0 : S0; // big decoder only 4186 ALU : S4; // any alu 4187 MEM : S3; 4188 %} 4189 4190 // Integer ALU0 reg-reg operation 4191 pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) 4192 %{ 4193 single_instruction; 4194 dst : S4(write); 4195 src : S3(read); 4196 D0 : S0; // Big decoder only 4197 ALU0 : S3; // only alu0 4198 %} 4199 4200 // Integer ALU0 reg-mem operation 4201 pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) 4202 %{ 4203 single_instruction; 4204 dst : S5(write); 4205 mem : S3(read); 4206 D0 : S0; // big decoder only 4207 ALU0 : S4; // ALU0 only 4208 MEM : S3; // any mem 4209 %} 4210 4211 // Integer ALU reg-reg operation 4212 pipe_class ialu_cr_reg_reg(rFlagsReg cr, rRegI src1, rRegI src2) 4213 %{ 4214 single_instruction; 4215 cr : S4(write); 4216 src1 : S3(read); 4217 src2 : S3(read); 4218 DECODE : S0; // any decoder 4219 ALU : S3; // any alu 4220 %} 4221 4222 // Integer ALU reg-imm operation 4223 pipe_class ialu_cr_reg_imm(rFlagsReg cr, rRegI src1) 4224 %{ 4225 single_instruction; 4226 cr : S4(write); 4227 src1 : S3(read); 4228 DECODE : S0; // any decoder 4229 ALU : S3; // any alu 4230 %} 4231 4232 // Integer ALU reg-mem operation 4233 pipe_class ialu_cr_reg_mem(rFlagsReg cr, rRegI src1, memory src2) 4234 %{ 4235 single_instruction; 4236 cr : S4(write); 4237 src1 : S3(read); 4238 src2 : S3(read); 4239 D0 : S0; // big decoder only 4240 ALU : S4; // any alu 4241 MEM : S3; 4242 %} 4243 4244 // Conditional move reg-reg 4245 pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y) 4246 %{ 4247 instruction_count(4); 4248 y : S4(read); 4249 q : S3(read); 4250 p : S3(read); 4251 DECODE : S0(4); // any decoder 4252 %} 4253 4254 // Conditional move reg-reg 4255 pipe_class pipe_cmov_reg( rRegI dst, rRegI src, rFlagsReg cr) 4256 %{ 4257 single_instruction; 4258 dst : S4(write); 4259 src : S3(read); 4260 cr : S3(read); 4261 DECODE : S0; // any decoder 4262 %} 4263 4264 // Conditional move reg-mem 4265 pipe_class pipe_cmov_mem( rFlagsReg cr, rRegI dst, memory src) 4266 %{ 4267 single_instruction; 4268 dst : S4(write); 4269 src : S3(read); 4270 cr : S3(read); 4271 DECODE : S0; // any decoder 4272 MEM : S3; 4273 %} 4274 4275 // Conditional move reg-reg long 4276 pipe_class pipe_cmov_reg_long( rFlagsReg cr, rRegL dst, rRegL src) 4277 %{ 4278 single_instruction; 4279 dst : S4(write); 4280 src : S3(read); 4281 cr : S3(read); 4282 DECODE : S0(2); // any 2 decoders 4283 %} 4284 4285 // XXX 4286 // // Conditional move double reg-reg 4287 // pipe_class pipe_cmovD_reg( rFlagsReg cr, regDPR1 dst, regD src) 4288 // %{ 4289 // single_instruction; 4290 // dst : S4(write); 4291 // src : S3(read); 4292 // cr : S3(read); 4293 // DECODE : S0; // any decoder 4294 // %} 4295 4296 // Float reg-reg operation 4297 pipe_class fpu_reg(regD dst) 4298 %{ 4299 instruction_count(2); 4300 dst : S3(read); 4301 DECODE : S0(2); // any 2 decoders 4302 FPU : S3; 4303 %} 4304 4305 // Float reg-reg operation 4306 pipe_class fpu_reg_reg(regD dst, regD src) 4307 %{ 4308 instruction_count(2); 4309 dst : S4(write); 4310 src : S3(read); 4311 DECODE : S0(2); // any 2 decoders 4312 FPU : S3; 4313 %} 4314 4315 // Float reg-reg operation 4316 pipe_class fpu_reg_reg_reg(regD dst, regD src1, regD src2) 4317 %{ 4318 instruction_count(3); 4319 dst : S4(write); 4320 src1 : S3(read); 4321 src2 : S3(read); 4322 DECODE : S0(3); // any 3 decoders 4323 FPU : S3(2); 4324 %} 4325 4326 // Float reg-reg operation 4327 pipe_class fpu_reg_reg_reg_reg(regD dst, regD src1, regD src2, regD src3) 4328 %{ 4329 instruction_count(4); 4330 dst : S4(write); 4331 src1 : S3(read); 4332 src2 : S3(read); 4333 src3 : S3(read); 4334 DECODE : S0(4); // any 3 decoders 4335 FPU : S3(2); 4336 %} 4337 4338 // Float reg-reg operation 4339 pipe_class fpu_reg_mem_reg_reg(regD dst, memory src1, regD src2, regD src3) 4340 %{ 4341 instruction_count(4); 4342 dst : S4(write); 4343 src1 : S3(read); 4344 src2 : S3(read); 4345 src3 : S3(read); 4346 DECODE : S1(3); // any 3 decoders 4347 D0 : S0; // Big decoder only 4348 FPU : S3(2); 4349 MEM : S3; 4350 %} 4351 4352 // Float reg-mem operation 4353 pipe_class fpu_reg_mem(regD dst, memory mem) 4354 %{ 4355 instruction_count(2); 4356 dst : S5(write); 4357 mem : S3(read); 4358 D0 : S0; // big decoder only 4359 DECODE : S1; // any decoder for FPU POP 4360 FPU : S4; 4361 MEM : S3; // any mem 4362 %} 4363 4364 // Float reg-mem operation 4365 pipe_class fpu_reg_reg_mem(regD dst, regD src1, memory mem) 4366 %{ 4367 instruction_count(3); 4368 dst : S5(write); 4369 src1 : S3(read); 4370 mem : S3(read); 4371 D0 : S0; // big decoder only 4372 DECODE : S1(2); // any decoder for FPU POP 4373 FPU : S4; 4374 MEM : S3; // any mem 4375 %} 4376 4377 // Float mem-reg operation 4378 pipe_class fpu_mem_reg(memory mem, regD src) 4379 %{ 4380 instruction_count(2); 4381 src : S5(read); 4382 mem : S3(read); 4383 DECODE : S0; // any decoder for FPU PUSH 4384 D0 : S1; // big decoder only 4385 FPU : S4; 4386 MEM : S3; // any mem 4387 %} 4388 4389 pipe_class fpu_mem_reg_reg(memory mem, regD src1, regD src2) 4390 %{ 4391 instruction_count(3); 4392 src1 : S3(read); 4393 src2 : S3(read); 4394 mem : S3(read); 4395 DECODE : S0(2); // any decoder for FPU PUSH 4396 D0 : S1; // big decoder only 4397 FPU : S4; 4398 MEM : S3; // any mem 4399 %} 4400 4401 pipe_class fpu_mem_reg_mem(memory mem, regD src1, memory src2) 4402 %{ 4403 instruction_count(3); 4404 src1 : S3(read); 4405 src2 : S3(read); 4406 mem : S4(read); 4407 DECODE : S0; // any decoder for FPU PUSH 4408 D0 : S0(2); // big decoder only 4409 FPU : S4; 4410 MEM : S3(2); // any mem 4411 %} 4412 4413 pipe_class fpu_mem_mem(memory dst, memory src1) 4414 %{ 4415 instruction_count(2); 4416 src1 : S3(read); 4417 dst : S4(read); 4418 D0 : S0(2); // big decoder only 4419 MEM : S3(2); // any mem 4420 %} 4421 4422 pipe_class fpu_mem_mem_mem(memory dst, memory src1, memory src2) 4423 %{ 4424 instruction_count(3); 4425 src1 : S3(read); 4426 src2 : S3(read); 4427 dst : S4(read); 4428 D0 : S0(3); // big decoder only 4429 FPU : S4; 4430 MEM : S3(3); // any mem 4431 %} 4432 4433 pipe_class fpu_mem_reg_con(memory mem, regD src1) 4434 %{ 4435 instruction_count(3); 4436 src1 : S4(read); 4437 mem : S4(read); 4438 DECODE : S0; // any decoder for FPU PUSH 4439 D0 : S0(2); // big decoder only 4440 FPU : S4; 4441 MEM : S3(2); // any mem 4442 %} 4443 4444 // Float load constant 4445 pipe_class fpu_reg_con(regD dst) 4446 %{ 4447 instruction_count(2); 4448 dst : S5(write); 4449 D0 : S0; // big decoder only for the load 4450 DECODE : S1; // any decoder for FPU POP 4451 FPU : S4; 4452 MEM : S3; // any mem 4453 %} 4454 4455 // Float load constant 4456 pipe_class fpu_reg_reg_con(regD dst, regD src) 4457 %{ 4458 instruction_count(3); 4459 dst : S5(write); 4460 src : S3(read); 4461 D0 : S0; // big decoder only for the load 4462 DECODE : S1(2); // any decoder for FPU POP 4463 FPU : S4; 4464 MEM : S3; // any mem 4465 %} 4466 4467 // UnConditional branch 4468 pipe_class pipe_jmp(label labl) 4469 %{ 4470 single_instruction; 4471 BR : S3; 4472 %} 4473 4474 // Conditional branch 4475 pipe_class pipe_jcc(cmpOp cmp, rFlagsReg cr, label labl) 4476 %{ 4477 single_instruction; 4478 cr : S1(read); 4479 BR : S3; 4480 %} 4481 4482 // Allocation idiom 4483 pipe_class pipe_cmpxchg(rRegP dst, rRegP heap_ptr) 4484 %{ 4485 instruction_count(1); force_serialization; 4486 fixed_latency(6); 4487 heap_ptr : S3(read); 4488 DECODE : S0(3); 4489 D0 : S2; 4490 MEM : S3; 4491 ALU : S3(2); 4492 dst : S5(write); 4493 BR : S5; 4494 %} 4495 4496 // Generic big/slow expanded idiom 4497 pipe_class pipe_slow() 4498 %{ 4499 instruction_count(10); multiple_bundles; force_serialization; 4500 fixed_latency(100); 4501 D0 : S0(2); 4502 MEM : S3(2); 4503 %} 4504 4505 // The real do-nothing guy 4506 pipe_class empty() 4507 %{ 4508 instruction_count(0); 4509 %} 4510 4511 // Define the class for the Nop node 4512 define 4513 %{ 4514 MachNop = empty; 4515 %} 4516 4517 %} 4518 4519 //----------INSTRUCTIONS------------------------------------------------------- 4520 // 4521 // match -- States which machine-independent subtree may be replaced 4522 // by this instruction. 4523 // ins_cost -- The estimated cost of this instruction is used by instruction 4524 // selection to identify a minimum cost tree of machine 4525 // instructions that matches a tree of machine-independent 4526 // instructions. 4527 // format -- A string providing the disassembly for this instruction. 4528 // The value of an instruction's operand may be inserted 4529 // by referring to it with a '$' prefix. 4530 // opcode -- Three instruction opcodes may be provided. These are referred 4531 // to within an encode class as $primary, $secondary, and $tertiary 4532 // rrspectively. The primary opcode is commonly used to 4533 // indicate the type of machine instruction, while secondary 4534 // and tertiary are often used for prefix options or addressing 4535 // modes. 4536 // ins_encode -- A list of encode classes with parameters. The encode class 4537 // name must have been defined in an 'enc_class' specification 4538 // in the encode section of the architecture description. 4539 4540 4541 //----------Load/Store/Move Instructions--------------------------------------- 4542 //----------Load Instructions-------------------------------------------------- 4543 4544 // Load Byte (8 bit signed) 4545 instruct loadB(rRegI dst, memory mem) 4546 %{ 4547 match(Set dst (LoadB mem)); 4548 4549 ins_cost(125); 4550 format %{ "movsbl $dst, $mem\t# byte" %} 4551 4552 ins_encode %{ 4553 __ movsbl($dst$$Register, $mem$$Address); 4554 %} 4555 4556 ins_pipe(ialu_reg_mem); 4557 %} 4558 4559 // Load Byte (8 bit signed) into Long Register 4560 instruct loadB2L(rRegL dst, memory mem) 4561 %{ 4562 match(Set dst (ConvI2L (LoadB mem))); 4563 4564 ins_cost(125); 4565 format %{ "movsbq $dst, $mem\t# byte -> long" %} 4566 4567 ins_encode %{ 4568 __ movsbq($dst$$Register, $mem$$Address); 4569 %} 4570 4571 ins_pipe(ialu_reg_mem); 4572 %} 4573 4574 // Load Unsigned Byte (8 bit UNsigned) 4575 instruct loadUB(rRegI dst, memory mem) 4576 %{ 4577 match(Set dst (LoadUB mem)); 4578 4579 ins_cost(125); 4580 format %{ "movzbl $dst, $mem\t# ubyte" %} 4581 4582 ins_encode %{ 4583 __ movzbl($dst$$Register, $mem$$Address); 4584 %} 4585 4586 ins_pipe(ialu_reg_mem); 4587 %} 4588 4589 // Load Unsigned Byte (8 bit UNsigned) into Long Register 4590 instruct loadUB2L(rRegL dst, memory mem) 4591 %{ 4592 match(Set dst (ConvI2L (LoadUB mem))); 4593 4594 ins_cost(125); 4595 format %{ "movzbq $dst, $mem\t# ubyte -> long" %} 4596 4597 ins_encode %{ 4598 __ movzbq($dst$$Register, $mem$$Address); 4599 %} 4600 4601 ins_pipe(ialu_reg_mem); 4602 %} 4603 4604 // Load Unsigned Byte (8 bit UNsigned) with a 8-bit mask into Long Register 4605 instruct loadUB2L_immI8(rRegL dst, memory mem, immI8 mask, rFlagsReg cr) %{ 4606 match(Set dst (ConvI2L (AndI (LoadUB mem) mask))); 4607 effect(KILL cr); 4608 4609 format %{ "movzbq $dst, $mem\t# ubyte & 8-bit mask -> long\n\t" 4610 "andl $dst, $mask" %} 4611 ins_encode %{ 4612 Register Rdst = $dst$$Register; 4613 __ movzbq(Rdst, $mem$$Address); 4614 __ andl(Rdst, $mask$$constant); 4615 %} 4616 ins_pipe(ialu_reg_mem); 4617 %} 4618 4619 // Load Short (16 bit signed) 4620 instruct loadS(rRegI dst, memory mem) 4621 %{ 4622 match(Set dst (LoadS mem)); 4623 4624 ins_cost(125); 4625 format %{ "movswl $dst, $mem\t# short" %} 4626 4627 ins_encode %{ 4628 __ movswl($dst$$Register, $mem$$Address); 4629 %} 4630 4631 ins_pipe(ialu_reg_mem); 4632 %} 4633 4634 // Load Short (16 bit signed) to Byte (8 bit signed) 4635 instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4636 match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour)); 4637 4638 ins_cost(125); 4639 format %{ "movsbl $dst, $mem\t# short -> byte" %} 4640 ins_encode %{ 4641 __ movsbl($dst$$Register, $mem$$Address); 4642 %} 4643 ins_pipe(ialu_reg_mem); 4644 %} 4645 4646 // Load Short (16 bit signed) into Long Register 4647 instruct loadS2L(rRegL dst, memory mem) 4648 %{ 4649 match(Set dst (ConvI2L (LoadS mem))); 4650 4651 ins_cost(125); 4652 format %{ "movswq $dst, $mem\t# short -> long" %} 4653 4654 ins_encode %{ 4655 __ movswq($dst$$Register, $mem$$Address); 4656 %} 4657 4658 ins_pipe(ialu_reg_mem); 4659 %} 4660 4661 // Load Unsigned Short/Char (16 bit UNsigned) 4662 instruct loadUS(rRegI dst, memory mem) 4663 %{ 4664 match(Set dst (LoadUS mem)); 4665 4666 ins_cost(125); 4667 format %{ "movzwl $dst, $mem\t# ushort/char" %} 4668 4669 ins_encode %{ 4670 __ movzwl($dst$$Register, $mem$$Address); 4671 %} 4672 4673 ins_pipe(ialu_reg_mem); 4674 %} 4675 4676 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed) 4677 instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4678 match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour)); 4679 4680 ins_cost(125); 4681 format %{ "movsbl $dst, $mem\t# ushort -> byte" %} 4682 ins_encode %{ 4683 __ movsbl($dst$$Register, $mem$$Address); 4684 %} 4685 ins_pipe(ialu_reg_mem); 4686 %} 4687 4688 // Load Unsigned Short/Char (16 bit UNsigned) into Long Register 4689 instruct loadUS2L(rRegL dst, memory mem) 4690 %{ 4691 match(Set dst (ConvI2L (LoadUS mem))); 4692 4693 ins_cost(125); 4694 format %{ "movzwq $dst, $mem\t# ushort/char -> long" %} 4695 4696 ins_encode %{ 4697 __ movzwq($dst$$Register, $mem$$Address); 4698 %} 4699 4700 ins_pipe(ialu_reg_mem); 4701 %} 4702 4703 // Load Unsigned Short/Char (16 bit UNsigned) with mask 0xFF into Long Register 4704 instruct loadUS2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4705 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4706 4707 format %{ "movzbq $dst, $mem\t# ushort/char & 0xFF -> long" %} 4708 ins_encode %{ 4709 __ movzbq($dst$$Register, $mem$$Address); 4710 %} 4711 ins_pipe(ialu_reg_mem); 4712 %} 4713 4714 // Load Unsigned Short/Char (16 bit UNsigned) with mask into Long Register 4715 instruct loadUS2L_immI16(rRegL dst, memory mem, immI16 mask, rFlagsReg cr) %{ 4716 match(Set dst (ConvI2L (AndI (LoadUS mem) mask))); 4717 effect(KILL cr); 4718 4719 format %{ "movzwq $dst, $mem\t# ushort/char & 16-bit mask -> long\n\t" 4720 "andl $dst, $mask" %} 4721 ins_encode %{ 4722 Register Rdst = $dst$$Register; 4723 __ movzwq(Rdst, $mem$$Address); 4724 __ andl(Rdst, $mask$$constant); 4725 %} 4726 ins_pipe(ialu_reg_mem); 4727 %} 4728 4729 // Load Integer 4730 instruct loadI(rRegI dst, memory mem) 4731 %{ 4732 match(Set dst (LoadI mem)); 4733 4734 ins_cost(125); 4735 format %{ "movl $dst, $mem\t# int" %} 4736 4737 ins_encode %{ 4738 __ movl($dst$$Register, $mem$$Address); 4739 %} 4740 4741 ins_pipe(ialu_reg_mem); 4742 %} 4743 4744 // Load Integer (32 bit signed) to Byte (8 bit signed) 4745 instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{ 4746 match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour)); 4747 4748 ins_cost(125); 4749 format %{ "movsbl $dst, $mem\t# int -> byte" %} 4750 ins_encode %{ 4751 __ movsbl($dst$$Register, $mem$$Address); 4752 %} 4753 ins_pipe(ialu_reg_mem); 4754 %} 4755 4756 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned) 4757 instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{ 4758 match(Set dst (AndI (LoadI mem) mask)); 4759 4760 ins_cost(125); 4761 format %{ "movzbl $dst, $mem\t# int -> ubyte" %} 4762 ins_encode %{ 4763 __ movzbl($dst$$Register, $mem$$Address); 4764 %} 4765 ins_pipe(ialu_reg_mem); 4766 %} 4767 4768 // Load Integer (32 bit signed) to Short (16 bit signed) 4769 instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{ 4770 match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen)); 4771 4772 ins_cost(125); 4773 format %{ "movswl $dst, $mem\t# int -> short" %} 4774 ins_encode %{ 4775 __ movswl($dst$$Register, $mem$$Address); 4776 %} 4777 ins_pipe(ialu_reg_mem); 4778 %} 4779 4780 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned) 4781 instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{ 4782 match(Set dst (AndI (LoadI mem) mask)); 4783 4784 ins_cost(125); 4785 format %{ "movzwl $dst, $mem\t# int -> ushort/char" %} 4786 ins_encode %{ 4787 __ movzwl($dst$$Register, $mem$$Address); 4788 %} 4789 ins_pipe(ialu_reg_mem); 4790 %} 4791 4792 // Load Integer into Long Register 4793 instruct loadI2L(rRegL dst, memory mem) 4794 %{ 4795 match(Set dst (ConvI2L (LoadI mem))); 4796 4797 ins_cost(125); 4798 format %{ "movslq $dst, $mem\t# int -> long" %} 4799 4800 ins_encode %{ 4801 __ movslq($dst$$Register, $mem$$Address); 4802 %} 4803 4804 ins_pipe(ialu_reg_mem); 4805 %} 4806 4807 // Load Integer with mask 0xFF into Long Register 4808 instruct loadI2L_immI_255(rRegL dst, memory mem, immI_255 mask) %{ 4809 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4810 4811 format %{ "movzbq $dst, $mem\t# int & 0xFF -> long" %} 4812 ins_encode %{ 4813 __ movzbq($dst$$Register, $mem$$Address); 4814 %} 4815 ins_pipe(ialu_reg_mem); 4816 %} 4817 4818 // Load Integer with mask 0xFFFF into Long Register 4819 instruct loadI2L_immI_65535(rRegL dst, memory mem, immI_65535 mask) %{ 4820 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4821 4822 format %{ "movzwq $dst, $mem\t# int & 0xFFFF -> long" %} 4823 ins_encode %{ 4824 __ movzwq($dst$$Register, $mem$$Address); 4825 %} 4826 ins_pipe(ialu_reg_mem); 4827 %} 4828 4829 // Load Integer with a 31-bit mask into Long Register 4830 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ 4831 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); 4832 effect(KILL cr); 4833 4834 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" 4835 "andl $dst, $mask" %} 4836 ins_encode %{ 4837 Register Rdst = $dst$$Register; 4838 __ movl(Rdst, $mem$$Address); 4839 __ andl(Rdst, $mask$$constant); 4840 %} 4841 ins_pipe(ialu_reg_mem); 4842 %} 4843 4844 // Load Unsigned Integer into Long Register 4845 instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 4846 %{ 4847 match(Set dst (AndL (ConvI2L (LoadI mem)) mask)); 4848 4849 ins_cost(125); 4850 format %{ "movl $dst, $mem\t# uint -> long" %} 4851 4852 ins_encode %{ 4853 __ movl($dst$$Register, $mem$$Address); 4854 %} 4855 4856 ins_pipe(ialu_reg_mem); 4857 %} 4858 4859 // Load Long 4860 instruct loadL(rRegL dst, memory mem) 4861 %{ 4862 match(Set dst (LoadL mem)); 4863 4864 ins_cost(125); 4865 format %{ "movq $dst, $mem\t# long" %} 4866 4867 ins_encode %{ 4868 __ movq($dst$$Register, $mem$$Address); 4869 %} 4870 4871 ins_pipe(ialu_reg_mem); // XXX 4872 %} 4873 4874 // Load Range 4875 instruct loadRange(rRegI dst, memory mem) 4876 %{ 4877 match(Set dst (LoadRange mem)); 4878 4879 ins_cost(125); // XXX 4880 format %{ "movl $dst, $mem\t# range" %} 4881 opcode(0x8B); 4882 ins_encode(REX_reg_mem(dst, mem), OpcP, reg_mem(dst, mem)); 4883 ins_pipe(ialu_reg_mem); 4884 %} 4885 4886 // Load Pointer 4887 instruct loadP(rRegP dst, memory mem) 4888 %{ 4889 match(Set dst (LoadP mem)); 4890 4891 ins_cost(125); // XXX 4892 format %{ "movq $dst, $mem\t# ptr" %} 4893 opcode(0x8B); 4894 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 4895 ins_pipe(ialu_reg_mem); // XXX 4896 %} 4897 4898 // Load Compressed Pointer 4899 instruct loadN(rRegN dst, memory mem) 4900 %{ 4901 match(Set dst (LoadN mem)); 4902 4903 ins_cost(125); // XXX 4904 format %{ "movl $dst, $mem\t# compressed ptr" %} 4905 ins_encode %{ 4906 __ movl($dst$$Register, $mem$$Address); 4907 %} 4908 ins_pipe(ialu_reg_mem); // XXX 4909 %} 4910 4911 4912 // Load Klass Pointer 4913 instruct loadKlass(rRegP dst, memory mem) 4914 %{ 4915 match(Set dst (LoadKlass mem)); 4916 4917 ins_cost(125); // XXX 4918 format %{ "movq $dst, $mem\t# class" %} 4919 opcode(0x8B); 4920 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 4921 ins_pipe(ialu_reg_mem); // XXX 4922 %} 4923 4924 // Load narrow Klass Pointer 4925 instruct loadNKlass(rRegN dst, memory mem) 4926 %{ 4927 match(Set dst (LoadNKlass mem)); 4928 4929 ins_cost(125); // XXX 4930 format %{ "movl $dst, $mem\t# compressed klass ptr" %} 4931 ins_encode %{ 4932 __ movl($dst$$Register, $mem$$Address); 4933 %} 4934 ins_pipe(ialu_reg_mem); // XXX 4935 %} 4936 4937 // Load Float 4938 instruct loadF(regF dst, memory mem) 4939 %{ 4940 match(Set dst (LoadF mem)); 4941 4942 ins_cost(145); // XXX 4943 format %{ "movss $dst, $mem\t# float" %} 4944 ins_encode %{ 4945 __ movflt($dst$$XMMRegister, $mem$$Address); 4946 %} 4947 ins_pipe(pipe_slow); // XXX 4948 %} 4949 4950 // Load Double 4951 instruct loadD_partial(regD dst, memory mem) 4952 %{ 4953 predicate(!UseXmmLoadAndClearUpper); 4954 match(Set dst (LoadD mem)); 4955 4956 ins_cost(145); // XXX 4957 format %{ "movlpd $dst, $mem\t# double" %} 4958 ins_encode %{ 4959 __ movdbl($dst$$XMMRegister, $mem$$Address); 4960 %} 4961 ins_pipe(pipe_slow); // XXX 4962 %} 4963 4964 instruct loadD(regD dst, memory mem) 4965 %{ 4966 predicate(UseXmmLoadAndClearUpper); 4967 match(Set dst (LoadD mem)); 4968 4969 ins_cost(145); // XXX 4970 format %{ "movsd $dst, $mem\t# double" %} 4971 ins_encode %{ 4972 __ movdbl($dst$$XMMRegister, $mem$$Address); 4973 %} 4974 ins_pipe(pipe_slow); // XXX 4975 %} 4976 4977 // Load Effective Address 4978 instruct leaP8(rRegP dst, indOffset8 mem) 4979 %{ 4980 match(Set dst mem); 4981 4982 ins_cost(110); // XXX 4983 format %{ "leaq $dst, $mem\t# ptr 8" %} 4984 opcode(0x8D); 4985 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 4986 ins_pipe(ialu_reg_reg_fat); 4987 %} 4988 4989 instruct leaP32(rRegP dst, indOffset32 mem) 4990 %{ 4991 match(Set dst mem); 4992 4993 ins_cost(110); 4994 format %{ "leaq $dst, $mem\t# ptr 32" %} 4995 opcode(0x8D); 4996 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 4997 ins_pipe(ialu_reg_reg_fat); 4998 %} 4999 5000 // instruct leaPIdx(rRegP dst, indIndex mem) 5001 // %{ 5002 // match(Set dst mem); 5003 5004 // ins_cost(110); 5005 // format %{ "leaq $dst, $mem\t# ptr idx" %} 5006 // opcode(0x8D); 5007 // ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5008 // ins_pipe(ialu_reg_reg_fat); 5009 // %} 5010 5011 instruct leaPIdxOff(rRegP dst, indIndexOffset mem) 5012 %{ 5013 match(Set dst mem); 5014 5015 ins_cost(110); 5016 format %{ "leaq $dst, $mem\t# ptr idxoff" %} 5017 opcode(0x8D); 5018 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5019 ins_pipe(ialu_reg_reg_fat); 5020 %} 5021 5022 instruct leaPIdxScale(rRegP dst, indIndexScale mem) 5023 %{ 5024 match(Set dst mem); 5025 5026 ins_cost(110); 5027 format %{ "leaq $dst, $mem\t# ptr idxscale" %} 5028 opcode(0x8D); 5029 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5030 ins_pipe(ialu_reg_reg_fat); 5031 %} 5032 5033 instruct leaPIdxScaleOff(rRegP dst, indIndexScaleOffset mem) 5034 %{ 5035 match(Set dst mem); 5036 5037 ins_cost(110); 5038 format %{ "leaq $dst, $mem\t# ptr idxscaleoff" %} 5039 opcode(0x8D); 5040 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5041 ins_pipe(ialu_reg_reg_fat); 5042 %} 5043 5044 instruct leaPPosIdxScaleOff(rRegP dst, indPosIndexScaleOffset mem) 5045 %{ 5046 match(Set dst mem); 5047 5048 ins_cost(110); 5049 format %{ "leaq $dst, $mem\t# ptr posidxscaleoff" %} 5050 opcode(0x8D); 5051 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5052 ins_pipe(ialu_reg_reg_fat); 5053 %} 5054 5055 // Load Effective Address which uses Narrow (32-bits) oop 5056 instruct leaPCompressedOopOffset(rRegP dst, indCompressedOopOffset mem) 5057 %{ 5058 predicate(UseCompressedOops && (Universe::narrow_oop_shift() != 0)); 5059 match(Set dst mem); 5060 5061 ins_cost(110); 5062 format %{ "leaq $dst, $mem\t# ptr compressedoopoff32" %} 5063 opcode(0x8D); 5064 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5065 ins_pipe(ialu_reg_reg_fat); 5066 %} 5067 5068 instruct leaP8Narrow(rRegP dst, indOffset8Narrow mem) 5069 %{ 5070 predicate(Universe::narrow_oop_shift() == 0); 5071 match(Set dst mem); 5072 5073 ins_cost(110); // XXX 5074 format %{ "leaq $dst, $mem\t# ptr off8narrow" %} 5075 opcode(0x8D); 5076 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5077 ins_pipe(ialu_reg_reg_fat); 5078 %} 5079 5080 instruct leaP32Narrow(rRegP dst, indOffset32Narrow mem) 5081 %{ 5082 predicate(Universe::narrow_oop_shift() == 0); 5083 match(Set dst mem); 5084 5085 ins_cost(110); 5086 format %{ "leaq $dst, $mem\t# ptr off32narrow" %} 5087 opcode(0x8D); 5088 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5089 ins_pipe(ialu_reg_reg_fat); 5090 %} 5091 5092 instruct leaPIdxOffNarrow(rRegP dst, indIndexOffsetNarrow mem) 5093 %{ 5094 predicate(Universe::narrow_oop_shift() == 0); 5095 match(Set dst mem); 5096 5097 ins_cost(110); 5098 format %{ "leaq $dst, $mem\t# ptr idxoffnarrow" %} 5099 opcode(0x8D); 5100 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5101 ins_pipe(ialu_reg_reg_fat); 5102 %} 5103 5104 instruct leaPIdxScaleNarrow(rRegP dst, indIndexScaleNarrow mem) 5105 %{ 5106 predicate(Universe::narrow_oop_shift() == 0); 5107 match(Set dst mem); 5108 5109 ins_cost(110); 5110 format %{ "leaq $dst, $mem\t# ptr idxscalenarrow" %} 5111 opcode(0x8D); 5112 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5113 ins_pipe(ialu_reg_reg_fat); 5114 %} 5115 5116 instruct leaPIdxScaleOffNarrow(rRegP dst, indIndexScaleOffsetNarrow mem) 5117 %{ 5118 predicate(Universe::narrow_oop_shift() == 0); 5119 match(Set dst mem); 5120 5121 ins_cost(110); 5122 format %{ "leaq $dst, $mem\t# ptr idxscaleoffnarrow" %} 5123 opcode(0x8D); 5124 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5125 ins_pipe(ialu_reg_reg_fat); 5126 %} 5127 5128 instruct leaPPosIdxScaleOffNarrow(rRegP dst, indPosIndexScaleOffsetNarrow mem) 5129 %{ 5130 predicate(Universe::narrow_oop_shift() == 0); 5131 match(Set dst mem); 5132 5133 ins_cost(110); 5134 format %{ "leaq $dst, $mem\t# ptr posidxscaleoffnarrow" %} 5135 opcode(0x8D); 5136 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 5137 ins_pipe(ialu_reg_reg_fat); 5138 %} 5139 5140 instruct loadConI(rRegI dst, immI src) 5141 %{ 5142 match(Set dst src); 5143 5144 format %{ "movl $dst, $src\t# int" %} 5145 ins_encode(load_immI(dst, src)); 5146 ins_pipe(ialu_reg_fat); // XXX 5147 %} 5148 5149 instruct loadConI0(rRegI dst, immI0 src, rFlagsReg cr) 5150 %{ 5151 match(Set dst src); 5152 effect(KILL cr); 5153 5154 ins_cost(50); 5155 format %{ "xorl $dst, $dst\t# int" %} 5156 opcode(0x33); /* + rd */ 5157 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5158 ins_pipe(ialu_reg); 5159 %} 5160 5161 instruct loadConL(rRegL dst, immL src) 5162 %{ 5163 match(Set dst src); 5164 5165 ins_cost(150); 5166 format %{ "movq $dst, $src\t# long" %} 5167 ins_encode(load_immL(dst, src)); 5168 ins_pipe(ialu_reg); 5169 %} 5170 5171 instruct loadConL0(rRegL dst, immL0 src, rFlagsReg cr) 5172 %{ 5173 match(Set dst src); 5174 effect(KILL cr); 5175 5176 ins_cost(50); 5177 format %{ "xorl $dst, $dst\t# long" %} 5178 opcode(0x33); /* + rd */ 5179 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5180 ins_pipe(ialu_reg); // XXX 5181 %} 5182 5183 instruct loadConUL32(rRegL dst, immUL32 src) 5184 %{ 5185 match(Set dst src); 5186 5187 ins_cost(60); 5188 format %{ "movl $dst, $src\t# long (unsigned 32-bit)" %} 5189 ins_encode(load_immUL32(dst, src)); 5190 ins_pipe(ialu_reg); 5191 %} 5192 5193 instruct loadConL32(rRegL dst, immL32 src) 5194 %{ 5195 match(Set dst src); 5196 5197 ins_cost(70); 5198 format %{ "movq $dst, $src\t# long (32-bit)" %} 5199 ins_encode(load_immL32(dst, src)); 5200 ins_pipe(ialu_reg); 5201 %} 5202 5203 instruct loadConP(rRegP dst, immP con) %{ 5204 match(Set dst con); 5205 5206 format %{ "movq $dst, $con\t# ptr" %} 5207 ins_encode(load_immP(dst, con)); 5208 ins_pipe(ialu_reg_fat); // XXX 5209 %} 5210 5211 instruct loadConP0(rRegP dst, immP0 src, rFlagsReg cr) 5212 %{ 5213 match(Set dst src); 5214 effect(KILL cr); 5215 5216 ins_cost(50); 5217 format %{ "xorl $dst, $dst\t# ptr" %} 5218 opcode(0x33); /* + rd */ 5219 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 5220 ins_pipe(ialu_reg); 5221 %} 5222 5223 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 5224 %{ 5225 match(Set dst src); 5226 effect(KILL cr); 5227 5228 ins_cost(60); 5229 format %{ "movl $dst, $src\t# ptr (positive 32-bit)" %} 5230 ins_encode(load_immP31(dst, src)); 5231 ins_pipe(ialu_reg); 5232 %} 5233 5234 instruct loadConF(regF dst, immF con) %{ 5235 match(Set dst con); 5236 ins_cost(125); 5237 format %{ "movss $dst, [$constantaddress]\t# load from constant table: float=$con" %} 5238 ins_encode %{ 5239 __ movflt($dst$$XMMRegister, $constantaddress($con)); 5240 %} 5241 ins_pipe(pipe_slow); 5242 %} 5243 5244 instruct loadConN0(rRegN dst, immN0 src, rFlagsReg cr) %{ 5245 match(Set dst src); 5246 effect(KILL cr); 5247 format %{ "xorq $dst, $src\t# compressed NULL ptr" %} 5248 ins_encode %{ 5249 __ xorq($dst$$Register, $dst$$Register); 5250 %} 5251 ins_pipe(ialu_reg); 5252 %} 5253 5254 instruct loadConN(rRegN dst, immN src) %{ 5255 match(Set dst src); 5256 5257 ins_cost(125); 5258 format %{ "movl $dst, $src\t# compressed ptr" %} 5259 ins_encode %{ 5260 address con = (address)$src$$constant; 5261 if (con == NULL) { 5262 ShouldNotReachHere(); 5263 } else { 5264 __ set_narrow_oop($dst$$Register, (jobject)$src$$constant); 5265 } 5266 %} 5267 ins_pipe(ialu_reg_fat); // XXX 5268 %} 5269 5270 instruct loadConNKlass(rRegN dst, immNKlass src) %{ 5271 match(Set dst src); 5272 5273 ins_cost(125); 5274 format %{ "movl $dst, $src\t# compressed klass ptr" %} 5275 ins_encode %{ 5276 address con = (address)$src$$constant; 5277 if (con == NULL) { 5278 ShouldNotReachHere(); 5279 } else { 5280 __ set_narrow_klass($dst$$Register, (Klass*)$src$$constant); 5281 } 5282 %} 5283 ins_pipe(ialu_reg_fat); // XXX 5284 %} 5285 5286 instruct loadConF0(regF dst, immF0 src) 5287 %{ 5288 match(Set dst src); 5289 ins_cost(100); 5290 5291 format %{ "xorps $dst, $dst\t# float 0.0" %} 5292 ins_encode %{ 5293 __ xorps($dst$$XMMRegister, $dst$$XMMRegister); 5294 %} 5295 ins_pipe(pipe_slow); 5296 %} 5297 5298 // Use the same format since predicate() can not be used here. 5299 instruct loadConD(regD dst, immD con) %{ 5300 match(Set dst con); 5301 ins_cost(125); 5302 format %{ "movsd $dst, [$constantaddress]\t# load from constant table: double=$con" %} 5303 ins_encode %{ 5304 __ movdbl($dst$$XMMRegister, $constantaddress($con)); 5305 %} 5306 ins_pipe(pipe_slow); 5307 %} 5308 5309 instruct loadConD0(regD dst, immD0 src) 5310 %{ 5311 match(Set dst src); 5312 ins_cost(100); 5313 5314 format %{ "xorpd $dst, $dst\t# double 0.0" %} 5315 ins_encode %{ 5316 __ xorpd ($dst$$XMMRegister, $dst$$XMMRegister); 5317 %} 5318 ins_pipe(pipe_slow); 5319 %} 5320 5321 instruct loadSSI(rRegI dst, stackSlotI src) 5322 %{ 5323 match(Set dst src); 5324 5325 ins_cost(125); 5326 format %{ "movl $dst, $src\t# int stk" %} 5327 opcode(0x8B); 5328 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 5329 ins_pipe(ialu_reg_mem); 5330 %} 5331 5332 instruct loadSSL(rRegL dst, stackSlotL src) 5333 %{ 5334 match(Set dst src); 5335 5336 ins_cost(125); 5337 format %{ "movq $dst, $src\t# long stk" %} 5338 opcode(0x8B); 5339 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5340 ins_pipe(ialu_reg_mem); 5341 %} 5342 5343 instruct loadSSP(rRegP dst, stackSlotP src) 5344 %{ 5345 match(Set dst src); 5346 5347 ins_cost(125); 5348 format %{ "movq $dst, $src\t# ptr stk" %} 5349 opcode(0x8B); 5350 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 5351 ins_pipe(ialu_reg_mem); 5352 %} 5353 5354 instruct loadSSF(regF dst, stackSlotF src) 5355 %{ 5356 match(Set dst src); 5357 5358 ins_cost(125); 5359 format %{ "movss $dst, $src\t# float stk" %} 5360 ins_encode %{ 5361 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 5362 %} 5363 ins_pipe(pipe_slow); // XXX 5364 %} 5365 5366 // Use the same format since predicate() can not be used here. 5367 instruct loadSSD(regD dst, stackSlotD src) 5368 %{ 5369 match(Set dst src); 5370 5371 ins_cost(125); 5372 format %{ "movsd $dst, $src\t# double stk" %} 5373 ins_encode %{ 5374 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 5375 %} 5376 ins_pipe(pipe_slow); // XXX 5377 %} 5378 5379 // Prefetch instructions. 5380 // Must be safe to execute with invalid address (cannot fault). 5381 5382 instruct prefetchr( memory mem ) %{ 5383 predicate(ReadPrefetchInstr==3); 5384 match(PrefetchRead mem); 5385 ins_cost(125); 5386 5387 format %{ "PREFETCHR $mem\t# Prefetch into level 1 cache" %} 5388 ins_encode %{ 5389 __ prefetchr($mem$$Address); 5390 %} 5391 ins_pipe(ialu_mem); 5392 %} 5393 5394 instruct prefetchrNTA( memory mem ) %{ 5395 predicate(ReadPrefetchInstr==0); 5396 match(PrefetchRead mem); 5397 ins_cost(125); 5398 5399 format %{ "PREFETCHNTA $mem\t# Prefetch into non-temporal cache for read" %} 5400 ins_encode %{ 5401 __ prefetchnta($mem$$Address); 5402 %} 5403 ins_pipe(ialu_mem); 5404 %} 5405 5406 instruct prefetchrT0( memory mem ) %{ 5407 predicate(ReadPrefetchInstr==1); 5408 match(PrefetchRead mem); 5409 ins_cost(125); 5410 5411 format %{ "PREFETCHT0 $mem\t# prefetch into L1 and L2 caches for read" %} 5412 ins_encode %{ 5413 __ prefetcht0($mem$$Address); 5414 %} 5415 ins_pipe(ialu_mem); 5416 %} 5417 5418 instruct prefetchrT2( memory mem ) %{ 5419 predicate(ReadPrefetchInstr==2); 5420 match(PrefetchRead mem); 5421 ins_cost(125); 5422 5423 format %{ "PREFETCHT2 $mem\t# prefetch into L2 caches for read" %} 5424 ins_encode %{ 5425 __ prefetcht2($mem$$Address); 5426 %} 5427 ins_pipe(ialu_mem); 5428 %} 5429 5430 instruct prefetchwNTA( memory mem ) %{ 5431 match(PrefetchWrite mem); 5432 ins_cost(125); 5433 5434 format %{ "PREFETCHNTA $mem\t# Prefetch to non-temporal cache for write" %} 5435 ins_encode %{ 5436 __ prefetchnta($mem$$Address); 5437 %} 5438 ins_pipe(ialu_mem); 5439 %} 5440 5441 // Prefetch instructions for allocation. 5442 5443 instruct prefetchAlloc( memory mem ) %{ 5444 predicate(AllocatePrefetchInstr==3); 5445 match(PrefetchAllocation mem); 5446 ins_cost(125); 5447 5448 format %{ "PREFETCHW $mem\t# Prefetch allocation into level 1 cache and mark modified" %} 5449 ins_encode %{ 5450 __ prefetchw($mem$$Address); 5451 %} 5452 ins_pipe(ialu_mem); 5453 %} 5454 5455 instruct prefetchAllocNTA( memory mem ) %{ 5456 predicate(AllocatePrefetchInstr==0); 5457 match(PrefetchAllocation mem); 5458 ins_cost(125); 5459 5460 format %{ "PREFETCHNTA $mem\t# Prefetch allocation to non-temporal cache for write" %} 5461 ins_encode %{ 5462 __ prefetchnta($mem$$Address); 5463 %} 5464 ins_pipe(ialu_mem); 5465 %} 5466 5467 instruct prefetchAllocT0( memory mem ) %{ 5468 predicate(AllocatePrefetchInstr==1); 5469 match(PrefetchAllocation mem); 5470 ins_cost(125); 5471 5472 format %{ "PREFETCHT0 $mem\t# Prefetch allocation to level 1 and 2 caches for write" %} 5473 ins_encode %{ 5474 __ prefetcht0($mem$$Address); 5475 %} 5476 ins_pipe(ialu_mem); 5477 %} 5478 5479 instruct prefetchAllocT2( memory mem ) %{ 5480 predicate(AllocatePrefetchInstr==2); 5481 match(PrefetchAllocation mem); 5482 ins_cost(125); 5483 5484 format %{ "PREFETCHT2 $mem\t# Prefetch allocation to level 2 cache for write" %} 5485 ins_encode %{ 5486 __ prefetcht2($mem$$Address); 5487 %} 5488 ins_pipe(ialu_mem); 5489 %} 5490 5491 //----------Store Instructions------------------------------------------------- 5492 5493 // Store Byte 5494 instruct storeB(memory mem, rRegI src) 5495 %{ 5496 match(Set mem (StoreB mem src)); 5497 5498 ins_cost(125); // XXX 5499 format %{ "movb $mem, $src\t# byte" %} 5500 opcode(0x88); 5501 ins_encode(REX_breg_mem(src, mem), OpcP, reg_mem(src, mem)); 5502 ins_pipe(ialu_mem_reg); 5503 %} 5504 5505 // Store Char/Short 5506 instruct storeC(memory mem, rRegI src) 5507 %{ 5508 match(Set mem (StoreC mem src)); 5509 5510 ins_cost(125); // XXX 5511 format %{ "movw $mem, $src\t# char/short" %} 5512 opcode(0x89); 5513 ins_encode(SizePrefix, REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5514 ins_pipe(ialu_mem_reg); 5515 %} 5516 5517 // Store Integer 5518 instruct storeI(memory mem, rRegI src) 5519 %{ 5520 match(Set mem (StoreI mem src)); 5521 5522 ins_cost(125); // XXX 5523 format %{ "movl $mem, $src\t# int" %} 5524 opcode(0x89); 5525 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 5526 ins_pipe(ialu_mem_reg); 5527 %} 5528 5529 // Store Long 5530 instruct storeL(memory mem, rRegL src) 5531 %{ 5532 match(Set mem (StoreL mem src)); 5533 5534 ins_cost(125); // XXX 5535 format %{ "movq $mem, $src\t# long" %} 5536 opcode(0x89); 5537 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5538 ins_pipe(ialu_mem_reg); // XXX 5539 %} 5540 5541 // Store Pointer 5542 instruct storeP(memory mem, any_RegP src) 5543 %{ 5544 match(Set mem (StoreP mem src)); 5545 5546 ins_cost(125); // XXX 5547 format %{ "movq $mem, $src\t# ptr" %} 5548 opcode(0x89); 5549 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 5550 ins_pipe(ialu_mem_reg); 5551 %} 5552 5553 instruct storeImmP0(memory mem, immP0 zero) 5554 %{ 5555 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5556 match(Set mem (StoreP mem zero)); 5557 5558 ins_cost(125); // XXX 5559 format %{ "movq $mem, R12\t# ptr (R12_heapbase==0)" %} 5560 ins_encode %{ 5561 __ movq($mem$$Address, r12); 5562 %} 5563 ins_pipe(ialu_mem_reg); 5564 %} 5565 5566 // Store NULL Pointer, mark word, or other simple pointer constant. 5567 instruct storeImmP(memory mem, immP31 src) 5568 %{ 5569 match(Set mem (StoreP mem src)); 5570 5571 ins_cost(150); // XXX 5572 format %{ "movq $mem, $src\t# ptr" %} 5573 opcode(0xC7); /* C7 /0 */ 5574 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5575 ins_pipe(ialu_mem_imm); 5576 %} 5577 5578 // Store Compressed Pointer 5579 instruct storeN(memory mem, rRegN src) 5580 %{ 5581 match(Set mem (StoreN mem src)); 5582 5583 ins_cost(125); // XXX 5584 format %{ "movl $mem, $src\t# compressed ptr" %} 5585 ins_encode %{ 5586 __ movl($mem$$Address, $src$$Register); 5587 %} 5588 ins_pipe(ialu_mem_reg); 5589 %} 5590 5591 instruct storeNKlass(memory mem, rRegN src) 5592 %{ 5593 match(Set mem (StoreNKlass mem src)); 5594 5595 ins_cost(125); // XXX 5596 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5597 ins_encode %{ 5598 __ movl($mem$$Address, $src$$Register); 5599 %} 5600 ins_pipe(ialu_mem_reg); 5601 %} 5602 5603 instruct storeImmN0(memory mem, immN0 zero) 5604 %{ 5605 predicate(Universe::narrow_oop_base() == NULL && Universe::narrow_klass_base() == NULL); 5606 match(Set mem (StoreN mem zero)); 5607 5608 ins_cost(125); // XXX 5609 format %{ "movl $mem, R12\t# compressed ptr (R12_heapbase==0)" %} 5610 ins_encode %{ 5611 __ movl($mem$$Address, r12); 5612 %} 5613 ins_pipe(ialu_mem_reg); 5614 %} 5615 5616 instruct storeImmN(memory mem, immN src) 5617 %{ 5618 match(Set mem (StoreN mem src)); 5619 5620 ins_cost(150); // XXX 5621 format %{ "movl $mem, $src\t# compressed ptr" %} 5622 ins_encode %{ 5623 address con = (address)$src$$constant; 5624 if (con == NULL) { 5625 __ movl($mem$$Address, (int32_t)0); 5626 } else { 5627 __ set_narrow_oop($mem$$Address, (jobject)$src$$constant); 5628 } 5629 %} 5630 ins_pipe(ialu_mem_imm); 5631 %} 5632 5633 instruct storeImmNKlass(memory mem, immNKlass src) 5634 %{ 5635 match(Set mem (StoreNKlass mem src)); 5636 5637 ins_cost(150); // XXX 5638 format %{ "movl $mem, $src\t# compressed klass ptr" %} 5639 ins_encode %{ 5640 __ set_narrow_klass($mem$$Address, (Klass*)$src$$constant); 5641 %} 5642 ins_pipe(ialu_mem_imm); 5643 %} 5644 5645 // Store Integer Immediate 5646 instruct storeImmI0(memory mem, immI0 zero) 5647 %{ 5648 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5649 match(Set mem (StoreI mem zero)); 5650 5651 ins_cost(125); // XXX 5652 format %{ "movl $mem, R12\t# int (R12_heapbase==0)" %} 5653 ins_encode %{ 5654 __ movl($mem$$Address, r12); 5655 %} 5656 ins_pipe(ialu_mem_reg); 5657 %} 5658 5659 instruct storeImmI(memory mem, immI src) 5660 %{ 5661 match(Set mem (StoreI mem src)); 5662 5663 ins_cost(150); 5664 format %{ "movl $mem, $src\t# int" %} 5665 opcode(0xC7); /* C7 /0 */ 5666 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5667 ins_pipe(ialu_mem_imm); 5668 %} 5669 5670 // Store Long Immediate 5671 instruct storeImmL0(memory mem, immL0 zero) 5672 %{ 5673 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5674 match(Set mem (StoreL mem zero)); 5675 5676 ins_cost(125); // XXX 5677 format %{ "movq $mem, R12\t# long (R12_heapbase==0)" %} 5678 ins_encode %{ 5679 __ movq($mem$$Address, r12); 5680 %} 5681 ins_pipe(ialu_mem_reg); 5682 %} 5683 5684 instruct storeImmL(memory mem, immL32 src) 5685 %{ 5686 match(Set mem (StoreL mem src)); 5687 5688 ins_cost(150); 5689 format %{ "movq $mem, $src\t# long" %} 5690 opcode(0xC7); /* C7 /0 */ 5691 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32(src)); 5692 ins_pipe(ialu_mem_imm); 5693 %} 5694 5695 // Store Short/Char Immediate 5696 instruct storeImmC0(memory mem, immI0 zero) 5697 %{ 5698 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5699 match(Set mem (StoreC mem zero)); 5700 5701 ins_cost(125); // XXX 5702 format %{ "movw $mem, R12\t# short/char (R12_heapbase==0)" %} 5703 ins_encode %{ 5704 __ movw($mem$$Address, r12); 5705 %} 5706 ins_pipe(ialu_mem_reg); 5707 %} 5708 5709 instruct storeImmI16(memory mem, immI16 src) 5710 %{ 5711 predicate(UseStoreImmI16); 5712 match(Set mem (StoreC mem src)); 5713 5714 ins_cost(150); 5715 format %{ "movw $mem, $src\t# short/char" %} 5716 opcode(0xC7); /* C7 /0 Same as 32 store immediate with prefix */ 5717 ins_encode(SizePrefix, REX_mem(mem), OpcP, RM_opc_mem(0x00, mem),Con16(src)); 5718 ins_pipe(ialu_mem_imm); 5719 %} 5720 5721 // Store Byte Immediate 5722 instruct storeImmB0(memory mem, immI0 zero) 5723 %{ 5724 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5725 match(Set mem (StoreB mem zero)); 5726 5727 ins_cost(125); // XXX 5728 format %{ "movb $mem, R12\t# short/char (R12_heapbase==0)" %} 5729 ins_encode %{ 5730 __ movb($mem$$Address, r12); 5731 %} 5732 ins_pipe(ialu_mem_reg); 5733 %} 5734 5735 instruct storeImmB(memory mem, immI8 src) 5736 %{ 5737 match(Set mem (StoreB mem src)); 5738 5739 ins_cost(150); // XXX 5740 format %{ "movb $mem, $src\t# byte" %} 5741 opcode(0xC6); /* C6 /0 */ 5742 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5743 ins_pipe(ialu_mem_imm); 5744 %} 5745 5746 // Store CMS card-mark Immediate 5747 instruct storeImmCM0_reg(memory mem, immI0 zero) 5748 %{ 5749 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5750 match(Set mem (StoreCM mem zero)); 5751 5752 ins_cost(125); // XXX 5753 format %{ "movb $mem, R12\t# CMS card-mark byte 0 (R12_heapbase==0)" %} 5754 ins_encode %{ 5755 __ movb($mem$$Address, r12); 5756 %} 5757 ins_pipe(ialu_mem_reg); 5758 %} 5759 5760 instruct storeImmCM0(memory mem, immI0 src) 5761 %{ 5762 match(Set mem (StoreCM mem src)); 5763 5764 ins_cost(150); // XXX 5765 format %{ "movb $mem, $src\t# CMS card-mark byte 0" %} 5766 opcode(0xC6); /* C6 /0 */ 5767 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con8or32(src)); 5768 ins_pipe(ialu_mem_imm); 5769 %} 5770 5771 // Store Float 5772 instruct storeF(memory mem, regF src) 5773 %{ 5774 match(Set mem (StoreF mem src)); 5775 5776 ins_cost(95); // XXX 5777 format %{ "movss $mem, $src\t# float" %} 5778 ins_encode %{ 5779 __ movflt($mem$$Address, $src$$XMMRegister); 5780 %} 5781 ins_pipe(pipe_slow); // XXX 5782 %} 5783 5784 // Store immediate Float value (it is faster than store from XMM register) 5785 instruct storeF0(memory mem, immF0 zero) 5786 %{ 5787 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5788 match(Set mem (StoreF mem zero)); 5789 5790 ins_cost(25); // XXX 5791 format %{ "movl $mem, R12\t# float 0. (R12_heapbase==0)" %} 5792 ins_encode %{ 5793 __ movl($mem$$Address, r12); 5794 %} 5795 ins_pipe(ialu_mem_reg); 5796 %} 5797 5798 instruct storeF_imm(memory mem, immF src) 5799 %{ 5800 match(Set mem (StoreF mem src)); 5801 5802 ins_cost(50); 5803 format %{ "movl $mem, $src\t# float" %} 5804 opcode(0xC7); /* C7 /0 */ 5805 ins_encode(REX_mem(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5806 ins_pipe(ialu_mem_imm); 5807 %} 5808 5809 // Store Double 5810 instruct storeD(memory mem, regD src) 5811 %{ 5812 match(Set mem (StoreD mem src)); 5813 5814 ins_cost(95); // XXX 5815 format %{ "movsd $mem, $src\t# double" %} 5816 ins_encode %{ 5817 __ movdbl($mem$$Address, $src$$XMMRegister); 5818 %} 5819 ins_pipe(pipe_slow); // XXX 5820 %} 5821 5822 // Store immediate double 0.0 (it is faster than store from XMM register) 5823 instruct storeD0_imm(memory mem, immD0 src) 5824 %{ 5825 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 5826 match(Set mem (StoreD mem src)); 5827 5828 ins_cost(50); 5829 format %{ "movq $mem, $src\t# double 0." %} 5830 opcode(0xC7); /* C7 /0 */ 5831 ins_encode(REX_mem_wide(mem), OpcP, RM_opc_mem(0x00, mem), Con32F_as_bits(src)); 5832 ins_pipe(ialu_mem_imm); 5833 %} 5834 5835 instruct storeD0(memory mem, immD0 zero) 5836 %{ 5837 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 5838 match(Set mem (StoreD mem zero)); 5839 5840 ins_cost(25); // XXX 5841 format %{ "movq $mem, R12\t# double 0. (R12_heapbase==0)" %} 5842 ins_encode %{ 5843 __ movq($mem$$Address, r12); 5844 %} 5845 ins_pipe(ialu_mem_reg); 5846 %} 5847 5848 instruct storeSSI(stackSlotI dst, rRegI src) 5849 %{ 5850 match(Set dst src); 5851 5852 ins_cost(100); 5853 format %{ "movl $dst, $src\t# int stk" %} 5854 opcode(0x89); 5855 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 5856 ins_pipe( ialu_mem_reg ); 5857 %} 5858 5859 instruct storeSSL(stackSlotL dst, rRegL src) 5860 %{ 5861 match(Set dst src); 5862 5863 ins_cost(100); 5864 format %{ "movq $dst, $src\t# long stk" %} 5865 opcode(0x89); 5866 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 5867 ins_pipe(ialu_mem_reg); 5868 %} 5869 5870 instruct storeSSP(stackSlotP dst, rRegP src) 5871 %{ 5872 match(Set dst src); 5873 5874 ins_cost(100); 5875 format %{ "movq $dst, $src\t# ptr stk" %} 5876 opcode(0x89); 5877 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 5878 ins_pipe(ialu_mem_reg); 5879 %} 5880 5881 instruct storeSSF(stackSlotF dst, regF src) 5882 %{ 5883 match(Set dst src); 5884 5885 ins_cost(95); // XXX 5886 format %{ "movss $dst, $src\t# float stk" %} 5887 ins_encode %{ 5888 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 5889 %} 5890 ins_pipe(pipe_slow); // XXX 5891 %} 5892 5893 instruct storeSSD(stackSlotD dst, regD src) 5894 %{ 5895 match(Set dst src); 5896 5897 ins_cost(95); // XXX 5898 format %{ "movsd $dst, $src\t# double stk" %} 5899 ins_encode %{ 5900 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 5901 %} 5902 ins_pipe(pipe_slow); // XXX 5903 %} 5904 5905 //----------BSWAP Instructions------------------------------------------------- 5906 instruct bytes_reverse_int(rRegI dst) %{ 5907 match(Set dst (ReverseBytesI dst)); 5908 5909 format %{ "bswapl $dst" %} 5910 opcode(0x0F, 0xC8); /*Opcode 0F /C8 */ 5911 ins_encode( REX_reg(dst), OpcP, opc2_reg(dst) ); 5912 ins_pipe( ialu_reg ); 5913 %} 5914 5915 instruct bytes_reverse_long(rRegL dst) %{ 5916 match(Set dst (ReverseBytesL dst)); 5917 5918 format %{ "bswapq $dst" %} 5919 opcode(0x0F, 0xC8); /* Opcode 0F /C8 */ 5920 ins_encode( REX_reg_wide(dst), OpcP, opc2_reg(dst) ); 5921 ins_pipe( ialu_reg); 5922 %} 5923 5924 instruct bytes_reverse_unsigned_short(rRegI dst, rFlagsReg cr) %{ 5925 match(Set dst (ReverseBytesUS dst)); 5926 effect(KILL cr); 5927 5928 format %{ "bswapl $dst\n\t" 5929 "shrl $dst,16\n\t" %} 5930 ins_encode %{ 5931 __ bswapl($dst$$Register); 5932 __ shrl($dst$$Register, 16); 5933 %} 5934 ins_pipe( ialu_reg ); 5935 %} 5936 5937 instruct bytes_reverse_short(rRegI dst, rFlagsReg cr) %{ 5938 match(Set dst (ReverseBytesS dst)); 5939 effect(KILL cr); 5940 5941 format %{ "bswapl $dst\n\t" 5942 "sar $dst,16\n\t" %} 5943 ins_encode %{ 5944 __ bswapl($dst$$Register); 5945 __ sarl($dst$$Register, 16); 5946 %} 5947 ins_pipe( ialu_reg ); 5948 %} 5949 5950 //---------- Zeros Count Instructions ------------------------------------------ 5951 5952 instruct countLeadingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 5953 predicate(UseCountLeadingZerosInstruction); 5954 match(Set dst (CountLeadingZerosI src)); 5955 effect(KILL cr); 5956 5957 format %{ "lzcntl $dst, $src\t# count leading zeros (int)" %} 5958 ins_encode %{ 5959 __ lzcntl($dst$$Register, $src$$Register); 5960 %} 5961 ins_pipe(ialu_reg); 5962 %} 5963 5964 instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, rFlagsReg cr) %{ 5965 predicate(!UseCountLeadingZerosInstruction); 5966 match(Set dst (CountLeadingZerosI src)); 5967 effect(KILL cr); 5968 5969 format %{ "bsrl $dst, $src\t# count leading zeros (int)\n\t" 5970 "jnz skip\n\t" 5971 "movl $dst, -1\n" 5972 "skip:\n\t" 5973 "negl $dst\n\t" 5974 "addl $dst, 31" %} 5975 ins_encode %{ 5976 Register Rdst = $dst$$Register; 5977 Register Rsrc = $src$$Register; 5978 Label skip; 5979 __ bsrl(Rdst, Rsrc); 5980 __ jccb(Assembler::notZero, skip); 5981 __ movl(Rdst, -1); 5982 __ bind(skip); 5983 __ negl(Rdst); 5984 __ addl(Rdst, BitsPerInt - 1); 5985 %} 5986 ins_pipe(ialu_reg); 5987 %} 5988 5989 instruct countLeadingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 5990 predicate(UseCountLeadingZerosInstruction); 5991 match(Set dst (CountLeadingZerosL src)); 5992 effect(KILL cr); 5993 5994 format %{ "lzcntq $dst, $src\t# count leading zeros (long)" %} 5995 ins_encode %{ 5996 __ lzcntq($dst$$Register, $src$$Register); 5997 %} 5998 ins_pipe(ialu_reg); 5999 %} 6000 6001 instruct countLeadingZerosL_bsr(rRegI dst, rRegL src, rFlagsReg cr) %{ 6002 predicate(!UseCountLeadingZerosInstruction); 6003 match(Set dst (CountLeadingZerosL src)); 6004 effect(KILL cr); 6005 6006 format %{ "bsrq $dst, $src\t# count leading zeros (long)\n\t" 6007 "jnz skip\n\t" 6008 "movl $dst, -1\n" 6009 "skip:\n\t" 6010 "negl $dst\n\t" 6011 "addl $dst, 63" %} 6012 ins_encode %{ 6013 Register Rdst = $dst$$Register; 6014 Register Rsrc = $src$$Register; 6015 Label skip; 6016 __ bsrq(Rdst, Rsrc); 6017 __ jccb(Assembler::notZero, skip); 6018 __ movl(Rdst, -1); 6019 __ bind(skip); 6020 __ negl(Rdst); 6021 __ addl(Rdst, BitsPerLong - 1); 6022 %} 6023 ins_pipe(ialu_reg); 6024 %} 6025 6026 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6027 predicate(UseCountTrailingZerosInstruction); 6028 match(Set dst (CountTrailingZerosI src)); 6029 effect(KILL cr); 6030 6031 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} 6032 ins_encode %{ 6033 __ tzcntl($dst$$Register, $src$$Register); 6034 %} 6035 ins_pipe(ialu_reg); 6036 %} 6037 6038 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ 6039 predicate(!UseCountTrailingZerosInstruction); 6040 match(Set dst (CountTrailingZerosI src)); 6041 effect(KILL cr); 6042 6043 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" 6044 "jnz done\n\t" 6045 "movl $dst, 32\n" 6046 "done:" %} 6047 ins_encode %{ 6048 Register Rdst = $dst$$Register; 6049 Label done; 6050 __ bsfl(Rdst, $src$$Register); 6051 __ jccb(Assembler::notZero, done); 6052 __ movl(Rdst, BitsPerInt); 6053 __ bind(done); 6054 %} 6055 ins_pipe(ialu_reg); 6056 %} 6057 6058 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6059 predicate(UseCountTrailingZerosInstruction); 6060 match(Set dst (CountTrailingZerosL src)); 6061 effect(KILL cr); 6062 6063 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} 6064 ins_encode %{ 6065 __ tzcntq($dst$$Register, $src$$Register); 6066 %} 6067 ins_pipe(ialu_reg); 6068 %} 6069 6070 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ 6071 predicate(!UseCountTrailingZerosInstruction); 6072 match(Set dst (CountTrailingZerosL src)); 6073 effect(KILL cr); 6074 6075 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" 6076 "jnz done\n\t" 6077 "movl $dst, 64\n" 6078 "done:" %} 6079 ins_encode %{ 6080 Register Rdst = $dst$$Register; 6081 Label done; 6082 __ bsfq(Rdst, $src$$Register); 6083 __ jccb(Assembler::notZero, done); 6084 __ movl(Rdst, BitsPerLong); 6085 __ bind(done); 6086 %} 6087 ins_pipe(ialu_reg); 6088 %} 6089 6090 6091 //---------- Population Count Instructions ------------------------------------- 6092 6093 instruct popCountI(rRegI dst, rRegI src, rFlagsReg cr) %{ 6094 predicate(UsePopCountInstruction); 6095 match(Set dst (PopCountI src)); 6096 effect(KILL cr); 6097 6098 format %{ "popcnt $dst, $src" %} 6099 ins_encode %{ 6100 __ popcntl($dst$$Register, $src$$Register); 6101 %} 6102 ins_pipe(ialu_reg); 6103 %} 6104 6105 instruct popCountI_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6106 predicate(UsePopCountInstruction); 6107 match(Set dst (PopCountI (LoadI mem))); 6108 effect(KILL cr); 6109 6110 format %{ "popcnt $dst, $mem" %} 6111 ins_encode %{ 6112 __ popcntl($dst$$Register, $mem$$Address); 6113 %} 6114 ins_pipe(ialu_reg); 6115 %} 6116 6117 // Note: Long.bitCount(long) returns an int. 6118 instruct popCountL(rRegI dst, rRegL src, rFlagsReg cr) %{ 6119 predicate(UsePopCountInstruction); 6120 match(Set dst (PopCountL src)); 6121 effect(KILL cr); 6122 6123 format %{ "popcnt $dst, $src" %} 6124 ins_encode %{ 6125 __ popcntq($dst$$Register, $src$$Register); 6126 %} 6127 ins_pipe(ialu_reg); 6128 %} 6129 6130 // Note: Long.bitCount(long) returns an int. 6131 instruct popCountL_mem(rRegI dst, memory mem, rFlagsReg cr) %{ 6132 predicate(UsePopCountInstruction); 6133 match(Set dst (PopCountL (LoadL mem))); 6134 effect(KILL cr); 6135 6136 format %{ "popcnt $dst, $mem" %} 6137 ins_encode %{ 6138 __ popcntq($dst$$Register, $mem$$Address); 6139 %} 6140 ins_pipe(ialu_reg); 6141 %} 6142 6143 6144 //----------MemBar Instructions----------------------------------------------- 6145 // Memory barrier flavors 6146 6147 instruct membar_acquire() 6148 %{ 6149 match(MemBarAcquire); 6150 match(LoadFence); 6151 ins_cost(0); 6152 6153 size(0); 6154 format %{ "MEMBAR-acquire ! (empty encoding)" %} 6155 ins_encode(); 6156 ins_pipe(empty); 6157 %} 6158 6159 instruct membar_acquire_lock() 6160 %{ 6161 match(MemBarAcquireLock); 6162 ins_cost(0); 6163 6164 size(0); 6165 format %{ "MEMBAR-acquire (prior CMPXCHG in FastLock so empty encoding)" %} 6166 ins_encode(); 6167 ins_pipe(empty); 6168 %} 6169 6170 instruct membar_release() 6171 %{ 6172 match(MemBarRelease); 6173 match(StoreFence); 6174 ins_cost(0); 6175 6176 size(0); 6177 format %{ "MEMBAR-release ! (empty encoding)" %} 6178 ins_encode(); 6179 ins_pipe(empty); 6180 %} 6181 6182 instruct membar_release_lock() 6183 %{ 6184 match(MemBarReleaseLock); 6185 ins_cost(0); 6186 6187 size(0); 6188 format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %} 6189 ins_encode(); 6190 ins_pipe(empty); 6191 %} 6192 6193 instruct membar_volatile(rFlagsReg cr) %{ 6194 match(MemBarVolatile); 6195 effect(KILL cr); 6196 ins_cost(400); 6197 6198 format %{ 6199 $$template 6200 if (os::is_MP()) { 6201 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 6202 } else { 6203 $$emit$$"MEMBAR-volatile ! (empty encoding)" 6204 } 6205 %} 6206 ins_encode %{ 6207 __ membar(Assembler::StoreLoad); 6208 %} 6209 ins_pipe(pipe_slow); 6210 %} 6211 6212 instruct unnecessary_membar_volatile() 6213 %{ 6214 match(MemBarVolatile); 6215 predicate(Matcher::post_store_load_barrier(n)); 6216 ins_cost(0); 6217 6218 size(0); 6219 format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %} 6220 ins_encode(); 6221 ins_pipe(empty); 6222 %} 6223 6224 instruct membar_storestore() %{ 6225 match(MemBarStoreStore); 6226 ins_cost(0); 6227 6228 size(0); 6229 format %{ "MEMBAR-storestore (empty encoding)" %} 6230 ins_encode( ); 6231 ins_pipe(empty); 6232 %} 6233 6234 //----------Move Instructions-------------------------------------------------- 6235 6236 instruct castX2P(rRegP dst, rRegL src) 6237 %{ 6238 match(Set dst (CastX2P src)); 6239 6240 format %{ "movq $dst, $src\t# long->ptr" %} 6241 ins_encode %{ 6242 if ($dst$$reg != $src$$reg) { 6243 __ movptr($dst$$Register, $src$$Register); 6244 } 6245 %} 6246 ins_pipe(ialu_reg_reg); // XXX 6247 %} 6248 6249 instruct castP2X(rRegL dst, rRegP src) 6250 %{ 6251 match(Set dst (CastP2X src)); 6252 6253 format %{ "movq $dst, $src\t# ptr -> long" %} 6254 ins_encode %{ 6255 if ($dst$$reg != $src$$reg) { 6256 __ movptr($dst$$Register, $src$$Register); 6257 } 6258 %} 6259 ins_pipe(ialu_reg_reg); // XXX 6260 %} 6261 6262 // Convert oop into int for vectors alignment masking 6263 instruct convP2I(rRegI dst, rRegP src) 6264 %{ 6265 match(Set dst (ConvL2I (CastP2X src))); 6266 6267 format %{ "movl $dst, $src\t# ptr -> int" %} 6268 ins_encode %{ 6269 __ movl($dst$$Register, $src$$Register); 6270 %} 6271 ins_pipe(ialu_reg_reg); // XXX 6272 %} 6273 6274 // Convert compressed oop into int for vectors alignment masking 6275 // in case of 32bit oops (heap < 4Gb). 6276 instruct convN2I(rRegI dst, rRegN src) 6277 %{ 6278 predicate(Universe::narrow_oop_shift() == 0); 6279 match(Set dst (ConvL2I (CastP2X (DecodeN src)))); 6280 6281 format %{ "movl $dst, $src\t# compressed ptr -> int" %} 6282 ins_encode %{ 6283 __ movl($dst$$Register, $src$$Register); 6284 %} 6285 ins_pipe(ialu_reg_reg); // XXX 6286 %} 6287 6288 // Convert oop pointer into compressed form 6289 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{ 6290 predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull); 6291 match(Set dst (EncodeP src)); 6292 effect(KILL cr); 6293 format %{ "encode_heap_oop $dst,$src" %} 6294 ins_encode %{ 6295 Register s = $src$$Register; 6296 Register d = $dst$$Register; 6297 if (s != d) { 6298 __ movq(d, s); 6299 } 6300 __ encode_heap_oop(d); 6301 %} 6302 ins_pipe(ialu_reg_long); 6303 %} 6304 6305 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6306 predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull); 6307 match(Set dst (EncodeP src)); 6308 effect(KILL cr); 6309 format %{ "encode_heap_oop_not_null $dst,$src" %} 6310 ins_encode %{ 6311 __ encode_heap_oop_not_null($dst$$Register, $src$$Register); 6312 %} 6313 ins_pipe(ialu_reg_long); 6314 %} 6315 6316 instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ 6317 predicate(n->bottom_type()->is_ptr()->ptr() != TypePtr::NotNull && 6318 n->bottom_type()->is_ptr()->ptr() != TypePtr::Constant); 6319 match(Set dst (DecodeN src)); 6320 effect(KILL cr); 6321 format %{ "decode_heap_oop $dst,$src" %} 6322 ins_encode %{ 6323 Register s = $src$$Register; 6324 Register d = $dst$$Register; 6325 if (s != d) { 6326 __ movq(d, s); 6327 } 6328 __ decode_heap_oop(d); 6329 %} 6330 ins_pipe(ialu_reg_long); 6331 %} 6332 6333 instruct decodeHeapOop_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6334 predicate(n->bottom_type()->is_ptr()->ptr() == TypePtr::NotNull || 6335 n->bottom_type()->is_ptr()->ptr() == TypePtr::Constant); 6336 match(Set dst (DecodeN src)); 6337 effect(KILL cr); 6338 format %{ "decode_heap_oop_not_null $dst,$src" %} 6339 ins_encode %{ 6340 Register s = $src$$Register; 6341 Register d = $dst$$Register; 6342 if (s != d) { 6343 __ decode_heap_oop_not_null(d, s); 6344 } else { 6345 __ decode_heap_oop_not_null(d); 6346 } 6347 %} 6348 ins_pipe(ialu_reg_long); 6349 %} 6350 6351 instruct encodeKlass_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{ 6352 match(Set dst (EncodePKlass src)); 6353 effect(KILL cr); 6354 format %{ "encode_klass_not_null $dst,$src" %} 6355 ins_encode %{ 6356 __ encode_klass_not_null($dst$$Register, $src$$Register); 6357 %} 6358 ins_pipe(ialu_reg_long); 6359 %} 6360 6361 instruct decodeKlass_not_null(rRegP dst, rRegN src, rFlagsReg cr) %{ 6362 match(Set dst (DecodeNKlass src)); 6363 effect(KILL cr); 6364 format %{ "decode_klass_not_null $dst,$src" %} 6365 ins_encode %{ 6366 Register s = $src$$Register; 6367 Register d = $dst$$Register; 6368 if (s != d) { 6369 __ decode_klass_not_null(d, s); 6370 } else { 6371 __ decode_klass_not_null(d); 6372 } 6373 %} 6374 ins_pipe(ialu_reg_long); 6375 %} 6376 6377 6378 //----------Conditional Move--------------------------------------------------- 6379 // Jump 6380 // dummy instruction for generating temp registers 6381 instruct jumpXtnd_offset(rRegL switch_val, immI2 shift, rRegI dest) %{ 6382 match(Jump (LShiftL switch_val shift)); 6383 ins_cost(350); 6384 predicate(false); 6385 effect(TEMP dest); 6386 6387 format %{ "leaq $dest, [$constantaddress]\n\t" 6388 "jmp [$dest + $switch_val << $shift]\n\t" %} 6389 ins_encode %{ 6390 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6391 // to do that and the compiler is using that register as one it can allocate. 6392 // So we build it all by hand. 6393 // Address index(noreg, switch_reg, (Address::ScaleFactor)$shift$$constant); 6394 // ArrayAddress dispatch(table, index); 6395 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant); 6396 __ lea($dest$$Register, $constantaddress); 6397 __ jmp(dispatch); 6398 %} 6399 ins_pipe(pipe_jmp); 6400 %} 6401 6402 instruct jumpXtnd_addr(rRegL switch_val, immI2 shift, immL32 offset, rRegI dest) %{ 6403 match(Jump (AddL (LShiftL switch_val shift) offset)); 6404 ins_cost(350); 6405 effect(TEMP dest); 6406 6407 format %{ "leaq $dest, [$constantaddress]\n\t" 6408 "jmp [$dest + $switch_val << $shift + $offset]\n\t" %} 6409 ins_encode %{ 6410 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6411 // to do that and the compiler is using that register as one it can allocate. 6412 // So we build it all by hand. 6413 // Address index(noreg, switch_reg, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6414 // ArrayAddress dispatch(table, index); 6415 Address dispatch($dest$$Register, $switch_val$$Register, (Address::ScaleFactor) $shift$$constant, (int) $offset$$constant); 6416 __ lea($dest$$Register, $constantaddress); 6417 __ jmp(dispatch); 6418 %} 6419 ins_pipe(pipe_jmp); 6420 %} 6421 6422 instruct jumpXtnd(rRegL switch_val, rRegI dest) %{ 6423 match(Jump switch_val); 6424 ins_cost(350); 6425 effect(TEMP dest); 6426 6427 format %{ "leaq $dest, [$constantaddress]\n\t" 6428 "jmp [$dest + $switch_val]\n\t" %} 6429 ins_encode %{ 6430 // We could use jump(ArrayAddress) except that the macro assembler needs to use r10 6431 // to do that and the compiler is using that register as one it can allocate. 6432 // So we build it all by hand. 6433 // Address index(noreg, switch_reg, Address::times_1); 6434 // ArrayAddress dispatch(table, index); 6435 Address dispatch($dest$$Register, $switch_val$$Register, Address::times_1); 6436 __ lea($dest$$Register, $constantaddress); 6437 __ jmp(dispatch); 6438 %} 6439 ins_pipe(pipe_jmp); 6440 %} 6441 6442 // Conditional move 6443 instruct cmovI_reg(rRegI dst, rRegI src, rFlagsReg cr, cmpOp cop) 6444 %{ 6445 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6446 6447 ins_cost(200); // XXX 6448 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6449 opcode(0x0F, 0x40); 6450 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6451 ins_pipe(pipe_cmov_reg); 6452 %} 6453 6454 instruct cmovI_regU(cmpOpU cop, rFlagsRegU cr, rRegI dst, rRegI src) %{ 6455 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6456 6457 ins_cost(200); // XXX 6458 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6459 opcode(0x0F, 0x40); 6460 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6461 ins_pipe(pipe_cmov_reg); 6462 %} 6463 6464 instruct cmovI_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, rRegI src) %{ 6465 match(Set dst (CMoveI (Binary cop cr) (Binary dst src))); 6466 ins_cost(200); 6467 expand %{ 6468 cmovI_regU(cop, cr, dst, src); 6469 %} 6470 %} 6471 6472 // Conditional move 6473 instruct cmovI_mem(cmpOp cop, rFlagsReg cr, rRegI dst, memory src) %{ 6474 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6475 6476 ins_cost(250); // XXX 6477 format %{ "cmovl$cop $dst, $src\t# signed, int" %} 6478 opcode(0x0F, 0x40); 6479 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6480 ins_pipe(pipe_cmov_mem); 6481 %} 6482 6483 // Conditional move 6484 instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src) 6485 %{ 6486 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6487 6488 ins_cost(250); // XXX 6489 format %{ "cmovl$cop $dst, $src\t# unsigned, int" %} 6490 opcode(0x0F, 0x40); 6491 ins_encode(REX_reg_mem(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6492 ins_pipe(pipe_cmov_mem); 6493 %} 6494 6495 instruct cmovI_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegI dst, memory src) %{ 6496 match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src)))); 6497 ins_cost(250); 6498 expand %{ 6499 cmovI_memU(cop, cr, dst, src); 6500 %} 6501 %} 6502 6503 // Conditional move 6504 instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop) 6505 %{ 6506 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6507 6508 ins_cost(200); // XXX 6509 format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %} 6510 opcode(0x0F, 0x40); 6511 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6512 ins_pipe(pipe_cmov_reg); 6513 %} 6514 6515 // Conditional move 6516 instruct cmovN_regU(cmpOpU cop, rFlagsRegU cr, rRegN dst, rRegN src) 6517 %{ 6518 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6519 6520 ins_cost(200); // XXX 6521 format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %} 6522 opcode(0x0F, 0x40); 6523 ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6524 ins_pipe(pipe_cmov_reg); 6525 %} 6526 6527 instruct cmovN_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegN dst, rRegN src) %{ 6528 match(Set dst (CMoveN (Binary cop cr) (Binary dst src))); 6529 ins_cost(200); 6530 expand %{ 6531 cmovN_regU(cop, cr, dst, src); 6532 %} 6533 %} 6534 6535 // Conditional move 6536 instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) 6537 %{ 6538 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6539 6540 ins_cost(200); // XXX 6541 format %{ "cmovq$cop $dst, $src\t# signed, ptr" %} 6542 opcode(0x0F, 0x40); 6543 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6544 ins_pipe(pipe_cmov_reg); // XXX 6545 %} 6546 6547 // Conditional move 6548 instruct cmovP_regU(cmpOpU cop, rFlagsRegU cr, rRegP dst, rRegP src) 6549 %{ 6550 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6551 6552 ins_cost(200); // XXX 6553 format %{ "cmovq$cop $dst, $src\t# unsigned, ptr" %} 6554 opcode(0x0F, 0x40); 6555 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6556 ins_pipe(pipe_cmov_reg); // XXX 6557 %} 6558 6559 instruct cmovP_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegP dst, rRegP src) %{ 6560 match(Set dst (CMoveP (Binary cop cr) (Binary dst src))); 6561 ins_cost(200); 6562 expand %{ 6563 cmovP_regU(cop, cr, dst, src); 6564 %} 6565 %} 6566 6567 // DISABLED: Requires the ADLC to emit a bottom_type call that 6568 // correctly meets the two pointer arguments; one is an incoming 6569 // register but the other is a memory operand. ALSO appears to 6570 // be buggy with implicit null checks. 6571 // 6572 //// Conditional move 6573 //instruct cmovP_mem(cmpOp cop, rFlagsReg cr, rRegP dst, memory src) 6574 //%{ 6575 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6576 // ins_cost(250); 6577 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6578 // opcode(0x0F,0x40); 6579 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6580 // ins_pipe( pipe_cmov_mem ); 6581 //%} 6582 // 6583 //// Conditional move 6584 //instruct cmovP_memU(cmpOpU cop, rFlagsRegU cr, rRegP dst, memory src) 6585 //%{ 6586 // match(Set dst (CMoveP (Binary cop cr) (Binary dst (LoadP src)))); 6587 // ins_cost(250); 6588 // format %{ "CMOV$cop $dst,$src\t# ptr" %} 6589 // opcode(0x0F,0x40); 6590 // ins_encode( enc_cmov(cop), reg_mem( dst, src ) ); 6591 // ins_pipe( pipe_cmov_mem ); 6592 //%} 6593 6594 instruct cmovL_reg(cmpOp cop, rFlagsReg cr, rRegL dst, rRegL src) 6595 %{ 6596 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6597 6598 ins_cost(200); // XXX 6599 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6600 opcode(0x0F, 0x40); 6601 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6602 ins_pipe(pipe_cmov_reg); // XXX 6603 %} 6604 6605 instruct cmovL_mem(cmpOp cop, rFlagsReg cr, rRegL dst, memory src) 6606 %{ 6607 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6608 6609 ins_cost(200); // XXX 6610 format %{ "cmovq$cop $dst, $src\t# signed, long" %} 6611 opcode(0x0F, 0x40); 6612 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6613 ins_pipe(pipe_cmov_mem); // XXX 6614 %} 6615 6616 instruct cmovL_regU(cmpOpU cop, rFlagsRegU cr, rRegL dst, rRegL src) 6617 %{ 6618 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6619 6620 ins_cost(200); // XXX 6621 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6622 opcode(0x0F, 0x40); 6623 ins_encode(REX_reg_reg_wide(dst, src), enc_cmov(cop), reg_reg(dst, src)); 6624 ins_pipe(pipe_cmov_reg); // XXX 6625 %} 6626 6627 instruct cmovL_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, rRegL src) %{ 6628 match(Set dst (CMoveL (Binary cop cr) (Binary dst src))); 6629 ins_cost(200); 6630 expand %{ 6631 cmovL_regU(cop, cr, dst, src); 6632 %} 6633 %} 6634 6635 instruct cmovL_memU(cmpOpU cop, rFlagsRegU cr, rRegL dst, memory src) 6636 %{ 6637 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6638 6639 ins_cost(200); // XXX 6640 format %{ "cmovq$cop $dst, $src\t# unsigned, long" %} 6641 opcode(0x0F, 0x40); 6642 ins_encode(REX_reg_mem_wide(dst, src), enc_cmov(cop), reg_mem(dst, src)); 6643 ins_pipe(pipe_cmov_mem); // XXX 6644 %} 6645 6646 instruct cmovL_memUCF(cmpOpUCF cop, rFlagsRegUCF cr, rRegL dst, memory src) %{ 6647 match(Set dst (CMoveL (Binary cop cr) (Binary dst (LoadL src)))); 6648 ins_cost(200); 6649 expand %{ 6650 cmovL_memU(cop, cr, dst, src); 6651 %} 6652 %} 6653 6654 instruct cmovF_reg(cmpOp cop, rFlagsReg cr, regF dst, regF src) 6655 %{ 6656 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6657 6658 ins_cost(200); // XXX 6659 format %{ "jn$cop skip\t# signed cmove float\n\t" 6660 "movss $dst, $src\n" 6661 "skip:" %} 6662 ins_encode %{ 6663 Label Lskip; 6664 // Invert sense of branch from sense of CMOV 6665 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6666 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6667 __ bind(Lskip); 6668 %} 6669 ins_pipe(pipe_slow); 6670 %} 6671 6672 // instruct cmovF_mem(cmpOp cop, rFlagsReg cr, regF dst, memory src) 6673 // %{ 6674 // match(Set dst (CMoveF (Binary cop cr) (Binary dst (LoadL src)))); 6675 6676 // ins_cost(200); // XXX 6677 // format %{ "jn$cop skip\t# signed cmove float\n\t" 6678 // "movss $dst, $src\n" 6679 // "skip:" %} 6680 // ins_encode(enc_cmovf_mem_branch(cop, dst, src)); 6681 // ins_pipe(pipe_slow); 6682 // %} 6683 6684 instruct cmovF_regU(cmpOpU cop, rFlagsRegU cr, regF dst, regF src) 6685 %{ 6686 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6687 6688 ins_cost(200); // XXX 6689 format %{ "jn$cop skip\t# unsigned cmove float\n\t" 6690 "movss $dst, $src\n" 6691 "skip:" %} 6692 ins_encode %{ 6693 Label Lskip; 6694 // Invert sense of branch from sense of CMOV 6695 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6696 __ movflt($dst$$XMMRegister, $src$$XMMRegister); 6697 __ bind(Lskip); 6698 %} 6699 ins_pipe(pipe_slow); 6700 %} 6701 6702 instruct cmovF_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regF dst, regF src) %{ 6703 match(Set dst (CMoveF (Binary cop cr) (Binary dst src))); 6704 ins_cost(200); 6705 expand %{ 6706 cmovF_regU(cop, cr, dst, src); 6707 %} 6708 %} 6709 6710 instruct cmovD_reg(cmpOp cop, rFlagsReg cr, regD dst, regD src) 6711 %{ 6712 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6713 6714 ins_cost(200); // XXX 6715 format %{ "jn$cop skip\t# signed cmove double\n\t" 6716 "movsd $dst, $src\n" 6717 "skip:" %} 6718 ins_encode %{ 6719 Label Lskip; 6720 // Invert sense of branch from sense of CMOV 6721 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6722 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6723 __ bind(Lskip); 6724 %} 6725 ins_pipe(pipe_slow); 6726 %} 6727 6728 instruct cmovD_regU(cmpOpU cop, rFlagsRegU cr, regD dst, regD src) 6729 %{ 6730 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6731 6732 ins_cost(200); // XXX 6733 format %{ "jn$cop skip\t# unsigned cmove double\n\t" 6734 "movsd $dst, $src\n" 6735 "skip:" %} 6736 ins_encode %{ 6737 Label Lskip; 6738 // Invert sense of branch from sense of CMOV 6739 __ jccb((Assembler::Condition)($cop$$cmpcode^1), Lskip); 6740 __ movdbl($dst$$XMMRegister, $src$$XMMRegister); 6741 __ bind(Lskip); 6742 %} 6743 ins_pipe(pipe_slow); 6744 %} 6745 6746 instruct cmovD_regUCF(cmpOpUCF cop, rFlagsRegUCF cr, regD dst, regD src) %{ 6747 match(Set dst (CMoveD (Binary cop cr) (Binary dst src))); 6748 ins_cost(200); 6749 expand %{ 6750 cmovD_regU(cop, cr, dst, src); 6751 %} 6752 %} 6753 6754 //----------Arithmetic Instructions-------------------------------------------- 6755 //----------Addition Instructions---------------------------------------------- 6756 6757 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 6758 %{ 6759 match(Set dst (AddI dst src)); 6760 effect(KILL cr); 6761 6762 format %{ "addl $dst, $src\t# int" %} 6763 opcode(0x03); 6764 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 6765 ins_pipe(ialu_reg_reg); 6766 %} 6767 6768 instruct addI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 6769 %{ 6770 match(Set dst (AddI dst src)); 6771 effect(KILL cr); 6772 6773 format %{ "addl $dst, $src\t# int" %} 6774 opcode(0x81, 0x00); /* /0 id */ 6775 ins_encode(OpcSErm(dst, src), Con8or32(src)); 6776 ins_pipe( ialu_reg ); 6777 %} 6778 6779 instruct addI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 6780 %{ 6781 match(Set dst (AddI dst (LoadI src))); 6782 effect(KILL cr); 6783 6784 ins_cost(125); // XXX 6785 format %{ "addl $dst, $src\t# int" %} 6786 opcode(0x03); 6787 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 6788 ins_pipe(ialu_reg_mem); 6789 %} 6790 6791 instruct addI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 6792 %{ 6793 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6794 effect(KILL cr); 6795 6796 ins_cost(150); // XXX 6797 format %{ "addl $dst, $src\t# int" %} 6798 opcode(0x01); /* Opcode 01 /r */ 6799 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 6800 ins_pipe(ialu_mem_reg); 6801 %} 6802 6803 instruct addI_mem_imm(memory dst, immI src, rFlagsReg cr) 6804 %{ 6805 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6806 effect(KILL cr); 6807 6808 ins_cost(125); // XXX 6809 format %{ "addl $dst, $src\t# int" %} 6810 opcode(0x81); /* Opcode 81 /0 id */ 6811 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 6812 ins_pipe(ialu_mem_imm); 6813 %} 6814 6815 instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 6816 %{ 6817 predicate(UseIncDec); 6818 match(Set dst (AddI dst src)); 6819 effect(KILL cr); 6820 6821 format %{ "incl $dst\t# int" %} 6822 opcode(0xFF, 0x00); // FF /0 6823 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6824 ins_pipe(ialu_reg); 6825 %} 6826 6827 instruct incI_mem(memory dst, immI1 src, rFlagsReg cr) 6828 %{ 6829 predicate(UseIncDec); 6830 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6831 effect(KILL cr); 6832 6833 ins_cost(125); // XXX 6834 format %{ "incl $dst\t# int" %} 6835 opcode(0xFF); /* Opcode FF /0 */ 6836 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x00, dst)); 6837 ins_pipe(ialu_mem_imm); 6838 %} 6839 6840 // XXX why does that use AddI 6841 instruct decI_rReg(rRegI dst, immI_M1 src, rFlagsReg cr) 6842 %{ 6843 predicate(UseIncDec); 6844 match(Set dst (AddI dst src)); 6845 effect(KILL cr); 6846 6847 format %{ "decl $dst\t# int" %} 6848 opcode(0xFF, 0x01); // FF /1 6849 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 6850 ins_pipe(ialu_reg); 6851 %} 6852 6853 // XXX why does that use AddI 6854 instruct decI_mem(memory dst, immI_M1 src, rFlagsReg cr) 6855 %{ 6856 predicate(UseIncDec); 6857 match(Set dst (StoreI dst (AddI (LoadI dst) src))); 6858 effect(KILL cr); 6859 6860 ins_cost(125); // XXX 6861 format %{ "decl $dst\t# int" %} 6862 opcode(0xFF); /* Opcode FF /1 */ 6863 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(0x01, dst)); 6864 ins_pipe(ialu_mem_imm); 6865 %} 6866 6867 instruct leaI_rReg_immI(rRegI dst, rRegI src0, immI src1) 6868 %{ 6869 match(Set dst (AddI src0 src1)); 6870 6871 ins_cost(110); 6872 format %{ "addr32 leal $dst, [$src0 + $src1]\t# int" %} 6873 opcode(0x8D); /* 0x8D /r */ 6874 ins_encode(Opcode(0x67), REX_reg_reg(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 6875 ins_pipe(ialu_reg_reg); 6876 %} 6877 6878 instruct addL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 6879 %{ 6880 match(Set dst (AddL dst src)); 6881 effect(KILL cr); 6882 6883 format %{ "addq $dst, $src\t# long" %} 6884 opcode(0x03); 6885 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 6886 ins_pipe(ialu_reg_reg); 6887 %} 6888 6889 instruct addL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 6890 %{ 6891 match(Set dst (AddL dst src)); 6892 effect(KILL cr); 6893 6894 format %{ "addq $dst, $src\t# long" %} 6895 opcode(0x81, 0x00); /* /0 id */ 6896 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 6897 ins_pipe( ialu_reg ); 6898 %} 6899 6900 instruct addL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 6901 %{ 6902 match(Set dst (AddL dst (LoadL src))); 6903 effect(KILL cr); 6904 6905 ins_cost(125); // XXX 6906 format %{ "addq $dst, $src\t# long" %} 6907 opcode(0x03); 6908 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 6909 ins_pipe(ialu_reg_mem); 6910 %} 6911 6912 instruct addL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 6913 %{ 6914 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6915 effect(KILL cr); 6916 6917 ins_cost(150); // XXX 6918 format %{ "addq $dst, $src\t# long" %} 6919 opcode(0x01); /* Opcode 01 /r */ 6920 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 6921 ins_pipe(ialu_mem_reg); 6922 %} 6923 6924 instruct addL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 6925 %{ 6926 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6927 effect(KILL cr); 6928 6929 ins_cost(125); // XXX 6930 format %{ "addq $dst, $src\t# long" %} 6931 opcode(0x81); /* Opcode 81 /0 id */ 6932 ins_encode(REX_mem_wide(dst), 6933 OpcSE(src), RM_opc_mem(0x00, dst), Con8or32(src)); 6934 ins_pipe(ialu_mem_imm); 6935 %} 6936 6937 instruct incL_rReg(rRegI dst, immL1 src, rFlagsReg cr) 6938 %{ 6939 predicate(UseIncDec); 6940 match(Set dst (AddL dst src)); 6941 effect(KILL cr); 6942 6943 format %{ "incq $dst\t# long" %} 6944 opcode(0xFF, 0x00); // FF /0 6945 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 6946 ins_pipe(ialu_reg); 6947 %} 6948 6949 instruct incL_mem(memory dst, immL1 src, rFlagsReg cr) 6950 %{ 6951 predicate(UseIncDec); 6952 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6953 effect(KILL cr); 6954 6955 ins_cost(125); // XXX 6956 format %{ "incq $dst\t# long" %} 6957 opcode(0xFF); /* Opcode FF /0 */ 6958 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x00, dst)); 6959 ins_pipe(ialu_mem_imm); 6960 %} 6961 6962 // XXX why does that use AddL 6963 instruct decL_rReg(rRegL dst, immL_M1 src, rFlagsReg cr) 6964 %{ 6965 predicate(UseIncDec); 6966 match(Set dst (AddL dst src)); 6967 effect(KILL cr); 6968 6969 format %{ "decq $dst\t# long" %} 6970 opcode(0xFF, 0x01); // FF /1 6971 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 6972 ins_pipe(ialu_reg); 6973 %} 6974 6975 // XXX why does that use AddL 6976 instruct decL_mem(memory dst, immL_M1 src, rFlagsReg cr) 6977 %{ 6978 predicate(UseIncDec); 6979 match(Set dst (StoreL dst (AddL (LoadL dst) src))); 6980 effect(KILL cr); 6981 6982 ins_cost(125); // XXX 6983 format %{ "decq $dst\t# long" %} 6984 opcode(0xFF); /* Opcode FF /1 */ 6985 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(0x01, dst)); 6986 ins_pipe(ialu_mem_imm); 6987 %} 6988 6989 instruct leaL_rReg_immL(rRegL dst, rRegL src0, immL32 src1) 6990 %{ 6991 match(Set dst (AddL src0 src1)); 6992 6993 ins_cost(110); 6994 format %{ "leaq $dst, [$src0 + $src1]\t# long" %} 6995 opcode(0x8D); /* 0x8D /r */ 6996 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1)); // XXX 6997 ins_pipe(ialu_reg_reg); 6998 %} 6999 7000 instruct addP_rReg(rRegP dst, rRegL src, rFlagsReg cr) 7001 %{ 7002 match(Set dst (AddP dst src)); 7003 effect(KILL cr); 7004 7005 format %{ "addq $dst, $src\t# ptr" %} 7006 opcode(0x03); 7007 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7008 ins_pipe(ialu_reg_reg); 7009 %} 7010 7011 instruct addP_rReg_imm(rRegP dst, immL32 src, rFlagsReg cr) 7012 %{ 7013 match(Set dst (AddP dst src)); 7014 effect(KILL cr); 7015 7016 format %{ "addq $dst, $src\t# ptr" %} 7017 opcode(0x81, 0x00); /* /0 id */ 7018 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7019 ins_pipe( ialu_reg ); 7020 %} 7021 7022 // XXX addP mem ops ???? 7023 7024 instruct leaP_rReg_imm(rRegP dst, rRegP src0, immL32 src1) 7025 %{ 7026 match(Set dst (AddP src0 src1)); 7027 7028 ins_cost(110); 7029 format %{ "leaq $dst, [$src0 + $src1]\t# ptr" %} 7030 opcode(0x8D); /* 0x8D /r */ 7031 ins_encode(REX_reg_reg_wide(dst, src0), OpcP, reg_lea(dst, src0, src1));// XXX 7032 ins_pipe(ialu_reg_reg); 7033 %} 7034 7035 instruct checkCastPP(rRegP dst) 7036 %{ 7037 match(Set dst (CheckCastPP dst)); 7038 7039 size(0); 7040 format %{ "# checkcastPP of $dst" %} 7041 ins_encode(/* empty encoding */); 7042 ins_pipe(empty); 7043 %} 7044 7045 instruct castPP(rRegP dst) 7046 %{ 7047 match(Set dst (CastPP dst)); 7048 7049 size(0); 7050 format %{ "# castPP of $dst" %} 7051 ins_encode(/* empty encoding */); 7052 ins_pipe(empty); 7053 %} 7054 7055 instruct castII(rRegI dst) 7056 %{ 7057 match(Set dst (CastII dst)); 7058 7059 size(0); 7060 format %{ "# castII of $dst" %} 7061 ins_encode(/* empty encoding */); 7062 ins_cost(0); 7063 ins_pipe(empty); 7064 %} 7065 7066 // LoadP-locked same as a regular LoadP when used with compare-swap 7067 instruct loadPLocked(rRegP dst, memory mem) 7068 %{ 7069 match(Set dst (LoadPLocked mem)); 7070 7071 ins_cost(125); // XXX 7072 format %{ "movq $dst, $mem\t# ptr locked" %} 7073 opcode(0x8B); 7074 ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem)); 7075 ins_pipe(ialu_reg_mem); // XXX 7076 %} 7077 7078 // Conditional-store of the updated heap-top. 7079 // Used during allocation of the shared heap. 7080 // Sets flags (EQ) on success. Implemented with a CMPXCHG on Intel. 7081 7082 instruct storePConditional(memory heap_top_ptr, 7083 rax_RegP oldval, rRegP newval, 7084 rFlagsReg cr) 7085 %{ 7086 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 7087 7088 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 7089 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 7090 opcode(0x0F, 0xB1); 7091 ins_encode(lock_prefix, 7092 REX_reg_mem_wide(newval, heap_top_ptr), 7093 OpcP, OpcS, 7094 reg_mem(newval, heap_top_ptr)); 7095 ins_pipe(pipe_cmpxchg); 7096 %} 7097 7098 // Conditional-store of an int value. 7099 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7100 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) 7101 %{ 7102 match(Set cr (StoreIConditional mem (Binary oldval newval))); 7103 effect(KILL oldval); 7104 7105 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7106 opcode(0x0F, 0xB1); 7107 ins_encode(lock_prefix, 7108 REX_reg_mem(newval, mem), 7109 OpcP, OpcS, 7110 reg_mem(newval, mem)); 7111 ins_pipe(pipe_cmpxchg); 7112 %} 7113 7114 // Conditional-store of a long value. 7115 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. 7116 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) 7117 %{ 7118 match(Set cr (StoreLConditional mem (Binary oldval newval))); 7119 effect(KILL oldval); 7120 7121 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} 7122 opcode(0x0F, 0xB1); 7123 ins_encode(lock_prefix, 7124 REX_reg_mem_wide(newval, mem), 7125 OpcP, OpcS, 7126 reg_mem(newval, mem)); 7127 ins_pipe(pipe_cmpxchg); 7128 %} 7129 7130 7131 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7132 instruct compareAndSwapP(rRegI res, 7133 memory mem_ptr, 7134 rax_RegP oldval, rRegP newval, 7135 rFlagsReg cr) 7136 %{ 7137 predicate(VM_Version::supports_cx8()); 7138 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7139 effect(KILL cr, KILL oldval); 7140 7141 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7142 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7143 "sete $res\n\t" 7144 "movzbl $res, $res" %} 7145 opcode(0x0F, 0xB1); 7146 ins_encode(lock_prefix, 7147 REX_reg_mem_wide(newval, mem_ptr), 7148 OpcP, OpcS, 7149 reg_mem(newval, mem_ptr), 7150 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7151 REX_reg_breg(res, res), // movzbl 7152 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7153 ins_pipe( pipe_cmpxchg ); 7154 %} 7155 7156 instruct compareAndSwapL(rRegI res, 7157 memory mem_ptr, 7158 rax_RegL oldval, rRegL newval, 7159 rFlagsReg cr) 7160 %{ 7161 predicate(VM_Version::supports_cx8()); 7162 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7163 effect(KILL cr, KILL oldval); 7164 7165 format %{ "cmpxchgq $mem_ptr,$newval\t# " 7166 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7167 "sete $res\n\t" 7168 "movzbl $res, $res" %} 7169 opcode(0x0F, 0xB1); 7170 ins_encode(lock_prefix, 7171 REX_reg_mem_wide(newval, mem_ptr), 7172 OpcP, OpcS, 7173 reg_mem(newval, mem_ptr), 7174 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7175 REX_reg_breg(res, res), // movzbl 7176 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7177 ins_pipe( pipe_cmpxchg ); 7178 %} 7179 7180 instruct compareAndSwapI(rRegI res, 7181 memory mem_ptr, 7182 rax_RegI oldval, rRegI newval, 7183 rFlagsReg cr) 7184 %{ 7185 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7186 effect(KILL cr, KILL oldval); 7187 7188 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7189 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7190 "sete $res\n\t" 7191 "movzbl $res, $res" %} 7192 opcode(0x0F, 0xB1); 7193 ins_encode(lock_prefix, 7194 REX_reg_mem(newval, mem_ptr), 7195 OpcP, OpcS, 7196 reg_mem(newval, mem_ptr), 7197 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7198 REX_reg_breg(res, res), // movzbl 7199 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7200 ins_pipe( pipe_cmpxchg ); 7201 %} 7202 7203 7204 instruct compareAndSwapN(rRegI res, 7205 memory mem_ptr, 7206 rax_RegN oldval, rRegN newval, 7207 rFlagsReg cr) %{ 7208 match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); 7209 effect(KILL cr, KILL oldval); 7210 7211 format %{ "cmpxchgl $mem_ptr,$newval\t# " 7212 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" 7213 "sete $res\n\t" 7214 "movzbl $res, $res" %} 7215 opcode(0x0F, 0xB1); 7216 ins_encode(lock_prefix, 7217 REX_reg_mem(newval, mem_ptr), 7218 OpcP, OpcS, 7219 reg_mem(newval, mem_ptr), 7220 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete 7221 REX_reg_breg(res, res), // movzbl 7222 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); 7223 ins_pipe( pipe_cmpxchg ); 7224 %} 7225 7226 instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{ 7227 predicate(n->as_LoadStore()->result_not_used()); 7228 match(Set dummy (GetAndAddI mem add)); 7229 effect(KILL cr); 7230 format %{ "ADDL [$mem],$add" %} 7231 ins_encode %{ 7232 if (os::is_MP()) { __ lock(); } 7233 __ addl($mem$$Address, $add$$constant); 7234 %} 7235 ins_pipe( pipe_cmpxchg ); 7236 %} 7237 7238 instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{ 7239 match(Set newval (GetAndAddI mem newval)); 7240 effect(KILL cr); 7241 format %{ "XADDL [$mem],$newval" %} 7242 ins_encode %{ 7243 if (os::is_MP()) { __ lock(); } 7244 __ xaddl($mem$$Address, $newval$$Register); 7245 %} 7246 ins_pipe( pipe_cmpxchg ); 7247 %} 7248 7249 instruct xaddL_no_res( memory mem, Universe dummy, immL32 add, rFlagsReg cr) %{ 7250 predicate(n->as_LoadStore()->result_not_used()); 7251 match(Set dummy (GetAndAddL mem add)); 7252 effect(KILL cr); 7253 format %{ "ADDQ [$mem],$add" %} 7254 ins_encode %{ 7255 if (os::is_MP()) { __ lock(); } 7256 __ addq($mem$$Address, $add$$constant); 7257 %} 7258 ins_pipe( pipe_cmpxchg ); 7259 %} 7260 7261 instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{ 7262 match(Set newval (GetAndAddL mem newval)); 7263 effect(KILL cr); 7264 format %{ "XADDQ [$mem],$newval" %} 7265 ins_encode %{ 7266 if (os::is_MP()) { __ lock(); } 7267 __ xaddq($mem$$Address, $newval$$Register); 7268 %} 7269 ins_pipe( pipe_cmpxchg ); 7270 %} 7271 7272 instruct xchgI( memory mem, rRegI newval) %{ 7273 match(Set newval (GetAndSetI mem newval)); 7274 format %{ "XCHGL $newval,[$mem]" %} 7275 ins_encode %{ 7276 __ xchgl($newval$$Register, $mem$$Address); 7277 %} 7278 ins_pipe( pipe_cmpxchg ); 7279 %} 7280 7281 instruct xchgL( memory mem, rRegL newval) %{ 7282 match(Set newval (GetAndSetL mem newval)); 7283 format %{ "XCHGL $newval,[$mem]" %} 7284 ins_encode %{ 7285 __ xchgq($newval$$Register, $mem$$Address); 7286 %} 7287 ins_pipe( pipe_cmpxchg ); 7288 %} 7289 7290 instruct xchgP( memory mem, rRegP newval) %{ 7291 match(Set newval (GetAndSetP mem newval)); 7292 format %{ "XCHGQ $newval,[$mem]" %} 7293 ins_encode %{ 7294 __ xchgq($newval$$Register, $mem$$Address); 7295 %} 7296 ins_pipe( pipe_cmpxchg ); 7297 %} 7298 7299 instruct xchgN( memory mem, rRegN newval) %{ 7300 match(Set newval (GetAndSetN mem newval)); 7301 format %{ "XCHGL $newval,$mem]" %} 7302 ins_encode %{ 7303 __ xchgl($newval$$Register, $mem$$Address); 7304 %} 7305 ins_pipe( pipe_cmpxchg ); 7306 %} 7307 7308 //----------Subtraction Instructions------------------------------------------- 7309 7310 // Integer Subtraction Instructions 7311 instruct subI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7312 %{ 7313 match(Set dst (SubI dst src)); 7314 effect(KILL cr); 7315 7316 format %{ "subl $dst, $src\t# int" %} 7317 opcode(0x2B); 7318 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 7319 ins_pipe(ialu_reg_reg); 7320 %} 7321 7322 instruct subI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 7323 %{ 7324 match(Set dst (SubI dst src)); 7325 effect(KILL cr); 7326 7327 format %{ "subl $dst, $src\t# int" %} 7328 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7329 ins_encode(OpcSErm(dst, src), Con8or32(src)); 7330 ins_pipe(ialu_reg); 7331 %} 7332 7333 instruct subI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 7334 %{ 7335 match(Set dst (SubI dst (LoadI src))); 7336 effect(KILL cr); 7337 7338 ins_cost(125); 7339 format %{ "subl $dst, $src\t# int" %} 7340 opcode(0x2B); 7341 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 7342 ins_pipe(ialu_reg_mem); 7343 %} 7344 7345 instruct subI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 7346 %{ 7347 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7348 effect(KILL cr); 7349 7350 ins_cost(150); 7351 format %{ "subl $dst, $src\t# int" %} 7352 opcode(0x29); /* Opcode 29 /r */ 7353 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 7354 ins_pipe(ialu_mem_reg); 7355 %} 7356 7357 instruct subI_mem_imm(memory dst, immI src, rFlagsReg cr) 7358 %{ 7359 match(Set dst (StoreI dst (SubI (LoadI dst) src))); 7360 effect(KILL cr); 7361 7362 ins_cost(125); // XXX 7363 format %{ "subl $dst, $src\t# int" %} 7364 opcode(0x81); /* Opcode 81 /5 id */ 7365 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7366 ins_pipe(ialu_mem_imm); 7367 %} 7368 7369 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7370 %{ 7371 match(Set dst (SubL dst src)); 7372 effect(KILL cr); 7373 7374 format %{ "subq $dst, $src\t# long" %} 7375 opcode(0x2B); 7376 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7377 ins_pipe(ialu_reg_reg); 7378 %} 7379 7380 instruct subL_rReg_imm(rRegI dst, immL32 src, rFlagsReg cr) 7381 %{ 7382 match(Set dst (SubL dst src)); 7383 effect(KILL cr); 7384 7385 format %{ "subq $dst, $src\t# long" %} 7386 opcode(0x81, 0x05); /* Opcode 81 /5 */ 7387 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 7388 ins_pipe(ialu_reg); 7389 %} 7390 7391 instruct subL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 7392 %{ 7393 match(Set dst (SubL dst (LoadL src))); 7394 effect(KILL cr); 7395 7396 ins_cost(125); 7397 format %{ "subq $dst, $src\t# long" %} 7398 opcode(0x2B); 7399 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 7400 ins_pipe(ialu_reg_mem); 7401 %} 7402 7403 instruct subL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 7404 %{ 7405 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7406 effect(KILL cr); 7407 7408 ins_cost(150); 7409 format %{ "subq $dst, $src\t# long" %} 7410 opcode(0x29); /* Opcode 29 /r */ 7411 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 7412 ins_pipe(ialu_mem_reg); 7413 %} 7414 7415 instruct subL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 7416 %{ 7417 match(Set dst (StoreL dst (SubL (LoadL dst) src))); 7418 effect(KILL cr); 7419 7420 ins_cost(125); // XXX 7421 format %{ "subq $dst, $src\t# long" %} 7422 opcode(0x81); /* Opcode 81 /5 id */ 7423 ins_encode(REX_mem_wide(dst), 7424 OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); 7425 ins_pipe(ialu_mem_imm); 7426 %} 7427 7428 // Subtract from a pointer 7429 // XXX hmpf??? 7430 instruct subP_rReg(rRegP dst, rRegI src, immI0 zero, rFlagsReg cr) 7431 %{ 7432 match(Set dst (AddP dst (SubI zero src))); 7433 effect(KILL cr); 7434 7435 format %{ "subq $dst, $src\t# ptr - int" %} 7436 opcode(0x2B); 7437 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 7438 ins_pipe(ialu_reg_reg); 7439 %} 7440 7441 instruct negI_rReg(rRegI dst, immI0 zero, rFlagsReg cr) 7442 %{ 7443 match(Set dst (SubI zero dst)); 7444 effect(KILL cr); 7445 7446 format %{ "negl $dst\t# int" %} 7447 opcode(0xF7, 0x03); // Opcode F7 /3 7448 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7449 ins_pipe(ialu_reg); 7450 %} 7451 7452 instruct negI_mem(memory dst, immI0 zero, rFlagsReg cr) 7453 %{ 7454 match(Set dst (StoreI dst (SubI zero (LoadI dst)))); 7455 effect(KILL cr); 7456 7457 format %{ "negl $dst\t# int" %} 7458 opcode(0xF7, 0x03); // Opcode F7 /3 7459 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7460 ins_pipe(ialu_reg); 7461 %} 7462 7463 instruct negL_rReg(rRegL dst, immL0 zero, rFlagsReg cr) 7464 %{ 7465 match(Set dst (SubL zero dst)); 7466 effect(KILL cr); 7467 7468 format %{ "negq $dst\t# long" %} 7469 opcode(0xF7, 0x03); // Opcode F7 /3 7470 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 7471 ins_pipe(ialu_reg); 7472 %} 7473 7474 instruct negL_mem(memory dst, immL0 zero, rFlagsReg cr) 7475 %{ 7476 match(Set dst (StoreL dst (SubL zero (LoadL dst)))); 7477 effect(KILL cr); 7478 7479 format %{ "negq $dst\t# long" %} 7480 opcode(0xF7, 0x03); // Opcode F7 /3 7481 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 7482 ins_pipe(ialu_reg); 7483 %} 7484 7485 //----------Multiplication/Division Instructions------------------------------- 7486 // Integer Multiplication Instructions 7487 // Multiply Register 7488 7489 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 7490 %{ 7491 match(Set dst (MulI dst src)); 7492 effect(KILL cr); 7493 7494 ins_cost(300); 7495 format %{ "imull $dst, $src\t# int" %} 7496 opcode(0x0F, 0xAF); 7497 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7498 ins_pipe(ialu_reg_reg_alu0); 7499 %} 7500 7501 instruct mulI_rReg_imm(rRegI dst, rRegI src, immI imm, rFlagsReg cr) 7502 %{ 7503 match(Set dst (MulI src imm)); 7504 effect(KILL cr); 7505 7506 ins_cost(300); 7507 format %{ "imull $dst, $src, $imm\t# int" %} 7508 opcode(0x69); /* 69 /r id */ 7509 ins_encode(REX_reg_reg(dst, src), 7510 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7511 ins_pipe(ialu_reg_reg_alu0); 7512 %} 7513 7514 instruct mulI_mem(rRegI dst, memory src, rFlagsReg cr) 7515 %{ 7516 match(Set dst (MulI dst (LoadI src))); 7517 effect(KILL cr); 7518 7519 ins_cost(350); 7520 format %{ "imull $dst, $src\t# int" %} 7521 opcode(0x0F, 0xAF); 7522 ins_encode(REX_reg_mem(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7523 ins_pipe(ialu_reg_mem_alu0); 7524 %} 7525 7526 instruct mulI_mem_imm(rRegI dst, memory src, immI imm, rFlagsReg cr) 7527 %{ 7528 match(Set dst (MulI (LoadI src) imm)); 7529 effect(KILL cr); 7530 7531 ins_cost(300); 7532 format %{ "imull $dst, $src, $imm\t# int" %} 7533 opcode(0x69); /* 69 /r id */ 7534 ins_encode(REX_reg_mem(dst, src), 7535 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7536 ins_pipe(ialu_reg_mem_alu0); 7537 %} 7538 7539 instruct mulL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 7540 %{ 7541 match(Set dst (MulL dst src)); 7542 effect(KILL cr); 7543 7544 ins_cost(300); 7545 format %{ "imulq $dst, $src\t# long" %} 7546 opcode(0x0F, 0xAF); 7547 ins_encode(REX_reg_reg_wide(dst, src), OpcP, OpcS, reg_reg(dst, src)); 7548 ins_pipe(ialu_reg_reg_alu0); 7549 %} 7550 7551 instruct mulL_rReg_imm(rRegL dst, rRegL src, immL32 imm, rFlagsReg cr) 7552 %{ 7553 match(Set dst (MulL src imm)); 7554 effect(KILL cr); 7555 7556 ins_cost(300); 7557 format %{ "imulq $dst, $src, $imm\t# long" %} 7558 opcode(0x69); /* 69 /r id */ 7559 ins_encode(REX_reg_reg_wide(dst, src), 7560 OpcSE(imm), reg_reg(dst, src), Con8or32(imm)); 7561 ins_pipe(ialu_reg_reg_alu0); 7562 %} 7563 7564 instruct mulL_mem(rRegL dst, memory src, rFlagsReg cr) 7565 %{ 7566 match(Set dst (MulL dst (LoadL src))); 7567 effect(KILL cr); 7568 7569 ins_cost(350); 7570 format %{ "imulq $dst, $src\t# long" %} 7571 opcode(0x0F, 0xAF); 7572 ins_encode(REX_reg_mem_wide(dst, src), OpcP, OpcS, reg_mem(dst, src)); 7573 ins_pipe(ialu_reg_mem_alu0); 7574 %} 7575 7576 instruct mulL_mem_imm(rRegL dst, memory src, immL32 imm, rFlagsReg cr) 7577 %{ 7578 match(Set dst (MulL (LoadL src) imm)); 7579 effect(KILL cr); 7580 7581 ins_cost(300); 7582 format %{ "imulq $dst, $src, $imm\t# long" %} 7583 opcode(0x69); /* 69 /r id */ 7584 ins_encode(REX_reg_mem_wide(dst, src), 7585 OpcSE(imm), reg_mem(dst, src), Con8or32(imm)); 7586 ins_pipe(ialu_reg_mem_alu0); 7587 %} 7588 7589 instruct mulHiL_rReg(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7590 %{ 7591 match(Set dst (MulHiL src rax)); 7592 effect(USE_KILL rax, KILL cr); 7593 7594 ins_cost(300); 7595 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} 7596 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7597 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7598 ins_pipe(ialu_reg_reg_alu0); 7599 %} 7600 7601 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7602 rFlagsReg cr) 7603 %{ 7604 match(Set rax (DivI rax div)); 7605 effect(KILL rdx, KILL cr); 7606 7607 ins_cost(30*100+10*100); // XXX 7608 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7609 "jne,s normal\n\t" 7610 "xorl rdx, rdx\n\t" 7611 "cmpl $div, -1\n\t" 7612 "je,s done\n" 7613 "normal: cdql\n\t" 7614 "idivl $div\n" 7615 "done:" %} 7616 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7617 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7618 ins_pipe(ialu_reg_reg_alu0); 7619 %} 7620 7621 instruct divL_rReg(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7622 rFlagsReg cr) 7623 %{ 7624 match(Set rax (DivL rax div)); 7625 effect(KILL rdx, KILL cr); 7626 7627 ins_cost(30*100+10*100); // XXX 7628 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7629 "cmpq rax, rdx\n\t" 7630 "jne,s normal\n\t" 7631 "xorl rdx, rdx\n\t" 7632 "cmpq $div, -1\n\t" 7633 "je,s done\n" 7634 "normal: cdqq\n\t" 7635 "idivq $div\n" 7636 "done:" %} 7637 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7638 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7639 ins_pipe(ialu_reg_reg_alu0); 7640 %} 7641 7642 // Integer DIVMOD with Register, both quotient and mod results 7643 instruct divModI_rReg_divmod(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, 7644 rFlagsReg cr) 7645 %{ 7646 match(DivModI rax div); 7647 effect(KILL cr); 7648 7649 ins_cost(30*100+10*100); // XXX 7650 format %{ "cmpl rax, 0x80000000\t# idiv\n\t" 7651 "jne,s normal\n\t" 7652 "xorl rdx, rdx\n\t" 7653 "cmpl $div, -1\n\t" 7654 "je,s done\n" 7655 "normal: cdql\n\t" 7656 "idivl $div\n" 7657 "done:" %} 7658 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7659 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7660 ins_pipe(pipe_slow); 7661 %} 7662 7663 // Long DIVMOD with Register, both quotient and mod results 7664 instruct divModL_rReg_divmod(rax_RegL rax, rdx_RegL rdx, no_rax_rdx_RegL div, 7665 rFlagsReg cr) 7666 %{ 7667 match(DivModL rax div); 7668 effect(KILL cr); 7669 7670 ins_cost(30*100+10*100); // XXX 7671 format %{ "movq rdx, 0x8000000000000000\t# ldiv\n\t" 7672 "cmpq rax, rdx\n\t" 7673 "jne,s normal\n\t" 7674 "xorl rdx, rdx\n\t" 7675 "cmpq $div, -1\n\t" 7676 "je,s done\n" 7677 "normal: cdqq\n\t" 7678 "idivq $div\n" 7679 "done:" %} 7680 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7681 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7682 ins_pipe(pipe_slow); 7683 %} 7684 7685 //----------- DivL-By-Constant-Expansions-------------------------------------- 7686 // DivI cases are handled by the compiler 7687 7688 // Magic constant, reciprocal of 10 7689 instruct loadConL_0x6666666666666667(rRegL dst) 7690 %{ 7691 effect(DEF dst); 7692 7693 format %{ "movq $dst, #0x666666666666667\t# Used in div-by-10" %} 7694 ins_encode(load_immL(dst, 0x6666666666666667)); 7695 ins_pipe(ialu_reg); 7696 %} 7697 7698 instruct mul_hi(rdx_RegL dst, no_rax_RegL src, rax_RegL rax, rFlagsReg cr) 7699 %{ 7700 effect(DEF dst, USE src, USE_KILL rax, KILL cr); 7701 7702 format %{ "imulq rdx:rax, rax, $src\t# Used in div-by-10" %} 7703 opcode(0xF7, 0x5); /* Opcode F7 /5 */ 7704 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); 7705 ins_pipe(ialu_reg_reg_alu0); 7706 %} 7707 7708 instruct sarL_rReg_63(rRegL dst, rFlagsReg cr) 7709 %{ 7710 effect(USE_DEF dst, KILL cr); 7711 7712 format %{ "sarq $dst, #63\t# Used in div-by-10" %} 7713 opcode(0xC1, 0x7); /* C1 /7 ib */ 7714 ins_encode(reg_opc_imm_wide(dst, 0x3F)); 7715 ins_pipe(ialu_reg); 7716 %} 7717 7718 instruct sarL_rReg_2(rRegL dst, rFlagsReg cr) 7719 %{ 7720 effect(USE_DEF dst, KILL cr); 7721 7722 format %{ "sarq $dst, #2\t# Used in div-by-10" %} 7723 opcode(0xC1, 0x7); /* C1 /7 ib */ 7724 ins_encode(reg_opc_imm_wide(dst, 0x2)); 7725 ins_pipe(ialu_reg); 7726 %} 7727 7728 instruct divL_10(rdx_RegL dst, no_rax_RegL src, immL10 div) 7729 %{ 7730 match(Set dst (DivL src div)); 7731 7732 ins_cost((5+8)*100); 7733 expand %{ 7734 rax_RegL rax; // Killed temp 7735 rFlagsReg cr; // Killed 7736 loadConL_0x6666666666666667(rax); // movq rax, 0x6666666666666667 7737 mul_hi(dst, src, rax, cr); // mulq rdx:rax <= rax * $src 7738 sarL_rReg_63(src, cr); // sarq src, 63 7739 sarL_rReg_2(dst, cr); // sarq rdx, 2 7740 subL_rReg(dst, src, cr); // subl rdx, src 7741 %} 7742 %} 7743 7744 //----------------------------------------------------------------------------- 7745 7746 instruct modI_rReg(rdx_RegI rdx, rax_RegI rax, no_rax_rdx_RegI div, 7747 rFlagsReg cr) 7748 %{ 7749 match(Set rdx (ModI rax div)); 7750 effect(KILL rax, KILL cr); 7751 7752 ins_cost(300); // XXX 7753 format %{ "cmpl rax, 0x80000000\t# irem\n\t" 7754 "jne,s normal\n\t" 7755 "xorl rdx, rdx\n\t" 7756 "cmpl $div, -1\n\t" 7757 "je,s done\n" 7758 "normal: cdql\n\t" 7759 "idivl $div\n" 7760 "done:" %} 7761 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7762 ins_encode(cdql_enc(div), REX_reg(div), OpcP, reg_opc(div)); 7763 ins_pipe(ialu_reg_reg_alu0); 7764 %} 7765 7766 instruct modL_rReg(rdx_RegL rdx, rax_RegL rax, no_rax_rdx_RegL div, 7767 rFlagsReg cr) 7768 %{ 7769 match(Set rdx (ModL rax div)); 7770 effect(KILL rax, KILL cr); 7771 7772 ins_cost(300); // XXX 7773 format %{ "movq rdx, 0x8000000000000000\t# lrem\n\t" 7774 "cmpq rax, rdx\n\t" 7775 "jne,s normal\n\t" 7776 "xorl rdx, rdx\n\t" 7777 "cmpq $div, -1\n\t" 7778 "je,s done\n" 7779 "normal: cdqq\n\t" 7780 "idivq $div\n" 7781 "done:" %} 7782 opcode(0xF7, 0x7); /* Opcode F7 /7 */ 7783 ins_encode(cdqq_enc(div), REX_reg_wide(div), OpcP, reg_opc(div)); 7784 ins_pipe(ialu_reg_reg_alu0); 7785 %} 7786 7787 // Integer Shift Instructions 7788 // Shift Left by one 7789 instruct salI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7790 %{ 7791 match(Set dst (LShiftI dst shift)); 7792 effect(KILL cr); 7793 7794 format %{ "sall $dst, $shift" %} 7795 opcode(0xD1, 0x4); /* D1 /4 */ 7796 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7797 ins_pipe(ialu_reg); 7798 %} 7799 7800 // Shift Left by one 7801 instruct salI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7802 %{ 7803 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7804 effect(KILL cr); 7805 7806 format %{ "sall $dst, $shift\t" %} 7807 opcode(0xD1, 0x4); /* D1 /4 */ 7808 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7809 ins_pipe(ialu_mem_imm); 7810 %} 7811 7812 // Shift Left by 8-bit immediate 7813 instruct salI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7814 %{ 7815 match(Set dst (LShiftI dst shift)); 7816 effect(KILL cr); 7817 7818 format %{ "sall $dst, $shift" %} 7819 opcode(0xC1, 0x4); /* C1 /4 ib */ 7820 ins_encode(reg_opc_imm(dst, shift)); 7821 ins_pipe(ialu_reg); 7822 %} 7823 7824 // Shift Left by 8-bit immediate 7825 instruct salI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7826 %{ 7827 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7828 effect(KILL cr); 7829 7830 format %{ "sall $dst, $shift" %} 7831 opcode(0xC1, 0x4); /* C1 /4 ib */ 7832 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7833 ins_pipe(ialu_mem_imm); 7834 %} 7835 7836 // Shift Left by variable 7837 instruct salI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7838 %{ 7839 match(Set dst (LShiftI dst shift)); 7840 effect(KILL cr); 7841 7842 format %{ "sall $dst, $shift" %} 7843 opcode(0xD3, 0x4); /* D3 /4 */ 7844 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7845 ins_pipe(ialu_reg_reg); 7846 %} 7847 7848 // Shift Left by variable 7849 instruct salI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7850 %{ 7851 match(Set dst (StoreI dst (LShiftI (LoadI dst) shift))); 7852 effect(KILL cr); 7853 7854 format %{ "sall $dst, $shift" %} 7855 opcode(0xD3, 0x4); /* D3 /4 */ 7856 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7857 ins_pipe(ialu_mem_reg); 7858 %} 7859 7860 // Arithmetic shift right by one 7861 instruct sarI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7862 %{ 7863 match(Set dst (RShiftI dst shift)); 7864 effect(KILL cr); 7865 7866 format %{ "sarl $dst, $shift" %} 7867 opcode(0xD1, 0x7); /* D1 /7 */ 7868 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7869 ins_pipe(ialu_reg); 7870 %} 7871 7872 // Arithmetic shift right by one 7873 instruct sarI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7874 %{ 7875 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 7876 effect(KILL cr); 7877 7878 format %{ "sarl $dst, $shift" %} 7879 opcode(0xD1, 0x7); /* D1 /7 */ 7880 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7881 ins_pipe(ialu_mem_imm); 7882 %} 7883 7884 // Arithmetic Shift Right by 8-bit immediate 7885 instruct sarI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7886 %{ 7887 match(Set dst (RShiftI dst shift)); 7888 effect(KILL cr); 7889 7890 format %{ "sarl $dst, $shift" %} 7891 opcode(0xC1, 0x7); /* C1 /7 ib */ 7892 ins_encode(reg_opc_imm(dst, shift)); 7893 ins_pipe(ialu_mem_imm); 7894 %} 7895 7896 // Arithmetic Shift Right by 8-bit immediate 7897 instruct sarI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7898 %{ 7899 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 7900 effect(KILL cr); 7901 7902 format %{ "sarl $dst, $shift" %} 7903 opcode(0xC1, 0x7); /* C1 /7 ib */ 7904 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7905 ins_pipe(ialu_mem_imm); 7906 %} 7907 7908 // Arithmetic Shift Right by variable 7909 instruct sarI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7910 %{ 7911 match(Set dst (RShiftI dst shift)); 7912 effect(KILL cr); 7913 7914 format %{ "sarl $dst, $shift" %} 7915 opcode(0xD3, 0x7); /* D3 /7 */ 7916 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7917 ins_pipe(ialu_reg_reg); 7918 %} 7919 7920 // Arithmetic Shift Right by variable 7921 instruct sarI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7922 %{ 7923 match(Set dst (StoreI dst (RShiftI (LoadI dst) shift))); 7924 effect(KILL cr); 7925 7926 format %{ "sarl $dst, $shift" %} 7927 opcode(0xD3, 0x7); /* D3 /7 */ 7928 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7929 ins_pipe(ialu_mem_reg); 7930 %} 7931 7932 // Logical shift right by one 7933 instruct shrI_rReg_1(rRegI dst, immI1 shift, rFlagsReg cr) 7934 %{ 7935 match(Set dst (URShiftI dst shift)); 7936 effect(KILL cr); 7937 7938 format %{ "shrl $dst, $shift" %} 7939 opcode(0xD1, 0x5); /* D1 /5 */ 7940 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7941 ins_pipe(ialu_reg); 7942 %} 7943 7944 // Logical shift right by one 7945 instruct shrI_mem_1(memory dst, immI1 shift, rFlagsReg cr) 7946 %{ 7947 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 7948 effect(KILL cr); 7949 7950 format %{ "shrl $dst, $shift" %} 7951 opcode(0xD1, 0x5); /* D1 /5 */ 7952 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 7953 ins_pipe(ialu_mem_imm); 7954 %} 7955 7956 // Logical Shift Right by 8-bit immediate 7957 instruct shrI_rReg_imm(rRegI dst, immI8 shift, rFlagsReg cr) 7958 %{ 7959 match(Set dst (URShiftI dst shift)); 7960 effect(KILL cr); 7961 7962 format %{ "shrl $dst, $shift" %} 7963 opcode(0xC1, 0x5); /* C1 /5 ib */ 7964 ins_encode(reg_opc_imm(dst, shift)); 7965 ins_pipe(ialu_reg); 7966 %} 7967 7968 // Logical Shift Right by 8-bit immediate 7969 instruct shrI_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 7970 %{ 7971 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 7972 effect(KILL cr); 7973 7974 format %{ "shrl $dst, $shift" %} 7975 opcode(0xC1, 0x5); /* C1 /5 ib */ 7976 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst), Con8or32(shift)); 7977 ins_pipe(ialu_mem_imm); 7978 %} 7979 7980 // Logical Shift Right by variable 7981 instruct shrI_rReg_CL(rRegI dst, rcx_RegI shift, rFlagsReg cr) 7982 %{ 7983 match(Set dst (URShiftI dst shift)); 7984 effect(KILL cr); 7985 7986 format %{ "shrl $dst, $shift" %} 7987 opcode(0xD3, 0x5); /* D3 /5 */ 7988 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 7989 ins_pipe(ialu_reg_reg); 7990 %} 7991 7992 // Logical Shift Right by variable 7993 instruct shrI_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 7994 %{ 7995 match(Set dst (StoreI dst (URShiftI (LoadI dst) shift))); 7996 effect(KILL cr); 7997 7998 format %{ "shrl $dst, $shift" %} 7999 opcode(0xD3, 0x5); /* D3 /5 */ 8000 ins_encode(REX_mem(dst), OpcP, RM_opc_mem(secondary, dst)); 8001 ins_pipe(ialu_mem_reg); 8002 %} 8003 8004 // Long Shift Instructions 8005 // Shift Left by one 8006 instruct salL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8007 %{ 8008 match(Set dst (LShiftL dst shift)); 8009 effect(KILL cr); 8010 8011 format %{ "salq $dst, $shift" %} 8012 opcode(0xD1, 0x4); /* D1 /4 */ 8013 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8014 ins_pipe(ialu_reg); 8015 %} 8016 8017 // Shift Left by one 8018 instruct salL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8019 %{ 8020 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8021 effect(KILL cr); 8022 8023 format %{ "salq $dst, $shift" %} 8024 opcode(0xD1, 0x4); /* D1 /4 */ 8025 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8026 ins_pipe(ialu_mem_imm); 8027 %} 8028 8029 // Shift Left by 8-bit immediate 8030 instruct salL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8031 %{ 8032 match(Set dst (LShiftL dst shift)); 8033 effect(KILL cr); 8034 8035 format %{ "salq $dst, $shift" %} 8036 opcode(0xC1, 0x4); /* C1 /4 ib */ 8037 ins_encode(reg_opc_imm_wide(dst, shift)); 8038 ins_pipe(ialu_reg); 8039 %} 8040 8041 // Shift Left by 8-bit immediate 8042 instruct salL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8043 %{ 8044 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8045 effect(KILL cr); 8046 8047 format %{ "salq $dst, $shift" %} 8048 opcode(0xC1, 0x4); /* C1 /4 ib */ 8049 ins_encode(REX_mem_wide(dst), OpcP, 8050 RM_opc_mem(secondary, dst), Con8or32(shift)); 8051 ins_pipe(ialu_mem_imm); 8052 %} 8053 8054 // Shift Left by variable 8055 instruct salL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8056 %{ 8057 match(Set dst (LShiftL dst shift)); 8058 effect(KILL cr); 8059 8060 format %{ "salq $dst, $shift" %} 8061 opcode(0xD3, 0x4); /* D3 /4 */ 8062 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8063 ins_pipe(ialu_reg_reg); 8064 %} 8065 8066 // Shift Left by variable 8067 instruct salL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8068 %{ 8069 match(Set dst (StoreL dst (LShiftL (LoadL dst) shift))); 8070 effect(KILL cr); 8071 8072 format %{ "salq $dst, $shift" %} 8073 opcode(0xD3, 0x4); /* D3 /4 */ 8074 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8075 ins_pipe(ialu_mem_reg); 8076 %} 8077 8078 // Arithmetic shift right by one 8079 instruct sarL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8080 %{ 8081 match(Set dst (RShiftL dst shift)); 8082 effect(KILL cr); 8083 8084 format %{ "sarq $dst, $shift" %} 8085 opcode(0xD1, 0x7); /* D1 /7 */ 8086 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8087 ins_pipe(ialu_reg); 8088 %} 8089 8090 // Arithmetic shift right by one 8091 instruct sarL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8092 %{ 8093 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8094 effect(KILL cr); 8095 8096 format %{ "sarq $dst, $shift" %} 8097 opcode(0xD1, 0x7); /* D1 /7 */ 8098 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8099 ins_pipe(ialu_mem_imm); 8100 %} 8101 8102 // Arithmetic Shift Right by 8-bit immediate 8103 instruct sarL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8104 %{ 8105 match(Set dst (RShiftL dst shift)); 8106 effect(KILL cr); 8107 8108 format %{ "sarq $dst, $shift" %} 8109 opcode(0xC1, 0x7); /* C1 /7 ib */ 8110 ins_encode(reg_opc_imm_wide(dst, shift)); 8111 ins_pipe(ialu_mem_imm); 8112 %} 8113 8114 // Arithmetic Shift Right by 8-bit immediate 8115 instruct sarL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8116 %{ 8117 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8118 effect(KILL cr); 8119 8120 format %{ "sarq $dst, $shift" %} 8121 opcode(0xC1, 0x7); /* C1 /7 ib */ 8122 ins_encode(REX_mem_wide(dst), OpcP, 8123 RM_opc_mem(secondary, dst), Con8or32(shift)); 8124 ins_pipe(ialu_mem_imm); 8125 %} 8126 8127 // Arithmetic Shift Right by variable 8128 instruct sarL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8129 %{ 8130 match(Set dst (RShiftL dst shift)); 8131 effect(KILL cr); 8132 8133 format %{ "sarq $dst, $shift" %} 8134 opcode(0xD3, 0x7); /* D3 /7 */ 8135 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8136 ins_pipe(ialu_reg_reg); 8137 %} 8138 8139 // Arithmetic Shift Right by variable 8140 instruct sarL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8141 %{ 8142 match(Set dst (StoreL dst (RShiftL (LoadL dst) shift))); 8143 effect(KILL cr); 8144 8145 format %{ "sarq $dst, $shift" %} 8146 opcode(0xD3, 0x7); /* D3 /7 */ 8147 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8148 ins_pipe(ialu_mem_reg); 8149 %} 8150 8151 // Logical shift right by one 8152 instruct shrL_rReg_1(rRegL dst, immI1 shift, rFlagsReg cr) 8153 %{ 8154 match(Set dst (URShiftL dst shift)); 8155 effect(KILL cr); 8156 8157 format %{ "shrq $dst, $shift" %} 8158 opcode(0xD1, 0x5); /* D1 /5 */ 8159 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst )); 8160 ins_pipe(ialu_reg); 8161 %} 8162 8163 // Logical shift right by one 8164 instruct shrL_mem_1(memory dst, immI1 shift, rFlagsReg cr) 8165 %{ 8166 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8167 effect(KILL cr); 8168 8169 format %{ "shrq $dst, $shift" %} 8170 opcode(0xD1, 0x5); /* D1 /5 */ 8171 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8172 ins_pipe(ialu_mem_imm); 8173 %} 8174 8175 // Logical Shift Right by 8-bit immediate 8176 instruct shrL_rReg_imm(rRegL dst, immI8 shift, rFlagsReg cr) 8177 %{ 8178 match(Set dst (URShiftL dst shift)); 8179 effect(KILL cr); 8180 8181 format %{ "shrq $dst, $shift" %} 8182 opcode(0xC1, 0x5); /* C1 /5 ib */ 8183 ins_encode(reg_opc_imm_wide(dst, shift)); 8184 ins_pipe(ialu_reg); 8185 %} 8186 8187 8188 // Logical Shift Right by 8-bit immediate 8189 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) 8190 %{ 8191 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8192 effect(KILL cr); 8193 8194 format %{ "shrq $dst, $shift" %} 8195 opcode(0xC1, 0x5); /* C1 /5 ib */ 8196 ins_encode(REX_mem_wide(dst), OpcP, 8197 RM_opc_mem(secondary, dst), Con8or32(shift)); 8198 ins_pipe(ialu_mem_imm); 8199 %} 8200 8201 // Logical Shift Right by variable 8202 instruct shrL_rReg_CL(rRegL dst, rcx_RegI shift, rFlagsReg cr) 8203 %{ 8204 match(Set dst (URShiftL dst shift)); 8205 effect(KILL cr); 8206 8207 format %{ "shrq $dst, $shift" %} 8208 opcode(0xD3, 0x5); /* D3 /5 */ 8209 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8210 ins_pipe(ialu_reg_reg); 8211 %} 8212 8213 // Logical Shift Right by variable 8214 instruct shrL_mem_CL(memory dst, rcx_RegI shift, rFlagsReg cr) 8215 %{ 8216 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); 8217 effect(KILL cr); 8218 8219 format %{ "shrq $dst, $shift" %} 8220 opcode(0xD3, 0x5); /* D3 /5 */ 8221 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); 8222 ins_pipe(ialu_mem_reg); 8223 %} 8224 8225 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24. 8226 // This idiom is used by the compiler for the i2b bytecode. 8227 instruct i2b(rRegI dst, rRegI src, immI_24 twentyfour) 8228 %{ 8229 match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour)); 8230 8231 format %{ "movsbl $dst, $src\t# i2b" %} 8232 opcode(0x0F, 0xBE); 8233 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8234 ins_pipe(ialu_reg_reg); 8235 %} 8236 8237 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16. 8238 // This idiom is used by the compiler the i2s bytecode. 8239 instruct i2s(rRegI dst, rRegI src, immI_16 sixteen) 8240 %{ 8241 match(Set dst (RShiftI (LShiftI src sixteen) sixteen)); 8242 8243 format %{ "movswl $dst, $src\t# i2s" %} 8244 opcode(0x0F, 0xBF); 8245 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8246 ins_pipe(ialu_reg_reg); 8247 %} 8248 8249 // ROL/ROR instructions 8250 8251 // ROL expand 8252 instruct rolI_rReg_imm1(rRegI dst, rFlagsReg cr) %{ 8253 effect(KILL cr, USE_DEF dst); 8254 8255 format %{ "roll $dst" %} 8256 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8257 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8258 ins_pipe(ialu_reg); 8259 %} 8260 8261 instruct rolI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) %{ 8262 effect(USE_DEF dst, USE shift, KILL cr); 8263 8264 format %{ "roll $dst, $shift" %} 8265 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8266 ins_encode( reg_opc_imm(dst, shift) ); 8267 ins_pipe(ialu_reg); 8268 %} 8269 8270 instruct rolI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8271 %{ 8272 effect(USE_DEF dst, USE shift, KILL cr); 8273 8274 format %{ "roll $dst, $shift" %} 8275 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8276 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8277 ins_pipe(ialu_reg_reg); 8278 %} 8279 // end of ROL expand 8280 8281 // Rotate Left by one 8282 instruct rolI_rReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8283 %{ 8284 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8285 8286 expand %{ 8287 rolI_rReg_imm1(dst, cr); 8288 %} 8289 %} 8290 8291 // Rotate Left by 8-bit immediate 8292 instruct rolI_rReg_i8(rRegI dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8293 %{ 8294 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8295 match(Set dst (OrI (LShiftI dst lshift) (URShiftI dst rshift))); 8296 8297 expand %{ 8298 rolI_rReg_imm8(dst, lshift, cr); 8299 %} 8300 %} 8301 8302 // Rotate Left by variable 8303 instruct rolI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8304 %{ 8305 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI zero shift)))); 8306 8307 expand %{ 8308 rolI_rReg_CL(dst, shift, cr); 8309 %} 8310 %} 8311 8312 // Rotate Left by variable 8313 instruct rolI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8314 %{ 8315 match(Set dst (OrI (LShiftI dst shift) (URShiftI dst (SubI c32 shift)))); 8316 8317 expand %{ 8318 rolI_rReg_CL(dst, shift, cr); 8319 %} 8320 %} 8321 8322 // ROR expand 8323 instruct rorI_rReg_imm1(rRegI dst, rFlagsReg cr) 8324 %{ 8325 effect(USE_DEF dst, KILL cr); 8326 8327 format %{ "rorl $dst" %} 8328 opcode(0xD1, 0x1); /* D1 /1 */ 8329 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8330 ins_pipe(ialu_reg); 8331 %} 8332 8333 instruct rorI_rReg_imm8(rRegI dst, immI8 shift, rFlagsReg cr) 8334 %{ 8335 effect(USE_DEF dst, USE shift, KILL cr); 8336 8337 format %{ "rorl $dst, $shift" %} 8338 opcode(0xC1, 0x1); /* C1 /1 ib */ 8339 ins_encode(reg_opc_imm(dst, shift)); 8340 ins_pipe(ialu_reg); 8341 %} 8342 8343 instruct rorI_rReg_CL(no_rcx_RegI dst, rcx_RegI shift, rFlagsReg cr) 8344 %{ 8345 effect(USE_DEF dst, USE shift, KILL cr); 8346 8347 format %{ "rorl $dst, $shift" %} 8348 opcode(0xD3, 0x1); /* D3 /1 */ 8349 ins_encode(REX_reg(dst), OpcP, reg_opc(dst)); 8350 ins_pipe(ialu_reg_reg); 8351 %} 8352 // end of ROR expand 8353 8354 // Rotate Right by one 8355 instruct rorI_rReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8356 %{ 8357 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8358 8359 expand %{ 8360 rorI_rReg_imm1(dst, cr); 8361 %} 8362 %} 8363 8364 // Rotate Right by 8-bit immediate 8365 instruct rorI_rReg_i8(rRegI dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8366 %{ 8367 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f)); 8368 match(Set dst (OrI (URShiftI dst rshift) (LShiftI dst lshift))); 8369 8370 expand %{ 8371 rorI_rReg_imm8(dst, rshift, cr); 8372 %} 8373 %} 8374 8375 // Rotate Right by variable 8376 instruct rorI_rReg_Var_C0(no_rcx_RegI dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8377 %{ 8378 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI zero shift)))); 8379 8380 expand %{ 8381 rorI_rReg_CL(dst, shift, cr); 8382 %} 8383 %} 8384 8385 // Rotate Right by variable 8386 instruct rorI_rReg_Var_C32(no_rcx_RegI dst, rcx_RegI shift, immI_32 c32, rFlagsReg cr) 8387 %{ 8388 match(Set dst (OrI (URShiftI dst shift) (LShiftI dst (SubI c32 shift)))); 8389 8390 expand %{ 8391 rorI_rReg_CL(dst, shift, cr); 8392 %} 8393 %} 8394 8395 // for long rotate 8396 // ROL expand 8397 instruct rolL_rReg_imm1(rRegL dst, rFlagsReg cr) %{ 8398 effect(USE_DEF dst, KILL cr); 8399 8400 format %{ "rolq $dst" %} 8401 opcode(0xD1, 0x0); /* Opcode D1 /0 */ 8402 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8403 ins_pipe(ialu_reg); 8404 %} 8405 8406 instruct rolL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) %{ 8407 effect(USE_DEF dst, USE shift, KILL cr); 8408 8409 format %{ "rolq $dst, $shift" %} 8410 opcode(0xC1, 0x0); /* Opcode C1 /0 ib */ 8411 ins_encode( reg_opc_imm_wide(dst, shift) ); 8412 ins_pipe(ialu_reg); 8413 %} 8414 8415 instruct rolL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8416 %{ 8417 effect(USE_DEF dst, USE shift, KILL cr); 8418 8419 format %{ "rolq $dst, $shift" %} 8420 opcode(0xD3, 0x0); /* Opcode D3 /0 */ 8421 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8422 ins_pipe(ialu_reg_reg); 8423 %} 8424 // end of ROL expand 8425 8426 // Rotate Left by one 8427 instruct rolL_rReg_i1(rRegL dst, immI1 lshift, immI_M1 rshift, rFlagsReg cr) 8428 %{ 8429 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8430 8431 expand %{ 8432 rolL_rReg_imm1(dst, cr); 8433 %} 8434 %} 8435 8436 // Rotate Left by 8-bit immediate 8437 instruct rolL_rReg_i8(rRegL dst, immI8 lshift, immI8 rshift, rFlagsReg cr) 8438 %{ 8439 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8440 match(Set dst (OrL (LShiftL dst lshift) (URShiftL dst rshift))); 8441 8442 expand %{ 8443 rolL_rReg_imm8(dst, lshift, cr); 8444 %} 8445 %} 8446 8447 // Rotate Left by variable 8448 instruct rolL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8449 %{ 8450 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI zero shift)))); 8451 8452 expand %{ 8453 rolL_rReg_CL(dst, shift, cr); 8454 %} 8455 %} 8456 8457 // Rotate Left by variable 8458 instruct rolL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8459 %{ 8460 match(Set dst (OrL (LShiftL dst shift) (URShiftL dst (SubI c64 shift)))); 8461 8462 expand %{ 8463 rolL_rReg_CL(dst, shift, cr); 8464 %} 8465 %} 8466 8467 // ROR expand 8468 instruct rorL_rReg_imm1(rRegL dst, rFlagsReg cr) 8469 %{ 8470 effect(USE_DEF dst, KILL cr); 8471 8472 format %{ "rorq $dst" %} 8473 opcode(0xD1, 0x1); /* D1 /1 */ 8474 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8475 ins_pipe(ialu_reg); 8476 %} 8477 8478 instruct rorL_rReg_imm8(rRegL dst, immI8 shift, rFlagsReg cr) 8479 %{ 8480 effect(USE_DEF dst, USE shift, KILL cr); 8481 8482 format %{ "rorq $dst, $shift" %} 8483 opcode(0xC1, 0x1); /* C1 /1 ib */ 8484 ins_encode(reg_opc_imm_wide(dst, shift)); 8485 ins_pipe(ialu_reg); 8486 %} 8487 8488 instruct rorL_rReg_CL(no_rcx_RegL dst, rcx_RegI shift, rFlagsReg cr) 8489 %{ 8490 effect(USE_DEF dst, USE shift, KILL cr); 8491 8492 format %{ "rorq $dst, $shift" %} 8493 opcode(0xD3, 0x1); /* D3 /1 */ 8494 ins_encode(REX_reg_wide(dst), OpcP, reg_opc(dst)); 8495 ins_pipe(ialu_reg_reg); 8496 %} 8497 // end of ROR expand 8498 8499 // Rotate Right by one 8500 instruct rorL_rReg_i1(rRegL dst, immI1 rshift, immI_M1 lshift, rFlagsReg cr) 8501 %{ 8502 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8503 8504 expand %{ 8505 rorL_rReg_imm1(dst, cr); 8506 %} 8507 %} 8508 8509 // Rotate Right by 8-bit immediate 8510 instruct rorL_rReg_i8(rRegL dst, immI8 rshift, immI8 lshift, rFlagsReg cr) 8511 %{ 8512 predicate(0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x3f)); 8513 match(Set dst (OrL (URShiftL dst rshift) (LShiftL dst lshift))); 8514 8515 expand %{ 8516 rorL_rReg_imm8(dst, rshift, cr); 8517 %} 8518 %} 8519 8520 // Rotate Right by variable 8521 instruct rorL_rReg_Var_C0(no_rcx_RegL dst, rcx_RegI shift, immI0 zero, rFlagsReg cr) 8522 %{ 8523 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI zero shift)))); 8524 8525 expand %{ 8526 rorL_rReg_CL(dst, shift, cr); 8527 %} 8528 %} 8529 8530 // Rotate Right by variable 8531 instruct rorL_rReg_Var_C64(no_rcx_RegL dst, rcx_RegI shift, immI_64 c64, rFlagsReg cr) 8532 %{ 8533 match(Set dst (OrL (URShiftL dst shift) (LShiftL dst (SubI c64 shift)))); 8534 8535 expand %{ 8536 rorL_rReg_CL(dst, shift, cr); 8537 %} 8538 %} 8539 8540 // Logical Instructions 8541 8542 // Integer Logical Instructions 8543 8544 // And Instructions 8545 // And Register with Register 8546 instruct andI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8547 %{ 8548 match(Set dst (AndI dst src)); 8549 effect(KILL cr); 8550 8551 format %{ "andl $dst, $src\t# int" %} 8552 opcode(0x23); 8553 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8554 ins_pipe(ialu_reg_reg); 8555 %} 8556 8557 // And Register with Immediate 255 8558 instruct andI_rReg_imm255(rRegI dst, immI_255 src) 8559 %{ 8560 match(Set dst (AndI dst src)); 8561 8562 format %{ "movzbl $dst, $dst\t# int & 0xFF" %} 8563 opcode(0x0F, 0xB6); 8564 ins_encode(REX_reg_breg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8565 ins_pipe(ialu_reg); 8566 %} 8567 8568 // And Register with Immediate 255 and promote to long 8569 instruct andI2L_rReg_imm255(rRegL dst, rRegI src, immI_255 mask) 8570 %{ 8571 match(Set dst (ConvI2L (AndI src mask))); 8572 8573 format %{ "movzbl $dst, $src\t# int & 0xFF -> long" %} 8574 opcode(0x0F, 0xB6); 8575 ins_encode(REX_reg_breg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8576 ins_pipe(ialu_reg); 8577 %} 8578 8579 // And Register with Immediate 65535 8580 instruct andI_rReg_imm65535(rRegI dst, immI_65535 src) 8581 %{ 8582 match(Set dst (AndI dst src)); 8583 8584 format %{ "movzwl $dst, $dst\t# int & 0xFFFF" %} 8585 opcode(0x0F, 0xB7); 8586 ins_encode(REX_reg_reg(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8587 ins_pipe(ialu_reg); 8588 %} 8589 8590 // And Register with Immediate 65535 and promote to long 8591 instruct andI2L_rReg_imm65535(rRegL dst, rRegI src, immI_65535 mask) 8592 %{ 8593 match(Set dst (ConvI2L (AndI src mask))); 8594 8595 format %{ "movzwl $dst, $src\t# int & 0xFFFF -> long" %} 8596 opcode(0x0F, 0xB7); 8597 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 8598 ins_pipe(ialu_reg); 8599 %} 8600 8601 // And Register with Immediate 8602 instruct andI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8603 %{ 8604 match(Set dst (AndI dst src)); 8605 effect(KILL cr); 8606 8607 format %{ "andl $dst, $src\t# int" %} 8608 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8609 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8610 ins_pipe(ialu_reg); 8611 %} 8612 8613 // And Register with Memory 8614 instruct andI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8615 %{ 8616 match(Set dst (AndI dst (LoadI src))); 8617 effect(KILL cr); 8618 8619 ins_cost(125); 8620 format %{ "andl $dst, $src\t# int" %} 8621 opcode(0x23); 8622 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8623 ins_pipe(ialu_reg_mem); 8624 %} 8625 8626 // And Memory with Register 8627 instruct andI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8628 %{ 8629 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8630 effect(KILL cr); 8631 8632 ins_cost(150); 8633 format %{ "andl $dst, $src\t# int" %} 8634 opcode(0x21); /* Opcode 21 /r */ 8635 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8636 ins_pipe(ialu_mem_reg); 8637 %} 8638 8639 // And Memory with Immediate 8640 instruct andI_mem_imm(memory dst, immI src, rFlagsReg cr) 8641 %{ 8642 match(Set dst (StoreI dst (AndI (LoadI dst) src))); 8643 effect(KILL cr); 8644 8645 ins_cost(125); 8646 format %{ "andl $dst, $src\t# int" %} 8647 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8648 ins_encode(REX_mem(dst), OpcSE(src), 8649 RM_opc_mem(secondary, dst), Con8or32(src)); 8650 ins_pipe(ialu_mem_imm); 8651 %} 8652 8653 // BMI1 instructions 8654 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ 8655 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); 8656 predicate(UseBMI1Instructions); 8657 effect(KILL cr); 8658 8659 ins_cost(125); 8660 format %{ "andnl $dst, $src1, $src2" %} 8661 8662 ins_encode %{ 8663 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); 8664 %} 8665 ins_pipe(ialu_reg_mem); 8666 %} 8667 8668 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ 8669 match(Set dst (AndI (XorI src1 minus_1) src2)); 8670 predicate(UseBMI1Instructions); 8671 effect(KILL cr); 8672 8673 format %{ "andnl $dst, $src1, $src2" %} 8674 8675 ins_encode %{ 8676 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); 8677 %} 8678 ins_pipe(ialu_reg); 8679 %} 8680 8681 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ 8682 match(Set dst (AndI (SubI imm_zero src) src)); 8683 predicate(UseBMI1Instructions); 8684 effect(KILL cr); 8685 8686 format %{ "blsil $dst, $src" %} 8687 8688 ins_encode %{ 8689 __ blsil($dst$$Register, $src$$Register); 8690 %} 8691 ins_pipe(ialu_reg); 8692 %} 8693 8694 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ 8695 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); 8696 predicate(UseBMI1Instructions); 8697 effect(KILL cr); 8698 8699 ins_cost(125); 8700 format %{ "blsil $dst, $src" %} 8701 8702 ins_encode %{ 8703 __ blsil($dst$$Register, $src$$Address); 8704 %} 8705 ins_pipe(ialu_reg_mem); 8706 %} 8707 8708 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8709 %{ 8710 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8711 predicate(UseBMI1Instructions); 8712 effect(KILL cr); 8713 8714 ins_cost(125); 8715 format %{ "blsmskl $dst, $src" %} 8716 8717 ins_encode %{ 8718 __ blsmskl($dst$$Register, $src$$Address); 8719 %} 8720 ins_pipe(ialu_reg_mem); 8721 %} 8722 8723 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8724 %{ 8725 match(Set dst (XorI (AddI src minus_1) src)); 8726 predicate(UseBMI1Instructions); 8727 effect(KILL cr); 8728 8729 format %{ "blsmskl $dst, $src" %} 8730 8731 ins_encode %{ 8732 __ blsmskl($dst$$Register, $src$$Register); 8733 %} 8734 8735 ins_pipe(ialu_reg); 8736 %} 8737 8738 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) 8739 %{ 8740 match(Set dst (AndI (AddI src minus_1) src) ); 8741 predicate(UseBMI1Instructions); 8742 effect(KILL cr); 8743 8744 format %{ "blsrl $dst, $src" %} 8745 8746 ins_encode %{ 8747 __ blsrl($dst$$Register, $src$$Register); 8748 %} 8749 8750 ins_pipe(ialu_reg_mem); 8751 %} 8752 8753 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) 8754 %{ 8755 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); 8756 predicate(UseBMI1Instructions); 8757 effect(KILL cr); 8758 8759 ins_cost(125); 8760 format %{ "blsrl $dst, $src" %} 8761 8762 ins_encode %{ 8763 __ blsrl($dst$$Register, $src$$Address); 8764 %} 8765 8766 ins_pipe(ialu_reg); 8767 %} 8768 8769 // Or Instructions 8770 // Or Register with Register 8771 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8772 %{ 8773 match(Set dst (OrI dst src)); 8774 effect(KILL cr); 8775 8776 format %{ "orl $dst, $src\t# int" %} 8777 opcode(0x0B); 8778 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8779 ins_pipe(ialu_reg_reg); 8780 %} 8781 8782 // Or Register with Immediate 8783 instruct orI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8784 %{ 8785 match(Set dst (OrI dst src)); 8786 effect(KILL cr); 8787 8788 format %{ "orl $dst, $src\t# int" %} 8789 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 8790 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8791 ins_pipe(ialu_reg); 8792 %} 8793 8794 // Or Register with Memory 8795 instruct orI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8796 %{ 8797 match(Set dst (OrI dst (LoadI src))); 8798 effect(KILL cr); 8799 8800 ins_cost(125); 8801 format %{ "orl $dst, $src\t# int" %} 8802 opcode(0x0B); 8803 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8804 ins_pipe(ialu_reg_mem); 8805 %} 8806 8807 // Or Memory with Register 8808 instruct orI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8809 %{ 8810 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8811 effect(KILL cr); 8812 8813 ins_cost(150); 8814 format %{ "orl $dst, $src\t# int" %} 8815 opcode(0x09); /* Opcode 09 /r */ 8816 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8817 ins_pipe(ialu_mem_reg); 8818 %} 8819 8820 // Or Memory with Immediate 8821 instruct orI_mem_imm(memory dst, immI src, rFlagsReg cr) 8822 %{ 8823 match(Set dst (StoreI dst (OrI (LoadI dst) src))); 8824 effect(KILL cr); 8825 8826 ins_cost(125); 8827 format %{ "orl $dst, $src\t# int" %} 8828 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 8829 ins_encode(REX_mem(dst), OpcSE(src), 8830 RM_opc_mem(secondary, dst), Con8or32(src)); 8831 ins_pipe(ialu_mem_imm); 8832 %} 8833 8834 // Xor Instructions 8835 // Xor Register with Register 8836 instruct xorI_rReg(rRegI dst, rRegI src, rFlagsReg cr) 8837 %{ 8838 match(Set dst (XorI dst src)); 8839 effect(KILL cr); 8840 8841 format %{ "xorl $dst, $src\t# int" %} 8842 opcode(0x33); 8843 ins_encode(REX_reg_reg(dst, src), OpcP, reg_reg(dst, src)); 8844 ins_pipe(ialu_reg_reg); 8845 %} 8846 8847 // Xor Register with Immediate -1 8848 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 8849 match(Set dst (XorI dst imm)); 8850 8851 format %{ "not $dst" %} 8852 ins_encode %{ 8853 __ notl($dst$$Register); 8854 %} 8855 ins_pipe(ialu_reg); 8856 %} 8857 8858 // Xor Register with Immediate 8859 instruct xorI_rReg_imm(rRegI dst, immI src, rFlagsReg cr) 8860 %{ 8861 match(Set dst (XorI dst src)); 8862 effect(KILL cr); 8863 8864 format %{ "xorl $dst, $src\t# int" %} 8865 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 8866 ins_encode(OpcSErm(dst, src), Con8or32(src)); 8867 ins_pipe(ialu_reg); 8868 %} 8869 8870 // Xor Register with Memory 8871 instruct xorI_rReg_mem(rRegI dst, memory src, rFlagsReg cr) 8872 %{ 8873 match(Set dst (XorI dst (LoadI src))); 8874 effect(KILL cr); 8875 8876 ins_cost(125); 8877 format %{ "xorl $dst, $src\t# int" %} 8878 opcode(0x33); 8879 ins_encode(REX_reg_mem(dst, src), OpcP, reg_mem(dst, src)); 8880 ins_pipe(ialu_reg_mem); 8881 %} 8882 8883 // Xor Memory with Register 8884 instruct xorI_mem_rReg(memory dst, rRegI src, rFlagsReg cr) 8885 %{ 8886 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 8887 effect(KILL cr); 8888 8889 ins_cost(150); 8890 format %{ "xorl $dst, $src\t# int" %} 8891 opcode(0x31); /* Opcode 31 /r */ 8892 ins_encode(REX_reg_mem(src, dst), OpcP, reg_mem(src, dst)); 8893 ins_pipe(ialu_mem_reg); 8894 %} 8895 8896 // Xor Memory with Immediate 8897 instruct xorI_mem_imm(memory dst, immI src, rFlagsReg cr) 8898 %{ 8899 match(Set dst (StoreI dst (XorI (LoadI dst) src))); 8900 effect(KILL cr); 8901 8902 ins_cost(125); 8903 format %{ "xorl $dst, $src\t# int" %} 8904 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 8905 ins_encode(REX_mem(dst), OpcSE(src), 8906 RM_opc_mem(secondary, dst), Con8or32(src)); 8907 ins_pipe(ialu_mem_imm); 8908 %} 8909 8910 8911 // Long Logical Instructions 8912 8913 // And Instructions 8914 // And Register with Register 8915 instruct andL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 8916 %{ 8917 match(Set dst (AndL dst src)); 8918 effect(KILL cr); 8919 8920 format %{ "andq $dst, $src\t# long" %} 8921 opcode(0x23); 8922 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 8923 ins_pipe(ialu_reg_reg); 8924 %} 8925 8926 // And Register with Immediate 255 8927 instruct andL_rReg_imm255(rRegL dst, immL_255 src) 8928 %{ 8929 match(Set dst (AndL dst src)); 8930 8931 format %{ "movzbq $dst, $dst\t# long & 0xFF" %} 8932 opcode(0x0F, 0xB6); 8933 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8934 ins_pipe(ialu_reg); 8935 %} 8936 8937 // And Register with Immediate 65535 8938 instruct andL_rReg_imm65535(rRegL dst, immL_65535 src) 8939 %{ 8940 match(Set dst (AndL dst src)); 8941 8942 format %{ "movzwq $dst, $dst\t# long & 0xFFFF" %} 8943 opcode(0x0F, 0xB7); 8944 ins_encode(REX_reg_reg_wide(dst, dst), OpcP, OpcS, reg_reg(dst, dst)); 8945 ins_pipe(ialu_reg); 8946 %} 8947 8948 // And Register with Immediate 8949 instruct andL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 8950 %{ 8951 match(Set dst (AndL dst src)); 8952 effect(KILL cr); 8953 8954 format %{ "andq $dst, $src\t# long" %} 8955 opcode(0x81, 0x04); /* Opcode 81 /4 */ 8956 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 8957 ins_pipe(ialu_reg); 8958 %} 8959 8960 // And Register with Memory 8961 instruct andL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 8962 %{ 8963 match(Set dst (AndL dst (LoadL src))); 8964 effect(KILL cr); 8965 8966 ins_cost(125); 8967 format %{ "andq $dst, $src\t# long" %} 8968 opcode(0x23); 8969 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 8970 ins_pipe(ialu_reg_mem); 8971 %} 8972 8973 // And Memory with Register 8974 instruct andL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 8975 %{ 8976 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 8977 effect(KILL cr); 8978 8979 ins_cost(150); 8980 format %{ "andq $dst, $src\t# long" %} 8981 opcode(0x21); /* Opcode 21 /r */ 8982 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 8983 ins_pipe(ialu_mem_reg); 8984 %} 8985 8986 // And Memory with Immediate 8987 instruct andL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 8988 %{ 8989 match(Set dst (StoreL dst (AndL (LoadL dst) src))); 8990 effect(KILL cr); 8991 8992 ins_cost(125); 8993 format %{ "andq $dst, $src\t# long" %} 8994 opcode(0x81, 0x4); /* Opcode 81 /4 id */ 8995 ins_encode(REX_mem_wide(dst), OpcSE(src), 8996 RM_opc_mem(secondary, dst), Con8or32(src)); 8997 ins_pipe(ialu_mem_imm); 8998 %} 8999 9000 // BMI1 instructions 9001 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ 9002 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); 9003 predicate(UseBMI1Instructions); 9004 effect(KILL cr); 9005 9006 ins_cost(125); 9007 format %{ "andnq $dst, $src1, $src2" %} 9008 9009 ins_encode %{ 9010 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); 9011 %} 9012 ins_pipe(ialu_reg_mem); 9013 %} 9014 9015 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ 9016 match(Set dst (AndL (XorL src1 minus_1) src2)); 9017 predicate(UseBMI1Instructions); 9018 effect(KILL cr); 9019 9020 format %{ "andnq $dst, $src1, $src2" %} 9021 9022 ins_encode %{ 9023 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); 9024 %} 9025 ins_pipe(ialu_reg_mem); 9026 %} 9027 9028 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ 9029 match(Set dst (AndL (SubL imm_zero src) src)); 9030 predicate(UseBMI1Instructions); 9031 effect(KILL cr); 9032 9033 format %{ "blsiq $dst, $src" %} 9034 9035 ins_encode %{ 9036 __ blsiq($dst$$Register, $src$$Register); 9037 %} 9038 ins_pipe(ialu_reg); 9039 %} 9040 9041 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ 9042 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); 9043 predicate(UseBMI1Instructions); 9044 effect(KILL cr); 9045 9046 ins_cost(125); 9047 format %{ "blsiq $dst, $src" %} 9048 9049 ins_encode %{ 9050 __ blsiq($dst$$Register, $src$$Address); 9051 %} 9052 ins_pipe(ialu_reg_mem); 9053 %} 9054 9055 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9056 %{ 9057 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); 9058 predicate(UseBMI1Instructions); 9059 effect(KILL cr); 9060 9061 ins_cost(125); 9062 format %{ "blsmskq $dst, $src" %} 9063 9064 ins_encode %{ 9065 __ blsmskq($dst$$Register, $src$$Address); 9066 %} 9067 ins_pipe(ialu_reg_mem); 9068 %} 9069 9070 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9071 %{ 9072 match(Set dst (XorL (AddL src minus_1) src)); 9073 predicate(UseBMI1Instructions); 9074 effect(KILL cr); 9075 9076 format %{ "blsmskq $dst, $src" %} 9077 9078 ins_encode %{ 9079 __ blsmskq($dst$$Register, $src$$Register); 9080 %} 9081 9082 ins_pipe(ialu_reg); 9083 %} 9084 9085 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) 9086 %{ 9087 match(Set dst (AndL (AddL src minus_1) src) ); 9088 predicate(UseBMI1Instructions); 9089 effect(KILL cr); 9090 9091 format %{ "blsrq $dst, $src" %} 9092 9093 ins_encode %{ 9094 __ blsrq($dst$$Register, $src$$Register); 9095 %} 9096 9097 ins_pipe(ialu_reg); 9098 %} 9099 9100 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) 9101 %{ 9102 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); 9103 predicate(UseBMI1Instructions); 9104 effect(KILL cr); 9105 9106 ins_cost(125); 9107 format %{ "blsrq $dst, $src" %} 9108 9109 ins_encode %{ 9110 __ blsrq($dst$$Register, $src$$Address); 9111 %} 9112 9113 ins_pipe(ialu_reg); 9114 %} 9115 9116 // Or Instructions 9117 // Or Register with Register 9118 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9119 %{ 9120 match(Set dst (OrL dst src)); 9121 effect(KILL cr); 9122 9123 format %{ "orq $dst, $src\t# long" %} 9124 opcode(0x0B); 9125 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9126 ins_pipe(ialu_reg_reg); 9127 %} 9128 9129 // Use any_RegP to match R15 (TLS register) without spilling. 9130 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ 9131 match(Set dst (OrL dst (CastP2X src))); 9132 effect(KILL cr); 9133 9134 format %{ "orq $dst, $src\t# long" %} 9135 opcode(0x0B); 9136 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9137 ins_pipe(ialu_reg_reg); 9138 %} 9139 9140 9141 // Or Register with Immediate 9142 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9143 %{ 9144 match(Set dst (OrL dst src)); 9145 effect(KILL cr); 9146 9147 format %{ "orq $dst, $src\t# long" %} 9148 opcode(0x81, 0x01); /* Opcode 81 /1 id */ 9149 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9150 ins_pipe(ialu_reg); 9151 %} 9152 9153 // Or Register with Memory 9154 instruct orL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9155 %{ 9156 match(Set dst (OrL dst (LoadL src))); 9157 effect(KILL cr); 9158 9159 ins_cost(125); 9160 format %{ "orq $dst, $src\t# long" %} 9161 opcode(0x0B); 9162 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9163 ins_pipe(ialu_reg_mem); 9164 %} 9165 9166 // Or Memory with Register 9167 instruct orL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9168 %{ 9169 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9170 effect(KILL cr); 9171 9172 ins_cost(150); 9173 format %{ "orq $dst, $src\t# long" %} 9174 opcode(0x09); /* Opcode 09 /r */ 9175 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9176 ins_pipe(ialu_mem_reg); 9177 %} 9178 9179 // Or Memory with Immediate 9180 instruct orL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9181 %{ 9182 match(Set dst (StoreL dst (OrL (LoadL dst) src))); 9183 effect(KILL cr); 9184 9185 ins_cost(125); 9186 format %{ "orq $dst, $src\t# long" %} 9187 opcode(0x81, 0x1); /* Opcode 81 /1 id */ 9188 ins_encode(REX_mem_wide(dst), OpcSE(src), 9189 RM_opc_mem(secondary, dst), Con8or32(src)); 9190 ins_pipe(ialu_mem_imm); 9191 %} 9192 9193 // Xor Instructions 9194 // Xor Register with Register 9195 instruct xorL_rReg(rRegL dst, rRegL src, rFlagsReg cr) 9196 %{ 9197 match(Set dst (XorL dst src)); 9198 effect(KILL cr); 9199 9200 format %{ "xorq $dst, $src\t# long" %} 9201 opcode(0x33); 9202 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); 9203 ins_pipe(ialu_reg_reg); 9204 %} 9205 9206 // Xor Register with Immediate -1 9207 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 9208 match(Set dst (XorL dst imm)); 9209 9210 format %{ "notq $dst" %} 9211 ins_encode %{ 9212 __ notq($dst$$Register); 9213 %} 9214 ins_pipe(ialu_reg); 9215 %} 9216 9217 // Xor Register with Immediate 9218 instruct xorL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) 9219 %{ 9220 match(Set dst (XorL dst src)); 9221 effect(KILL cr); 9222 9223 format %{ "xorq $dst, $src\t# long" %} 9224 opcode(0x81, 0x06); /* Opcode 81 /6 id */ 9225 ins_encode(OpcSErm_wide(dst, src), Con8or32(src)); 9226 ins_pipe(ialu_reg); 9227 %} 9228 9229 // Xor Register with Memory 9230 instruct xorL_rReg_mem(rRegL dst, memory src, rFlagsReg cr) 9231 %{ 9232 match(Set dst (XorL dst (LoadL src))); 9233 effect(KILL cr); 9234 9235 ins_cost(125); 9236 format %{ "xorq $dst, $src\t# long" %} 9237 opcode(0x33); 9238 ins_encode(REX_reg_mem_wide(dst, src), OpcP, reg_mem(dst, src)); 9239 ins_pipe(ialu_reg_mem); 9240 %} 9241 9242 // Xor Memory with Register 9243 instruct xorL_mem_rReg(memory dst, rRegL src, rFlagsReg cr) 9244 %{ 9245 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9246 effect(KILL cr); 9247 9248 ins_cost(150); 9249 format %{ "xorq $dst, $src\t# long" %} 9250 opcode(0x31); /* Opcode 31 /r */ 9251 ins_encode(REX_reg_mem_wide(src, dst), OpcP, reg_mem(src, dst)); 9252 ins_pipe(ialu_mem_reg); 9253 %} 9254 9255 // Xor Memory with Immediate 9256 instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr) 9257 %{ 9258 match(Set dst (StoreL dst (XorL (LoadL dst) src))); 9259 effect(KILL cr); 9260 9261 ins_cost(125); 9262 format %{ "xorq $dst, $src\t# long" %} 9263 opcode(0x81, 0x6); /* Opcode 81 /6 id */ 9264 ins_encode(REX_mem_wide(dst), OpcSE(src), 9265 RM_opc_mem(secondary, dst), Con8or32(src)); 9266 ins_pipe(ialu_mem_imm); 9267 %} 9268 9269 // Convert Int to Boolean 9270 instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr) 9271 %{ 9272 match(Set dst (Conv2B src)); 9273 effect(KILL cr); 9274 9275 format %{ "testl $src, $src\t# ci2b\n\t" 9276 "setnz $dst\n\t" 9277 "movzbl $dst, $dst" %} 9278 ins_encode(REX_reg_reg(src, src), opc_reg_reg(0x85, src, src), // testl 9279 setNZ_reg(dst), 9280 REX_reg_breg(dst, dst), // movzbl 9281 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9282 ins_pipe(pipe_slow); // XXX 9283 %} 9284 9285 // Convert Pointer to Boolean 9286 instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr) 9287 %{ 9288 match(Set dst (Conv2B src)); 9289 effect(KILL cr); 9290 9291 format %{ "testq $src, $src\t# cp2b\n\t" 9292 "setnz $dst\n\t" 9293 "movzbl $dst, $dst" %} 9294 ins_encode(REX_reg_reg_wide(src, src), opc_reg_reg(0x85, src, src), // testq 9295 setNZ_reg(dst), 9296 REX_reg_breg(dst, dst), // movzbl 9297 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst)); 9298 ins_pipe(pipe_slow); // XXX 9299 %} 9300 9301 instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr) 9302 %{ 9303 match(Set dst (CmpLTMask p q)); 9304 effect(KILL cr); 9305 9306 ins_cost(400); 9307 format %{ "cmpl $p, $q\t# cmpLTMask\n\t" 9308 "setlt $dst\n\t" 9309 "movzbl $dst, $dst\n\t" 9310 "negl $dst" %} 9311 ins_encode(REX_reg_reg(p, q), opc_reg_reg(0x3B, p, q), // cmpl 9312 setLT_reg(dst), 9313 REX_reg_breg(dst, dst), // movzbl 9314 Opcode(0x0F), Opcode(0xB6), reg_reg(dst, dst), 9315 neg_reg(dst)); 9316 ins_pipe(pipe_slow); 9317 %} 9318 9319 instruct cmpLTMask0(rRegI dst, immI0 zero, rFlagsReg cr) 9320 %{ 9321 match(Set dst (CmpLTMask dst zero)); 9322 effect(KILL cr); 9323 9324 ins_cost(100); 9325 format %{ "sarl $dst, #31\t# cmpLTMask0" %} 9326 ins_encode %{ 9327 __ sarl($dst$$Register, 31); 9328 %} 9329 ins_pipe(ialu_reg); 9330 %} 9331 9332 /* Better to save a register than avoid a branch */ 9333 instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9334 %{ 9335 match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q))); 9336 effect(KILL cr); 9337 ins_cost(300); 9338 format %{ "subl $p,$q\t# cadd_cmpLTMask\n\t" 9339 "jge done\n\t" 9340 "addl $p,$y\n" 9341 "done: " %} 9342 ins_encode %{ 9343 Register Rp = $p$$Register; 9344 Register Rq = $q$$Register; 9345 Register Ry = $y$$Register; 9346 Label done; 9347 __ subl(Rp, Rq); 9348 __ jccb(Assembler::greaterEqual, done); 9349 __ addl(Rp, Ry); 9350 __ bind(done); 9351 %} 9352 ins_pipe(pipe_cmplt); 9353 %} 9354 9355 /* Better to save a register than avoid a branch */ 9356 instruct and_cmpLTMask(rRegI p, rRegI q, rRegI y, rFlagsReg cr) 9357 %{ 9358 match(Set y (AndI (CmpLTMask p q) y)); 9359 effect(KILL cr); 9360 9361 ins_cost(300); 9362 9363 format %{ "cmpl $p, $q\t# and_cmpLTMask\n\t" 9364 "jlt done\n\t" 9365 "xorl $y, $y\n" 9366 "done: " %} 9367 ins_encode %{ 9368 Register Rp = $p$$Register; 9369 Register Rq = $q$$Register; 9370 Register Ry = $y$$Register; 9371 Label done; 9372 __ cmpl(Rp, Rq); 9373 __ jccb(Assembler::less, done); 9374 __ xorl(Ry, Ry); 9375 __ bind(done); 9376 %} 9377 ins_pipe(pipe_cmplt); 9378 %} 9379 9380 9381 //---------- FP Instructions------------------------------------------------ 9382 9383 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2) 9384 %{ 9385 match(Set cr (CmpF src1 src2)); 9386 9387 ins_cost(145); 9388 format %{ "ucomiss $src1, $src2\n\t" 9389 "jnp,s exit\n\t" 9390 "pushfq\t# saw NaN, set CF\n\t" 9391 "andq [rsp], #0xffffff2b\n\t" 9392 "popfq\n" 9393 "exit:" %} 9394 ins_encode %{ 9395 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9396 emit_cmpfp_fixup(_masm); 9397 %} 9398 ins_pipe(pipe_slow); 9399 %} 9400 9401 instruct cmpF_cc_reg_CF(rFlagsRegUCF cr, regF src1, regF src2) %{ 9402 match(Set cr (CmpF src1 src2)); 9403 9404 ins_cost(100); 9405 format %{ "ucomiss $src1, $src2" %} 9406 ins_encode %{ 9407 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9408 %} 9409 ins_pipe(pipe_slow); 9410 %} 9411 9412 instruct cmpF_cc_mem(rFlagsRegU cr, regF src1, memory src2) 9413 %{ 9414 match(Set cr (CmpF src1 (LoadF src2))); 9415 9416 ins_cost(145); 9417 format %{ "ucomiss $src1, $src2\n\t" 9418 "jnp,s exit\n\t" 9419 "pushfq\t# saw NaN, set CF\n\t" 9420 "andq [rsp], #0xffffff2b\n\t" 9421 "popfq\n" 9422 "exit:" %} 9423 ins_encode %{ 9424 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9425 emit_cmpfp_fixup(_masm); 9426 %} 9427 ins_pipe(pipe_slow); 9428 %} 9429 9430 instruct cmpF_cc_memCF(rFlagsRegUCF cr, regF src1, memory src2) %{ 9431 match(Set cr (CmpF src1 (LoadF src2))); 9432 9433 ins_cost(100); 9434 format %{ "ucomiss $src1, $src2" %} 9435 ins_encode %{ 9436 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9437 %} 9438 ins_pipe(pipe_slow); 9439 %} 9440 9441 instruct cmpF_cc_imm(rFlagsRegU cr, regF src, immF con) %{ 9442 match(Set cr (CmpF src con)); 9443 9444 ins_cost(145); 9445 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9446 "jnp,s exit\n\t" 9447 "pushfq\t# saw NaN, set CF\n\t" 9448 "andq [rsp], #0xffffff2b\n\t" 9449 "popfq\n" 9450 "exit:" %} 9451 ins_encode %{ 9452 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9453 emit_cmpfp_fixup(_masm); 9454 %} 9455 ins_pipe(pipe_slow); 9456 %} 9457 9458 instruct cmpF_cc_immCF(rFlagsRegUCF cr, regF src, immF con) %{ 9459 match(Set cr (CmpF src con)); 9460 ins_cost(100); 9461 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con" %} 9462 ins_encode %{ 9463 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9464 %} 9465 ins_pipe(pipe_slow); 9466 %} 9467 9468 instruct cmpD_cc_reg(rFlagsRegU cr, regD src1, regD src2) 9469 %{ 9470 match(Set cr (CmpD src1 src2)); 9471 9472 ins_cost(145); 9473 format %{ "ucomisd $src1, $src2\n\t" 9474 "jnp,s exit\n\t" 9475 "pushfq\t# saw NaN, set CF\n\t" 9476 "andq [rsp], #0xffffff2b\n\t" 9477 "popfq\n" 9478 "exit:" %} 9479 ins_encode %{ 9480 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9481 emit_cmpfp_fixup(_masm); 9482 %} 9483 ins_pipe(pipe_slow); 9484 %} 9485 9486 instruct cmpD_cc_reg_CF(rFlagsRegUCF cr, regD src1, regD src2) %{ 9487 match(Set cr (CmpD src1 src2)); 9488 9489 ins_cost(100); 9490 format %{ "ucomisd $src1, $src2 test" %} 9491 ins_encode %{ 9492 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9493 %} 9494 ins_pipe(pipe_slow); 9495 %} 9496 9497 instruct cmpD_cc_mem(rFlagsRegU cr, regD src1, memory src2) 9498 %{ 9499 match(Set cr (CmpD src1 (LoadD src2))); 9500 9501 ins_cost(145); 9502 format %{ "ucomisd $src1, $src2\n\t" 9503 "jnp,s exit\n\t" 9504 "pushfq\t# saw NaN, set CF\n\t" 9505 "andq [rsp], #0xffffff2b\n\t" 9506 "popfq\n" 9507 "exit:" %} 9508 ins_encode %{ 9509 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9510 emit_cmpfp_fixup(_masm); 9511 %} 9512 ins_pipe(pipe_slow); 9513 %} 9514 9515 instruct cmpD_cc_memCF(rFlagsRegUCF cr, regD src1, memory src2) %{ 9516 match(Set cr (CmpD src1 (LoadD src2))); 9517 9518 ins_cost(100); 9519 format %{ "ucomisd $src1, $src2" %} 9520 ins_encode %{ 9521 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9522 %} 9523 ins_pipe(pipe_slow); 9524 %} 9525 9526 instruct cmpD_cc_imm(rFlagsRegU cr, regD src, immD con) %{ 9527 match(Set cr (CmpD src con)); 9528 9529 ins_cost(145); 9530 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9531 "jnp,s exit\n\t" 9532 "pushfq\t# saw NaN, set CF\n\t" 9533 "andq [rsp], #0xffffff2b\n\t" 9534 "popfq\n" 9535 "exit:" %} 9536 ins_encode %{ 9537 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9538 emit_cmpfp_fixup(_masm); 9539 %} 9540 ins_pipe(pipe_slow); 9541 %} 9542 9543 instruct cmpD_cc_immCF(rFlagsRegUCF cr, regD src, immD con) %{ 9544 match(Set cr (CmpD src con)); 9545 ins_cost(100); 9546 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con" %} 9547 ins_encode %{ 9548 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9549 %} 9550 ins_pipe(pipe_slow); 9551 %} 9552 9553 // Compare into -1,0,1 9554 instruct cmpF_reg(rRegI dst, regF src1, regF src2, rFlagsReg cr) 9555 %{ 9556 match(Set dst (CmpF3 src1 src2)); 9557 effect(KILL cr); 9558 9559 ins_cost(275); 9560 format %{ "ucomiss $src1, $src2\n\t" 9561 "movl $dst, #-1\n\t" 9562 "jp,s done\n\t" 9563 "jb,s done\n\t" 9564 "setne $dst\n\t" 9565 "movzbl $dst, $dst\n" 9566 "done:" %} 9567 ins_encode %{ 9568 __ ucomiss($src1$$XMMRegister, $src2$$XMMRegister); 9569 emit_cmpfp3(_masm, $dst$$Register); 9570 %} 9571 ins_pipe(pipe_slow); 9572 %} 9573 9574 // Compare into -1,0,1 9575 instruct cmpF_mem(rRegI dst, regF src1, memory src2, rFlagsReg cr) 9576 %{ 9577 match(Set dst (CmpF3 src1 (LoadF src2))); 9578 effect(KILL cr); 9579 9580 ins_cost(275); 9581 format %{ "ucomiss $src1, $src2\n\t" 9582 "movl $dst, #-1\n\t" 9583 "jp,s done\n\t" 9584 "jb,s done\n\t" 9585 "setne $dst\n\t" 9586 "movzbl $dst, $dst\n" 9587 "done:" %} 9588 ins_encode %{ 9589 __ ucomiss($src1$$XMMRegister, $src2$$Address); 9590 emit_cmpfp3(_masm, $dst$$Register); 9591 %} 9592 ins_pipe(pipe_slow); 9593 %} 9594 9595 // Compare into -1,0,1 9596 instruct cmpF_imm(rRegI dst, regF src, immF con, rFlagsReg cr) %{ 9597 match(Set dst (CmpF3 src con)); 9598 effect(KILL cr); 9599 9600 ins_cost(275); 9601 format %{ "ucomiss $src, [$constantaddress]\t# load from constant table: float=$con\n\t" 9602 "movl $dst, #-1\n\t" 9603 "jp,s done\n\t" 9604 "jb,s done\n\t" 9605 "setne $dst\n\t" 9606 "movzbl $dst, $dst\n" 9607 "done:" %} 9608 ins_encode %{ 9609 __ ucomiss($src$$XMMRegister, $constantaddress($con)); 9610 emit_cmpfp3(_masm, $dst$$Register); 9611 %} 9612 ins_pipe(pipe_slow); 9613 %} 9614 9615 // Compare into -1,0,1 9616 instruct cmpD_reg(rRegI dst, regD src1, regD src2, rFlagsReg cr) 9617 %{ 9618 match(Set dst (CmpD3 src1 src2)); 9619 effect(KILL cr); 9620 9621 ins_cost(275); 9622 format %{ "ucomisd $src1, $src2\n\t" 9623 "movl $dst, #-1\n\t" 9624 "jp,s done\n\t" 9625 "jb,s done\n\t" 9626 "setne $dst\n\t" 9627 "movzbl $dst, $dst\n" 9628 "done:" %} 9629 ins_encode %{ 9630 __ ucomisd($src1$$XMMRegister, $src2$$XMMRegister); 9631 emit_cmpfp3(_masm, $dst$$Register); 9632 %} 9633 ins_pipe(pipe_slow); 9634 %} 9635 9636 // Compare into -1,0,1 9637 instruct cmpD_mem(rRegI dst, regD src1, memory src2, rFlagsReg cr) 9638 %{ 9639 match(Set dst (CmpD3 src1 (LoadD src2))); 9640 effect(KILL cr); 9641 9642 ins_cost(275); 9643 format %{ "ucomisd $src1, $src2\n\t" 9644 "movl $dst, #-1\n\t" 9645 "jp,s done\n\t" 9646 "jb,s done\n\t" 9647 "setne $dst\n\t" 9648 "movzbl $dst, $dst\n" 9649 "done:" %} 9650 ins_encode %{ 9651 __ ucomisd($src1$$XMMRegister, $src2$$Address); 9652 emit_cmpfp3(_masm, $dst$$Register); 9653 %} 9654 ins_pipe(pipe_slow); 9655 %} 9656 9657 // Compare into -1,0,1 9658 instruct cmpD_imm(rRegI dst, regD src, immD con, rFlagsReg cr) %{ 9659 match(Set dst (CmpD3 src con)); 9660 effect(KILL cr); 9661 9662 ins_cost(275); 9663 format %{ "ucomisd $src, [$constantaddress]\t# load from constant table: double=$con\n\t" 9664 "movl $dst, #-1\n\t" 9665 "jp,s done\n\t" 9666 "jb,s done\n\t" 9667 "setne $dst\n\t" 9668 "movzbl $dst, $dst\n" 9669 "done:" %} 9670 ins_encode %{ 9671 __ ucomisd($src$$XMMRegister, $constantaddress($con)); 9672 emit_cmpfp3(_masm, $dst$$Register); 9673 %} 9674 ins_pipe(pipe_slow); 9675 %} 9676 9677 // -----------Trig and Trancendental Instructions------------------------------ 9678 instruct cosD_reg(regD dst) %{ 9679 match(Set dst (CosD dst)); 9680 9681 format %{ "dcos $dst\n\t" %} 9682 opcode(0xD9, 0xFF); 9683 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9684 ins_pipe( pipe_slow ); 9685 %} 9686 9687 instruct sinD_reg(regD dst) %{ 9688 match(Set dst (SinD dst)); 9689 9690 format %{ "dsin $dst\n\t" %} 9691 opcode(0xD9, 0xFE); 9692 ins_encode( Push_SrcXD(dst), OpcP, OpcS, Push_ResultXD(dst) ); 9693 ins_pipe( pipe_slow ); 9694 %} 9695 9696 instruct tanD_reg(regD dst) %{ 9697 match(Set dst (TanD dst)); 9698 9699 format %{ "dtan $dst\n\t" %} 9700 ins_encode( Push_SrcXD(dst), 9701 Opcode(0xD9), Opcode(0xF2), //fptan 9702 Opcode(0xDD), Opcode(0xD8), //fstp st 9703 Push_ResultXD(dst) ); 9704 ins_pipe( pipe_slow ); 9705 %} 9706 9707 instruct log10D_reg(regD dst) %{ 9708 // The source and result Double operands in XMM registers 9709 match(Set dst (Log10D dst)); 9710 // fldlg2 ; push log_10(2) on the FPU stack; full 80-bit number 9711 // fyl2x ; compute log_10(2) * log_2(x) 9712 format %{ "fldlg2\t\t\t#Log10\n\t" 9713 "fyl2x\t\t\t# Q=Log10*Log_2(x)\n\t" 9714 %} 9715 ins_encode(Opcode(0xD9), Opcode(0xEC), // fldlg2 9716 Push_SrcXD(dst), 9717 Opcode(0xD9), Opcode(0xF1), // fyl2x 9718 Push_ResultXD(dst)); 9719 9720 ins_pipe( pipe_slow ); 9721 %} 9722 9723 instruct logD_reg(regD dst) %{ 9724 // The source and result Double operands in XMM registers 9725 match(Set dst (LogD dst)); 9726 // fldln2 ; push log_e(2) on the FPU stack; full 80-bit number 9727 // fyl2x ; compute log_e(2) * log_2(x) 9728 format %{ "fldln2\t\t\t#Log_e\n\t" 9729 "fyl2x\t\t\t# Q=Log_e*Log_2(x)\n\t" 9730 %} 9731 ins_encode( Opcode(0xD9), Opcode(0xED), // fldln2 9732 Push_SrcXD(dst), 9733 Opcode(0xD9), Opcode(0xF1), // fyl2x 9734 Push_ResultXD(dst)); 9735 ins_pipe( pipe_slow ); 9736 %} 9737 9738 instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9739 match(Set dst (PowD src0 src1)); // Raise src0 to the src1'th power 9740 effect(KILL rax, KILL rdx, KILL rcx, KILL cr); 9741 format %{ "fast_pow $src0 $src1 -> $dst // KILL $rax, $rcx, $rdx" %} 9742 ins_encode %{ 9743 __ subptr(rsp, 8); 9744 __ movdbl(Address(rsp, 0), $src1$$XMMRegister); 9745 __ fld_d(Address(rsp, 0)); 9746 __ movdbl(Address(rsp, 0), $src0$$XMMRegister); 9747 __ fld_d(Address(rsp, 0)); 9748 __ fast_pow(); 9749 __ fstp_d(Address(rsp, 0)); 9750 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9751 __ addptr(rsp, 8); 9752 %} 9753 ins_pipe( pipe_slow ); 9754 %} 9755 9756 instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{ 9757 match(Set dst (ExpD src)); 9758 effect(KILL rax, KILL rcx, KILL rdx, KILL cr); 9759 format %{ "fast_exp $dst -> $src // KILL $rax, $rcx, $rdx" %} 9760 ins_encode %{ 9761 __ subptr(rsp, 8); 9762 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9763 __ fld_d(Address(rsp, 0)); 9764 __ fast_exp(); 9765 __ fstp_d(Address(rsp, 0)); 9766 __ movdbl($dst$$XMMRegister, Address(rsp, 0)); 9767 __ addptr(rsp, 8); 9768 %} 9769 ins_pipe( pipe_slow ); 9770 %} 9771 9772 //----------Arithmetic Conversion Instructions--------------------------------- 9773 9774 instruct roundFloat_nop(regF dst) 9775 %{ 9776 match(Set dst (RoundFloat dst)); 9777 9778 ins_cost(0); 9779 ins_encode(); 9780 ins_pipe(empty); 9781 %} 9782 9783 instruct roundDouble_nop(regD dst) 9784 %{ 9785 match(Set dst (RoundDouble dst)); 9786 9787 ins_cost(0); 9788 ins_encode(); 9789 ins_pipe(empty); 9790 %} 9791 9792 instruct convF2D_reg_reg(regD dst, regF src) 9793 %{ 9794 match(Set dst (ConvF2D src)); 9795 9796 format %{ "cvtss2sd $dst, $src" %} 9797 ins_encode %{ 9798 __ cvtss2sd ($dst$$XMMRegister, $src$$XMMRegister); 9799 %} 9800 ins_pipe(pipe_slow); // XXX 9801 %} 9802 9803 instruct convF2D_reg_mem(regD dst, memory src) 9804 %{ 9805 match(Set dst (ConvF2D (LoadF src))); 9806 9807 format %{ "cvtss2sd $dst, $src" %} 9808 ins_encode %{ 9809 __ cvtss2sd ($dst$$XMMRegister, $src$$Address); 9810 %} 9811 ins_pipe(pipe_slow); // XXX 9812 %} 9813 9814 instruct convD2F_reg_reg(regF dst, regD src) 9815 %{ 9816 match(Set dst (ConvD2F src)); 9817 9818 format %{ "cvtsd2ss $dst, $src" %} 9819 ins_encode %{ 9820 __ cvtsd2ss ($dst$$XMMRegister, $src$$XMMRegister); 9821 %} 9822 ins_pipe(pipe_slow); // XXX 9823 %} 9824 9825 instruct convD2F_reg_mem(regF dst, memory src) 9826 %{ 9827 match(Set dst (ConvD2F (LoadD src))); 9828 9829 format %{ "cvtsd2ss $dst, $src" %} 9830 ins_encode %{ 9831 __ cvtsd2ss ($dst$$XMMRegister, $src$$Address); 9832 %} 9833 ins_pipe(pipe_slow); // XXX 9834 %} 9835 9836 // XXX do mem variants 9837 instruct convF2I_reg_reg(rRegI dst, regF src, rFlagsReg cr) 9838 %{ 9839 match(Set dst (ConvF2I src)); 9840 effect(KILL cr); 9841 9842 format %{ "cvttss2sil $dst, $src\t# f2i\n\t" 9843 "cmpl $dst, #0x80000000\n\t" 9844 "jne,s done\n\t" 9845 "subq rsp, #8\n\t" 9846 "movss [rsp], $src\n\t" 9847 "call f2i_fixup\n\t" 9848 "popq $dst\n" 9849 "done: "%} 9850 ins_encode %{ 9851 Label done; 9852 __ cvttss2sil($dst$$Register, $src$$XMMRegister); 9853 __ cmpl($dst$$Register, 0x80000000); 9854 __ jccb(Assembler::notEqual, done); 9855 __ subptr(rsp, 8); 9856 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9857 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2i_fixup()))); 9858 __ pop($dst$$Register); 9859 __ bind(done); 9860 %} 9861 ins_pipe(pipe_slow); 9862 %} 9863 9864 instruct convF2L_reg_reg(rRegL dst, regF src, rFlagsReg cr) 9865 %{ 9866 match(Set dst (ConvF2L src)); 9867 effect(KILL cr); 9868 9869 format %{ "cvttss2siq $dst, $src\t# f2l\n\t" 9870 "cmpq $dst, [0x8000000000000000]\n\t" 9871 "jne,s done\n\t" 9872 "subq rsp, #8\n\t" 9873 "movss [rsp], $src\n\t" 9874 "call f2l_fixup\n\t" 9875 "popq $dst\n" 9876 "done: "%} 9877 ins_encode %{ 9878 Label done; 9879 __ cvttss2siq($dst$$Register, $src$$XMMRegister); 9880 __ cmp64($dst$$Register, 9881 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9882 __ jccb(Assembler::notEqual, done); 9883 __ subptr(rsp, 8); 9884 __ movflt(Address(rsp, 0), $src$$XMMRegister); 9885 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::f2l_fixup()))); 9886 __ pop($dst$$Register); 9887 __ bind(done); 9888 %} 9889 ins_pipe(pipe_slow); 9890 %} 9891 9892 instruct convD2I_reg_reg(rRegI dst, regD src, rFlagsReg cr) 9893 %{ 9894 match(Set dst (ConvD2I src)); 9895 effect(KILL cr); 9896 9897 format %{ "cvttsd2sil $dst, $src\t# d2i\n\t" 9898 "cmpl $dst, #0x80000000\n\t" 9899 "jne,s done\n\t" 9900 "subq rsp, #8\n\t" 9901 "movsd [rsp], $src\n\t" 9902 "call d2i_fixup\n\t" 9903 "popq $dst\n" 9904 "done: "%} 9905 ins_encode %{ 9906 Label done; 9907 __ cvttsd2sil($dst$$Register, $src$$XMMRegister); 9908 __ cmpl($dst$$Register, 0x80000000); 9909 __ jccb(Assembler::notEqual, done); 9910 __ subptr(rsp, 8); 9911 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9912 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2i_fixup()))); 9913 __ pop($dst$$Register); 9914 __ bind(done); 9915 %} 9916 ins_pipe(pipe_slow); 9917 %} 9918 9919 instruct convD2L_reg_reg(rRegL dst, regD src, rFlagsReg cr) 9920 %{ 9921 match(Set dst (ConvD2L src)); 9922 effect(KILL cr); 9923 9924 format %{ "cvttsd2siq $dst, $src\t# d2l\n\t" 9925 "cmpq $dst, [0x8000000000000000]\n\t" 9926 "jne,s done\n\t" 9927 "subq rsp, #8\n\t" 9928 "movsd [rsp], $src\n\t" 9929 "call d2l_fixup\n\t" 9930 "popq $dst\n" 9931 "done: "%} 9932 ins_encode %{ 9933 Label done; 9934 __ cvttsd2siq($dst$$Register, $src$$XMMRegister); 9935 __ cmp64($dst$$Register, 9936 ExternalAddress((address) StubRoutines::x86::double_sign_flip())); 9937 __ jccb(Assembler::notEqual, done); 9938 __ subptr(rsp, 8); 9939 __ movdbl(Address(rsp, 0), $src$$XMMRegister); 9940 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup()))); 9941 __ pop($dst$$Register); 9942 __ bind(done); 9943 %} 9944 ins_pipe(pipe_slow); 9945 %} 9946 9947 instruct convI2F_reg_reg(regF dst, rRegI src) 9948 %{ 9949 predicate(!UseXmmI2F); 9950 match(Set dst (ConvI2F src)); 9951 9952 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 9953 ins_encode %{ 9954 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Register); 9955 %} 9956 ins_pipe(pipe_slow); // XXX 9957 %} 9958 9959 instruct convI2F_reg_mem(regF dst, memory src) 9960 %{ 9961 match(Set dst (ConvI2F (LoadI src))); 9962 9963 format %{ "cvtsi2ssl $dst, $src\t# i2f" %} 9964 ins_encode %{ 9965 __ cvtsi2ssl ($dst$$XMMRegister, $src$$Address); 9966 %} 9967 ins_pipe(pipe_slow); // XXX 9968 %} 9969 9970 instruct convI2D_reg_reg(regD dst, rRegI src) 9971 %{ 9972 predicate(!UseXmmI2D); 9973 match(Set dst (ConvI2D src)); 9974 9975 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 9976 ins_encode %{ 9977 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Register); 9978 %} 9979 ins_pipe(pipe_slow); // XXX 9980 %} 9981 9982 instruct convI2D_reg_mem(regD dst, memory src) 9983 %{ 9984 match(Set dst (ConvI2D (LoadI src))); 9985 9986 format %{ "cvtsi2sdl $dst, $src\t# i2d" %} 9987 ins_encode %{ 9988 __ cvtsi2sdl ($dst$$XMMRegister, $src$$Address); 9989 %} 9990 ins_pipe(pipe_slow); // XXX 9991 %} 9992 9993 instruct convXI2F_reg(regF dst, rRegI src) 9994 %{ 9995 predicate(UseXmmI2F); 9996 match(Set dst (ConvI2F src)); 9997 9998 format %{ "movdl $dst, $src\n\t" 9999 "cvtdq2psl $dst, $dst\t# i2f" %} 10000 ins_encode %{ 10001 __ movdl($dst$$XMMRegister, $src$$Register); 10002 __ cvtdq2ps($dst$$XMMRegister, $dst$$XMMRegister); 10003 %} 10004 ins_pipe(pipe_slow); // XXX 10005 %} 10006 10007 instruct convXI2D_reg(regD dst, rRegI src) 10008 %{ 10009 predicate(UseXmmI2D); 10010 match(Set dst (ConvI2D src)); 10011 10012 format %{ "movdl $dst, $src\n\t" 10013 "cvtdq2pdl $dst, $dst\t# i2d" %} 10014 ins_encode %{ 10015 __ movdl($dst$$XMMRegister, $src$$Register); 10016 __ cvtdq2pd($dst$$XMMRegister, $dst$$XMMRegister); 10017 %} 10018 ins_pipe(pipe_slow); // XXX 10019 %} 10020 10021 instruct convL2F_reg_reg(regF dst, rRegL src) 10022 %{ 10023 match(Set dst (ConvL2F src)); 10024 10025 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10026 ins_encode %{ 10027 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Register); 10028 %} 10029 ins_pipe(pipe_slow); // XXX 10030 %} 10031 10032 instruct convL2F_reg_mem(regF dst, memory src) 10033 %{ 10034 match(Set dst (ConvL2F (LoadL src))); 10035 10036 format %{ "cvtsi2ssq $dst, $src\t# l2f" %} 10037 ins_encode %{ 10038 __ cvtsi2ssq ($dst$$XMMRegister, $src$$Address); 10039 %} 10040 ins_pipe(pipe_slow); // XXX 10041 %} 10042 10043 instruct convL2D_reg_reg(regD dst, rRegL src) 10044 %{ 10045 match(Set dst (ConvL2D src)); 10046 10047 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10048 ins_encode %{ 10049 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Register); 10050 %} 10051 ins_pipe(pipe_slow); // XXX 10052 %} 10053 10054 instruct convL2D_reg_mem(regD dst, memory src) 10055 %{ 10056 match(Set dst (ConvL2D (LoadL src))); 10057 10058 format %{ "cvtsi2sdq $dst, $src\t# l2d" %} 10059 ins_encode %{ 10060 __ cvtsi2sdq ($dst$$XMMRegister, $src$$Address); 10061 %} 10062 ins_pipe(pipe_slow); // XXX 10063 %} 10064 10065 instruct convI2L_reg_reg(rRegL dst, rRegI src) 10066 %{ 10067 match(Set dst (ConvI2L src)); 10068 10069 ins_cost(125); 10070 format %{ "movslq $dst, $src\t# i2l" %} 10071 ins_encode %{ 10072 __ movslq($dst$$Register, $src$$Register); 10073 %} 10074 ins_pipe(ialu_reg_reg); 10075 %} 10076 10077 // instruct convI2L_reg_reg_foo(rRegL dst, rRegI src) 10078 // %{ 10079 // match(Set dst (ConvI2L src)); 10080 // // predicate(_kids[0]->_leaf->as_Type()->type()->is_int()->_lo >= 0 && 10081 // // _kids[0]->_leaf->as_Type()->type()->is_int()->_hi >= 0); 10082 // predicate(((const TypeNode*) n)->type()->is_long()->_hi == 10083 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_hi && 10084 // ((const TypeNode*) n)->type()->is_long()->_lo == 10085 // (unsigned int) ((const TypeNode*) n)->type()->is_long()->_lo); 10086 10087 // format %{ "movl $dst, $src\t# unsigned i2l" %} 10088 // ins_encode(enc_copy(dst, src)); 10089 // // opcode(0x63); // needs REX.W 10090 // // ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst,src)); 10091 // ins_pipe(ialu_reg_reg); 10092 // %} 10093 10094 // Zero-extend convert int to long 10095 instruct convI2L_reg_reg_zex(rRegL dst, rRegI src, immL_32bits mask) 10096 %{ 10097 match(Set dst (AndL (ConvI2L src) mask)); 10098 10099 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10100 ins_encode %{ 10101 if ($dst$$reg != $src$$reg) { 10102 __ movl($dst$$Register, $src$$Register); 10103 } 10104 %} 10105 ins_pipe(ialu_reg_reg); 10106 %} 10107 10108 // Zero-extend convert int to long 10109 instruct convI2L_reg_mem_zex(rRegL dst, memory src, immL_32bits mask) 10110 %{ 10111 match(Set dst (AndL (ConvI2L (LoadI src)) mask)); 10112 10113 format %{ "movl $dst, $src\t# i2l zero-extend\n\t" %} 10114 ins_encode %{ 10115 __ movl($dst$$Register, $src$$Address); 10116 %} 10117 ins_pipe(ialu_reg_mem); 10118 %} 10119 10120 instruct zerox_long_reg_reg(rRegL dst, rRegL src, immL_32bits mask) 10121 %{ 10122 match(Set dst (AndL src mask)); 10123 10124 format %{ "movl $dst, $src\t# zero-extend long" %} 10125 ins_encode %{ 10126 __ movl($dst$$Register, $src$$Register); 10127 %} 10128 ins_pipe(ialu_reg_reg); 10129 %} 10130 10131 instruct convL2I_reg_reg(rRegI dst, rRegL src) 10132 %{ 10133 match(Set dst (ConvL2I src)); 10134 10135 format %{ "movl $dst, $src\t# l2i" %} 10136 ins_encode %{ 10137 __ movl($dst$$Register, $src$$Register); 10138 %} 10139 ins_pipe(ialu_reg_reg); 10140 %} 10141 10142 10143 instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{ 10144 match(Set dst (MoveF2I src)); 10145 effect(DEF dst, USE src); 10146 10147 ins_cost(125); 10148 format %{ "movl $dst, $src\t# MoveF2I_stack_reg" %} 10149 ins_encode %{ 10150 __ movl($dst$$Register, Address(rsp, $src$$disp)); 10151 %} 10152 ins_pipe(ialu_reg_mem); 10153 %} 10154 10155 instruct MoveI2F_stack_reg(regF dst, stackSlotI src) %{ 10156 match(Set dst (MoveI2F src)); 10157 effect(DEF dst, USE src); 10158 10159 ins_cost(125); 10160 format %{ "movss $dst, $src\t# MoveI2F_stack_reg" %} 10161 ins_encode %{ 10162 __ movflt($dst$$XMMRegister, Address(rsp, $src$$disp)); 10163 %} 10164 ins_pipe(pipe_slow); 10165 %} 10166 10167 instruct MoveD2L_stack_reg(rRegL dst, stackSlotD src) %{ 10168 match(Set dst (MoveD2L src)); 10169 effect(DEF dst, USE src); 10170 10171 ins_cost(125); 10172 format %{ "movq $dst, $src\t# MoveD2L_stack_reg" %} 10173 ins_encode %{ 10174 __ movq($dst$$Register, Address(rsp, $src$$disp)); 10175 %} 10176 ins_pipe(ialu_reg_mem); 10177 %} 10178 10179 instruct MoveL2D_stack_reg_partial(regD dst, stackSlotL src) %{ 10180 predicate(!UseXmmLoadAndClearUpper); 10181 match(Set dst (MoveL2D src)); 10182 effect(DEF dst, USE src); 10183 10184 ins_cost(125); 10185 format %{ "movlpd $dst, $src\t# MoveL2D_stack_reg" %} 10186 ins_encode %{ 10187 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10188 %} 10189 ins_pipe(pipe_slow); 10190 %} 10191 10192 instruct MoveL2D_stack_reg(regD dst, stackSlotL src) %{ 10193 predicate(UseXmmLoadAndClearUpper); 10194 match(Set dst (MoveL2D src)); 10195 effect(DEF dst, USE src); 10196 10197 ins_cost(125); 10198 format %{ "movsd $dst, $src\t# MoveL2D_stack_reg" %} 10199 ins_encode %{ 10200 __ movdbl($dst$$XMMRegister, Address(rsp, $src$$disp)); 10201 %} 10202 ins_pipe(pipe_slow); 10203 %} 10204 10205 10206 instruct MoveF2I_reg_stack(stackSlotI dst, regF src) %{ 10207 match(Set dst (MoveF2I src)); 10208 effect(DEF dst, USE src); 10209 10210 ins_cost(95); // XXX 10211 format %{ "movss $dst, $src\t# MoveF2I_reg_stack" %} 10212 ins_encode %{ 10213 __ movflt(Address(rsp, $dst$$disp), $src$$XMMRegister); 10214 %} 10215 ins_pipe(pipe_slow); 10216 %} 10217 10218 instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{ 10219 match(Set dst (MoveI2F src)); 10220 effect(DEF dst, USE src); 10221 10222 ins_cost(100); 10223 format %{ "movl $dst, $src\t# MoveI2F_reg_stack" %} 10224 ins_encode %{ 10225 __ movl(Address(rsp, $dst$$disp), $src$$Register); 10226 %} 10227 ins_pipe( ialu_mem_reg ); 10228 %} 10229 10230 instruct MoveD2L_reg_stack(stackSlotL dst, regD src) %{ 10231 match(Set dst (MoveD2L src)); 10232 effect(DEF dst, USE src); 10233 10234 ins_cost(95); // XXX 10235 format %{ "movsd $dst, $src\t# MoveL2D_reg_stack" %} 10236 ins_encode %{ 10237 __ movdbl(Address(rsp, $dst$$disp), $src$$XMMRegister); 10238 %} 10239 ins_pipe(pipe_slow); 10240 %} 10241 10242 instruct MoveL2D_reg_stack(stackSlotD dst, rRegL src) %{ 10243 match(Set dst (MoveL2D src)); 10244 effect(DEF dst, USE src); 10245 10246 ins_cost(100); 10247 format %{ "movq $dst, $src\t# MoveL2D_reg_stack" %} 10248 ins_encode %{ 10249 __ movq(Address(rsp, $dst$$disp), $src$$Register); 10250 %} 10251 ins_pipe(ialu_mem_reg); 10252 %} 10253 10254 instruct MoveF2I_reg_reg(rRegI dst, regF src) %{ 10255 match(Set dst (MoveF2I src)); 10256 effect(DEF dst, USE src); 10257 ins_cost(85); 10258 format %{ "movd $dst,$src\t# MoveF2I" %} 10259 ins_encode %{ 10260 __ movdl($dst$$Register, $src$$XMMRegister); 10261 %} 10262 ins_pipe( pipe_slow ); 10263 %} 10264 10265 instruct MoveD2L_reg_reg(rRegL dst, regD src) %{ 10266 match(Set dst (MoveD2L src)); 10267 effect(DEF dst, USE src); 10268 ins_cost(85); 10269 format %{ "movd $dst,$src\t# MoveD2L" %} 10270 ins_encode %{ 10271 __ movdq($dst$$Register, $src$$XMMRegister); 10272 %} 10273 ins_pipe( pipe_slow ); 10274 %} 10275 10276 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{ 10277 match(Set dst (MoveI2F src)); 10278 effect(DEF dst, USE src); 10279 ins_cost(100); 10280 format %{ "movd $dst,$src\t# MoveI2F" %} 10281 ins_encode %{ 10282 __ movdl($dst$$XMMRegister, $src$$Register); 10283 %} 10284 ins_pipe( pipe_slow ); 10285 %} 10286 10287 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{ 10288 match(Set dst (MoveL2D src)); 10289 effect(DEF dst, USE src); 10290 ins_cost(100); 10291 format %{ "movd $dst,$src\t# MoveL2D" %} 10292 ins_encode %{ 10293 __ movdq($dst$$XMMRegister, $src$$Register); 10294 %} 10295 ins_pipe( pipe_slow ); 10296 %} 10297 10298 10299 // ======================================================================= 10300 // fast clearing of an array 10301 instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10302 rFlagsReg cr) 10303 %{ 10304 predicate(!UseFastStosb); 10305 match(Set dummy (ClearArray cnt base)); 10306 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10307 10308 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10309 "rep stosq\t# Store rax to *rdi++ while rcx--" %} 10310 ins_encode %{ 10311 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10312 %} 10313 ins_pipe(pipe_slow); 10314 %} 10315 10316 instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy, 10317 rFlagsReg cr) 10318 %{ 10319 predicate(UseFastStosb); 10320 match(Set dummy (ClearArray cnt base)); 10321 effect(USE_KILL cnt, USE_KILL base, KILL zero, KILL cr); 10322 format %{ "xorq rax, rax\t# ClearArray:\n\t" 10323 "shlq rcx,3\t# Convert doublewords to bytes\n\t" 10324 "rep stosb\t# Store rax to *rdi++ while rcx--" %} 10325 ins_encode %{ 10326 __ clear_mem($base$$Register, $cnt$$Register, $zero$$Register); 10327 %} 10328 ins_pipe( pipe_slow ); 10329 %} 10330 10331 instruct string_compare(rdi_RegP str1, rcx_RegI cnt1, rsi_RegP str2, rdx_RegI cnt2, 10332 rax_RegI result, regD tmp1, rFlagsReg cr) 10333 %{ 10334 match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2))); 10335 effect(TEMP tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr); 10336 10337 format %{ "String Compare $str1,$cnt1,$str2,$cnt2 -> $result // KILL $tmp1" %} 10338 ins_encode %{ 10339 __ string_compare($str1$$Register, $str2$$Register, 10340 $cnt1$$Register, $cnt2$$Register, $result$$Register, 10341 $tmp1$$XMMRegister); 10342 %} 10343 ins_pipe( pipe_slow ); 10344 %} 10345 10346 // fast search of substring with known size. 10347 instruct string_indexof_con(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, immI int_cnt2, 10348 rbx_RegI result, regD vec, rax_RegI cnt2, rcx_RegI tmp, rFlagsReg cr) 10349 %{ 10350 predicate(UseSSE42Intrinsics); 10351 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2))); 10352 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, KILL cnt2, KILL tmp, KILL cr); 10353 10354 format %{ "String IndexOf $str1,$cnt1,$str2,$int_cnt2 -> $result // KILL $vec, $cnt1, $cnt2, $tmp" %} 10355 ins_encode %{ 10356 int icnt2 = (int)$int_cnt2$$constant; 10357 if (icnt2 >= 8) { 10358 // IndexOf for constant substrings with size >= 8 elements 10359 // which don't need to be loaded through stack. 10360 __ string_indexofC8($str1$$Register, $str2$$Register, 10361 $cnt1$$Register, $cnt2$$Register, 10362 icnt2, $result$$Register, 10363 $vec$$XMMRegister, $tmp$$Register); 10364 } else { 10365 // Small strings are loaded through stack if they cross page boundary. 10366 __ string_indexof($str1$$Register, $str2$$Register, 10367 $cnt1$$Register, $cnt2$$Register, 10368 icnt2, $result$$Register, 10369 $vec$$XMMRegister, $tmp$$Register); 10370 } 10371 %} 10372 ins_pipe( pipe_slow ); 10373 %} 10374 10375 instruct string_indexof(rdi_RegP str1, rdx_RegI cnt1, rsi_RegP str2, rax_RegI cnt2, 10376 rbx_RegI result, regD vec, rcx_RegI tmp, rFlagsReg cr) 10377 %{ 10378 predicate(UseSSE42Intrinsics); 10379 match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2))); 10380 effect(TEMP vec, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL tmp, KILL cr); 10381 10382 format %{ "String IndexOf $str1,$cnt1,$str2,$cnt2 -> $result // KILL all" %} 10383 ins_encode %{ 10384 __ string_indexof($str1$$Register, $str2$$Register, 10385 $cnt1$$Register, $cnt2$$Register, 10386 (-1), $result$$Register, 10387 $vec$$XMMRegister, $tmp$$Register); 10388 %} 10389 ins_pipe( pipe_slow ); 10390 %} 10391 10392 // fast string equals 10393 instruct string_equals(rdi_RegP str1, rsi_RegP str2, rcx_RegI cnt, rax_RegI result, 10394 regD tmp1, regD tmp2, rbx_RegI tmp3, rFlagsReg cr) 10395 %{ 10396 match(Set result (StrEquals (Binary str1 str2) cnt)); 10397 effect(TEMP tmp1, TEMP tmp2, USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL tmp3, KILL cr); 10398 10399 format %{ "String Equals $str1,$str2,$cnt -> $result // KILL $tmp1, $tmp2, $tmp3" %} 10400 ins_encode %{ 10401 __ char_arrays_equals(false, $str1$$Register, $str2$$Register, 10402 $cnt$$Register, $result$$Register, $tmp3$$Register, 10403 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10404 %} 10405 ins_pipe( pipe_slow ); 10406 %} 10407 10408 // fast array equals 10409 instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI result, 10410 regD tmp1, regD tmp2, rcx_RegI tmp3, rbx_RegI tmp4, rFlagsReg cr) 10411 %{ 10412 match(Set result (AryEq ary1 ary2)); 10413 effect(TEMP tmp1, TEMP tmp2, USE_KILL ary1, USE_KILL ary2, KILL tmp3, KILL tmp4, KILL cr); 10414 //ins_cost(300); 10415 10416 format %{ "Array Equals $ary1,$ary2 -> $result // KILL $tmp1, $tmp2, $tmp3, $tmp4" %} 10417 ins_encode %{ 10418 __ char_arrays_equals(true, $ary1$$Register, $ary2$$Register, 10419 $tmp3$$Register, $result$$Register, $tmp4$$Register, 10420 $tmp1$$XMMRegister, $tmp2$$XMMRegister); 10421 %} 10422 ins_pipe( pipe_slow ); 10423 %} 10424 10425 // encode char[] to byte[] in ISO_8859_1 10426 instruct encode_iso_array(rsi_RegP src, rdi_RegP dst, rdx_RegI len, 10427 regD tmp1, regD tmp2, regD tmp3, regD tmp4, 10428 rcx_RegI tmp5, rax_RegI result, rFlagsReg cr) %{ 10429 match(Set result (EncodeISOArray src (Binary dst len))); 10430 effect(TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, USE_KILL src, USE_KILL dst, USE_KILL len, KILL tmp5, KILL cr); 10431 10432 format %{ "Encode array $src,$dst,$len -> $result // KILL RCX, RDX, $tmp1, $tmp2, $tmp3, $tmp4, RSI, RDI " %} 10433 ins_encode %{ 10434 __ encode_iso_array($src$$Register, $dst$$Register, $len$$Register, 10435 $tmp1$$XMMRegister, $tmp2$$XMMRegister, $tmp3$$XMMRegister, 10436 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); 10437 %} 10438 ins_pipe( pipe_slow ); 10439 %} 10440 10441 //----------Overflow Math Instructions----------------------------------------- 10442 10443 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10444 %{ 10445 match(Set cr (OverflowAddI op1 op2)); 10446 effect(DEF cr, USE_KILL op1, USE op2); 10447 10448 format %{ "addl $op1, $op2\t# overflow check int" %} 10449 10450 ins_encode %{ 10451 __ addl($op1$$Register, $op2$$Register); 10452 %} 10453 ins_pipe(ialu_reg_reg); 10454 %} 10455 10456 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) 10457 %{ 10458 match(Set cr (OverflowAddI op1 op2)); 10459 effect(DEF cr, USE_KILL op1, USE op2); 10460 10461 format %{ "addl $op1, $op2\t# overflow check int" %} 10462 10463 ins_encode %{ 10464 __ addl($op1$$Register, $op2$$constant); 10465 %} 10466 ins_pipe(ialu_reg_reg); 10467 %} 10468 10469 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10470 %{ 10471 match(Set cr (OverflowAddL op1 op2)); 10472 effect(DEF cr, USE_KILL op1, USE op2); 10473 10474 format %{ "addq $op1, $op2\t# overflow check long" %} 10475 ins_encode %{ 10476 __ addq($op1$$Register, $op2$$Register); 10477 %} 10478 ins_pipe(ialu_reg_reg); 10479 %} 10480 10481 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) 10482 %{ 10483 match(Set cr (OverflowAddL op1 op2)); 10484 effect(DEF cr, USE_KILL op1, USE op2); 10485 10486 format %{ "addq $op1, $op2\t# overflow check long" %} 10487 ins_encode %{ 10488 __ addq($op1$$Register, $op2$$constant); 10489 %} 10490 ins_pipe(ialu_reg_reg); 10491 %} 10492 10493 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10494 %{ 10495 match(Set cr (OverflowSubI op1 op2)); 10496 10497 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10498 ins_encode %{ 10499 __ cmpl($op1$$Register, $op2$$Register); 10500 %} 10501 ins_pipe(ialu_reg_reg); 10502 %} 10503 10504 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10505 %{ 10506 match(Set cr (OverflowSubI op1 op2)); 10507 10508 format %{ "cmpl $op1, $op2\t# overflow check int" %} 10509 ins_encode %{ 10510 __ cmpl($op1$$Register, $op2$$constant); 10511 %} 10512 ins_pipe(ialu_reg_reg); 10513 %} 10514 10515 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10516 %{ 10517 match(Set cr (OverflowSubL op1 op2)); 10518 10519 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10520 ins_encode %{ 10521 __ cmpq($op1$$Register, $op2$$Register); 10522 %} 10523 ins_pipe(ialu_reg_reg); 10524 %} 10525 10526 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10527 %{ 10528 match(Set cr (OverflowSubL op1 op2)); 10529 10530 format %{ "cmpq $op1, $op2\t# overflow check long" %} 10531 ins_encode %{ 10532 __ cmpq($op1$$Register, $op2$$constant); 10533 %} 10534 ins_pipe(ialu_reg_reg); 10535 %} 10536 10537 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) 10538 %{ 10539 match(Set cr (OverflowSubI zero op2)); 10540 effect(DEF cr, USE_KILL op2); 10541 10542 format %{ "negl $op2\t# overflow check int" %} 10543 ins_encode %{ 10544 __ negl($op2$$Register); 10545 %} 10546 ins_pipe(ialu_reg_reg); 10547 %} 10548 10549 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) 10550 %{ 10551 match(Set cr (OverflowSubL zero op2)); 10552 effect(DEF cr, USE_KILL op2); 10553 10554 format %{ "negq $op2\t# overflow check long" %} 10555 ins_encode %{ 10556 __ negq($op2$$Register); 10557 %} 10558 ins_pipe(ialu_reg_reg); 10559 %} 10560 10561 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) 10562 %{ 10563 match(Set cr (OverflowMulI op1 op2)); 10564 effect(DEF cr, USE_KILL op1, USE op2); 10565 10566 format %{ "imull $op1, $op2\t# overflow check int" %} 10567 ins_encode %{ 10568 __ imull($op1$$Register, $op2$$Register); 10569 %} 10570 ins_pipe(ialu_reg_reg_alu0); 10571 %} 10572 10573 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) 10574 %{ 10575 match(Set cr (OverflowMulI op1 op2)); 10576 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10577 10578 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} 10579 ins_encode %{ 10580 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); 10581 %} 10582 ins_pipe(ialu_reg_reg_alu0); 10583 %} 10584 10585 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) 10586 %{ 10587 match(Set cr (OverflowMulL op1 op2)); 10588 effect(DEF cr, USE_KILL op1, USE op2); 10589 10590 format %{ "imulq $op1, $op2\t# overflow check long" %} 10591 ins_encode %{ 10592 __ imulq($op1$$Register, $op2$$Register); 10593 %} 10594 ins_pipe(ialu_reg_reg_alu0); 10595 %} 10596 10597 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) 10598 %{ 10599 match(Set cr (OverflowMulL op1 op2)); 10600 effect(DEF cr, TEMP tmp, USE op1, USE op2); 10601 10602 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} 10603 ins_encode %{ 10604 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); 10605 %} 10606 ins_pipe(ialu_reg_reg_alu0); 10607 %} 10608 10609 10610 //----------Control Flow Instructions------------------------------------------ 10611 // Signed compare Instructions 10612 10613 // XXX more variants!! 10614 instruct compI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) 10615 %{ 10616 match(Set cr (CmpI op1 op2)); 10617 effect(DEF cr, USE op1, USE op2); 10618 10619 format %{ "cmpl $op1, $op2" %} 10620 opcode(0x3B); /* Opcode 3B /r */ 10621 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10622 ins_pipe(ialu_cr_reg_reg); 10623 %} 10624 10625 instruct compI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) 10626 %{ 10627 match(Set cr (CmpI op1 op2)); 10628 10629 format %{ "cmpl $op1, $op2" %} 10630 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10631 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10632 ins_pipe(ialu_cr_reg_imm); 10633 %} 10634 10635 instruct compI_rReg_mem(rFlagsReg cr, rRegI op1, memory op2) 10636 %{ 10637 match(Set cr (CmpI op1 (LoadI op2))); 10638 10639 ins_cost(500); // XXX 10640 format %{ "cmpl $op1, $op2" %} 10641 opcode(0x3B); /* Opcode 3B /r */ 10642 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10643 ins_pipe(ialu_cr_reg_mem); 10644 %} 10645 10646 instruct testI_reg(rFlagsReg cr, rRegI src, immI0 zero) 10647 %{ 10648 match(Set cr (CmpI src zero)); 10649 10650 format %{ "testl $src, $src" %} 10651 opcode(0x85); 10652 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10653 ins_pipe(ialu_cr_reg_imm); 10654 %} 10655 10656 instruct testI_reg_imm(rFlagsReg cr, rRegI src, immI con, immI0 zero) 10657 %{ 10658 match(Set cr (CmpI (AndI src con) zero)); 10659 10660 format %{ "testl $src, $con" %} 10661 opcode(0xF7, 0x00); 10662 ins_encode(REX_reg(src), OpcP, reg_opc(src), Con32(con)); 10663 ins_pipe(ialu_cr_reg_imm); 10664 %} 10665 10666 instruct testI_reg_mem(rFlagsReg cr, rRegI src, memory mem, immI0 zero) 10667 %{ 10668 match(Set cr (CmpI (AndI src (LoadI mem)) zero)); 10669 10670 format %{ "testl $src, $mem" %} 10671 opcode(0x85); 10672 ins_encode(REX_reg_mem(src, mem), OpcP, reg_mem(src, mem)); 10673 ins_pipe(ialu_cr_reg_mem); 10674 %} 10675 10676 // Unsigned compare Instructions; really, same as signed except they 10677 // produce an rFlagsRegU instead of rFlagsReg. 10678 instruct compU_rReg(rFlagsRegU cr, rRegI op1, rRegI op2) 10679 %{ 10680 match(Set cr (CmpU op1 op2)); 10681 10682 format %{ "cmpl $op1, $op2\t# unsigned" %} 10683 opcode(0x3B); /* Opcode 3B /r */ 10684 ins_encode(REX_reg_reg(op1, op2), OpcP, reg_reg(op1, op2)); 10685 ins_pipe(ialu_cr_reg_reg); 10686 %} 10687 10688 instruct compU_rReg_imm(rFlagsRegU cr, rRegI op1, immI op2) 10689 %{ 10690 match(Set cr (CmpU op1 op2)); 10691 10692 format %{ "cmpl $op1, $op2\t# unsigned" %} 10693 opcode(0x81,0x07); /* Opcode 81 /7 */ 10694 ins_encode(OpcSErm(op1, op2), Con8or32(op2)); 10695 ins_pipe(ialu_cr_reg_imm); 10696 %} 10697 10698 instruct compU_rReg_mem(rFlagsRegU cr, rRegI op1, memory op2) 10699 %{ 10700 match(Set cr (CmpU op1 (LoadI op2))); 10701 10702 ins_cost(500); // XXX 10703 format %{ "cmpl $op1, $op2\t# unsigned" %} 10704 opcode(0x3B); /* Opcode 3B /r */ 10705 ins_encode(REX_reg_mem(op1, op2), OpcP, reg_mem(op1, op2)); 10706 ins_pipe(ialu_cr_reg_mem); 10707 %} 10708 10709 // // // Cisc-spilled version of cmpU_rReg 10710 // //instruct compU_mem_rReg(rFlagsRegU cr, memory op1, rRegI op2) 10711 // //%{ 10712 // // match(Set cr (CmpU (LoadI op1) op2)); 10713 // // 10714 // // format %{ "CMPu $op1,$op2" %} 10715 // // ins_cost(500); 10716 // // opcode(0x39); /* Opcode 39 /r */ 10717 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10718 // //%} 10719 10720 instruct testU_reg(rFlagsRegU cr, rRegI src, immI0 zero) 10721 %{ 10722 match(Set cr (CmpU src zero)); 10723 10724 format %{ "testl $src, $src\t# unsigned" %} 10725 opcode(0x85); 10726 ins_encode(REX_reg_reg(src, src), OpcP, reg_reg(src, src)); 10727 ins_pipe(ialu_cr_reg_imm); 10728 %} 10729 10730 instruct compP_rReg(rFlagsRegU cr, rRegP op1, rRegP op2) 10731 %{ 10732 match(Set cr (CmpP op1 op2)); 10733 10734 format %{ "cmpq $op1, $op2\t# ptr" %} 10735 opcode(0x3B); /* Opcode 3B /r */ 10736 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10737 ins_pipe(ialu_cr_reg_reg); 10738 %} 10739 10740 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2) 10741 %{ 10742 match(Set cr (CmpP op1 (LoadP op2))); 10743 10744 ins_cost(500); // XXX 10745 format %{ "cmpq $op1, $op2\t# ptr" %} 10746 opcode(0x3B); /* Opcode 3B /r */ 10747 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10748 ins_pipe(ialu_cr_reg_mem); 10749 %} 10750 10751 // // // Cisc-spilled version of cmpP_rReg 10752 // //instruct compP_mem_rReg(rFlagsRegU cr, memory op1, rRegP op2) 10753 // //%{ 10754 // // match(Set cr (CmpP (LoadP op1) op2)); 10755 // // 10756 // // format %{ "CMPu $op1,$op2" %} 10757 // // ins_cost(500); 10758 // // opcode(0x39); /* Opcode 39 /r */ 10759 // // ins_encode( OpcP, reg_mem( op1, op2) ); 10760 // //%} 10761 10762 // XXX this is generalized by compP_rReg_mem??? 10763 // Compare raw pointer (used in out-of-heap check). 10764 // Only works because non-oop pointers must be raw pointers 10765 // and raw pointers have no anti-dependencies. 10766 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2) 10767 %{ 10768 predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none); 10769 match(Set cr (CmpP op1 (LoadP op2))); 10770 10771 format %{ "cmpq $op1, $op2\t# raw ptr" %} 10772 opcode(0x3B); /* Opcode 3B /r */ 10773 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10774 ins_pipe(ialu_cr_reg_mem); 10775 %} 10776 10777 // This will generate a signed flags result. This should be OK since 10778 // any compare to a zero should be eq/neq. 10779 instruct testP_reg(rFlagsReg cr, rRegP src, immP0 zero) 10780 %{ 10781 match(Set cr (CmpP src zero)); 10782 10783 format %{ "testq $src, $src\t# ptr" %} 10784 opcode(0x85); 10785 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10786 ins_pipe(ialu_cr_reg_imm); 10787 %} 10788 10789 // This will generate a signed flags result. This should be OK since 10790 // any compare to a zero should be eq/neq. 10791 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero) 10792 %{ 10793 predicate(!UseCompressedOops || (Universe::narrow_oop_base() != NULL)); 10794 match(Set cr (CmpP (LoadP op) zero)); 10795 10796 ins_cost(500); // XXX 10797 format %{ "testq $op, 0xffffffffffffffff\t# ptr" %} 10798 opcode(0xF7); /* Opcode F7 /0 */ 10799 ins_encode(REX_mem_wide(op), 10800 OpcP, RM_opc_mem(0x00, op), Con_d32(0xFFFFFFFF)); 10801 ins_pipe(ialu_cr_reg_imm); 10802 %} 10803 10804 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero) 10805 %{ 10806 predicate(UseCompressedOops && (Universe::narrow_oop_base() == NULL) && (Universe::narrow_klass_base() == NULL)); 10807 match(Set cr (CmpP (LoadP mem) zero)); 10808 10809 format %{ "cmpq R12, $mem\t# ptr (R12_heapbase==0)" %} 10810 ins_encode %{ 10811 __ cmpq(r12, $mem$$Address); 10812 %} 10813 ins_pipe(ialu_cr_reg_mem); 10814 %} 10815 10816 instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2) 10817 %{ 10818 match(Set cr (CmpN op1 op2)); 10819 10820 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10821 ins_encode %{ __ cmpl($op1$$Register, $op2$$Register); %} 10822 ins_pipe(ialu_cr_reg_reg); 10823 %} 10824 10825 instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem) 10826 %{ 10827 match(Set cr (CmpN src (LoadN mem))); 10828 10829 format %{ "cmpl $src, $mem\t# compressed ptr" %} 10830 ins_encode %{ 10831 __ cmpl($src$$Register, $mem$$Address); 10832 %} 10833 ins_pipe(ialu_cr_reg_mem); 10834 %} 10835 10836 instruct compN_rReg_imm(rFlagsRegU cr, rRegN op1, immN op2) %{ 10837 match(Set cr (CmpN op1 op2)); 10838 10839 format %{ "cmpl $op1, $op2\t# compressed ptr" %} 10840 ins_encode %{ 10841 __ cmp_narrow_oop($op1$$Register, (jobject)$op2$$constant); 10842 %} 10843 ins_pipe(ialu_cr_reg_imm); 10844 %} 10845 10846 instruct compN_mem_imm(rFlagsRegU cr, memory mem, immN src) 10847 %{ 10848 match(Set cr (CmpN src (LoadN mem))); 10849 10850 format %{ "cmpl $mem, $src\t# compressed ptr" %} 10851 ins_encode %{ 10852 __ cmp_narrow_oop($mem$$Address, (jobject)$src$$constant); 10853 %} 10854 ins_pipe(ialu_cr_reg_mem); 10855 %} 10856 10857 instruct compN_rReg_imm_klass(rFlagsRegU cr, rRegN op1, immNKlass op2) %{ 10858 match(Set cr (CmpN op1 op2)); 10859 10860 format %{ "cmpl $op1, $op2\t# compressed klass ptr" %} 10861 ins_encode %{ 10862 __ cmp_narrow_klass($op1$$Register, (Klass*)$op2$$constant); 10863 %} 10864 ins_pipe(ialu_cr_reg_imm); 10865 %} 10866 10867 instruct compN_mem_imm_klass(rFlagsRegU cr, memory mem, immNKlass src) 10868 %{ 10869 match(Set cr (CmpN src (LoadNKlass mem))); 10870 10871 format %{ "cmpl $mem, $src\t# compressed klass ptr" %} 10872 ins_encode %{ 10873 __ cmp_narrow_klass($mem$$Address, (Klass*)$src$$constant); 10874 %} 10875 ins_pipe(ialu_cr_reg_mem); 10876 %} 10877 10878 instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ 10879 match(Set cr (CmpN src zero)); 10880 10881 format %{ "testl $src, $src\t# compressed ptr" %} 10882 ins_encode %{ __ testl($src$$Register, $src$$Register); %} 10883 ins_pipe(ialu_cr_reg_imm); 10884 %} 10885 10886 instruct testN_mem(rFlagsReg cr, memory mem, immN0 zero) 10887 %{ 10888 predicate(Universe::narrow_oop_base() != NULL); 10889 match(Set cr (CmpN (LoadN mem) zero)); 10890 10891 ins_cost(500); // XXX 10892 format %{ "testl $mem, 0xffffffff\t# compressed ptr" %} 10893 ins_encode %{ 10894 __ cmpl($mem$$Address, (int)0xFFFFFFFF); 10895 %} 10896 ins_pipe(ialu_cr_reg_mem); 10897 %} 10898 10899 instruct testN_mem_reg0(rFlagsReg cr, memory mem, immN0 zero) 10900 %{ 10901 predicate(Universe::narrow_oop_base() == NULL && (Universe::narrow_klass_base() == NULL)); 10902 match(Set cr (CmpN (LoadN mem) zero)); 10903 10904 format %{ "cmpl R12, $mem\t# compressed ptr (R12_heapbase==0)" %} 10905 ins_encode %{ 10906 __ cmpl(r12, $mem$$Address); 10907 %} 10908 ins_pipe(ialu_cr_reg_mem); 10909 %} 10910 10911 // Yanked all unsigned pointer compare operations. 10912 // Pointer compares are done with CmpP which is already unsigned. 10913 10914 instruct compL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) 10915 %{ 10916 match(Set cr (CmpL op1 op2)); 10917 10918 format %{ "cmpq $op1, $op2" %} 10919 opcode(0x3B); /* Opcode 3B /r */ 10920 ins_encode(REX_reg_reg_wide(op1, op2), OpcP, reg_reg(op1, op2)); 10921 ins_pipe(ialu_cr_reg_reg); 10922 %} 10923 10924 instruct compL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) 10925 %{ 10926 match(Set cr (CmpL op1 op2)); 10927 10928 format %{ "cmpq $op1, $op2" %} 10929 opcode(0x81, 0x07); /* Opcode 81 /7 */ 10930 ins_encode(OpcSErm_wide(op1, op2), Con8or32(op2)); 10931 ins_pipe(ialu_cr_reg_imm); 10932 %} 10933 10934 instruct compL_rReg_mem(rFlagsReg cr, rRegL op1, memory op2) 10935 %{ 10936 match(Set cr (CmpL op1 (LoadL op2))); 10937 10938 format %{ "cmpq $op1, $op2" %} 10939 opcode(0x3B); /* Opcode 3B /r */ 10940 ins_encode(REX_reg_mem_wide(op1, op2), OpcP, reg_mem(op1, op2)); 10941 ins_pipe(ialu_cr_reg_mem); 10942 %} 10943 10944 instruct testL_reg(rFlagsReg cr, rRegL src, immL0 zero) 10945 %{ 10946 match(Set cr (CmpL src zero)); 10947 10948 format %{ "testq $src, $src" %} 10949 opcode(0x85); 10950 ins_encode(REX_reg_reg_wide(src, src), OpcP, reg_reg(src, src)); 10951 ins_pipe(ialu_cr_reg_imm); 10952 %} 10953 10954 instruct testL_reg_imm(rFlagsReg cr, rRegL src, immL32 con, immL0 zero) 10955 %{ 10956 match(Set cr (CmpL (AndL src con) zero)); 10957 10958 format %{ "testq $src, $con\t# long" %} 10959 opcode(0xF7, 0x00); 10960 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src), Con32(con)); 10961 ins_pipe(ialu_cr_reg_imm); 10962 %} 10963 10964 instruct testL_reg_mem(rFlagsReg cr, rRegL src, memory mem, immL0 zero) 10965 %{ 10966 match(Set cr (CmpL (AndL src (LoadL mem)) zero)); 10967 10968 format %{ "testq $src, $mem" %} 10969 opcode(0x85); 10970 ins_encode(REX_reg_mem_wide(src, mem), OpcP, reg_mem(src, mem)); 10971 ins_pipe(ialu_cr_reg_mem); 10972 %} 10973 10974 // Manifest a CmpL result in an integer register. Very painful. 10975 // This is the test to avoid. 10976 instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags) 10977 %{ 10978 match(Set dst (CmpL3 src1 src2)); 10979 effect(KILL flags); 10980 10981 ins_cost(275); // XXX 10982 format %{ "cmpq $src1, $src2\t# CmpL3\n\t" 10983 "movl $dst, -1\n\t" 10984 "jl,s done\n\t" 10985 "setne $dst\n\t" 10986 "movzbl $dst, $dst\n\t" 10987 "done:" %} 10988 ins_encode(cmpl3_flag(src1, src2, dst)); 10989 ins_pipe(pipe_slow); 10990 %} 10991 10992 //----------Max and Min-------------------------------------------------------- 10993 // Min Instructions 10994 10995 instruct cmovI_reg_g(rRegI dst, rRegI src, rFlagsReg cr) 10996 %{ 10997 effect(USE_DEF dst, USE src, USE cr); 10998 10999 format %{ "cmovlgt $dst, $src\t# min" %} 11000 opcode(0x0F, 0x4F); 11001 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11002 ins_pipe(pipe_cmov_reg); 11003 %} 11004 11005 11006 instruct minI_rReg(rRegI dst, rRegI src) 11007 %{ 11008 match(Set dst (MinI dst src)); 11009 11010 ins_cost(200); 11011 expand %{ 11012 rFlagsReg cr; 11013 compI_rReg(cr, dst, src); 11014 cmovI_reg_g(dst, src, cr); 11015 %} 11016 %} 11017 11018 instruct cmovI_reg_l(rRegI dst, rRegI src, rFlagsReg cr) 11019 %{ 11020 effect(USE_DEF dst, USE src, USE cr); 11021 11022 format %{ "cmovllt $dst, $src\t# max" %} 11023 opcode(0x0F, 0x4C); 11024 ins_encode(REX_reg_reg(dst, src), OpcP, OpcS, reg_reg(dst, src)); 11025 ins_pipe(pipe_cmov_reg); 11026 %} 11027 11028 11029 instruct maxI_rReg(rRegI dst, rRegI src) 11030 %{ 11031 match(Set dst (MaxI dst src)); 11032 11033 ins_cost(200); 11034 expand %{ 11035 rFlagsReg cr; 11036 compI_rReg(cr, dst, src); 11037 cmovI_reg_l(dst, src, cr); 11038 %} 11039 %} 11040 11041 // ============================================================================ 11042 // Branch Instructions 11043 11044 // Jump Direct - Label defines a relative address from JMP+1 11045 instruct jmpDir(label labl) 11046 %{ 11047 match(Goto); 11048 effect(USE labl); 11049 11050 ins_cost(300); 11051 format %{ "jmp $labl" %} 11052 size(5); 11053 ins_encode %{ 11054 Label* L = $labl$$label; 11055 __ jmp(*L, false); // Always long jump 11056 %} 11057 ins_pipe(pipe_jmp); 11058 %} 11059 11060 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11061 instruct jmpCon(cmpOp cop, rFlagsReg cr, label labl) 11062 %{ 11063 match(If cop cr); 11064 effect(USE labl); 11065 11066 ins_cost(300); 11067 format %{ "j$cop $labl" %} 11068 size(6); 11069 ins_encode %{ 11070 Label* L = $labl$$label; 11071 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11072 %} 11073 ins_pipe(pipe_jcc); 11074 %} 11075 11076 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11077 instruct jmpLoopEnd(cmpOp cop, rFlagsReg cr, label labl) 11078 %{ 11079 match(CountedLoopEnd cop cr); 11080 effect(USE labl); 11081 11082 ins_cost(300); 11083 format %{ "j$cop $labl\t# loop end" %} 11084 size(6); 11085 ins_encode %{ 11086 Label* L = $labl$$label; 11087 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11088 %} 11089 ins_pipe(pipe_jcc); 11090 %} 11091 11092 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11093 instruct jmpLoopEndU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11094 match(CountedLoopEnd cop cmp); 11095 effect(USE labl); 11096 11097 ins_cost(300); 11098 format %{ "j$cop,u $labl\t# loop end" %} 11099 size(6); 11100 ins_encode %{ 11101 Label* L = $labl$$label; 11102 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11103 %} 11104 ins_pipe(pipe_jcc); 11105 %} 11106 11107 instruct jmpLoopEndUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11108 match(CountedLoopEnd cop cmp); 11109 effect(USE labl); 11110 11111 ins_cost(200); 11112 format %{ "j$cop,u $labl\t# loop end" %} 11113 size(6); 11114 ins_encode %{ 11115 Label* L = $labl$$label; 11116 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11117 %} 11118 ins_pipe(pipe_jcc); 11119 %} 11120 11121 // Jump Direct Conditional - using unsigned comparison 11122 instruct jmpConU(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11123 match(If cop cmp); 11124 effect(USE labl); 11125 11126 ins_cost(300); 11127 format %{ "j$cop,u $labl" %} 11128 size(6); 11129 ins_encode %{ 11130 Label* L = $labl$$label; 11131 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11132 %} 11133 ins_pipe(pipe_jcc); 11134 %} 11135 11136 instruct jmpConUCF(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11137 match(If cop cmp); 11138 effect(USE labl); 11139 11140 ins_cost(200); 11141 format %{ "j$cop,u $labl" %} 11142 size(6); 11143 ins_encode %{ 11144 Label* L = $labl$$label; 11145 __ jcc((Assembler::Condition)($cop$$cmpcode), *L, false); // Always long jump 11146 %} 11147 ins_pipe(pipe_jcc); 11148 %} 11149 11150 instruct jmpConUCF2(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11151 match(If cop cmp); 11152 effect(USE labl); 11153 11154 ins_cost(200); 11155 format %{ $$template 11156 if ($cop$$cmpcode == Assembler::notEqual) { 11157 $$emit$$"jp,u $labl\n\t" 11158 $$emit$$"j$cop,u $labl" 11159 } else { 11160 $$emit$$"jp,u done\n\t" 11161 $$emit$$"j$cop,u $labl\n\t" 11162 $$emit$$"done:" 11163 } 11164 %} 11165 ins_encode %{ 11166 Label* l = $labl$$label; 11167 if ($cop$$cmpcode == Assembler::notEqual) { 11168 __ jcc(Assembler::parity, *l, false); 11169 __ jcc(Assembler::notEqual, *l, false); 11170 } else if ($cop$$cmpcode == Assembler::equal) { 11171 Label done; 11172 __ jccb(Assembler::parity, done); 11173 __ jcc(Assembler::equal, *l, false); 11174 __ bind(done); 11175 } else { 11176 ShouldNotReachHere(); 11177 } 11178 %} 11179 ins_pipe(pipe_jcc); 11180 %} 11181 11182 // ============================================================================ 11183 // The 2nd slow-half of a subtype check. Scan the subklass's 2ndary 11184 // superklass array for an instance of the superklass. Set a hidden 11185 // internal cache on a hit (cache is checked with exposed code in 11186 // gen_subtype_check()). Return NZ for a miss or zero for a hit. The 11187 // encoding ALSO sets flags. 11188 11189 instruct partialSubtypeCheck(rdi_RegP result, 11190 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11191 rFlagsReg cr) 11192 %{ 11193 match(Set result (PartialSubtypeCheck sub super)); 11194 effect(KILL rcx, KILL cr); 11195 11196 ins_cost(1100); // slightly larger than the next version 11197 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11198 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11199 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11200 "repne scasq\t# Scan *rdi++ for a match with rax while rcx--\n\t" 11201 "jne,s miss\t\t# Missed: rdi not-zero\n\t" 11202 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11203 "xorq $result, $result\t\t Hit: rdi zero\n\t" 11204 "miss:\t" %} 11205 11206 opcode(0x1); // Force a XOR of RDI 11207 ins_encode(enc_PartialSubtypeCheck()); 11208 ins_pipe(pipe_slow); 11209 %} 11210 11211 instruct partialSubtypeCheck_vs_Zero(rFlagsReg cr, 11212 rsi_RegP sub, rax_RegP super, rcx_RegI rcx, 11213 immP0 zero, 11214 rdi_RegP result) 11215 %{ 11216 match(Set cr (CmpP (PartialSubtypeCheck sub super) zero)); 11217 effect(KILL rcx, KILL result); 11218 11219 ins_cost(1000); 11220 format %{ "movq rdi, [$sub + in_bytes(Klass::secondary_supers_offset())]\n\t" 11221 "movl rcx, [rdi + Array<Klass*>::length_offset_in_bytes()]\t# length to scan\n\t" 11222 "addq rdi, Array<Klass*>::base_offset_in_bytes()\t# Skip to start of data; set NZ in case count is zero\n\t" 11223 "repne scasq\t# Scan *rdi++ for a match with rax while cx-- != 0\n\t" 11224 "jne,s miss\t\t# Missed: flags nz\n\t" 11225 "movq [$sub + in_bytes(Klass::secondary_super_cache_offset())], $super\t# Hit: update cache\n\t" 11226 "miss:\t" %} 11227 11228 opcode(0x0); // No need to XOR RDI 11229 ins_encode(enc_PartialSubtypeCheck()); 11230 ins_pipe(pipe_slow); 11231 %} 11232 11233 // ============================================================================ 11234 // Branch Instructions -- short offset versions 11235 // 11236 // These instructions are used to replace jumps of a long offset (the default 11237 // match) with jumps of a shorter offset. These instructions are all tagged 11238 // with the ins_short_branch attribute, which causes the ADLC to suppress the 11239 // match rules in general matching. Instead, the ADLC generates a conversion 11240 // method in the MachNode which can be used to do in-place replacement of the 11241 // long variant with the shorter variant. The compiler will determine if a 11242 // branch can be taken by the is_short_branch_offset() predicate in the machine 11243 // specific code section of the file. 11244 11245 // Jump Direct - Label defines a relative address from JMP+1 11246 instruct jmpDir_short(label labl) %{ 11247 match(Goto); 11248 effect(USE labl); 11249 11250 ins_cost(300); 11251 format %{ "jmp,s $labl" %} 11252 size(2); 11253 ins_encode %{ 11254 Label* L = $labl$$label; 11255 __ jmpb(*L); 11256 %} 11257 ins_pipe(pipe_jmp); 11258 ins_short_branch(1); 11259 %} 11260 11261 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11262 instruct jmpCon_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11263 match(If cop cr); 11264 effect(USE labl); 11265 11266 ins_cost(300); 11267 format %{ "j$cop,s $labl" %} 11268 size(2); 11269 ins_encode %{ 11270 Label* L = $labl$$label; 11271 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11272 %} 11273 ins_pipe(pipe_jcc); 11274 ins_short_branch(1); 11275 %} 11276 11277 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11278 instruct jmpLoopEnd_short(cmpOp cop, rFlagsReg cr, label labl) %{ 11279 match(CountedLoopEnd cop cr); 11280 effect(USE labl); 11281 11282 ins_cost(300); 11283 format %{ "j$cop,s $labl\t# loop end" %} 11284 size(2); 11285 ins_encode %{ 11286 Label* L = $labl$$label; 11287 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11288 %} 11289 ins_pipe(pipe_jcc); 11290 ins_short_branch(1); 11291 %} 11292 11293 // Jump Direct Conditional - Label defines a relative address from Jcc+1 11294 instruct jmpLoopEndU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11295 match(CountedLoopEnd cop cmp); 11296 effect(USE labl); 11297 11298 ins_cost(300); 11299 format %{ "j$cop,us $labl\t# loop end" %} 11300 size(2); 11301 ins_encode %{ 11302 Label* L = $labl$$label; 11303 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11304 %} 11305 ins_pipe(pipe_jcc); 11306 ins_short_branch(1); 11307 %} 11308 11309 instruct jmpLoopEndUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11310 match(CountedLoopEnd cop cmp); 11311 effect(USE labl); 11312 11313 ins_cost(300); 11314 format %{ "j$cop,us $labl\t# loop end" %} 11315 size(2); 11316 ins_encode %{ 11317 Label* L = $labl$$label; 11318 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11319 %} 11320 ins_pipe(pipe_jcc); 11321 ins_short_branch(1); 11322 %} 11323 11324 // Jump Direct Conditional - using unsigned comparison 11325 instruct jmpConU_short(cmpOpU cop, rFlagsRegU cmp, label labl) %{ 11326 match(If cop cmp); 11327 effect(USE labl); 11328 11329 ins_cost(300); 11330 format %{ "j$cop,us $labl" %} 11331 size(2); 11332 ins_encode %{ 11333 Label* L = $labl$$label; 11334 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11335 %} 11336 ins_pipe(pipe_jcc); 11337 ins_short_branch(1); 11338 %} 11339 11340 instruct jmpConUCF_short(cmpOpUCF cop, rFlagsRegUCF cmp, label labl) %{ 11341 match(If cop cmp); 11342 effect(USE labl); 11343 11344 ins_cost(300); 11345 format %{ "j$cop,us $labl" %} 11346 size(2); 11347 ins_encode %{ 11348 Label* L = $labl$$label; 11349 __ jccb((Assembler::Condition)($cop$$cmpcode), *L); 11350 %} 11351 ins_pipe(pipe_jcc); 11352 ins_short_branch(1); 11353 %} 11354 11355 instruct jmpConUCF2_short(cmpOpUCF2 cop, rFlagsRegUCF cmp, label labl) %{ 11356 match(If cop cmp); 11357 effect(USE labl); 11358 11359 ins_cost(300); 11360 format %{ $$template 11361 if ($cop$$cmpcode == Assembler::notEqual) { 11362 $$emit$$"jp,u,s $labl\n\t" 11363 $$emit$$"j$cop,u,s $labl" 11364 } else { 11365 $$emit$$"jp,u,s done\n\t" 11366 $$emit$$"j$cop,u,s $labl\n\t" 11367 $$emit$$"done:" 11368 } 11369 %} 11370 size(4); 11371 ins_encode %{ 11372 Label* l = $labl$$label; 11373 if ($cop$$cmpcode == Assembler::notEqual) { 11374 __ jccb(Assembler::parity, *l); 11375 __ jccb(Assembler::notEqual, *l); 11376 } else if ($cop$$cmpcode == Assembler::equal) { 11377 Label done; 11378 __ jccb(Assembler::parity, done); 11379 __ jccb(Assembler::equal, *l); 11380 __ bind(done); 11381 } else { 11382 ShouldNotReachHere(); 11383 } 11384 %} 11385 ins_pipe(pipe_jcc); 11386 ins_short_branch(1); 11387 %} 11388 11389 // ============================================================================ 11390 // inlined locking and unlocking 11391 11392 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ 11393 match(Set cr (FastLock object box)); 11394 effect(TEMP tmp, TEMP scr, USE_KILL box); 11395 ins_cost(300); 11396 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} 11397 ins_encode %{ 11398 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register, _counters); 11399 %} 11400 ins_pipe(pipe_slow); 11401 %} 11402 11403 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ 11404 match(Set cr (FastUnlock object box)); 11405 effect(TEMP tmp, USE_KILL box); 11406 ins_cost(300); 11407 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} 11408 ins_encode %{ 11409 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); 11410 %} 11411 ins_pipe(pipe_slow); 11412 %} 11413 11414 11415 // ============================================================================ 11416 // Safepoint Instructions 11417 instruct safePoint_poll(rFlagsReg cr) 11418 %{ 11419 predicate(!Assembler::is_polling_page_far()); 11420 match(SafePoint); 11421 effect(KILL cr); 11422 11423 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 11424 "# Safepoint: poll for GC" %} 11425 ins_cost(125); 11426 ins_encode %{ 11427 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type); 11428 __ testl(rax, addr); 11429 %} 11430 ins_pipe(ialu_reg_mem); 11431 %} 11432 11433 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll) 11434 %{ 11435 predicate(Assembler::is_polling_page_far()); 11436 match(SafePoint poll); 11437 effect(KILL cr, USE poll); 11438 11439 format %{ "testl rax, [$poll]\t" 11440 "# Safepoint: poll for GC" %} 11441 ins_cost(125); 11442 ins_encode %{ 11443 __ relocate(relocInfo::poll_type); 11444 __ testl(rax, Address($poll$$Register, 0)); 11445 %} 11446 ins_pipe(ialu_reg_mem); 11447 %} 11448 11449 // ============================================================================ 11450 // Procedure Call/Return Instructions 11451 // Call Java Static Instruction 11452 // Note: If this code changes, the corresponding ret_addr_offset() and 11453 // compute_padding() functions will have to be adjusted. 11454 instruct CallStaticJavaDirect(method meth) %{ 11455 match(CallStaticJava); 11456 predicate(!((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11457 effect(USE meth); 11458 11459 ins_cost(300); 11460 format %{ "call,static " %} 11461 opcode(0xE8); /* E8 cd */ 11462 ins_encode(clear_avx, Java_Static_Call(meth), call_epilog); 11463 ins_pipe(pipe_slow); 11464 ins_alignment(4); 11465 %} 11466 11467 // Call Java Static Instruction (method handle version) 11468 // Note: If this code changes, the corresponding ret_addr_offset() and 11469 // compute_padding() functions will have to be adjusted. 11470 instruct CallStaticJavaHandle(method meth, rbp_RegP rbp_mh_SP_save) %{ 11471 match(CallStaticJava); 11472 predicate(((CallStaticJavaNode*) n)->is_method_handle_invoke()); 11473 effect(USE meth); 11474 // RBP is saved by all callees (for interpreter stack correction). 11475 // We use it here for a similar purpose, in {preserve,restore}_SP. 11476 11477 ins_cost(300); 11478 format %{ "call,static/MethodHandle " %} 11479 opcode(0xE8); /* E8 cd */ 11480 ins_encode(clear_avx, preserve_SP, 11481 Java_Static_Call(meth), 11482 restore_SP, 11483 call_epilog); 11484 ins_pipe(pipe_slow); 11485 ins_alignment(4); 11486 %} 11487 11488 // Call Java Dynamic Instruction 11489 // Note: If this code changes, the corresponding ret_addr_offset() and 11490 // compute_padding() functions will have to be adjusted. 11491 instruct CallDynamicJavaDirect(method meth) 11492 %{ 11493 match(CallDynamicJava); 11494 effect(USE meth); 11495 11496 ins_cost(300); 11497 format %{ "movq rax, #Universe::non_oop_word()\n\t" 11498 "call,dynamic " %} 11499 ins_encode(clear_avx, Java_Dynamic_Call(meth), call_epilog); 11500 ins_pipe(pipe_slow); 11501 ins_alignment(4); 11502 %} 11503 11504 // Call Runtime Instruction 11505 instruct CallRuntimeDirect(method meth) 11506 %{ 11507 match(CallRuntime); 11508 effect(USE meth); 11509 11510 ins_cost(300); 11511 format %{ "call,runtime " %} 11512 ins_encode(clear_avx, Java_To_Runtime(meth)); 11513 ins_pipe(pipe_slow); 11514 %} 11515 11516 // Call runtime without safepoint 11517 instruct CallLeafDirect(method meth) 11518 %{ 11519 match(CallLeaf); 11520 effect(USE meth); 11521 11522 ins_cost(300); 11523 format %{ "call_leaf,runtime " %} 11524 ins_encode(clear_avx, Java_To_Runtime(meth)); 11525 ins_pipe(pipe_slow); 11526 %} 11527 11528 // Call runtime without safepoint 11529 instruct CallLeafNoFPDirect(method meth) 11530 %{ 11531 match(CallLeafNoFP); 11532 effect(USE meth); 11533 11534 ins_cost(300); 11535 format %{ "call_leaf_nofp,runtime " %} 11536 ins_encode(Java_To_Runtime(meth)); 11537 ins_pipe(pipe_slow); 11538 %} 11539 11540 // Return Instruction 11541 // Remove the return address & jump to it. 11542 // Notice: We always emit a nop after a ret to make sure there is room 11543 // for safepoint patching 11544 instruct Ret() 11545 %{ 11546 match(Return); 11547 11548 format %{ "ret" %} 11549 opcode(0xC3); 11550 ins_encode(OpcP); 11551 ins_pipe(pipe_jmp); 11552 %} 11553 11554 // Tail Call; Jump from runtime stub to Java code. 11555 // Also known as an 'interprocedural jump'. 11556 // Target of jump will eventually return to caller. 11557 // TailJump below removes the return address. 11558 instruct TailCalljmpInd(no_rbp_RegP jump_target, rbx_RegP method_oop) 11559 %{ 11560 match(TailCall jump_target method_oop); 11561 11562 ins_cost(300); 11563 format %{ "jmp $jump_target\t# rbx holds method oop" %} 11564 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11565 ins_encode(REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11566 ins_pipe(pipe_jmp); 11567 %} 11568 11569 // Tail Jump; remove the return address; jump to target. 11570 // TailCall above leaves the return address around. 11571 instruct tailjmpInd(no_rbp_RegP jump_target, rax_RegP ex_oop) 11572 %{ 11573 match(TailJump jump_target ex_oop); 11574 11575 ins_cost(300); 11576 format %{ "popq rdx\t# pop return address\n\t" 11577 "jmp $jump_target" %} 11578 opcode(0xFF, 0x4); /* Opcode FF /4 */ 11579 ins_encode(Opcode(0x5a), // popq rdx 11580 REX_reg(jump_target), OpcP, reg_opc(jump_target)); 11581 ins_pipe(pipe_jmp); 11582 %} 11583 11584 // Create exception oop: created by stack-crawling runtime code. 11585 // Created exception is now available to this handler, and is setup 11586 // just prior to jumping to this handler. No code emitted. 11587 instruct CreateException(rax_RegP ex_oop) 11588 %{ 11589 match(Set ex_oop (CreateEx)); 11590 11591 size(0); 11592 // use the following format syntax 11593 format %{ "# exception oop is in rax; no code emitted" %} 11594 ins_encode(); 11595 ins_pipe(empty); 11596 %} 11597 11598 // Rethrow exception: 11599 // The exception oop will come in the first argument position. 11600 // Then JUMP (not call) to the rethrow stub code. 11601 instruct RethrowException() 11602 %{ 11603 match(Rethrow); 11604 11605 // use the following format syntax 11606 format %{ "jmp rethrow_stub" %} 11607 ins_encode(enc_rethrow); 11608 ins_pipe(pipe_jmp); 11609 %} 11610 11611 11612 // ============================================================================ 11613 // This name is KNOWN by the ADLC and cannot be changed. 11614 // The ADLC forces a 'TypeRawPtr::BOTTOM' output type 11615 // for this guy. 11616 instruct tlsLoadP(r15_RegP dst) %{ 11617 match(Set dst (ThreadLocal)); 11618 effect(DEF dst); 11619 11620 size(0); 11621 format %{ "# TLS is in R15" %} 11622 ins_encode( /*empty encoding*/ ); 11623 ins_pipe(ialu_reg_reg); 11624 %} 11625 11626 11627 //----------PEEPHOLE RULES----------------------------------------------------- 11628 // These must follow all instruction definitions as they use the names 11629 // defined in the instructions definitions. 11630 // 11631 // peepmatch ( root_instr_name [preceding_instruction]* ); 11632 // 11633 // peepconstraint %{ 11634 // (instruction_number.operand_name relational_op instruction_number.operand_name 11635 // [, ...] ); 11636 // // instruction numbers are zero-based using left to right order in peepmatch 11637 // 11638 // peepreplace ( instr_name ( [instruction_number.operand_name]* ) ); 11639 // // provide an instruction_number.operand_name for each operand that appears 11640 // // in the replacement instruction's match rule 11641 // 11642 // ---------VM FLAGS--------------------------------------------------------- 11643 // 11644 // All peephole optimizations can be turned off using -XX:-OptoPeephole 11645 // 11646 // Each peephole rule is given an identifying number starting with zero and 11647 // increasing by one in the order seen by the parser. An individual peephole 11648 // can be enabled, and all others disabled, by using -XX:OptoPeepholeAt=# 11649 // on the command-line. 11650 // 11651 // ---------CURRENT LIMITATIONS---------------------------------------------- 11652 // 11653 // Only match adjacent instructions in same basic block 11654 // Only equality constraints 11655 // Only constraints between operands, not (0.dest_reg == RAX_enc) 11656 // Only one replacement instruction 11657 // 11658 // ---------EXAMPLE---------------------------------------------------------- 11659 // 11660 // // pertinent parts of existing instructions in architecture description 11661 // instruct movI(rRegI dst, rRegI src) 11662 // %{ 11663 // match(Set dst (CopyI src)); 11664 // %} 11665 // 11666 // instruct incI_rReg(rRegI dst, immI1 src, rFlagsReg cr) 11667 // %{ 11668 // match(Set dst (AddI dst src)); 11669 // effect(KILL cr); 11670 // %} 11671 // 11672 // // Change (inc mov) to lea 11673 // peephole %{ 11674 // // increment preceeded by register-register move 11675 // peepmatch ( incI_rReg movI ); 11676 // // require that the destination register of the increment 11677 // // match the destination register of the move 11678 // peepconstraint ( 0.dst == 1.dst ); 11679 // // construct a replacement instruction that sets 11680 // // the destination to ( move's source register + one ) 11681 // peepreplace ( leaI_rReg_immI( 0.dst 1.src 0.src ) ); 11682 // %} 11683 // 11684 11685 // Implementation no longer uses movX instructions since 11686 // machine-independent system no longer uses CopyX nodes. 11687 // 11688 // peephole 11689 // %{ 11690 // peepmatch (incI_rReg movI); 11691 // peepconstraint (0.dst == 1.dst); 11692 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11693 // %} 11694 11695 // peephole 11696 // %{ 11697 // peepmatch (decI_rReg movI); 11698 // peepconstraint (0.dst == 1.dst); 11699 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11700 // %} 11701 11702 // peephole 11703 // %{ 11704 // peepmatch (addI_rReg_imm movI); 11705 // peepconstraint (0.dst == 1.dst); 11706 // peepreplace (leaI_rReg_immI(0.dst 1.src 0.src)); 11707 // %} 11708 11709 // peephole 11710 // %{ 11711 // peepmatch (incL_rReg movL); 11712 // peepconstraint (0.dst == 1.dst); 11713 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11714 // %} 11715 11716 // peephole 11717 // %{ 11718 // peepmatch (decL_rReg movL); 11719 // peepconstraint (0.dst == 1.dst); 11720 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11721 // %} 11722 11723 // peephole 11724 // %{ 11725 // peepmatch (addL_rReg_imm movL); 11726 // peepconstraint (0.dst == 1.dst); 11727 // peepreplace (leaL_rReg_immL(0.dst 1.src 0.src)); 11728 // %} 11729 11730 // peephole 11731 // %{ 11732 // peepmatch (addP_rReg_imm movP); 11733 // peepconstraint (0.dst == 1.dst); 11734 // peepreplace (leaP_rReg_imm(0.dst 1.src 0.src)); 11735 // %} 11736 11737 // // Change load of spilled value to only a spill 11738 // instruct storeI(memory mem, rRegI src) 11739 // %{ 11740 // match(Set mem (StoreI mem src)); 11741 // %} 11742 // 11743 // instruct loadI(rRegI dst, memory mem) 11744 // %{ 11745 // match(Set dst (LoadI mem)); 11746 // %} 11747 // 11748 11749 peephole 11750 %{ 11751 peepmatch (loadI storeI); 11752 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11753 peepreplace (storeI(1.mem 1.mem 1.src)); 11754 %} 11755 11756 peephole 11757 %{ 11758 peepmatch (loadL storeL); 11759 peepconstraint (1.src == 0.dst, 1.mem == 0.mem); 11760 peepreplace (storeL(1.mem 1.mem 1.src)); 11761 %} 11762 11763 //----------SMARTSPILL RULES--------------------------------------------------- 11764 // These must follow all instruction definitions as they use the names 11765 // defined in the instructions definitions.